Développer un plugin Shopware 6 : premiers pas
Shopware 6 est une plateforme moderne, bâtie sur Symfony, avec une administration en Vue.js et une couche de données structurée (la DAL). Développer un plugin propre demande de maîtriser cet écosystème — mais le résultat est un code robuste, testable et durable. Voici l’anatomie d’un plugin Shopware 6, avec du code concret et les points clés du développement.
Anatomie d’un plugin Shopware 6
Un plugin Shopware 6 est, à la base, un bundle Symfony. Sa structure type :
composer.json: déclare le plugin, son namespace et la classe de base.- une classe Bootstrap qui étend la classe
Pluginde Shopware (namespace Shopware/Core/Framework). src/Resources/config/services.xml: la déclaration des services (injection de dépendances).src/Resources/app/administration/: l’extension de l’administration en Vue.js.src/Migration/: les migrations de base de données.
La classe de base est minimaliste : elle sert de point d’entrée et peut surcharger les méthodes du cycle de vie (install, update, activate, uninstall).
<?php declare(strict_types=1);
namespace Swag\Example;
use Shopware\Core\Framework\Plugin;
class SwagExample extends Plugin
{
}
Installer et activer le plugin
Une fois le plugin déposé, tout passe par la console Symfony de Shopware :
bin/console plugin:refresh
bin/console plugin:install --activate SwagExample
bin/console cache:clear
Le plugin:refresh fait découvrir le plugin, l’installation l’active, et le vidage de cache est presque toujours nécessaire (oublier cette étape fait croire à un bug inexistant).
Symfony au cœur
Tout repose sur le conteneur de services Symfony : on déclare ses services dans services.xml, on injecte les dépendances, et on réagit aux événements via des subscribers (implémentant EventSubscriberInterface). C’est l’équivalent propre des « hooks » : plutôt que de modifier le cœur, on écoute les événements émis par Shopware.
<?php declare(strict_types=1);
namespace Swag\Example\Subscriber;
use Shopware\Core\Checkout\Order\OrderEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class OrderSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten',
];
}
public function onOrderWritten($event): void
{
// Logique métier : notification, synchronisation ERP, etc.
}
}
La DAL (Data Abstraction Layer)
Shopware n’expose pas directement le SQL : on passe par la DAL, qui manipule des entités via des repositories. Pour stocker vos propres données, vous définissez une EntityDefinition (champs, relations), une entité et une collection, puis une migration qui crée la table. La DAL gère ensuite la lecture/écriture, les critères de recherche, les associations et la traduction. C’est plus verbeux qu’un simple INSERT, mais cohérent et puissant.
Une lecture typique passe par un objet Criteria :
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true));
$criteria->addAssociation('manufacturer');
$products = $this->productRepository->search($criteria, $context);
On compose ainsi filtres, tris, associations et agrégations sans écrire une ligne de SQL — et le code reste compatible avec les évolutions internes de Shopware.
Les migrations de base de données
Chaque modification de schéma vit dans une classe de src/Migration/, horodatée et versionnée. C’est ce qui garantit qu’un même plugin produit le même schéma sur tous les environnements (local, préproduction, production). Négliger les migrations, c’est s’exposer à des bases désynchronisées et à des bugs impossibles à reproduire.
L’administration en Vue.js
L’interface d’administration de Shopware 6 est une application Vue.js. Un plugin l’étend en ajoutant des modules, des composants, ou en surchargeant des vues existantes via le système d’override de composants. On y branche ses écrans de configuration, ses listes et ses formulaires, alimentés par l’Admin API. La règle d’or : étendre proprement plutôt que tout réécrire, pour rester compatible avec les mises à jour de l’administration.
Store API et Admin API
Shopware expose deux API : l’Admin API (back-office, gestion, intégrations) et la Store API (parcours client). Cette dernière est la clé des architectures headless : un frontend découplé (Vue, React, Next) consomme la Store API pour offrir une expérience rapide et sur mesure. Un plugin peut d’ailleurs enrichir la Store API avec ses propres routes, pour exposer une fonctionnalité métier au front découplé.
Bonnes pratiques
- Respecter les standards Shopware : services, subscribers, DAL — pas de contournement du cœur.
- Migrations versionnées : chaque évolution de schéma a sa migration.
- Tests : Shopware se prête bien aux tests automatisés ; on en profite.
- Compatibilité de version : suivre les dépréciations entre versions mineures de Shopware 6.
- Internationalisation : prévoir les snippets de traduction côté admin et storefront.
Erreurs courantes
- Vouloir écrire en base directement au lieu de passer par la DAL.
- Négliger les migrations (schéma désynchronisé entre environnements).
- Surcharger lourdement l’administration au lieu d’étendre proprement.
- Ignorer le cache Shopware lors du développement (et croire à un bug).
FAQ
Faut-il connaître Symfony ? Oui, c’est le socle de Shopware 6 ; Vue.js est nécessaire pour l’administration.
Shopware convient-il au B2B ? Très bien : tarifs par groupe, workflows et intégrations ERP/PIM en font une plateforme B2B solide.
Peut-on faire du headless ? Oui, via la Store API — voir mon guide Shopware headless. Pour situer Shopware face à PrestaShop, voir aussi Shopware vs PrestaShop.
Un besoin de plugin Shopware 6 ? Découvrez mon offre de développement de plugin Shopware 6 sur mesure ou décrivez votre projet.