Automattic\WooCommerce\Internal\PushNotifications\DataStores

PushTokensDataStore::get_by_token_or_device_idpublicWC 10.5.0

Find tokens for this user and platform that match either the token or device UUID. We check the token value to avoid creating a duplicate. We check the device UUID value because only one token should be issued per device, therefore if we already have one then we can update it to avoid creating a duplicate.

Method of the class: PushTokensDataStore{}

No Hooks.

Returns

null|PushToken.

Usage

$PushTokensDataStore = new PushTokensDataStore();
$PushTokensDataStore->get_by_token_or_device_id( $data ): ?PushToken;
$data(array) (required)
Token data with keys: user_id, platform, origin, token (optional), device_uuid (optional).

Changelog

Since 10.5.0 Introduced.

PushTokensDataStore::get_by_token_or_device_id() code WC 10.8.1

public function get_by_token_or_device_id( array $data ): ?PushToken {
	$user_id     = $data['user_id'] ?? null;
	$platform    = $data['platform'] ?? null;
	$origin      = $data['origin'] ?? null;
	$token       = $data['token'] ?? null;
	$device_uuid = $data['device_uuid'] ?? null;

	if (
		! $user_id
		|| ! $platform
		|| ! $origin
		|| (
			/**
			 * Platforms iOS and Android require token OR device UUID.
			 */
			PushToken::PLATFORM_BROWSER !== $platform
			&& ! $token
			&& ! $device_uuid
		)
		|| (
			/**
			 * Browsers don't have device UUIDs, so require token.
			 */
			PushToken::PLATFORM_BROWSER === $platform
			&& ! $token
		)
	) {
		throw new PushTokenInvalidDataException(
			'Can\'t retrieve push token because the push token data provided is invalid.'
		);
	}

	$query = new WP_Query(
		array(
			'post_type'      => PushToken::POST_TYPE,
			'post_status'    => 'private',
			'author'         => $user_id,
			'posts_per_page' => -1,
			'orderby'        => 'ID',
			'order'          => 'DESC',
			'fields'         => 'ids',
		)
	);

	/**
	 * 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 ) ) {
		return null;
	}

	update_meta_cache( 'post', $post_ids );

	foreach ( $post_ids as $post_id ) {
		try {
			$meta = $this->build_meta_array_from_database( $post_id );
		} catch ( Exception $e ) {
			wc_get_logger()->warning(
				'Failed to load meta for push token.',
				array(
					'token_id' => $post_id,
					'error'    => $e->getMessage(),
				)
			);

			continue;
		}

		if (
			$meta['platform'] === $platform
			&& $meta['origin'] === $origin
			&& (
				( $token && $token === $meta['token'] )
				|| ( $device_uuid && $device_uuid === $meta['device_uuid'] )
			)
		) {
			return new PushToken(
				array(
					'id'            => $post_id,
					'user_id'       => $user_id,
					'token'         => $meta['token'],
					'device_uuid'   => $meta['device_uuid'] ?? null,
					'platform'      => $meta['platform'],
					'origin'        => $meta['origin'],
					/**
					 * These meta items were added after the ability to store
					 * tokens, so may not be available for older tokens. Use
					 * sensible defaults.
					 */
					'device_locale' => $meta['device_locale'] ?? PushToken::DEFAULT_DEVICE_LOCALE,
					'metadata'      => $meta['metadata'] ?? array(),
				)
			);
		}
	}

	return null;
}