array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function delete( $url, $options = [] ) {
return $this->do_request( 'DELETE', $url, $options );
}
/**
* Determines whether there are valid tokens available.
*
* @return bool Whether there are valid tokens.
*/
public function has_valid_tokens() {
return ! empty( $this->token ) && $this->token->has_expired() === false;
}
/**
* Gets the stored tokens and refreshes them if they've expired.
*
* @return OAuth_Token The stored tokens.
*
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function get_tokens() {
if ( empty( $this->token ) ) {
throw new Empty_Token_Exception();
}
if ( $this->token->has_expired() ) {
$this->token = $this->refresh_tokens( $this->token );
}
return $this->token;
}
/**
* Stores the passed token.
*
* @param OAuth_Token $token The token to store.
*
* @return OAuth_Token The stored token.
*
* @throws Failed_Storage_Exception Exception thrown if storing of the token fails.
*/
public function store_token( OAuth_Token $token ) {
$saved = $this->options_helper->set( $this->token_option, $token->to_array() );
if ( $saved === false ) {
throw new Failed_Storage_Exception();
}
return $token;
}
/**
* Clears the stored token from storage.
*
* @return bool The stored token.
*
* @throws Failed_Storage_Exception Exception thrown if clearing of the token fails.
*/
public function clear_token() {
$saved = $this->options_helper->set( $this->token_option, [] );
if ( $saved === false ) {
throw new Failed_Storage_Exception();
}
return true;
}
/**
* Performs the specified request.
*
* @param string $method The HTTP method to use.
* @param string $url The URL to send the request to.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
protected function do_request( $method, $url, array $options ) {
$defaults = [
'headers' => $this->provider->getHeaders( $this->get_tokens()->access_token ),
];
$options = \array_merge_recursive( $defaults, $options );
if ( \array_key_exists( 'params', $options ) ) {
$url .= '?' . \http_build_query( $options['params'] );
unset( $options['params'] );
}
$request = $this->provider
->getAuthenticatedRequest( $method, $url, null, $options );
return $this->provider->getParsedResponse( $request );
}
/**
* Refreshes the outdated tokens.
*
* @param OAuth_Token $tokens The outdated tokens.
*
* @return OAuth_Token The refreshed tokens.
*
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
*/
protected function refresh_tokens( OAuth_Token $tokens ) {
// We do this dance with transients since we need to make sure we don't
// delete valid tokens because of a race condition when two calls are
// made simultaneously to this function and refresh token rotation is
// turned on in the OAuth server. This is not 100% safe, but should at
// least be much better than not having any lock at all.
$lock_name = \sprintf( 'lock:%s', $this->token_option );
$can_lock = \get_transient( $lock_name ) === false;
$has_lock = $can_lock && \set_transient( $lock_name, true, 30 );
try {
$new_tokens = $this->provider->getAccessToken(
'refresh_token',
[
'refresh_token' => $tokens->refresh_token,
]
);
$token_obj = OAuth_Token::from_response( $new_tokens );
return $this->store_token( $token_obj );
} catch ( Exception $exception ) {
// If we tried to refresh but the refresh token is invalid, delete
// the tokens so that we don't try again. Only do this if we got the
// lock at the beginning of the call.
if ( $has_lock && $exception->getMessage() === 'invalid_grant' ) {
try {
// To protect from race conditions, only do this if we've
// seen an error before with the same token.
if ( $tokens->error_count >= 1 ) {
$this->clear_token();
}
else {
$tokens->error_count += 1;
$this->store_token( $tokens );
}
} catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
// Pass through.
}
}
throw new Authentication_Failed_Exception( $exception );
} finally {
\delete_transient( $lock_name );
}
}
}
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/despertacidade.com/web/wp-content/plugins/wordpress-seo/src/config/oauth-client.php:1) in /var/www/html/despertacidade.com/web/wp-includes/rest-api/class-wp-rest-server.php on line 1794
{"version":"1.0","provider_name":"Desperta Cidade - Portal de not\u00edcias de Feira de Santana - Bahia","provider_url":"https:\/\/despertacidade.com","author_name":"Ag\u00eancia Brasil","author_url":"https:\/\/despertacidade.com\/author\/agenciabrasil\/","title":"Salvador, Curitiba e Goi\u00e2nia recebem sinal 5G - Desperta Cidade - Portal de not\u00edcias de Feira de Santana - Bahia","type":"rich","width":600,"height":338,"html":"
Salvador, Curitiba e Goi\u00e2nia recebem sinal 5G<\/a><\/blockquote>