# photonic/2.43/Modules/OAuth2.php

Photonic Gallery &amp; Lightbox for Flickr, SmugMug &amp; Others, version 2.43. 193 lines.

- Page: https://pluginprobe.com/plugins/photonic/2.43/code/Modules/OAuth2.php
- Raw: https://pluginprobe.com/plugins/photonic/2.43/raw/Modules/OAuth2.php
- Modified: 2020-05-06T23:30:18+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/photonic/2.43/code/Modules/OAuth2.php#L10-L20`.

```php
<?php
namespace Photonic_Plugin\Modules;

use Photonic_Plugin\Core\Photonic;

require_once('Core.php');
require_once('Authenticator.php');

abstract class OAuth2 extends Core {
	use Authenticator;

	public $scope, $response_type, $client_id, $client_secret, $state, $access_token, $refresh_token_valid;

	protected function __construct() {
		parent::__construct();
	}

	public abstract function authentication_url();

	public abstract function access_token_url();

	public abstract function refresh_access_token($token, $save);

	protected abstract function set_token_validity($validity);

	public function redirect_url() {
		return get_site_url();
	}

	public function get_authorization_url($args = []) {
		$url = add_query_arg('test', 'test');
		$url = remove_query_arg('test', $url);
		$parameters = array_merge([
			'response_type' => $this->response_type,
			'redirect_uri' => $this->redirect_url(),
			'client_id' => $this->client_id,
			'scope' => $this->scope,
			'access_type' => 'offline',
			'state' => md5($this->client_secret.$this->provider).'::'.urlencode($url),
		], $args);
		return $this->authentication_url()."?".Authenticator::build_query($parameters);
	}

	/**
	 * Takes an OAuth request token and exchanges it for an access token.
	 *
	 * @param $request_token
	 */
	function get_access_token($request_token) {
		$code = $request_token['code'];
		$state_args = explode('::', $request_token['state']);

		if ($state_args[0] == md5($this->client_secret.$this->provider)) {
			$url = urldecode($state_args[1]);
			$response = Photonic::http($this->access_token_URL(), 'POST', [
				'code' => $code,
				'grant_type' => 'authorization_code',
				'client_id' => $this->client_id,
				'client_secret' => $this->client_secret,
				'redirect_uri' => $this->redirect_url(),
			]);

			if (is_wp_error($response)) {
				$url = add_query_arg('error', $response->get_error_code(), $url);
			}
			else if ($response == null) {
				$url = add_query_arg('error', 'null', $url);
			}
		}
		else {
			$url = remove_query_arg(['token', 'code', 'state']);
		}
		wp_redirect($url);
		exit();
	}

	/**
	 * @param $base_token
	 */
	public function authenticate($base_token) {
		$photonic_authentication = get_option('photonic_authentication');
		if (!isset($photonic_authentication)) {
			$photonic_authentication = [];
		}

		if (!isset($photonic_authentication[$this->provider]) && !empty($base_token)) {
			// Nothing is in the authentication option, but there is a token in overall Photonic Options.
			// Refresh it if required, and save it to the authentication option.
			$token = $this->refresh_access_token($base_token, true);
		}
		else if (isset($photonic_authentication[$this->provider])) {
			$token = $photonic_authentication[$this->provider];
			if (!empty($token)) {
				if ($this->is_token_expired($token)) {
					$token = $this->refresh_access_token($base_token, true);
				}
				else {
					$this->set_token_validity(true);
				}
			}
		}

		if (!empty($token)) {
			$this->access_token = $token['oauth_token'];
		}
		else {
			$this->set_token_validity(false);
		}
	}

	function is_token_expired($token) {
		if (empty($token)) {
			return true;
		}
		if (!isset($token['oauth_token']) || !isset($token['oauth_token_created']) || !isset($token['oauth_token_expires'])) {
			return true;
		}
		if (!isset($token['client_id']) || (isset($token['client_id']) && $token['client_id'] !== $this->client_id)) {
			return true;
		}
		$current = time();
		if ($token['oauth_token_created'] + $token['oauth_token_expires'] < $current) {
			return true;
		}
		return false;
	}

	/**
	 * Checks if a token will expire soon. This is used to trigger a refresh for sources such as Instagram. Google uses a separate "Refresh Token",
	 * so this is not applicable to it. The <code>soon_limit</code> defines how many days is "soon", and a refresh is triggered if the current date
	 * is in the "soon" range. E.g. If you have a soon limit of 30 days, and your token expires in 15 days when you load the page, this method will
	 * return <code>true</code>.
	 *
	 * For cases where the token does not exist yet, the method returns <code>null</code>.
	 *
	 * @param $soon_limit int Number of days to check the expiry limit for.
	 * @return int|null If there is no token, return null. Otherwise, if there are < $soon_limit days left, return 1, if token is expired return -1, and if there is time return 0.
	 */
	function is_token_expiring_soon($soon_limit) {
		$photonic_authentication = get_option('photonic_authentication');
		if (empty($photonic_authentication) || empty($photonic_authentication[$this->provider]) ||
			empty($photonic_authentication[$this->provider]['oauth_token']) || empty($photonic_authentication[$this->provider]['oauth_token_created']) || empty($photonic_authentication[$this->provider]['oauth_token_expires'])) {
			return null; // There is no token!
		}

		$token = $photonic_authentication[$this->provider];
		$token_expiry = $token['oauth_token_created'] + $token['oauth_token_expires'];

		$current = time();
		$test_expiry = $current + $soon_limit * 24 * 60 * 60;

		$time_left = $token_expiry - $test_expiry;

		if ($current >= $token_expiry) {
			return -1; // already expired
		}
		else if ($time_left <= 0) {
			return 1; // Expiring soon
		}
		else {
			return 0; // There is still time
		}
/*		if ($current + $soon_limit * 24 * 60 * 60 > $token['oauth_token_created'] + $token['oauth_token_expires']) {
			return true;
		}
		return false;*/
	}

	/**
	 * Takes a token response from a request token call, then puts it in an appropriate array.
	 *
	 * @param $response
	 * @return array
	 */
	public function parse_token($response) {
		$token = [];
		if (!is_wp_error($response) && is_array($response)) {
			$body = $response['body'];
			$body = json_decode($body);
			if (empty($body->error)) {
				$token['oauth_token'] = $body->access_token;
				$token['oauth_token_type'] = $body->token_type;
				$token['oauth_token_created'] = time();
				$token['oauth_token_expires'] = $body->expires_in;
				$this->set_token_validity(true);
			}
			else {
				$this->set_token_validity(false);
			}
		}
		return $token;
	}
}
```
