Automattic\WooCommerce\Internal\PushNotifications\DataStores
PushTokensDataStore::get_tokens_for_roles │ public │ WC 10.7.0 Returns push tokens belonging to users with the given roles.
When called without pagination parameters, returns all tokens as a flat array (cached per-request). When $page and $per_page are provided, returns a paginated result with total counts.
The eligible-user lookup is restricted to users that actually own push tokens, so the role check runs against a handful of IDs instead of scanning every user's capabilities meta, which does not scale on sites with very large user tables.
Method of the class: PushTokensDataStore{}
No Hooks.
Returns
PushToken[]|Array{tokens:. PushToken[], total: int, total_pages: int}
Usage
$PushTokensDataStore = new PushTokensDataStore();
$PushTokensDataStore->get_tokens_for_roles( $roles, ?int $page, ?int $per_page );
$roles(string[]) (required)
The roles to query tokens for.
?int $page
.
Default: null
?int $per_page
.
Default: null
Changelog
PushTokensDataStore::get_tokens_for_roles() PushTokensDataStore::get tokens for roles code
WC 11.0.1
public function get_tokens_for_roles( array $roles, ?int $page = null, ?int $per_page = null ) {
$paginate = null !== $page && null !== $per_page;
$cache_key = $paginate ? implode( ',', $roles ) . ":$page:$per_page" : implode( ',', $roles );
$empty_result = $paginate
? array(
'tokens' => array(),
'total' => 0,
'total_pages' => 0,
)
: array();
if ( empty( $roles ) ) {
return $empty_result;
}
if ( isset( $this->tokens_by_roles_cache[ $cache_key ] ) ) {
return $this->tokens_by_roles_cache[ $cache_key ];
}
global $wpdb;
// Exactly this SQL to leverage the wp_posts type_status_author index; low token cardinality keeps it fast at any store size.
$users_with_tokens = $wpdb->get_col(
$wpdb->prepare(
"SELECT DISTINCT post_author FROM {$wpdb->posts} WHERE post_type = %s AND post_status = 'private'",
PushToken::POST_TYPE
)
);
// An empty include must short-circuit: WP_User_Query would ignore it and scan all users by role.
$user_ids = empty( $users_with_tokens ) ? array() : get_users(
array(
'role__in' => $roles,
'fields' => 'ID',
'include' => $users_with_tokens,
)
);
if ( empty( $user_ids ) ) {
$this->tokens_by_roles_cache[ $cache_key ] = $empty_result;
return $this->tokens_by_roles_cache[ $cache_key ];
}
$query_args = array(
'post_type' => PushToken::POST_TYPE,
'post_status' => 'private',
'author__in' => $user_ids,
'posts_per_page' => $paginate ? $per_page : -1,
'fields' => 'ids',
);
if ( $paginate ) {
$query_args['paged'] = $page;
$query_args['orderby'] = 'ID';
$query_args['order'] = 'ASC';
}
$query = new WP_Query( $query_args );
/**
* Typehint for PHPStan, specifies these are IDs and not instances of
* WP_Post.
*
* @var int[] $post_ids
*/
$post_ids = $query->posts;
if ( empty( $post_ids ) ) {
$this->tokens_by_roles_cache[ $cache_key ] = $empty_result;
return $this->tokens_by_roles_cache[ $cache_key ];
}
_prime_post_caches( $post_ids, false, true );
$tokens = array();
foreach ( $post_ids as $post_id ) {
try {
$tokens[] = $this->read( (int) $post_id );
} catch ( WC_Data_Exception $e ) {
wc_get_logger()->warning(
'Skipping malformed push token during role-based query.',
array(
'token_id' => $post_id,
'error' => $e->getMessage(),
)
);
}
}
$result = $paginate
? array(
'tokens' => $tokens,
'total' => (int) $query->found_posts,
'total_pages' => (int) $query->max_num_pages,
)
: $tokens;
$this->tokens_by_roles_cache[ $cache_key ] = $result;
return $result;
}