|
1 | | -# shopify-api-php-sdk |
2 | | -php-sdk helps to connect with shopify private app and call shopify REST and Graphql Api |
| 1 | +# SHOPIFY API PHP SDK |
| 2 | +PHP SDK helps to connect with shopify [Custom App](https://shopify.dev/concepts/apps#custom-apps), [Public App](https://shopify.dev/concepts/apps#public-apps) and [Private App](https://shopify.dev/concepts/apps#private-apps) using [RESTApi](https://shopify.dev/docs/admin-api/rest/reference) and [Graphql](https://shopify.dev/docs/admin-api/graphql/reference). |
| 3 | +* Call GET, POST, PUT and DELETE RestApi method. |
| 4 | +* Process GraphQL Admin API for [Query root](https://shopify.dev/docs/admin-api/graphql/reference/queryroot) and [Mutations](https://shopify.dev/docs/admin-api/graphql/reference/mutation). |
| 5 | +* Queryroot is used to get resources and mutations is used to update resources (products/orders/customers). |
| 6 | +* Automatic manage Shopify API rate limits. |
| 7 | +* Compatible with [Cursor Based Pagination](https://shopify.dev/tutorials/make-paginated-requests-to-rest-admin-api) to resource with pagination. |
| 8 | + |
| 9 | +## Requirements |
| 10 | +1. For Api call need [Guzzle](https://github.com/guzzle/guzzle). The recommended way to install Guzzle is through [Composer](https://getcomposer.org/). |
| 11 | + ``` |
| 12 | + composer require guzzlehttp/guzzle |
| 13 | + ``` |
| 14 | +2. To prepare graphql query with [GraphQL query builder](https://github.com/rudiedirkx/graphql-query). |
| 15 | + |
| 16 | + Clone with Clone with SSH |
| 17 | + ``` |
| 18 | + git@github.com:rudiedirkx/graphql-query.git |
| 19 | + ``` |
| 20 | +## Getting started |
| 21 | +### Initialize the client |
| 22 | +#### 1. For Private App |
| 23 | +* To create instance of Client, you need `shop`, `api_key`, `password` of private app, `api_params` is an array to pass api version with `YYYY-DD/unstable` format otherwise latest version will be assigned. |
| 24 | + |
| 25 | + ``` |
| 26 | + <?php |
| 27 | + require(__DIR__ . '/../vendor/autoload.php'); |
| 28 | + use Shopify\PrivateApp; |
| 29 | + |
| 30 | + $api_params['version'] = '2019-10'; |
| 31 | + $client = new Shopify\PrivateApp($shop, $api_key, $password, $api_params); |
| 32 | + ``` |
| 33 | +#### 2. For Public/Custom App (under development) |
| 34 | +* To create instance of Client, you need `shop`, `api_key`, `api_secret_key` of private app, `api_params` is an array to pass api version with `YYYY-DD/unstable` format otherwise latest version will be assigned. |
| 35 | + |
| 36 | + ``` |
| 37 | + <?php |
| 38 | + require(__DIR__ . '/../vendor/autoload.php'); |
| 39 | + use Shopify\PuplicApp; |
| 40 | + |
| 41 | + $api_params['version'] = '2019-10'; |
| 42 | + $client = new Shopify\PrivateApp($shop, $api_key, $api_secret_key, $api_params); |
| 43 | + ``` |
| 44 | +
|
| 45 | +### Call REST Api |
| 46 | +* Get Products with limit 250 with `call()` function |
| 47 | + ``` |
| 48 | + $response = $client->call('GET','products',['limit'=>250]); |
| 49 | + print_r($response); |
| 50 | + ``` |
| 51 | +* Get products of next page with page_info |
| 52 | + ``` |
| 53 | + $response = $client->call('GET','products',['limit'=>250]); |
| 54 | + ``` |
| 55 | + |
| 56 | + ####### Check next page available with `hasNextPage()` function ####### |
| 57 | +
|
| 58 | + ``` |
| 59 | + if($client->hasNextPage()) |
| 60 | + { |
| 61 | + $next_page_response $client->call('GET','products',['limit'=>20,'page_info'=>$client->getNextPage()]); |
| 62 | + print_r($next_page_response); |
| 63 | + } |
| 64 | + ``` |
| 65 | + |
| 66 | + ####### Check if previous page available with `hasPrevPage()` function ####### |
| 67 | +
|
| 68 | + ``` |
| 69 | + if($client->hasPrevPage()) |
| 70 | + { |
| 71 | + $next_page_response $client->call('GET','products',['limit'=>20,'page_info'=>$client->getPrevPage()]); |
| 72 | + print_r($next_page_response); |
| 73 | + } |
| 74 | + ``` |
| 75 | + |
| 76 | +### Call GraphQL Api |
| 77 | +
|
| 78 | +* Get product title, description with id by `query()` function |
| 79 | + |
| 80 | + ``` |
| 81 | + { |
| 82 | + product(id: "gid://shopify/Product/1432379031652") { |
| 83 | + title |
| 84 | + description |
| 85 | + } |
| 86 | + } |
| 87 | + ``` |
| 88 | + |
| 89 | + ####### Prepare query ####### |
| 90 | + |
| 91 | + ``` |
| 92 | + <?php |
| 93 | + use rdx\graphqlquery\Query; |
| 94 | + |
| 95 | + $query = Query::query(""); |
| 96 | + $query->fields('product'); |
| 97 | + $query->product->attribute('id', "gid://shopify/Product/1432379031652"); |
| 98 | + $query->product->field('title'); |
| 99 | + $query->product->field('description'); |
| 100 | + $graphqlString = $query->build(); |
| 101 | + |
| 102 | + ``` |
| 103 | + |
| 104 | + ####### Call GraphQL qith `callGraphql()` function ####### |
| 105 | + |
| 106 | + ``` |
| 107 | + $response = $client->callGraphql($graphqlString); |
| 108 | + ``` |
| 109 | + |
| 110 | +* Create customer with graphql `mutation()` function |
| 111 | +
|
| 112 | + ``` |
| 113 | + mutation { |
| 114 | + customerCreate(input: { firstName: "John", lastName: "Tate", email: "john@johns-apparel.com" }) { |
| 115 | + customer { |
| 116 | + id |
| 117 | + } |
| 118 | + } |
| 119 | + } |
| 120 | + ``` |
| 121 | + |
| 122 | + ####### Prepare mutation ####### |
| 123 | + |
| 124 | + ``` |
| 125 | + <?php |
| 126 | + use rdx\graphqlquery\Query; |
| 127 | + |
| 128 | + $query = Query::mutation(); |
| 129 | + $query->fields('customerCreate'); |
| 130 | + $query->customerCreate->attribute('input',['firstName'=>'John','lastName'=> "Tate", 'email'=> "john@johns-apparel.com"]); |
| 131 | + $query->customerCreate->field('customer'); |
| 132 | + $query->customerCreate->customer->field('id'); |
| 133 | + $graphqlString = $query->build(); |
| 134 | + ``` |
| 135 | + |
| 136 | + ####### Call GraphQL qith `callGraphql()` function ####### |
| 137 | + |
| 138 | + ``` |
| 139 | + $response = $client->callGraphql($graphqlString); |
| 140 | + ``` |
| 141 | +
|
| 142 | +### Error Handling |
| 143 | +
|
| 144 | +Below errors handled with `ApiException` Class |
| 145 | +* Trying to pass invalid api version |
| 146 | +* Trying to pass invalid shop domain |
| 147 | +* Http REST api call exception from Guzzle(`GuzzleHttp\Exception\RequestException`) |
| 148 | + ``` |
| 149 | + try |
| 150 | + { |
| 151 | + $client = new Shopify\PrivateApp($shop, $api_key, $password, $api_params); |
| 152 | + $response = $client->call('GET','products',['limit'=>20]); |
| 153 | + print_r($response); |
| 154 | + } |
| 155 | + catch (\Shopify\Exception\ApiException $e) |
| 156 | + { |
| 157 | + echo "Errors: ".$e->getError().'<br> status code: '.$e->getCode(); |
| 158 | + } |
| 159 | + ``` |
| 160 | +## References |
| 161 | +* [Shopify API Reference](https://shopify.dev/docs/admin-api/) |
| 162 | +* [GraphQL Query Builder](https://github.com/rudiedirkx/graphql-query) |
| 163 | +* [Guzzle Documentation](http://docs.guzzlephp.org/en/stable/) |
| 164 | +
|
| 165 | +
|
| 166 | +
|
| 167 | +
|
| 168 | +
|
| 169 | +
|
0 commit comments