index-shop/site/config/config.php
isUnknown ade0ed1a67 Add virtual pages from Shopify and panel refresh button
This simplifies product management by eliminating manual Kirby page creation. Products are now automatically loaded as virtual pages from the Shopify API.

Changes:
- Add virtual pages via page.children:after hook
- Create shopify.php helper with caching (60min TTL)
- Add shopify-refresh panel plugin for cache management
- Remove manual product content files (now virtual)
- Update site.yml blueprint to show refresh button
- Fix cache implementation to use get/set pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-16 12:44:28 +01:00

183 lines
6.8 KiB
PHP

<?php
require_once __DIR__ . '/shopify.php';
return [
'debug' => true,
'languages' => true,
'cache' => [
'shopify' => true
],
'thumbs' => [
'quality' => 85,
'format' => 'webp',
'presets' => [
'product-card' => [
'width' => 600,
'height' => 600,
'crop' => true,
'format' => 'webp'
],
'product-detail' => [
'width' => 1200,
'format' => 'webp'
],
'default' => [
'width' => 1024,
'format' => 'webp'
],
],
'srcsets' => [
'default' => [400, 600, 800, 1024, 1440, 2048],
'webp' => [
'400w' => ['width' => 400, 'format' => 'webp'],
'600w' => ['width' => 600, 'format' => 'webp'],
'800w' => ['width' => 800, 'format' => 'webp'],
'1024w' => ['width' => 1024, 'format' => 'webp'],
'1440w' => ['width' => 1440, 'format' => 'webp'],
],
],
],
'routes' => [
// SNIPCART ROUTES - Désactivées, voir assets/snipcart-archive/README.md pour restauration
/*
[
'pattern' => '(:any)/validate.json',
'method' => 'GET',
'action' => function ($slug) {
$page = page($slug);
if (!$page || $page->intendedTemplate() !== 'product') {
header('Content-Type: application/json');
http_response_code(404);
echo json_encode(['error' => 'Product not found']);
return;
}
// Récupérer le stock actuel
$stock = (int) $page->stock()->value();
// Préparer la réponse JSON pour Snipcart
$response = [
'id' => $page->slug(),
'price' => (float) $page->price()->value(),
'url' => $page->url() . '/validate.json',
'name' => $page->title()->value(),
'description' => $page->description()->value(),
'image' => $page->images()->first() ? $page->images()->first()->url() : '',
'inventory' => $stock,
'stock' => $stock
];
// Ajouter les options si disponibles
if ($page->hasOptions()->toBool() && $page->optionValues()->isNotEmpty()) {
$values = $page->optionValues()->split(',');
$trimmedValues = array_map('trim', $values);
$snipcartOptions = implode('|', $trimmedValues);
$response['customFields'] = [
[
'name' => $page->optionLabel()->value(),
'options' => $snipcartOptions,
'required' => true
]
];
}
header('Content-Type: application/json');
echo json_encode($response);
}
],
[
'pattern' => 'snipcart-webhook',
'method' => 'POST',
'action' => function () {
// Webhook handler pour Snipcart
// Vérifie la signature et décrémente le stock
$requestBody = file_get_contents('php://input');
$event = json_decode($requestBody, true);
// Vérifier la signature Snipcart (à implémenter avec la clé secrète)
// $signature = $_SERVER['HTTP_X_SNIPCART_REQUESTTOKEN'] ?? '';
if (!$event || !isset($event['eventName'])) {
return Response::json(['error' => 'Invalid request'], 400);
}
// Gérer l'événement order.completed
if ($event['eventName'] === 'order.completed') {
$order = $event['content'] ?? null;
if ($order && isset($order['items'])) {
// Impersonate pour avoir les permissions d'écriture
kirby()->impersonate('kirby');
foreach ($order['items'] as $item) {
$productId = $item['id'] ?? null;
$quantity = $item['quantity'] ?? 0;
if ($productId && $quantity > 0) {
// Trouver le produit par son slug
$products = site()->index()->filterBy('intendedTemplate', 'product');
foreach ($products as $product) {
if ($product->slug() === $productId) {
// Décrémenter le stock
$currentStock = (int) $product->stock()->value();
$newStock = max(0, $currentStock - $quantity);
// Mettre à jour le stock
try {
$product->update([
'stock' => $newStock
]);
} catch (Exception $e) {
// Log l'erreur mais continue le traitement
error_log('Webhook stock update error: ' . $e->getMessage());
}
break;
}
}
}
}
}
}
return Response::json(['status' => 'success'], 200);
}
]
*/
],
'hooks' => [
'page.children:after' => function ($children, $page) {
if ($page->isHomePage()) {
$products = getShopifyProducts();
foreach ($products as $product) {
$children = $children->add([
\Kirby\Cms\Page::factory([
'slug' => $product['handle'],
'template' => 'product',
'model' => 'product',
'num' => 0,
'parent' => $page,
'content' => [
'title' => $product['title'],
'shopifyHandle' => $product['handle']
]
])
]);
}
}
return $children;
}
]
];