Hi!
I know this is not exactly the format one should ask questions here but maybe you have an idea on where to go next.
I’m currently adjusting the kirby-shopify plugin to the graphql api and it’s mostly working out. The only thing that’s left is storing the fetched products in a cache to no fetch the products on every pageload.
My function of fetching looks like this:
public static function fetchProductsData($query){
$shopifyApiCache = kirby()->cache('moritzebeling.kirby-shopify.api');
$products = $shopifyApiCache->get('products');
if($products === null) {
$products = [];
$result = self::query($query);
$products = array_map(function($product){
$product = $product['node'];
$product['priceRange'] = [
'min' => $product['priceRange']['minVariantPrice']['amount'],
'max' => $product['priceRange']['maxVariantPrice']['amount'],
'currencyCode' => $product['priceRange']['minVariantPrice']['currencyCode']
];
$product['variants'] = array_map(function($variant){
$variant = $variant['node'];
$variant['price'] = $variant['priceV2'];
$variant['currencyCode'] = $variant['priceV2']["currencyCode"];
unset($variant['priceV2']);
return $variant;
},$product['variants']['edges']);
$product['images'] = array_map(function($image){
$image = $image['node'];
$image['src'] = $image['originalSrc'];
unset($image['originalSrc']);
return $image;
} ,$product['images']['edges']);
return $product;
}, $result['products']);
$shopifyApiCache->set('products', $products);
}
return $products;
}
which gets called in the shopify.products pagemodel:
<?php
use Kirby\Data\Data;
use Kirby\Data\Yaml;
class ShopifyProductsPage extends Page
{
public function subpages()
{
return Pages::factory($this->inventory()['children'], $this);
}
public function children()
{
$products = KirbyShopify::fetchProductsData();
$productsPage = KirbyShopify::$productsPage;
$pages = [];
$counter = 0;
foreach($products as $product){
$slug = Str::slug($product['handle']);
$kirbyProductRoot = $productsPage->root() . '/' . $counter . '_' . $slug . '/shopify.product.txt';
$kirbyProduct = F::exists($kirbyProductRoot) ? new \Kirby\Toolkit\Collection(\Kirby\Data\Data::read($kirbyProductRoot)) : false;
if($kirbyProduct) $kirbyProduct = $kirbyProduct->toArray();
$shopifyProduct = [
'title' => $product['title'],
'shopifyTitle' => $product['title'],
'shopifyID' => $product['id'],
'shopifyHandle' => $product['handle'],
'shopifyImages' => \Kirby\Data\Yaml::encode($product['images']),
'shopifyFeaturedImage' => count($product['images']) > 0 ? \Kirby\Data\Yaml::encode([$product['images'][0]]) : '',
'shopifyDescriptionHTML' => $product['descriptionHtml'],
'shopifyPrice' => count($product['variants']) > 0 ? $product['variants'][0]['price']['amount'] : '',
'shopifyType' => $product['productType'],
'shopifyTags' => $product['tags'],
'shopifyVariants' => \Kirby\Data\Yaml::encode($product['variants']),
];
if ($kirbyProduct) {
foreach ($shopifyProduct as $k => $value) {
unset($kirbyProduct[strtolower($k)]);
}
}
$pages[] = [
'slug' => $slug,
'num' => $counter,
'template' => 'shopify.product',
'model' => 'shopify.product',
'content' => $kirbyProduct ? array_merge($shopifyProduct, $kirbyProduct) : $shopifyProduct,
];
$counter++;
}
return Pages::factory($pages, $this);
}
}
With this code I get the error in the panel on the shopify.products page:
The section "products" could not be loaded: Call to a member function root() on null
What really boggles my mind is that when I test the two arrays, the one thats fetched directly and the other that should be stored in the cache, they are the same:
$shopifyApiCache = kirby()->cache('moritzebeling.kirby-shopify.api');
$productsCache = $shopifyApiCache->get('products');
$products = KirbyShopify::fetchProductsData();
$arraysAreEqual = $products === $productsCache;
var_dump($arraysAreEqual); // returns true
What exactly does the error message mean and what could I try next?
My page blueprint looks like this:
title: Products
options:
delete: false
changeTemplate: false
changeStatus: true
sections:
products:
headline: Products
type: pages
info: "{{ page.shopifyHandle }}"
template: shopify.product