File: //home/globfdxw/www/wp-content/plugins/wpforms-google-calendar/src/Api/Client.php
<?php
namespace WPFormsGoogleCalendar\Api;
use InvalidArgumentException;
use WPFormsGoogleCalendar\Plugin;
use WPFormsGoogleCalendar\Api\Http\Request;
/**
* Client class.
*
* @since 1.0.0
*/
class Client {
/**
* Google Calendar API URL.
*
* @since 1.0.0
*
* @var string
*/
private const API_URL = 'https://www.googleapis.com/calendar/v3/';
/**
* WPForms website URL.
*
* @since 1.0.0
*
* @var string
*/
private const MIDDLEWARE_URL = 'https://wpforms.com/oauth/google-calendar-connect/';
/**
* Account settings.
*
* @since 1.0.0
*
* @var array
*/
private $account;
/**
* Class for making HTTP requests.
*
* @since 1.0.0
*
* @var Request
*/
private $request;
/**
* Client constructor.
*
* @since 1.0.0
*
* @param array $account Account settings.
*
* @throws InvalidArgumentException If the access token, refresh token, or account ID is empty.
*/
public function __construct( array $account ) {
if ( empty( $account['access_token'] ) ) {
throw new InvalidArgumentException( 'Access token cannot be empty.' );
}
if ( empty( $account['refresh_token'] ) ) {
throw new InvalidArgumentException( 'Refresh token cannot be empty.' );
}
if ( empty( $account['id'] ) ) {
throw new InvalidArgumentException( 'Account ID cannot be empty.' );
}
$this->account = $account;
$this->maybe_refresh_token();
$this->request = new Request( $this->account['access_token'] );
}
/**
* Check if the access token is expired.
*
* @since 1.0.0
*
* @return bool
*/
private function is_expired_token(): bool {
$expires_in = $this->account['expires_in'] ?? 0;
/**
* Adding one minute to cover a very rare case when a few seconds are left,
* and the site runs multiple API requests.
* The last one could be outdated.
*/
return ( time() + MINUTE_IN_SECONDS ) > $expires_in;
}
/**
* Refresh the access token if it is expired.
*
* @since 1.0.0
*
* @throws InvalidArgumentException If the response body does not contain the access token or expires in.
*/
private function maybe_refresh_token(): void {
if ( ! $this->is_expired_token() ) {
return;
}
$response = wp_remote_post(
self::get_middleware_url(),
[
'body' => [
'refresh_token' => $this->account['refresh_token'],
],
]
);
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! isset( $response_body['data']['access_token'], $response_body['data']['expires_in'] ) ) {
throw new InvalidArgumentException( esc_html__( 'Cannot refresh the token.', 'wpforms-google-calendar' ) );
}
$this->account = array_merge(
$this->account,
[
'access_token' => $response_body['data']['access_token'],
'expires_in' => time() + (int) ( $response_body['data']['expires_in'] ),
]
);
wpforms_update_providers_options( Plugin::SLUG, $this->account, $this->account['id'] );
}
/**
* Get authorization url to begin OAuth flow.
*
* @since 1.0.0
*
* @param string $redirect_uri Redirect URI.
*
* @return string
*/
public static function get_auth_url( string $redirect_uri ): string {
$redirect_uri = add_query_arg(
[
'nonce' => wp_create_nonce( 'wpforms-google-calendar-connect' ),
],
$redirect_uri
);
$state = rawurlencode(
base64_encode( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
wp_json_encode(
[
'redirect_uri' => $redirect_uri,
]
)
)
);
return add_query_arg(
[
'action' => 'init',
'state' => $state,
],
self::get_middleware_url()
);
}
/**
* Get a calendar list.
*
* @since 1.0.0
*
* @noinspection PhpUnusedLocalVariableInspection
*/
public function get_calendar_list(): array {
$response = $this->request->get(
self::API_URL . 'users/me/calendarList/',
[
'minAccessRole' => 'writer',
'maxResults' => 250,
]
);
$body = $response->get_body();
if ( empty( $body['items'] ) ) {
return [];
}
$calendars = [];
foreach ( $body['items'] as $key => $calendar ) {
if ( ! isset( $calendar['id'], $calendar['summary'], $calendar['timeZone'] ) ) {
continue;
}
$calendars[ $calendar['id'] ] = [
'name' => $calendar['summary'],
'timezone' => $calendar['timeZone'],
];
}
return $calendars;
}
/**
* Create an event.
*
* @since 1.0.0
*
* @param array $event_data Event data.
*
* @return bool
*/
public function create_event( array $event_data ): bool {
if ( empty( $event_data['calendar_id'] ) ) {
return false;
}
$response = $this->request->post( self::API_URL . "calendars/{$event_data['calendar_id']}/events/?sendUpdates=all", $event_data );
return ! $response->has_errors();
}
/**
* Get middleware URL.
*
* @since 1.0.0
*
* @return string
* @noinspection PhpUndefinedConstantInspection
*/
private static function get_middleware_url(): string {
if ( defined( 'WPFORMS_GOOGLE_CALENDAR_MIDDLEWARE_URL' ) && WPFORMS_GOOGLE_CALENDAR_MIDDLEWARE_URL ) {
return (string) WPFORMS_GOOGLE_CALENDAR_MIDDLEWARE_URL;
}
return self::MIDDLEWARE_URL;
}
}