Hooks utilisés
| Hook | Rôle |
|---|---|
displayBanner, displayNavFullWidth, displayFooter, displayFooterBefore, displayHome, displayLeftColumn, displayProductAdditionalInfo, displayShoppingCartFooter | Emplacements proposés dans l'onglet « Où l'afficher ». Toujours greffés ; le rendu dépend des emplacements enregistrés et de la page courante. |
tout hook display* saisi en mode « Avancé » | Greffé à l'enregistrement (Settings\HookSynchronizer), boutique par boutique. |
displayHeader | JSON-LD LocalBusiness dans le <head>. |
actionFrontControllerSetMedia | CSS et JS, seulement si un emplacement s'affiche sur la page. |
actionWebsourceBuilderRegisterBlocks | Bloc « Magasin / horaires » de Websource Builder. |
actionWebsourceThemeExport, actionWebsourceThemeImport | Section storeinfo (version 1) du paquet de thème. |
Le module se place en dernière position de displayFooter (dernière colonne du pied de page).
Widget
{widget name='websourcestoreinfo'}
{widget name='websourcestoreinfo' store='main' layout='compact'}
{widget name='websourcestoreinfo' store='maison-lumen' layout='card' title='Notre magasin'}
| Paramètre | Valeurs |
|---|---|
store | main (magasin principal), all, un numéro de magasin ou son identifiant court (slug). |
layout | compact, card, footer. Défaut card. |
title | Titre affiché (ignoré en compact hors barre). |
Sans store ni layout, et appelé depuis un hook, le widget rend les emplacements enregistrés pour ce hook. CSS et JS sont insérés une seule fois.
API PHP
// Depuis un autre module ou un contrôleur
echo WebsourceStoreInfo::renderStoreById('main', 'compact');
$module = Module::getInstanceByName('websourcestoreinfo');
echo $module->renderStore('all', 'card', 'Nos magasins');
Classes principales (Websource\StoreInfo\…) : Store\StoreRepository (table wssi_store), Store\StoreSanitizer (MAX_SEASONS 6, MAX_EXCEPTIONS 60), Store\NativeStoreReader (Contact > Magasins), Store\StoreViewBuilder, Hours\HoursParser, Hours\OpeningCalculator, Hours\StatusPresenter, Hours\Labels (fr, en), Directions\DirectionsBuilder, Render\StoreRenderer, Render\SchemaOrgBuilder, Settings\Settings, Settings\PlacementCatalog, Settings\HookSynchronizer, Media\ImageUploader (8 Mo, 1200 px et 480 px), ThemePackage\ThemePackage.
Bloc Websource Builder
Classe Builder\StoreBlock, type store_info, libellé « Magasin / horaires », catégorie « Sections ».
| Champ | Valeurs |
|---|---|
| Quel magasin ? | main, all, store_<id> |
| Présentation | card Carte détaillée, compact Barre compacte, footer Colonne simple |
| Titre | défaut « Notre magasin » |
Page de configuration (AJAX)
Contrôleur AdminWebsourceStoreInfo, requêtes POST ajax=1&action=… (jeton du back-office), réponses JSON.
| Action | Paramètres | Réponse |
|---|---|---|
saveStore | id (0 = création), active, payload (JSON du magasin) | {"store": {id, slug, active, content}} ou {"error": "Indiquez le nom du magasin."} (422) |
deleteStore | id | {"ok": true} |
toggleStore | id, active | {"ok": true} |
reorder | ids (JSON) | {"ok": true} |
uploadImage | fichier photo | {"file": "<nom>.webp"} ou {"error": "…"} |
saveSettings | payload = {"settings": {…}, "placements": […]} | réglages et emplacements assainis |
preview | payload = {store, settings, layout, at, check, id, title} | {"html": "…", "feedback": {"w1": {"ok": true, "text": "9h – 12h / 14h – 18h"}}} |
Réglages et données
| Clé / table | Contenu |
|---|---|
WSSI_SETTINGS (par boutique) | {"main_store":1,"multi_display":"main|list","schema":true,"map":true,"providers":["google","waze","apple","osm"],"show":{"photo":true,"description":true,"phone":true,"email":true,"hours":true,"directions":true},"follow_theme":true,"design":{"bg":"","title_color":"","borders":true,"radius":"none|sm|md|lg","width":"box|wide"}} |
WSSI_PLACEMENTS (par boutique) | [{"position":"footer_col","page":"all","hook":"displayFooter","layout":"footer","store":"main","title":"Notre magasin"}] |
{prefix}wssi_store | id_wssi_store, id_shop, slug, position, active, content (JSON), date_upd |
modules/websourcestoreinfo/uploads/ | Photos (grande et petite taille). |
Contenu d'un magasin : source (manual, native), native_id, name, names{id_lang}, description{}, note{}, address1, address2, postcode, city, country, country_iso, phone, email, latitude, longitude, image, use_native_hours, hours{1..7} (1 = lundi), seasons[] (label, labels{}, from et to au format MM-JJ, hours{}), exceptions[] (label, labels{}, from, to au format AAAA-MM-JJ, hours).
Correspondance emplacement → hook : header_bardisplayBanner, under_headerdisplayNavFullWidth, footer_coldisplayFooter, before_footerdisplayFooterBefore, contact_pagedisplayLeftColumn (page contact), homedisplayHome, product_pickupdisplayProductAdditionalInfo, cartdisplayShoppingCartFooter, custom hook libre display[A-Za-z0-9]{2,80}.
Mises à niveau : upgrade-1.0.1.php (hooks par boutique), upgrade-1.1.0.php (dernière position dans displayFooter), upgrade-1.2.0.php (displayHeader), upgrade-1.3.0.php (hooks de paquet de thème).
Syntaxe des horaires
9h-12h / 14h-18h30, 10:00-19:00, 18h-2h (plage qui passe minuit), 24h/24, fermé ou vide. Une exception remplace les horaires du jour ; une saison remplace la semaine entière pendant sa période. Le calcul se fait dans le fuseau PS_TIMEZONE ; views/js/front.js rafraîchit le badge toutes les 30 secondes à partir de data-wssi-live.
Données structurées
Un nœud LocalBusiness par magasin actif, @id{base}#store-<slug>, parentOrganization{base}#organization, address, telephone, email, geo, hasMap, openingHoursSpecification, image. Magasin principal sur toutes les pages, tous les magasins sur la page des magasins. Désactivable (schema).
Liens d'itinéraire
| Clé | Adresse |
|---|---|
google | https://www.google.com/maps/dir/?api=1&destination=<lat,lng ou adresse> |
waze | https://waze.com/ul?ll=<lat,lng>&navigate=yes |
apple | https://maps.apple.com/?daddr=<lat,lng ou adresse> |
osm | https://www.openstreetmap.org/directions?route=;<lat,lng> |
Carte : https://www.openstreetmap.org/export/embed.html?bbox=…, insérée en iframe uniquement après le clic sur [data-wssi-map-button].
Template et CSS
Template views/templates/hook/store.tpl, surchargeable dans themes/<theme>/modules/websourcestoreinfo/views/templates/hook/. Variables Smarty : $wssi_stores, $wssi_layout, $wssi_title, $wssi_style, $wssi_wide, $wssi_multi, $wssi_show.
Classes : .wssi, .wssi--card, .wssi--compact, .wssi--footer, .wssi--wide, .wssi--multi, .wssi__store, .wssi__badge (is-open, is-closed…), .wssi__hours, .wssi__actions, .wssi__btn, .wssi__dir, .wssi__map, .wssi__note.
| Variable CSS | Rôle |
|---|---|
--wssi-bg, --wssi-fg, --wssi-title, --wssi-line | Fond, texte, titre, filets. |
--wssi-radius, --wssi-shadow | Arrondi et ombre de la carte. |
Variables du thème reprises avec repli : --color-brand-600, --color-brand-50, --color-ink, --color-line, --radius-xl, --radius-2xl, --wst-card-shadow ; dans le pied de page : --color-footer-ink, --color-footer-muted, --color-footer-line, --color-accent-wst.
Tests
php tests/run.php (logique d'ouverture), php tests/view_smoke.php, SMARTY_DIR=… php tests/render_smoke.php.