From 8be839daafcedc19fe4cb638b0da3b0955fa440f Mon Sep 17 00:00:00 2001 From: Robert Reinhard Date: Tue, 17 May 2022 14:26:24 -0700 Subject: [PATCH] Support more than 250 results --- src/services/ShopifyAdminApi.php | 73 +++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/src/services/ShopifyAdminApi.php b/src/services/ShopifyAdminApi.php index afc21e7..0a4a6cc 100644 --- a/src/services/ShopifyAdminApi.php +++ b/src/services/ShopifyAdminApi.php @@ -21,7 +21,7 @@ public function __construct() { list($url, $token) = $this->getCreds(); $this->client = new Client([ - 'base_uri' => $url.'/admin/api/2022-01/', + 'base_uri' => $url.'/admin/api/2022-04/', 'headers' => [ 'X-Shopify-Access-Token' => $token, ], @@ -59,24 +59,58 @@ public function execute($payload) else throw new Exception($response->getBody()); } + /** + * Execute a GQL query and paginate through the results + */ + public function paginate($payload) + { + $results = []; + do { + + // Fetch this page and add to the results + $response = $this->execute($payload); + $results = array_merge( + $results, + $this->flattenEdges($response)['results'], + ); + + // If there is another page, add the end cursor to the next + // request + $pageInfo = $response['results']['pageInfo'] ?? []; + $hasNextPage = $pageInfo['hasNextPage'] ?? false; + if ($hasNextPage) { + $payload['variables'] = array_merge( + $payload['variables'] ?? [], + ['cursor' => $pageInfo['endCursor']], + ); + } + } while ($hasNextPage); + + // Return the final list of results, fixing string keys + return $results; + } + /** * Get all products */ public function getProducts() { - $response = $this->execute([ - 'query' => '{ - products(first:250) { + return $this->paginate([ + 'query' => 'query getProducts($cursor: String) { + results: products(first:250, after:$cursor) { edges { node { title handle } } + pageInfo { + hasNextPage + endCursor + } } }' ]); - return $this->flattenEdges($response)['products']; } /** @@ -84,9 +118,9 @@ public function getProducts() */ public function getVariants() { - $response = $this->execute([ - 'query' => '{ - productVariants(first:250) { + $variants = $this->paginate([ + 'query' => 'query getVariants($cursor: String) { + results: productVariants(first:250, after:$cursor) { edges { node { title @@ -97,25 +131,29 @@ public function getVariants() } } } + pageInfo { + hasNextPage + endCursor + } } }' ]); - // Get array of variants - $variants = $this->flattenEdges($response)['productVariants']; - // Remove variants that are missing a sku $variants = array_filter($variants, function($variant) { return !empty($variant['sku']); }); // Make a title that is more useful for displaying in the CMS. - return array_map(function($variant) { + $variants = array_map(function($variant) { $variant['dashboardTitle'] = $variant['product']['title'] .' - '.$variant['title'] .(($sku = $variant['sku']) ? ' ('.$sku.')' : null); return $variant; }, $variants); + + // Convert string keys to integer + return array_values($variants); } /** @@ -123,19 +161,22 @@ public function getVariants() */ public function getCollections() { - $response = $this->execute([ - 'query' => '{ - collections(first:250) { + return $this->paginate([ + 'query' => 'collections($cursor: String) { + results: collections(first:250, after:$cursor) { edges { node { title handle } } + pageInfo { + hasNextPage + endCursor + } } }' ]); - return $this->flattenEdges($response)['collections']; } /**