Source of file ShopifyClient.php
Size: 12,058 Bytes - Last Modified: 2021-12-24T06:46:30+00:00
/var/www/docs.ssmods.com/process/src/src/Client/ShopifyClient.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 | <?php namespace Dynamic\Shopify\Client; use Dynamic\Shopify\Extension\ShopifySiteConfigExtension; use Exception; use GuzzleHttp\Promise\Promise; use Osiset\BasicShopifyAPI\BasicShopifyAPI; use Osiset\BasicShopifyAPI\Options; use Osiset\BasicShopifyAPI\ResponseAccess; use Osiset\BasicShopifyAPI\Session; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Injector\Injectable; use SilverStripe\Dev\Debug; use SilverStripe\ORM\ArrayList; use SilverStripe\SiteConfig\SiteConfig; use SilverStripe\View\ArrayData; /** * Class ShopifyClient * @package Dynamic\Shopify\Client * * @mixin BasicShopifyAPI */ class ShopifyClient { use Configurable; use Injectable; const EXCEPTION_NO_API_KEY = 0; const EXCEPTION_NO_API_PASSWORD = 1; const EXCEPTION_NO_DOMAIN = 2; /** * Configures the version of the api that you want to use * * @config string */ private static $api_version = '2021-01'; /** * @config null|string */ private static $api_key = null; /** * @config null|string */ private static $api_password = null; /** * @config null|string */ private static $storefront_access_token = null; /** * @config null|string */ private static $shopify_domain = null; /** * @config null|string */ private static $custom_domain = null; /** * @config null|string */ private static $shared_secret = null; /** * Set this to false when creating your own custom shopify buy js * @config null|string */ private static $inject_javascript = true; /** * @var BasicShopifyAPI */ protected $client = null; /** * Get the configured Guzzle client * * @throws Exception */ public function __construct() { $this->setClient(); } /** * @param string $method * @param array $args */ public function __call(string $method, array $args) { return call_user_func_array([$this->getClient(), $method], $args); } /** * @return $this * @throws Exception * * TODO move config fetches to separate methods, supporting ENV values as well */ protected function setClient() { /*if (!$key = self::config()->get('api_key')) { throw new Exception('No api key is set.', self::EXCEPTION_NO_API_KEY); }//*/ if (!$password = self::config()->get('api_password')) { throw new Exception('No api password is set.', self::EXCEPTION_NO_API_PASSWORD); } if (!$domain = self::config()->get('shopify_domain')) { throw new Exception('No shopify domain is set.', self::EXCEPTION_NO_DOMAIN); } $options = new Options(); $options->setVersion(static::config()->get('api_version')); $options->setApiPassword($password); $options->setType(true); $client = new BasicShopifyAPI($options); $client->setSession(new Session($domain)); $this->client = $client; $this->updateLocalCache(); return $this; } /** * @return BasicShopifyAPI|null * @throws Exception */ protected function getClient() { if (!$this->client) { $this->setClient(); } return $this->client; } /** * @return mixed */ public static function get_domain() { if (!$domain = self::config()->get('custom_domain')) { $domain = self::config()->get('shopify_domain'); } return $domain; } /** * Updates locally stored config options set in shopify */ protected function updateLocalCache() { /** @var SiteConfig|ShopifySiteConfigExtension $config */ $config = SiteConfig::current_site_config(); $config->ShopCurrencyCode = $this->currencyCode(); if ($config->isChanged()) { $config->write(); } } /** * Gets the shop's currency code * @return array|Promise * @throws Exception */ public function currencyCode() { $result = $this->getClient()->graph('query {shop{currencyCode}}'); if ($result && $result['body']) { return $result['body']->data->shop->currencyCode; } return ''; } /** * @param array $options * @return array|Promise * @throws Exception */ public function products(int $limit = 10, string $cursor = null) { return $this->getClient()->graph( 'query ($limit: Int!, $cursor: String) { products(first: $limit, after: $cursor) { edges { cursor node { id title handle descriptionHtml vendor productType createdAt updatedAt publishedOnCurrentPublication images(first: 10) { edges { node { id altText originalSrc } } } variants(first: 25) { edges { node { id title sku price compareAtPrice position inventoryQuantity image { id altText originalSrc } } } } } } pageInfo { hasNextPage } } } ', [ 'limit' => (int)$limit, 'cursor' => $cursor ] ); } /** * @param $productId * @param array $options * @return array|Promise * @throws Exception */ public function product($productId, array $options = []) { return $this->getClient()->graph( 'query ($id: ID!){ product(id: $id) { id title handle descriptionHtml vendor productType createdAt updatedAt publishedOnCurrentPublication images(first: 10) { edges { node { id altText originalSrc } } } variants(first: 25) { edges { node { id title sku price compareAtPrice position inventoryQuantity image { id altText originalSrc } } } } } } ', [ 'id' => "gid://shopify/Product/{$productId}", ] ); } /** * Get the available Collections * * @return mixed|\Psr\Http\Message\ResponseInterface * @throws \GuzzleHttp\Exception\GuzzleException */ public function collections(int $limit = 25, string $cursor = null) { return $this->getClient()->graph(' query ($limit: Int!, $cursor: String){ collections(first: $limit, after: $cursor) { edges { cursor node { id title handle descriptionHtml productsCount updatedAt sortOrder publishedOnCurrentPublication image { id altText originalSrc } } } pageInfo { hasNextPage } } } ', [ 'limit' => (int)$limit, 'cursor' => $cursor, ]); } public function collection($collectionId) { return $this->getClient()->graph(' query ($id: ID!){ collection(id: $id) { id title handle descriptionHtml productsCount updatedAt sortOrder publishedOnCurrentPublication image { id altText originalSrc } } } ', [ 'id' => "gid://shopify/Collection/{$collectionId}", ]); } /** * @param $productID * @param int $limit * @param string|null $cursor * @return array|Promise * @throws Exception */ public function productCollections($productId, int $limit = 25, string $cursor = null) { return $this->getClient()->graph( 'query ($id: ID!, $limit: Int!, $cursor: String){ product(id: $id) { collections(first: $limit, after: $cursor) { edges { cursor node { id title } } pageInfo { hasNextPage } } } } ', [ 'id' => "gid://shopify/Product/{$productId}", "limit" => (int)$limit, "cursor" => $cursor, ] ); } /** * return products of a given collection by handle * * @param $handle * @param array $options * @return array|Promise * @throws Exception */ public function collectionProducts($handle) { return $this->getClient()->graph( 'query ($handle: String!){ collectionByHandle(handle: $handle) { products(first: 100) { edges { node { id title } } } } }', ["handle" => $handle] ); } /** * @param $productId * @param int $limit * @param string|null $cursor * @param bool $variant * @return array|Promise|ResponseAccess * @throws Exception */ public function productMedia($productId, int $limit = 25, $cursor = null, $variant = false) { $queryType = $variant ? 'productVariant' : 'product'; $idType = $variant ? 'ProductVariant' : 'Product'; return $this->getClient()->graph( 'query ($id: ID!, $limit: Int!, $cursor: String){ ' . $queryType . '(id: $id) { id media(first: $limit, after: $cursor) { edges { cursor node { ... fieldsForMediaTypes } } pageInfo { hasNextPage } } } } fragment fieldsForMediaTypes on Media { alt mediaContentType preview { image { id altText originalSrc width height } } status ... on Video { id sources { format height mimeType url width } originalSource { format height mimeType url width } } ... on ExternalVideo { id embeddedUrl } ... on Model3d { sources { format mimeType url } originalSource { format mimeType url } } ... on MediaImage { id image { altText originalSrc width height } } } ', [ 'id' => "gid://shopify/{$idType}/{$productId}", 'limit' => (int)$limit, 'cursor' => $cursor, ] ); } /** * @param string $collectionId * * @return array|Promise|ResponseAccess * @throws Exception */ public function collectionMedia($collectionId) { return $this->getClient()->graph(' query ($id: ID!){ collection(id: $id) { image { id altText originalSrc width height } } } ', [ 'id' => "gid://shopify/Collection/{$collectionId}", ]); } } |