<?php 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @link http://www.yiiframework.com/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @copyright Copyright (c) 2008 Yii Software LLC
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @license http://www.yiiframework.com/license/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								namespace yii\authclient;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								use yii\base\Exception;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								use yii\base\InvalidParamException;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								use Yii;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								use yii\helpers\Json;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * BaseClient is a base class for the OAuth clients.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @see http://oauth.net/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 * @property OAuthToken $accessToken Auth token instance. Note that the type of this property differs in
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * getter and setter. See [[getAccessToken()]] and [[setAccessToken()]] for details.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @property array $curlOptions CURL options. This property is read-only.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @property string $returnUrl Return URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @property signature\BaseMethod $signatureMethod Signature method instance. Note that the type of this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * property differs in getter and setter. See [[getSignatureMethod()]] and [[setSignatureMethod()]] for details.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @author Paul Klimov < klimov.paul @ gmail . com > 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * @since 2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								abstract class BaseOAuth extends BaseClient implements ClientInterface
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const CONTENT_TYPE_JSON = 'json'; // JSON format
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const CONTENT_TYPE_URLENCODED = 'urlencoded'; // urlencoded query string, like name1=value1& name2=value2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const CONTENT_TYPE_XML = 'xml'; // XML format
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const CONTENT_TYPE_AUTO = 'auto'; // attempts to determine format automatically
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var string protocol version.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public $version = '1.0';
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var string URL, which user will be redirected after authentication at the OAuth provider web site.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Note: this should be absolute URL (with http:// or https:// leading).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * By default current URL will be used.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									private $_returnUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var string API base URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									public $apiBaseUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var string authorize URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									public $authUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var string auth request scope.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									public $scope;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var array cURL request options. Option values from this field will overwrite corresponding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * values from {@link defaultCurlOptions()}.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									private $_curlOptions = [];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var OAuthToken|array access token instance or its array configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									private $_accessToken;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @var signature\BaseMethod|array signature method instance or its array configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									private $_signatureMethod = [];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $returnUrl return URL
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function setReturnUrl($returnUrl)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$this->_returnUrl = $returnUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return string return URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function getReturnUrl()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if ($this->_returnUrl === null) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$this->_returnUrl = $this->defaultReturnUrl();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->_returnUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $curlOptions cURL options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function setCurlOptions(array $curlOptions)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$this->_curlOptions = $curlOptions;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array cURL options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function getCurlOptions()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->_curlOptions;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array|OAuthToken $token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function setAccessToken($token)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!is_object($token)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$token = $this->createToken($token);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$this->_accessToken = $token;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$this->saveAccessToken($token);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return OAuthToken auth token instance.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function getAccessToken()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!is_object($this->_accessToken)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$this->_accessToken = $this->restoreAccessToken();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->_accessToken;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array|signature\BaseMethod $signatureMethod signature method instance or its array configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @throws InvalidParamException on wrong argument.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function setSignatureMethod($signatureMethod)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!is_object($signatureMethod) & &  !is_array($signatureMethod)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											throw new InvalidParamException('"' . get_class($this) . '::signatureMethod" should be instance of "\yii\autclient\signature\BaseMethod" or its array configuration. "' . gettype($signatureMethod) . '" has been given.');
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$this->_signatureMethod = $signatureMethod;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return signature\BaseMethod signature method instance.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function getSignatureMethod()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!is_object($this->_signatureMethod)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$this->_signatureMethod = $this->createSignatureMethod($this->_signatureMethod);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->_signatureMethod;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Composes default {@link returnUrl} value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return string return URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function defaultReturnUrl()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return Yii::$app->getRequest()->getAbsoluteUrl();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Sends HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $method request type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $url request URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $params request params.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @throws Exception on failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function sendRequest($method, $url, array $params = [])
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$curlOptions = $this->mergeCurlOptions(
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$this->defaultCurlOptions(),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$this->getCurlOptions(),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											array(
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												CURLOPT_RETURNTRANSFER => true,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												CURLOPT_URL => $url,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$this->composeRequestCurlOptions(strtoupper($method), $url, $params)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$curlResource = curl_init();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										foreach ($curlOptions as $option => $value) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											curl_setopt($curlResource, $option, $value);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$response = curl_exec($curlResource);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$responseHeaders = curl_getinfo($curlResource);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// check cURL error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$errorNumber = curl_errno($curlResource);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$errorMessage = curl_error($curlResource);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										curl_close($curlResource);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if ($errorNumber > 0) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											throw new Exception('Curl error requesting "' .  $url . '": #' . $errorNumber . ' - ' . $errorMessage);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if ($responseHeaders['http_code'] != 200) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											throw new Exception('Request failed with code: ' . $responseHeaders['http_code'] . ', message: ' . $response);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->processResponse($response, $this->determineContentTypeByHeaders($responseHeaders));
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Merge CUrl options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * If each options array has an element with the same key value, the latter
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * will overwrite the former.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $options1 options to be merged to.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $options2 options to be merged from. You can specify additional
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * arrays via third argument, fourth argument etc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array merged options (the original options are not changed.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function mergeCurlOptions($options1, $options2)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$args = func_get_args();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$res = array_shift($args);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										while (!empty($args)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$next = array_shift($args);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											foreach ($next as $k => $v) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$res[$k]=$v;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $res;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Returns default cURL options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array cURL options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function defaultCurlOptions()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return [
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CURLOPT_USERAGENT => Yii::$app->name . ' OAuth ' . $this->version . ' Client',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CURLOPT_CONNECTTIMEOUT => 30,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CURLOPT_TIMEOUT => 30,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CURLOPT_SSL_VERIFYPEER => false,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Processes raw response converting it to actual data.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $rawResponse raw response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $contentType response content type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @throws Exception on failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array actual response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function processResponse($rawResponse, $contentType = self::CONTENT_TYPE_AUTO)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (empty($rawResponse)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return [];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch ($contentType) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case self::CONTENT_TYPE_AUTO: {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$contentType = $this->determineContentTypeByRaw($rawResponse);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if ($contentType == self::CONTENT_TYPE_AUTO) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													throw new Exception('Unable to determine response content type automatically.');
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$response = $this->processResponse($rawResponse, $contentType);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case self::CONTENT_TYPE_JSON: {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$response = Json::decode($rawResponse, true);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if (isset($response['error'])) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													throw new Exception('Response error: ' . $response['error']);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case self::CONTENT_TYPE_URLENCODED: {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$response = [];
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												parse_str($rawResponse, $response);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case self::CONTENT_TYPE_XML: {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$response = $this->convertXmlToArray($rawResponse);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											default: {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												throw new Exception('Unknown response type "' . $contentType . '".');
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $response;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Converts XML document to array.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string|\SimpleXMLElement $xml xml to process.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array XML array representation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function convertXmlToArray($xml)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!is_object($xml)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$xml = simplexml_load_string($xml);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$result = (array)$xml;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										foreach ($result as $key => $value) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if (is_object($value)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$result[$key] = $this->convertXmlToArray($value);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $result;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Attempts to determine HTTP request content type by headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $headers request headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return string content type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function determineContentTypeByHeaders(array $headers)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (isset($headers['content_type'])) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if (stripos($headers['content_type'], 'json') !== false) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return self::CONTENT_TYPE_JSON;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if (stripos($headers['content_type'], 'urlencoded') !== false) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return self::CONTENT_TYPE_URLENCODED;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if (stripos($headers['content_type'], 'xml') !== false) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return self::CONTENT_TYPE_XML;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return self::CONTENT_TYPE_AUTO;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Attempts to determine the content type from raw content.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $rawContent raw response content.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return string response type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function determineContentTypeByRaw($rawContent)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (preg_match('/^\\{.*\\}$/is', $rawContent)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return self::CONTENT_TYPE_JSON;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (preg_match('/^[^=|^& ]+=[^=|^& ]+(& [^=|^& ]+=[^=|^& ]+)*$/is', $rawContent)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return self::CONTENT_TYPE_URLENCODED;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (preg_match('/^< . * > $/is', $rawContent)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return self::CONTENT_TYPE_XML;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return self::CONTENT_TYPE_AUTO;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Creates signature method instance from its configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $signatureMethodConfig signature method configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return signature\BaseMethod signature method instance.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function createSignatureMethod(array $signatureMethodConfig)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!array_key_exists('class', $signatureMethodConfig)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$signatureMethodConfig['class'] = signature\HmacSha1::className();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return Yii::createObject($signatureMethodConfig);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Creates token from its configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $tokenConfig token configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return OAuthToken token instance.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function createToken(array $tokenConfig = [])
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!array_key_exists('class', $tokenConfig)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$tokenConfig['class'] = OAuthToken::className();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return Yii::createObject($tokenConfig);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Composes URL from base URL and GET params.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $url base URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $params GET params.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return string composed URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function composeUrl($url, array $params = [])
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (strpos($url, '?') === false) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$url .= '?';
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} else {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$url .= '&'; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$url .= http_build_query($params, '', '& ', PHP_QUERY_RFC3986);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $url;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Saves token as persistent state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param OAuthToken $token auth token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return static self reference.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function saveAccessToken(OAuthToken $token)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->setState('token', $token);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Restores access token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return OAuthToken auth token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function restoreAccessToken()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$token = $this->getState('token');
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (is_object($token)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* @var $token OAuthToken */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if ($token->getIsExpired()) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												$token = $this->refreshAccessToken($token);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $token;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Sets persistent state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $key state key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param mixed $value state value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return static self reference.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function setState($key, $value)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$session = Yii::$app->getSession();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$key = $this->getStateKeyPrefix() . $key;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$session->set($key, $value);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Returns persistent state value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $key state key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return mixed state value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function getState($key)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$session = Yii::$app->getSession();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$key = $this->getStateKeyPrefix() . $key;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$value = $session->get($key);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $value;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Removes persistent state value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $key state key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return boolean success.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function removeState($key)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$session = Yii::$app->getSession();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$key = $this->getStateKeyPrefix() . $key;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$session->remove($key);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Returns session key prefix, which is used to store internal states.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return string session key prefix.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									protected function getStateKeyPrefix()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return get_class($this) . '_' . sha1($this->authUrl) . '_';
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Performs request to the OAuth API.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $apiSubUrl API sub URL, which will be append to [[apiBaseUrl]], or absolute API URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $method request method.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $params request parameters.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array API response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @throws Exception on failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									public function api($apiSubUrl, $method = 'GET', array $params = [])
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (preg_match('/^https?:\\/\\//is', $apiSubUrl)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$url = $apiSubUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} else {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											$url = $this->apiBaseUrl . '/' . $apiSubUrl;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										$accessToken = $this->getAccessToken();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if (!is_object($accessToken) || !$accessToken->getIsValid()) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											throw new Exception('Invalid access token.');
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return $this->apiInternal($accessToken, $url, $method, $params);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Composes HTTP request CUrl options, which will be merged with the default ones.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $method request type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $url request URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $params request params.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array CUrl options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @throws Exception on failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									abstract protected function composeRequestCurlOptions($method, $url, array $params);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Gets new auth token to replace expired one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param OAuthToken $token expired auth token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return OAuthToken new auth token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									abstract public function refreshAccessToken(OAuthToken $token);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/**
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * Performs request to the OAuth API.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param OAuthToken $accessToken actual access token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $url absolute API URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param string $method request method.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @param array $params request parameters.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @return array API response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * @throws Exception on failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									abstract protected function apiInternal($accessToken, $url, $method, array $params);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}