CHAPITRE 23 — Le catalogue produit dynamique en profondeur
📦 Chapitre 23 — Le catalogue produit dynamique en profondeur
Le catalogue produit dynamique transforme votre table llx_product en pages web auto-générées.générées automatiquement. Ce chapitre détaille toutel'ensemble ladu mécaniquefonctionnement côté développeur : architecture, classes, configuration,configuration extensibilité.et points d'extension.
🏗️ Architecture en couches
Couche | Rôle |
|---|---|
| Lit les produits Dolibarr (filtres, tris, multilingue) |
| Génère
en fonction des produits publiés. |
| Le |
| Régénère automatiquement les wrappers |
| Filet de sécurité |
📋 Le modèle de données produit
Chaque produit Dolibarr utilisé dans le catalogue exploite plusieurs tables :
Table | Données |
|---|---|
| Champs natifs : ref, label, description, prix, tosell. |
| Traductions natives (label, description par |
|
|
|
|
| Liens |
🧩 Provisionner les extrafields
champs personnalisés
Les 11onze extrafieldschamps personnalisés nécessaires ne sont pas danslivrés Dolibarren destandard base.avec Dolibarr. Pour les créer en une commande, utilisez le script presetde provisionnement générique :
php htdocs/custom/infrasstudio/scripts/preset_default.php \
htdocs/custom/infrasstudio/presets/keaticweb.json
Le fichier JSON livre les définitions par défaut (voir Chapitre 28 pour le format). Vous pouvez créer votre propre preset si vous avez besoin d'autres extrafields.champs personnalisés.
📊 Utiliser StudioProductCatalog
La classe expose plusieurs méthodes pour interroger les produits :
dol_include_once('/infrasstudio/class/studioproductcatalog.class.php');
$catalog = new StudioProductCatalog($db);
// Tous les produits publiés, localedans la langue courante
$products = $catalog->fetchPublishedProducts(array(), $iso2);
// Filtres
$products = $catalog->fetchPublishedProducts(array(
'univers' => 'supply-chain',
'type' => 'saas',
), $iso2);
// Un produit par refréférence
$product = $catalog->fetchProductBySlug('supplyflow-pro', $iso2);
// Univers utilisés (pour le filtre du catalogue)
$univers = $catalog->fetchUsedUnivers();
Format normalisé d'un produit
array(
'id' => 5,
'ref' => 'supplyflow-pro',
'label' => 'SupplyFlow Pro', // résolu selon localela langue
'description' => '<p>Description...</p>',
'price' => 290.00,
'badge' => 'Nouveau',
'hero_image' => '/medias/...',
'cta_label' => 'Demander une démo',
'cta_url' => '/contact',
'tagline' => 'Optimisez votre supply chain...',
'deployment' => 'Cloud SaaS',
'compatibility'=> 'SAP, Oracle, Sage',
'support' => '24/7',
'languages' => 'fr,en,de',
'features' => array('Prévision IA', 'Multi-entrepôts'),
'pricing_tiers'=> array(...),
'univers' => 'supply-chain',
'type' => 'saas',
)
🌍 Cartographie catégorie →vers univers
Les produits sont rattachés à des catégories Dolibarr. Le module mappeassocie ceschaque catégoriescatégorie à un univers (concept éditorial : Supply Chain, Health, Legal, …etc.).
MappingCartographie par défaut
// Les 6six univers livrés par défaut
'supply-chain' => array(...catégories supply chain),
'health' => array(...catégories santé),
'legal' => array(...catégories juridique),
'digital-humanities' => array(...catégories sciences humaines),
'transversal' => array(...catégories outils transversaux),
'fsm' => array(...catégories field service)
OverrideSurcharge par JSON
Pour personnaliser, posezdéfinissez la constante :
// Via dolibarr_set_const ou via setupla page de configuration admin
$conf->global->INFRASSTUDIO_PRODUCT_UNIVERS_MAP = json_encode(array(
'mon-univers' => array(12, 13, 14), // IDsidentifiants de catégories
'autre' => array(15, 16),
));
🔧 StudioSolutionWrapper
Cette classe gère la génération des wrappers Apache à partir des produits publiés.
GénérerGénération manuellement
manuelle
dol_include_once('/infrasstudio/class/studiosolutionwrapper.class.php');
require_once DOL_DOCUMENT_ROOT . '/website/class/website.class.php';
$website = new Website($db);
$website->fetch(0, 'monsite');
$wrapper = new StudioSolutionWrapper($db);
$stats = $wrapper->rebuildAll($website, '/var/www/monsite');
print_r($stats);
// array('created' => 3, 'updated' => 2, 'deleted' => 1, 'skipped' => 5)
Anatomie d'un wrapper généré
<?php
// /var/www/monsite/solution-supplyflow-pro.php
// Generated by StudioSolutionWrapper — do not edit manually.
$solution_ref = 'supplyflow-pro';
$infrasstudio_current_product_ref = 'supplyflow-pro';
global $dolibarr_main_data_root, $conf;
if (empty($dolibarr_main_data_root)) {
$res = include './page42.tpl.php'; // page solution-detail
} else {
$res = include $dolibarr_main_data_root
. ($conf->entity > 1 ? '/' . $conf->entity : '')
. '/website/monsite/page42.tpl.php';
}
if ($res === false) { http_response_code(500); print 'Failed to make include'; }
✅ Sécurité anti-collision — — Le module ne touche qu'aux wrappers qu'il a lui-même créés (présence du marqueur "« StudioSolutionWrapper" » dans lel'en-tête header)du fichier). Les pages Dolibarr standards portant un slug commençant par solution- sont préservées.*
⚙️ Configuration du wrappergénérateur builder
de wrappers
Constante | Rôle |
|---|---|
| Référence du site cible. |
| Docroot Apache absolu (
). |
| Préfixe des wrappers (par défaut
).
,
. |
|
). |
📄 Le templategabarit solution-detail
C'estIl s'agit d'une page Dolibarr Website normaleclassique (avec unson slug,slug unet son tpl.php), mais utilisée par tous les wrappers. Elle reçoit la variable globale $solution_ref qui identifie le produit à afficher.
Squelette typique
type
<?php
// page42.tpl.php (slug='solution-detail', type_container='page')
require_once __DIR__ . '/master.inc.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/website.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/website.inc.php';
dol_include_once('/infrasstudio/class/studioproductcatalog.class.php');
$catalog = new StudioProductCatalog($db);
$iso2 = infrasstudio_current_lang();
$product = $catalog->fetchProductBySlug($solution_ref, $iso2);
if (!$product) {
http_response_code(404);
print '<h1>Produit introuvable</h1>';
exit;
}
ob_start();
try {
?>
<html lang="<?php echo $iso2; ?>">
<head>
<title><?php echo dol_escape_htmltag($product['label']); ?></title>
</head>
<body>
<section class="hero">
<h1><?php echo dol_escape_htmltag($product['label']); ?></h1>
<p><?php echo dol_escape_htmltag($product['tagline']); ?></p>
<img src="<?php echo $product['hero_image']; ?>" alt="...">
</section>
<section class="features">
<ul>
<?php foreach ($product['features'] as $feature): ?>
<li><?php echo dol_escape_htmltag($feature); ?></li>
<?php endforeach; ?>
</ul>
</section>
</body>
</html>
<?php
} catch (Exception $e) { print $e->getMessage(); }
include dol_buildpath('/infrasstudio/core/tpl/website_output.tpl.php', 0);
💡 MixerMélanger slots et données produit — — Vous pouvez mélangercombiner les deux : les zones « éditoriales »(par (exemple un titre marketing au-dessus de la grille) en slots, et les zones « produit » (label, prix, features)fonctionnalités) lues via StudioProductCatalog. Les deux cohabitent sans conflit.
🪝 Le trigger PRODUCT_*/CATEGORY_*
PRODUCT et CATEGORY
Le module installe un trigger qui écoute :
PRODUCT_CREATEPRODUCT_MODIFYPRODUCT_DELETEPRODUCT_PRICE_MODIFYCATEGORY_LINK(uniquement si l'objet lié est un produit)CATEGORY_UNLINK
À chaque événement, le trigger appelle StudioSolutionWrapper::rebuildAll() sur le site configuré.
ℹ️Note Abort silencieux— — Si INFRASSTUDIO_WEBSITE_KEY ou INFRASSTUDIO_PUBLIC_DOCROOT ne sont pas configurés,configurées, le trigger sortse termine silencieusement. Pas deNi bruit, pasni d'erreur. PratiqueCette pourdiscrétion lesconvient aux instances Dolibarr qui n'utilisent pas le catalogue dynamique.
La ⏰tâche Le cronplanifiée horaire de (filet de sécurité
sécurité)
Une tâche cronplanifiée tournes'exécute toutes les heures et appelle StudioSolutionWrapper::rebuildAllConfigured(). Elle lit les constantes et relance la régénération.
UtilitéCette tâche apporte les bénéfices suivants :
- Rattrapage si un trigger a été manqué (import en masse, modification SQL directe,
…etc.). - Synchronisation après une
migration.migration de serveur. - Garantie de cohérence sans intervention manuelle.
Reconstruction ⌨️manuelle CLIen :ligne rebuildde manuel
commande
php htdocs/custom/infrasstudio/scripts/rebuild_solution_wrappers.php \
<ref-site-ou-id> <docroot-public> [entity]
# Exemple
php htdocs/custom/infrasstudio/scripts/rebuild_solution_wrappers.php \
monsite /var/www/monsite 2
📋 Récapitulatif
✅ Vous savez maintenantdésormais :
- Comprendre l'architecture du catalogue (
StudioProductCatalogStudioProductCatalog,+StudioSolutionWrapper,StudioSolutionWrappergabarit,+trigger,tpltâche+ trigger + cron)planifiée). - Provisionner les
extrafieldschamps personnalisés produit avec le preset générique. - Interroger les produits via
StudioProductCatalog. MapperCartographier les catégories Dolibarr vers vos univers viaINFRASSTUDIO_PRODUCT_UNIVERS_MAP.- Comprendre comment
StudioSolutionWrapper::rebuildAll()génère les wrappers Apache. - Configurer
prefixle préfixe ettemplatelepageurlslug du gabarit par site. - Écrire le
templategabaritsolution-detailqui sert tous les produits. - Comprendre le rôle du trigger automatique et
du crondefiletla tâche planifiée de sécurité. - Lancer
ununerebuildreconstructionmanuelmanuelleviaenCLI.ligne de commande.
🎉 Fin de la Partie IV — — Vous maîtrisez maintenantdésormais l'intégration côté développeur : préparer un site, annoter avec des slots, comprendre la grammaire, brancher des données Dolibarr, gérer le multilingue, créer vos gabarits,gabarits et exploiter le catalogue dynamique. Vous pouvezêtes en mesure de livrer un site clé en main.
La Partie V aborde l'administration et la maintenance. Si vous êtes adminadministrateur Dolibarr, c'est votre prochaine destination.