Created
February 10, 2024 15:28
-
-
Save cgsmith/ec530b1a26a728431cec731c2ba35219 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace CGSMITH\Traits; | |
trait ParseOrder | |
{ | |
/** | |
* @param $unparsedOrders | |
* @return array | |
* @throws \Exception | |
*/ | |
public function parseOrders($unparsedOrders) | |
{ | |
$result = []; | |
foreach ($unparsedOrders as $unparsedOrder) { | |
if ($shipwiseOrder = $this->parseOrder($unparsedOrder)) { | |
$result[] = $shipwiseOrder; | |
} | |
} | |
return $result; | |
} | |
public function parseOrder($unparsedOrder) { | |
return $this; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace CGSMITH; | |
use CGSMITH\Traits\ParseOrder; | |
use GuzzleHttp; | |
class Shopify | |
{ | |
use ParseOrder; | |
protected $config; | |
protected $client; | |
protected $auth; | |
private $api_key; | |
private $api_secret; | |
protected $api_version = '2023-01'; | |
/** @var int $location_id Location ID for Shopify call */ | |
protected $location_id; | |
protected $excludedProducts; | |
protected $statesToSkip = []; | |
/** | |
* Pass config to shopify api | |
* @param $api_key | |
* @param $api_secret | |
* @param $location_id | |
* @param GuzzleHttp\Client $client | |
* @param array $excludedProducts default is a blank array | |
*/ | |
public function __construct( | |
$api_key, | |
$api_secret, | |
$location_id, | |
GuzzleHttp\Client $client, | |
$excludedProducts = [], | |
$statesToSkip = [], | |
$apiAccessToken = null, | |
) { | |
$this->excludedProducts = $excludedProducts; | |
$this->statesToSkip = $statesToSkip; | |
$this->api_key = $api_key; | |
$this->api_secret = $api_secret; | |
$this->location_id = $location_id; | |
$this->client = $client; | |
if (isset($apiAccessToken)) { | |
$this->auth = ['X-Shopify-Access-Token' => $apiAccessToken]; | |
} else { | |
$this->auth = ['Authorization' => 'Basic ' . base64_encode($this->api_key . ':' . $this->api_secret)]; | |
} | |
} | |
public function getOrderByName($name) | |
{ | |
$orders = json_decode( | |
$this->client->request( | |
'GET', | |
'admin/api/' . $this->api_version . '/orders.json?name=' . $name . '&status=any', | |
[ | |
'headers' => $this->auth, | |
] | |
)->getBody()->getContents(), | |
true | |
); | |
return $orders['orders']; | |
} | |
/** | |
* Get all orders - Shopify defaults to just open orders | |
* | |
* @see https://help.shopify.com/en/api/reference/orders/order#index | |
* @return mixed | |
* @throws \Exception | |
*/ | |
public function getOrders($timeframe = '-4 hours') | |
{ | |
$nextShopifyPage = 1; | |
$orderArray = array(); | |
$startDate = new \DateTime($timeframe, new \DateTimeZone('America/Chicago')); | |
// Loop over pages in shopify | |
try { | |
$response = $this->client->request( | |
'GET', | |
'admin/api/' . $this->api_version . '/orders.json', | |
[ | |
'headers' => $this->auth, | |
'query' => [ | |
'created_at_min' => $startDate->format(DATE_ISO8601), | |
'status' => 'open', | |
'fufillment_status' => 'unfulfilled', | |
'limit' => 250, | |
], | |
] | |
); | |
} catch (\Exception $e) { | |
echo $e->getMessage(); | |
return $orderArray; | |
} | |
$orders = json_decode($response->getBody()->getContents(), true); | |
/** | |
* Just get the orders as a long list of an array | |
*/ | |
if (is_array($orders['orders'])) { | |
foreach ($orders['orders'] as $order) { | |
$orderArray[] = $order; | |
} | |
} | |
// Set to true to enter while loop | |
$nextShopifyPage = true; | |
while ($nextShopifyPage) { | |
$nextShopifyPage = false; | |
if (json_decode($response->hasHeader('Link'))) { | |
$parsed = GuzzleHttp\Psr7\parse_header($response->getHeader('Link')); | |
foreach ($parsed as $item) { | |
if ($item['rel'] == 'next') { | |
$nextShopifyPage = substr(substr($item[0], 1), 0, -1); | |
} | |
} | |
if ($nextShopifyPage) { | |
$response = $this->client->get($nextShopifyPage, ['headers' => $this->auth]); | |
$orders = json_decode($response->getBody()->getContents(), true); | |
/** | |
* Just get the orders as a long list of an array | |
*/ | |
if (is_array($orders['orders'])) { | |
foreach ($orders['orders'] as $order) { | |
$orderArray[] = $order; | |
} | |
} | |
} | |
} | |
} | |
return $orderArray; | |
} | |
/** | |
* Get single order from API | |
* | |
* @param $id integer Order ID to fetch | |
* @return mixed | |
*/ | |
public function getOrder($id) | |
{ | |
try { | |
$response = $this->client->request( | |
'GET', | |
"admin/api/" . $this->api_version . "/orders/{$id}.json", | |
[ | |
'headers' => $this->auth, | |
] | |
); | |
return json_decode($response->getBody()->getContents(), true); | |
} catch (\Exception $e) { | |
return false; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$config = [ | |
'shopify-integration' => [ | |
'base_uri' => 'https://shopify-url.myshopify.com/', // Shopify API | |
'api_key' => '1234', | |
'api_secret' => '5678', | |
'access_token' => 'shpat_1234' | |
] | |
]; | |
$shopify = new Shopify( | |
$config['shopify-integration']['api_key'], | |
$config['shopify-integration']['api_secret'], | |
$config['shopify-integration']['location_id'], | |
new Client($config['shopify-integration']), | |
apiAccessToken: $config['shopify-integration']['access_token'], | |
); | |
// Run this part on a cron every hour or so... mutate into your object then pass to the order management system. | |
$shopify->getOrders(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment