From a7e1bd628fff7d7704873f7f78a46bba46e738c4 Mon Sep 17 00:00:00 2001 From: kshitij Date: Mon, 28 Dec 2020 16:57:56 +0530 Subject: [PATCH] changes in private and public auth call --- .idea/php.xml | 1 + .idea/shopify-api-php-sdk.iml | 1 + src/Client.php | 292 ++++++++++++++++++++++++++-------- src/PublicApp.php | 14 +- 4 files changed, 238 insertions(+), 70 deletions(-) diff --git a/.idea/php.xml b/.idea/php.xml index ef79d01..c854783 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -44,6 +44,7 @@ + diff --git a/.idea/shopify-api-php-sdk.iml b/.idea/shopify-api-php-sdk.iml index 98f4474..3cf9ed4 100644 --- a/.idea/shopify-api-php-sdk.iml +++ b/.idea/shopify-api-php-sdk.iml @@ -41,6 +41,7 @@ + diff --git a/src/Client.php b/src/Client.php index e4a9ae3..0387e62 100755 --- a/src/Client.php +++ b/src/Client.php @@ -12,32 +12,37 @@ class Client implements ClientInterface { /** - * Define constant for current Shopify api version + * define constant for current Shopify api version */ - const SHOPIFY_API_VERSION = '2020-10'; + const SHOPIFY_API_VERSION = '2020-07'; /** - * Define rest api call + * define rest api call */ const REST_API = 'rest'; /** - * Header parameter of shopify access token + * define private app + */ + const PRIVATE_APP = 'private'; + + /** + * header parameter of shopify access token */ const SHOPIFY_ACCESS_TOKEN = 'X-Shopify-Access-Token'; /** - * Define response header pagination string + * denine response header pagination string */ const PAGINATION_STRING = 'Link'; /** - * Response header parameter of shopify api limit + * response header parameter of shopify api limit */ const API_CALL_RATE_LIMIT_HEADER = 'http_x_shopify_shop_api_call_limit'; /** - * Define graphQL api call + * define graphQL api call */ const GRAPHQL = 'graphql'; @@ -47,6 +52,12 @@ class Client implements ClientInterface */ protected $graphql_api_url = "https://{shopify_domain}/admin/api/{version}/graphql.json"; + /** + * rest api url for custom/public app + * @var string + */ + protected $rest_api_url = 'https://{shopify_domain}/admin/api/{version}/{resource}.json'; + /** * Shopify domain name * @var string @@ -72,11 +83,10 @@ class Client implements ClientInterface protected $api_secret_key; /** - * Access token for public app + * access token for public app * @var string */ protected $access_token; - /** * array('version') * @var array @@ -90,10 +100,16 @@ class Client implements ClientInterface protected $base_urls; /** - * Get api header array according to private and public app + * get api header array according to private and public app for rest api * @var array */ - protected $requestHeaders; + protected $restApiRequestHeaders; + + /** + * get api header array according to private and public app for graphql api + * @var array + */ + protected $graphqlApiRequestHeaders; /** * Shopify api version @@ -102,25 +118,25 @@ class Client implements ClientInterface protected $api_version; /** - * Get response header + * get response header * @var string */ protected $next_page; /** - * Get response header + * get response header * @var string */ protected $prev_page; /** - * Static variable to api is going to reach + * static variable to api is going to reach * @var bool */ protected static $wait_next_api_call = false; /** - * Prepare data for rest api request + * prepare data for rest api request * @param $method * @param $path * @param array $params @@ -130,14 +146,14 @@ class Client implements ClientInterface */ public function call($method, $path , array $params = []) { - $url = $this->base_urls[self::REST_API]; + $url = $this->getRestApiUrl(); $options = []; $allowed_http_methods = $this->getHttpMethods(); if(!in_array($method, $allowed_http_methods)){ throw new ApiException(implode(",",$allowed_http_methods)." http methods are allowed.",0); } - if(isset($this->requestHeaders[self::REST_API]) && is_array($this->requestHeaders[self::REST_API])) { - $options['headers'] = $this->requestHeaders[self::REST_API]; + if(is_array($this->getRestApiHeaders()) && count($this->getRestApiHeaders())) { + $options['headers'] = $this->getRestApiHeaders(); } // Change url in case of access_scopes @@ -148,15 +164,17 @@ public function call($method, $path , array $params = []) $url=strtr($url, [ '{resource}' => $path, ]); - if(in_array($method,['GET','DELETE'])) { $options['query'] = $params; }else { $options['json'] = $params; } + if(self::$wait_next_api_call) + { + usleep(1000000 * rand(3, 6)); + } $http_response = $this->request($method,$url,$options); - if (strtoupper($method) === 'GET' && $http_response->getHeaderLine(self::PAGINATION_STRING)) { $this->next_page = $this->parseLinkString($http_response->getHeaderLine(self::PAGINATION_STRING),'next'); $this->prev_page = $this->parseLinkString($http_response->getHeaderLine(self::PAGINATION_STRING),'previous'); @@ -172,14 +190,14 @@ public function call($method, $path , array $params = []) * Prepare data for graphql api request * @param string $url * @return string - * + * */ public function apiScopeUrl($url){ return str_replace('api/'.$this->getApiVersion().'/', 'oauth/', $url); } /** - * Prepare data for graphql api request + * prepare data for graphql api request * @param string $query * @return mixed|void * @throws ApiException @@ -187,16 +205,12 @@ public function apiScopeUrl($url){ */ public function callGraphql($query) { - $url = $this->base_urls[self::GRAPHQL]; + $url = $this->getGraphqlApiUrl(); $options = []; - if(isset($this->requestHeaders[self::GRAPHQL]) && is_array($this->requestHeaders[self::GRAPHQL])) { - $options['headers'] = $this->requestHeaders[self::GRAPHQL]; + if(is_array($this->getRestApiHeaders()) && count($this->getRestApiHeaders())) { + $options['headers'] = $this->getRestApiHeaders(); } $options['body'] = $query; - if(self::$wait_next_api_call) - { - usleep(1000000 * rand(3, 6)); - } $http_response = $this->request('POST', $url, $options); $response = \GuzzleHttp\json_decode($http_response->getBody()->getContents(),true); if(isset($response['errors'])) @@ -208,7 +222,7 @@ public function callGraphql($query) } /** - * Send http request + * send http request * @param string $method * @param string $url * @param array $options @@ -217,16 +231,16 @@ public function callGraphql($query) */ public function request($method,$url,array $options) { - try { - + try + { $client = new \GuzzleHttp\Client(); return $client->request($method, $url, $options); } - catch (RequestException $e) { - $error_response = $e->getResponse()->getBody()->getContents(); - if(!empty($error_response)) { - $json_error = json_decode($error_response,true); - $error_message = isset($json_error['errors'])?json_encode($json_error['errors']):json_encode($json_error); + catch (RequestException $e) + { + $json_error = json_decode($e->getResponse()->getBody()->getContents(),true); + if (isset($json_error['errors'])) { + $error_message = \GuzzleHttp\json_encode($json_error); } else { $error_message = $e->getMessage(); @@ -236,7 +250,7 @@ public function request($method,$url,array $options) } /** - * Get previous page_info for any resource(products/orders) + * get previous page_info for any resource(products/orders) * @return string */ public function getPrevPage() @@ -245,7 +259,7 @@ public function getPrevPage() } /** - * Check previous page_info for any resource(products/orders) + * check previous page_info for any resource(products/orders) * @return string */ public function hasPrevPage() @@ -254,7 +268,7 @@ public function hasPrevPage() } /** - * Get next page_info for any resource(products/orders) + * get next page_info for any resource(products/orders) * @return string */ public function getNextPage(){ @@ -262,7 +276,7 @@ public function getNextPage(){ } /** - * Check next page_info for any resource(products/orders) + * check next page_info for any resource(products/orders) * @return string */ public function hasNextPage(){ @@ -270,7 +284,7 @@ public function hasNextPage(){ } /** - * Parse header string for previous and next page_info + * parse header string for previous and next page_info * @param $pagination_string * @param $page_link * @return string @@ -282,9 +296,33 @@ public function parseLinkString($pagination_string,$page_link) return isset($matches[2]) ? $matches[2] : NULL; } + /** + * return allowed http api methods + * @return array + */ + public function getHttpMethods() + { + return ['POST', 'PUT','GET', 'DELETE']; + } + + /** + * set shopify domain + * @param $shop + * Exception for invalid shop name + * @throws ApiException + */ + public function setShop($shop) + { + if (!preg_match('/^[a-zA-Z0-9\-]{3,100}\.myshopify\.(?:com|io)$/', $shop)) { + throw new ApiException( + 'Shop name should be 3-100 letters, numbers, or hyphens eg mypetstore.myshopify.com',0 + ); + } + $this->shop = $shop; + } /** - * Get latest api version + * return latest api version * @return string */ public function getApiVersion() @@ -293,14 +331,14 @@ public function getApiVersion() } /** - * Set api version + * set api version * @param api_version * Exception for valid value * @throws ApiException */ - protected function setApiVersion() + public function setApiVersion($ap_params) { - $this->api_version = !empty($this->api_params['version'])?$this->api_params['version']:self::SHOPIFY_API_VERSION; + $this->api_version = !empty($ap_params['version'])?$ap_params['version']:self::SHOPIFY_API_VERSION; if (!preg_match('/^[0-9]{4}-[0-9]{2}$|^unstable$/', $this->api_version)) { throw new ApiException('Api Version must be of YYYY-MM or unstable',0); @@ -308,36 +346,164 @@ protected function setApiVersion() } /** - * Get allowed http api methods - * @return array + * return Shopify domain + * @return string */ - public function getHttpMethods() + public function getShop() { - return ['POST', 'PUT','GET', 'DELETE']; + return $this->shop; } /** - * Set shopify domain - * @param $shop - * Exception for invalid shop name - * @throws ApiException + * set rest api url + * @param $rest_api_url + * @param $app_type */ - protected function setShop($shop) + public function setRestApiUrl($rest_api_url, $app_type = '') { - if (!preg_match('/^[a-zA-Z0-9\-]{3,100}\.myshopify\.(?:com|io)$/', $shop)) { - throw new ApiException( - 'Shop name should be 3-100 letters, numbers, or hyphens eg mypetstore.myshopify.com',0 - ); + if($app_type == self::PRIVATE_APP) + { + $this->rest_api_url = strtr($rest_api_url, [ + '{api_key}' => $this->api_key, + '{password}' => $this->password, + '{shopify_domain}' => $this->shop, + '{version}' => $this->getApiVersion(), + ]); + }else{ + $this->rest_api_url = strtr($rest_api_url, [ + '{shopify_domain}' => $this->shop, + '{version}' => $this->getApiVersion(), + ]); } - $this->shop = $shop; } /** - * Return shopify domain + * get rest api url app * @return string */ - public function getShop() + public function getRestApiUrl(){ + return $this->rest_api_url; + } + + /** + * set graphql api url + * @param $graphql_api_url + */ + public function setGraphqlApiUrl($graphql_api_url) { - return $this->shop; + $this->graphql_api_url = strtr($graphql_api_url, [ + '{shopify_domain}' => $this->shop, '{version}' => $this->getApiVersion() + ]); + } + + /** + * get graphql api url + * @return string + */ + public function getGraphqlApiUrl(){ + return $this->graphql_api_url; + } + + /** + * set rest api headers + * @return string + */ + public function setRestApiHeaders($access_token = ''){ + $this->restApiRequestHeaders['Content-Type'] = "application/json"; + if($access_token){ + $this->restApiRequestHeaders[self::SHOPIFY_ACCESS_TOKEN] = $this->access_token; + } + } + + + /** + * get rest api headers + * @return array + */ + public function getRestApiHeaders(){ + return $this->restApiRequestHeaders; + } + + /** + * get graphql api url + * @return string + */ + public function setGraphqlApiHeaders($access_token){ + $this->graphqlApiRequestHeaders['Content-Type'] = "application/graphql"; + $this->graphqlApiRequestHeaders['X-GraphQL-Cost-Include-Fields'] = true; + $this->graphqlApiRequestHeaders[self::SHOPIFY_ACCESS_TOKEN] = $access_token; + } + + /** + * get graphql api url + * @return string + */ + public function getGraphqlApiHeaders(){ + return $this->graphqlApiRequestHeaders; + } + + + /** + * set api_key of public or private app + * @param $api_key + */ + public function setApiKey($api_key){ + $this->api_key = $api_key; + } + + /** + * get api_key of public or private app + * @return string + */ + public function getApiKey(){ + return $this->api_key; + } + + /** + * set api_key of public or private app + * @param $api_password + */ + public function setApiPassword($api_password){ + $this->password = $api_password; + } + + /** + * get api_password of private app + * @return string + */ + public function getApiPassword(){ + return $this->password; + } + + /** + * set api secret key for public app + * @param $api_secret_key + */ + public function setApiSecretKey($api_secret_key){ + $this->api_secret_key = $api_secret_key; + } + + /** + * get api secret key for public app + * @return string + */ + public function getApiSecretKey(){ + return $this->api_secret_key; + } + + /** + * set api_params of public or private app + * @param $api_params + */ + public function setApiParams($api_params){ + $this->api_params = $api_params; + } + + /** + * get api_params of public or private app + * @return string + */ + public function getApiParams(){ + return $this->api_params; } } \ No newline at end of file diff --git a/src/PublicApp.php b/src/PublicApp.php index 04ca656..93ab713 100755 --- a/src/PublicApp.php +++ b/src/PublicApp.php @@ -11,7 +11,7 @@ class PublicApp extends Client implements AppInterface { /** - * Define scope for api access + * define scope for api access */ const SCOPE = 'read_products,read_orders'; @@ -22,7 +22,7 @@ class PublicApp extends Client implements AppInterface private $oauth_url = 'https://{shopify_domain}/admin/oauth/'; /** - * Random unique value for each authorization request + * random unique value for each authorization request * @var state */ private $state; @@ -51,7 +51,7 @@ public function __construct($shop, $api_key, $api_secret_key, array $api_params } /** - * Assign access token for api call + * assign access token for api call * @param $access_token */ public function setAccessToken($access_token) @@ -96,7 +96,7 @@ public function getAccessToken($get_params) } /** - * Prepare url to authorize public app with Oauth for given shop domain + * prepare url to authorize public app with Oauth for given shop domain * @param $scope * @param null $redirect_url * @param $state @@ -123,7 +123,7 @@ public function prepareAuthorizeUrl($redirect_url='', $scope='', $state=false) } /** - * Set random unique value for authorization request + * set random unique value for authorization request * @param $state */ public function setState($state) @@ -132,7 +132,7 @@ public function setState($state) } /** - * Get random unique value for authorization request + * get random unique value for authorization request * @return string */ public function getState() @@ -157,7 +157,7 @@ public function validateHmac($data, $hmac) } /** - * Check random value same with previous value set for authorization request + * check random value same with previous value set for authorization request * @param $state * @return bool */