Yoast\WP\SEO\MyYoast_Client\Application

MyYoast_Client::get_user_tokenpublicYoast 1.0

Returns a valid user-level access token, auto-refreshing if expired.

Метод класса: MyYoast_Client{}

Хуков нет.

Возвращает

Token_Set|null. The user token set, or null if the user hasn't authorized.

Использование

$MyYoast_Client = new MyYoast_Client();
$MyYoast_Client->get_user_token( $user_id, $required_scopes ): ?Token_Set;
$user_id(int) (обязательный)
The WordPress user ID.
$required_scopes(string[])
Optional scopes required for the token; if provided, no token will be returned unless it has at least these scopes. This is to avoid refreshing a token that would trigger an immediate re-authorization due to missing scopes.
По умолчанию: []

Код MyYoast_Client::get_user_token() Yoast 27.7

public function get_user_token( int $user_id, array $required_scopes = [] ): ?Token_Set {
	$token_set = $this->user_token_storage->get( $user_id );
	if ( $token_set === null ) {
		return null;
	}

	if ( ! $token_set->has_scopes( $required_scopes ) ) {
		// Required scopes are missing, treat as if no token is available.
		return null;
	}

	if ( ! $token_set->is_expired() ) {
		return $token_set;
	}

	$refresh_token = $token_set->get_refresh_token();
	if ( $refresh_token === null ) {
		return null;
	}

	try {
		// If the client was just re-registered, this refresh will fail with invalid_grant.
		// error_count is 0 on first attempt; after one invalid_grant it becomes 1.
		// On the second consecutive invalid_grant (error_count >= 1), clear and give up.
		$grant         = new Refresh_Token_Grant( $refresh_token );
		$lock_key      = 'wpseo_myyoast_refresh:' . \hash( 'sha256', $refresh_token );
		$new_token_set = $this->lock_helper->execute(
			$lock_key,
			function () use ( $grant ) {
				return $this->grant_handler->request_token( $grant );
			},
			self::REFRESH_LOCK_TTL_IN_SECONDS,
		);
		try {
			$this->user_token_storage->store( $user_id, $new_token_set );
		} catch ( Token_Storage_Exception $e ) {
			// Next request will re-refresh from the old stored token.
			$this->logger->warning( 'Failed to persist refreshed token: {error}', [ 'error' => $e->getMessage() ] );
		}
		return $new_token_set;
	} catch ( Lock_Timeout_Exception $e ) {
		// Concurrent refresh in progress, treat as transient failure.
		$this->logger->debug( 'Skipping token refresh for user {user_id}: concurrent refresh in progress.', [ 'user_id' => $user_id ] );
		return null;
	} catch ( Token_Request_Failed_Exception $e ) {
		if ( $e->get_error_code() === 'invalid_grant' ) {
			if ( $token_set->get_error_count() >= 1 ) {
				$this->logger->warning( 'Repeated invalid_grant for user {user_id}, clearing stored tokens.', [ 'user_id' => $user_id ] );
				$this->user_token_storage->delete( $user_id );
				return null;
			}

			try {
				$this->user_token_storage->store( $user_id, $token_set->with_incremented_error_count() );
			} catch ( Token_Storage_Exception $e ) {
				// Failure to persist error count is non-critical; token will be retried next request.
				$this->logger->warning( 'Failed to persist token error count: {error}', [ 'error' => $e->getMessage() ] );
			}
		}

		return null;
	}
}