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
*/