Sommaire
Architecture globale, du monolithe au modulaire
PrestaShop et son architecture monolithique historique
PrestaShop a été conçu comme une solution tout-en-un. Le code métier, la logique de présentation et la couche de données sont étroitement couplés. Cette approche présente des avantages pour démarrer rapidement, mais révèle des limites sur certains projets.
Caractéristiques de l'architecture PrestaShop :
- Framework propriétaire basé sur le pattern MVC (partiellement)
- Couplage fort entre les composants
- Classes globales accessibles partout (
Context,Db,Configuration) - Logique métier souvent mélangée avec la présentation
- Système de modules qui s'appuient sur des hooks
Exemple typique en PrestaShop :
// Récupération d'un produit dans PrestaShop
$product = new Product($id_product, true, $id_lang);
$price = Product::getPriceStatic($id_product, true);
// Utilisation du contexte global
$cart = Context::getContext()->cart;
$customer = Context::getContext()->customer;
Le contexte global (Context::getContext()) est omniprésent, ce qui facilite l'accès aux données mais crée des dépendances cachées et complique les tests unitaires.
Sylius et son architecture modulaire basée sur Symfony
Sylius est construit sur Symfony, framework PHP de référence qui implémente les principes SOLID et favorise l'injection de dépendances. L'architecture est découplée en composants indépendants.
Caractéristiques de l'architecture Sylius :
- Framework Symfony 6.x/7.x
- Architecture hexagonale (séparation domaine/infrastructure)
- Injection de dépendances systématique
- Séparation claire des responsabilités
- Composants réutilisables (Product, Order, Customer, etc.)
- Event-driven architecture
Même exemple en Sylius :
// Récupération d'un produit dans Sylius
class ProductController extends AbstractController
{
public function __construct(
private ProductRepositoryInterface $productRepository,
private OrderItemQuantityModifierInterface $orderItemQuantityModifier
) {}
public function showAction(Request $request): Response
{
$product = $this->productRepository->find($request->get('id'));
// Pas de contexte global, tout passe par l'injection de dépendances
}
}
Les dépendances sont explicites, injectées via le constructeur. Le code est testable, maintenable et suit les standards modernes.
Gestion des données de ObjectModel à Doctrine
PrestaShop : ObjectModel, un ORM maison
PrestaShop utilise ObjectModel, un système d'abstraction de base de données développé en interne. Chaque entité hérite de cette classe de base.
class Product extends ObjectModel
{
public $id_product;
public $name;
public $price;
public static $definition = [
'table' => 'product',
'primary' => 'id_product',
'multilang' => true,
'fields' => [
'price' => ['type' => self::TYPE_FLOAT, 'validate' => 'isPrice'],
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
],
];
// Les requêtes SQL se font souvent manuellement
public static function getProducts($id_lang, $start, $limit)
{
return Db::getInstance()->executeS('
SELECT p.* FROM '._DB_PREFIX_.'product p
WHERE p.active = 1
LIMIT '.(int)$start.', '.(int)$limit
);
}
}
Ce système est fonctionnel mais limité :
- Pas de relations complexes gérées automatiquement
- Requêtes SQL souvent écrites manuellement
- Difficultés avec les jointures complexes
- Pas de lazy loading
- Multi-langues géré de façon propriétaire
Sylius : Doctrine ORM, l'ORM de référence PHP
Sylius utilise Doctrine, l'ORM standard de l'écosystème Symfony. Les entités sont des POPO (Plain Old PHP Objects) annotées ou configurées via YAML/XML.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Product\Model\Product as BaseProduct;
#[ORM\Entity]
#[ORM\Table(name: 'sylius_product')]
class Product extends BaseProduct
{
// Les propriétés et relations sont définies via attributs
#[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
private float $price;
#[ORM\ManyToOne(targetEntity: Taxon::class)]
private ?Taxon $mainTaxon = null;
#[ORM\OneToMany(mappedBy: 'product', targetEntity: ProductVariant::class)]
private Collection $variants;
}
Avantages de Doctrine :
- Gestion automatique des relations (OneToMany, ManyToMany, etc.)
- DQL (Doctrine Query Language) au lieu de SQL brut
- Lazy loading et eager loading optimisés
- Migrations de schéma versionnées
- Support natif des locales via extensions (Translatable)
- Cache de second niveau
Exemple de requête avec Doctrine :
// Repository Doctrine
$products = $this->productRepository->createQueryBuilder('p')
->leftJoin('p.variants', 'v')
->where('p.enabled = :enabled')
->andWhere('v.onHand > :stock')
->setParameter('enabled', true)
->setParameter('stock', 0)
->getQuery()
->getResult();
Le DQL est plus lisible, sécurisé (paramètres bindés automatiquement) et permet l'utilisation du cache de requêtes.
Modules vs bundles, deux philosophies d'extension
PrestaShop : le système de modules
Les modules PrestaShop sont des dossiers autonomes contenant une classe principale héritant de Module. Ils interagissent avec le core via un système de hooks.
class MyModule extends Module
{
public function __construct()
{
$this->name = 'mymodule';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
parent::__construct();
}
public function install()
{
return parent::install()
&& $this->registerHook('displayHeader')
&& $this->registerHook('actionProductSave');
}
public function hookDisplayHeader($params)
{
// Ajout de CSS/JS
$this->context->controller->addCSS($this->_path.'views/css/style.css');
}
public function hookActionProductSave($params)
{
// Logique métier lors de la sauvegarde produit
$product = $params['object'];
// ...
}
}
Les limites du système PrestaShop :
- Namespace global, risques de conflits
- Difficile de surcharger proprement les classes du core
- Hooks parfois insuffisants, nécessitant des overrides
- Pas de gestion de dépendances entre modules
- Tests difficiles à mettre en place
Sylius : les bundles Symfony
Dans Sylius, les extensions sont des bundles Symfony. Un bundle est un ensemble cohérent de code (contrôleurs, entités, services, templates) qui peut enrichir ou modifier l'application.
namespace App\Bundle\CustomBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CustomBundle extends Bundle
{
// Le bundle est automatiquement enregistré dans config/bundles.php
}
Configuration des services dans un bundle :
# config/services.yaml
services:
App\EventListener\ProductListener:
tags:
- { name: kernel.event_listener, event: sylius.product.pre_create, method: onProductPreCreate }
Listener d'événement :
namespace App\EventListener;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
class ProductListener
{
public function onProductPreCreate(ResourceControllerEvent $event): void
{
$product = $event->getSubject();
// Logique métier avant création
}
}
Avantages des bundles :
- Namespaces propres, pas de conflits
- Injection de dépendances native
- Système d'événements structuré
- Testabilité maximale
- Composer pour gérer les dépendances
- Override propre via configuration
Templating, de Smarty à Twig
PrestaShop : Smarty, le moteur de templates historique
PrestaShop utilise Smarty, un moteur de templates séparant PHP et HTML.
{* templates/catalog/product.tpl *}
<div class="product">
<h1>{$product.name}</h1>
<p class="price">{$product.price}</p>
{if $product.images}
<div class="images">
{foreach from=$product.images item=image}
<img src="{$image.url}" alt="{$product.name}">
{/foreach}
</div>
{/if}
{hook h='displayProductButtons'}
</div>
Smarty est fonctionnel mais vieillissant. La syntaxe est parfois verbeuse et les performances peuvent être un point faible sur des catalogues volumineux.
Sylius : Twig, le standard Symfony
Sylius utilise Twig, le moteur de templates moderne de Symfony. Twig est plus rapide, plus sécurisé (échappement automatique) et mieux intégré.
{# templates/product/show.html.twig #}
<div class="product">
<h1>{{ product.name }}</h1>
<p class="price">{{ product.price|sylius_format_money }}</p>
{% if product.images is not empty %}
<div class="images">
{% for image in product.images %}
<img src="{{ image.path|imagine_filter('sylius_large') }}"
alt="{{ product.name }}">
{% endfor %}
</div>
{% endif %}
{{ sylius_template_event('sylius.shop.product.show.buttons', {'product': product}) }}
</div>
Avantages de Twig :
- Syntaxe claire et concise
- Échappement automatique (sécurité XSS)
- Héritage de templates puissant
- Filtres et fonctions extensibles
- Cache natif très performant
- Intégration parfaite avec Symfony
Héritage de templates :
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
{% block stylesheets %}
<link rel="stylesheet" href="/css/main.css">
{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{# templates/product/show.html.twig #}
{% extends 'base.html.twig' %}
{% block content %}
<div class="product">
{{ product.name }}
</div>
{% endblock %}
Hooks vs Event Dispatcher, du couplage au découplage
PrestaShop : les hooks
Les hooks PrestaShop permettent aux modules d'injecter du code à des points précis de l'application.
// Dans le core PrestaShop
Hook::exec('displayProductButtons', ['product' => $product]);
// Dans un module
public function hookDisplayProductButtons($params)
{
$product = $params['product'];
return $this->display(__FILE__, 'views/templates/hook/product-button.tpl');
}
Limites des hooks :
- Nombre limité de hooks disponibles
- Impossible de modifier les données en profondeur
- Ordre d'exécution parfois problématique
- Difficile de débugger une chaîne de hooks
- Couplage fort avec les positions dans le code
Sylius : Event Dispatcher et Template Events
Sylius utilise le composant EventDispatcher de Symfony, basé sur le pattern Observer. N'importe quelle action peut déclencher un événement, et plusieurs listeners peuvent y réagir.
Événements métier :
// Dispatch d'un événement
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class ProductService
{
public function __construct(
private EventDispatcherInterface $eventDispatcher
) {}
public function createProduct(Product $product): void
{
// Logique de création
$this->eventDispatcher->dispatch(
new ProductCreatedEvent($product),
'app.product.created'
);
}
}
// Listener
class SendProductNotificationListener
{
public function onProductCreated(ProductCreatedEvent $event): void
{
$product = $event->getProduct();
// Envoi notification, mise à jour cache, etc.
}
}
Template Events (équivalent des hooks d'affichage) :
# config/packages/sylius_ui.yaml
sylius_ui:
events:
sylius.shop.product.show.buttons:
blocks:
custom_button:
template: '@App/Product/_customButton.html.twig'
priority: 10
{# templates/Product/_customButton.html.twig #}
<button class="custom-action">Custom Action</button>
Avantages :
- Découplage total entre émetteur et récepteurs
- Priorités d'exécution configurables
- Événements typés (auto-complétion IDE)
- Possibilité de modifier les données via événements
- Débuggage facilité (profiler Symfony)
Overrides vs Decoration, modifier le comportement
PrestaShop : les overrides
PrestaShop permet de surcharger des classes du core via le système d'overrides.
// override/classes/Product.php
class Product extends ProductCore
{
public function add($autodate = true, $nullValues = false)
{
// Logique custom avant
$result = parent::add($autodate, $nullValues);
// Logique custom après
return $result;
}
}
Problèmes des overrides :
- Conflits entre modules (deux modules ne peuvent pas override la même classe)
- Difficile à maintenir lors des mises à jour
- Impossible à tester unitairement
- Modification globale sans contrôle fin
- Casse facilement lors des montées de version
Sylius : decoration pattern et interfaces
Sylius privilégie le decoration pattern, basé sur l'injection de dépendances et les interfaces.
Exemple : décorer un service de calcul de prix
// Service original (interface)
interface ProductPriceCalculatorInterface
{
public function calculate(ProductInterface $product): int;
}
// Décorateur
class CustomProductPriceCalculator implements ProductPriceCalculatorInterface
{
public function __construct(
private ProductPriceCalculatorInterface $decoratedCalculator
) {}
public function calculate(ProductInterface $product): int
{
$basePrice = $this->decoratedCalculator->calculate($product);
// Logique custom : réduction de 10% si produit en promo
if ($product->hasPromotion()) {
return (int) ($basePrice * 0.9);
}
return $basePrice;
}
}
Configuration du décorateur :
# config/services.yaml
services:
App\Calculator\CustomProductPriceCalculator:
decorates: 'sylius.calculator.product_price'
arguments:
$decoratedCalculator: '@.inner'
Avantages :
- Pas de conflit entre décorateurs (ils s'empilent)
- Testable unitairement (mock de l'interface)
- Modification ciblée d'un comportement
- Compatible avec les mises à jour
- Respecte le principe Open/Closed (SOLID)
Routing, de dispatcher.php aux routes Symfony
PrestaShop : routing dynamique
PrestaShop utilise un système de routing propriétaire basé sur les contrôleurs et la réécriture d'URL.
// URL : /product/123-mon-produit
// Route vers : ProductController
// Paramètres extraits de l'URL rewritée
Les friendly URLs sont gérées via la table ps_meta et le .htaccess. Ajouter des routes personnalisées nécessite des configurations complexes.
Sylius : système de routing Symfony
Sylius utilise le composant Routing de Symfony. Les routes sont déclaratives, typées et versionnées.
# config/routes/shop.yaml
app_shop_product_show:
path: /products/{slug}
methods: [GET]
defaults:
_controller: sylius.controller.product:showAction
_sylius:
template: '@SyliusShop/Product/show.html.twig'
Route avec attributs PHP :
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractController
{
#[Route('/products/{slug}', name: 'app_product_show', methods: ['GET'])]
public function show(string $slug): Response
{
// Logic
}
}
Avantages :
- Routes clairement définies et documentées
- Génération d'URL automatique (
{{ path('app_product_show', {slug: product.slug}) }}) - Contraintes sur les paramètres (regex, type)
- Préfixes et groupes de routes
- Débuggage facile (
bin/console debug:router)
Gestion du catalogue, concepts produits
PrestaShop : produit avec combinaisons
Dans PrestaShop, un produit peut avoir des "combinaisons" (déclinaisons).
Produit : T-shirt
├─ Combinaison : Taille S, Couleur Rouge (SKU: TSHIRT-S-RED)
├─ Combinaison : Taille M, Couleur Rouge (SKU: TSHIRT-M-RED)
└─ Combinaison : Taille S, Couleur Bleu (SKU: TSHIRT-S-BLUE)
Chaque combinaison a son propre stock, prix, référence. Les attributs (taille, couleur) sont partagés entre produits.
Limites :
- Gestion complexe des attributs interdépendants
- Difficile de gérer des variantes avec des caractéristiques très différentes
- Stock géré au niveau combinaison, pas toujours intuitif
Sylius : Product et ProductVariant
Sylius sépare clairement Product (concept) et ProductVariant (SKU réel).
Product : T-shirt (concept marketing)
└─ ProductVariant : T-shirt S Rouge (SKU, prix, stock)
└─ ProductVariant : T-shirt M Rouge
└─ ProductVariant : T-shirt S Bleu
Modèle d'entités :
class Product
{
private string $code; // Identifiant unique
private Collection $variants; // Toutes les variantes
private Collection $attributes; // Attributs produit (matière, etc.)
}
class ProductVariant
{
private string $code; // SKU
private Product $product;
private int $onHand; // Stock physique
private int $onHold; // Stock réservé
private Collection $optionValues; // Taille S, Couleur Rouge
}
class ProductOption
{
private string $code; // 'taille' ou 'couleur'
private Collection $values; // S, M, L ou Rouge, Bleu
}
Avantages :
- Séparation claire concept/SKU
- Gestion fine du stock (onHand, onHold, reserved)
- Options de variantes configurables
- Support natif des produits configurables
- Possibilité d'avoir des variantes très différentes
Système de prix et promotions
PrestaShop : prix spécifiques et règles panier
PrestaShop gère les prix via :
- Prix de base produit
- Prix spécifiques (par groupe, pays, devise, quantité)
- Règles panier (codes promo, réductions automatiques)
// Calcul de prix dans PrestaShop
$price = Product::getPriceStatic(
$id_product,
$usetax,
$id_product_attribute,
$decimals,
$divisor,
$only_reduc,
$usereduc,
$quantity,
$force_associated_tax,
$id_customer,
$id_cart,
$id_address
);
Cette méthode statique avec 12 paramètres illustre la complexité accumulée au fil des versions.
Sylius : système de pricing unifié
Sylius utilise un système de pricing moderne basé sur des services dédiés.
// Calculateurs de prix injectés
class ProductController
{
public function __construct(
private ProductVariantPriceCalculatorInterface $calculator
) {}
public function showAction(ProductVariant $variant): Response
{
$price = $this->calculator->calculate($variant, [
'channel' => $this->getChannel(),
]);
}
}
ChannelPricing : prix par canal
class ChannelPricing
{
private Channel $channel;
private int $price; // En centimes
private ?int $originalPrice; // Prix barré
}
Chaque variante a un prix par canal (boutique). Le prix peut varier selon le canal, sans confusion.
Promotions : système d'actions et de règles
// Promotion : -10% sur la catégorie T-shirts
$promotion = new CatalogPromotion();
$promotion->addScope(new ForTaxonsScopeConfiguration(['tshirts']));
$promotion->addAction(new PercentageDiscountActionConfiguration(0.1));
Les promotions sont des entités à part entière, avec priorités, dates de validité, et règles composables.
Gestion des commandes, workflow et états
PrestaShop : états de commande linéaires
PrestaShop définit des états de commande via une table de configuration (ps_order_state).
En attente de paiement → Paiement accepté → En préparation → Expédié → Livré
Les transitions sont souvent gérées manuellement ou via hooks. Il n'y a pas de validation automatique des transitions possibles.
Sylius : State Machine (Workflow Symfony)
Sylius utilise le composant Workflow de Symfony pour gérer les états de commande, paiement et expédition.
Configuration du workflow :
# config/packages/sylius_order.yaml
winzou_state_machine:
sylius_order_checkout:
class: Sylius\Component\Core\Model\Order
property_path: checkoutState
states:
cart: ~
addressed: ~
shipping_selected: ~
payment_selected: ~
completed: ~
transitions:
address:
from: [cart]
to: addressed
select_shipping:
from: [addressed]
to: shipping_selected
select_payment:
from: [shipping_selected]
to: payment_selected
complete:
from: [payment_selected]
to: completed
Utilisation dans le code :
use SM\Factory\FactoryInterface;
class CheckoutService
{
public function __construct(
private FactoryInterface $stateMachineFactory
) {}
public function completeCheckout(OrderInterface $order): void
{
$stateMachine = $this->stateMachineFactory->get($order, 'sylius_order_checkout');
if ($stateMachine->can('complete')) {
$stateMachine->apply('complete');
// Events dispatched automatiquement
}
}
}
Avantages :
- Transitions validées automatiquement
- Impossible de passer d'un état invalide à un autre
- Événements déclenchés sur chaque transition
- Visualisation graphique du workflow
- Callbacks avant/après transition
Multi-boutiques, des approches différentes
PrestaShop : système multi-boutiques intégré
PrestaShop permet de gérer plusieurs boutiques partageant la même installation.
Multistore PrestaShop
├─ Boutique FR (URL: fr.example.com)
├─ Boutique EN (URL: en.example.com)
└─ Boutique B2B (URL: b2b.example.com)
Chaque boutique peut avoir :
- Son propre catalogue (ou partagé)
- Ses propres clients (ou partagés)
- Ses propres commandes
- Ses propres thèmes
Configuration : interface graphique dans le back-office.
Sylius : système de channels
Sylius utilise le concept de "channel" (canal de vente).
class Channel
{
private string $code;
private string $name;
private Locale $defaultLocale;
private Collection $locales;
private Collection $currencies;
private Currency $baseCurrency;
private string $hostname;
private string $color; // Pour l'admin
}
Un channel représente un point de vente :
- Site web classique
- Application mobile
- Point de vente physique
- Marketplace
Avantages :
- Prix par canal (même produit, prix différent selon canal)
- Promotions par canal
- Thème par canal
- Inventaire partagé ou séparé
- Gestion fine des locales et devises par canal
Configuration déclarative :
# config/packages/sylius_channel.yaml
sylius_channel:
default_channel: web_fr
channels:
web_fr:
locales: [fr_FR]
currencies: [EUR]
hostname: www.example.fr
web_en:
locales: [en_US, en_GB]
currencies: [USD, GBP]
hostname: www.example.com
API : de webservices à API Platform
PrestaShop : Webservices XML
PrestaShop propose une API XML/REST basique.
GET /api/products/1
<?xml version="1.0" encoding="UTF-8"?>
<prestashop>
<product>
<id>1</id>
<name>
<language id="1">Product Name</language>
</name>
<price>19.99</price>
</product>
</prestashop>
Limites :
- Format XML imposé (JSON limité)
- Authentification par clé simple
- Pas de pagination moderne
- Pas de filtres avancés
- Documentation basique
- Performances limitées
Sylius : API Platform (JSON-LD, GraphQL)
Sylius 1.12+ intègre API Platform, framework de référence pour les API REST/GraphQL.
GET /api/v2/shop/products/tshirt-slug
{
"@context": "/api/v2/contexts/Product",
"@id": "/api/v2/shop/products/tshirt-slug",
"@type": "Product",
"code": "TSHIRT",
"name": "T-Shirt Premium",
"slug": "tshirt-slug",
"variants": [
{
"@id": "/api/v2/shop/product-variants/tshirt-s-red",
"code": "TSHIRT-S-RED",
"price": 1999,
"stock": 15
}
]
}
Caractéristiques :
- JSON-LD (Linked Data) avec hypermedia
- GraphQL disponible
- Authentification JWT
- Filtres, tris, pagination automatiques
- Documentation OpenAPI générée automatiquement
- Performances optimisées (cache HTTP, Varnish)
- Extensibilité totale
Définir une ressource API :
use ApiPlatform\Core\Annotation\ApiResource;
#[ApiResource(
collectionOperations: ['get', 'post'],
itemOperations: ['get', 'put', 'delete'],
attributes: ['pagination_items_per_page' => 30]
)]
class Product extends BaseProduct
{
// L'API est générée automatiquement
}
Tests : de l'artisanal à l'industriel
PrestaShop : tests limités
PrestaShop propose quelques tests unitaires et fonctionnels, mais la couverture est partielle. Tester du code custom est complexe à cause des dépendances globales.
// Difficile à tester à cause du contexte global
class MyModule extends Module
{
public function processOrder($id_cart)
{
$cart = new Cart($id_cart);
$customer = Context::getContext()->customer;
// Impossible de mocker Context
}
}
Sylius : tests omniprésents
Sylius est conçu pour être testé. L'injection de dépendances permet de mocker facilement.
Test unitaire :
use PHPUnit\Framework\TestCase;
class ProductPriceCalculatorTest extends TestCase
{
public function testCalculateWithPromotion(): void
{
$product = $this->createMock(ProductInterface::class);
$product->method('hasPromotion')->willReturn(true);
$calculator = new CustomProductPriceCalculator($basePriceCalculator);
$price = $calculator->calculate($product);
$this->assertEquals(900, $price); // 10% de réduction
}
}
Test fonctionnel (Behat) :
Feature: Shopping cart
In order to buy products
As a customer
I need to be able to add products to cart
Scenario: Adding a product to cart
Given there is a product "T-Shirt" priced at €20
When I add this product to the cart
Then I should have 1 item in my cart
And my cart total should be €20
Sylius inclut Behat et PHPUnit par défaut, avec des contextes pré-configurés pour tester les scénarios e-commerce.
Migration progressive : stratégies possibles
Approche Big Bang (recommandée)
Développer entièrement Sylius en parallèle, migrer les données, puis basculer d'un coup.
Avantages : migration propre, pas de systèmes hybrides complexes.
Inconvénient : nécessite une phase de développement complète avant bascule
Approche hybride (déconseillée mais possible)
Utiliser PrestaShop et Sylius en parallèle avec synchronisation de données.
Cas d'usage : migration très progressive, tests A/B
Complexité : très élevée, nécessite une synchronisation bidirectionnelle
Synthèse : changement de culture technique
Passer de PrestaShop à Sylius, c'est adopter :
| Aspect | PrestaShop | Sylius |
|---|---|---|
| Framework | Propriétaire | Symfony (standard) |
| Architecture | Monolithique | Modulaire/Hexagonale |
| ORM | ObjectModel | Doctrine |
| Templates | Smarty | Twig |
| Extension | Modules + Hooks | Bundles + Events |
| Override | Classes globales | Decoration Pattern |
| API | XML/REST basique | API Platform (REST/GraphQL) |
| Tests | Limité | PHPUnit + Behat natifs |
| DI | Contexte global | Injection de dépendances |
| Routing | Dynamique propriétaire | Routing Symfony |
| Workflow | États manuels | State Machine |
Ce que cela implique pour un développeur PrestaShop :
- Apprendre Symfony : framework, composants, bonnes pratiques
- Maîtriser Doctrine : ORM, DQL, relations, migrations
- Adopter les design patterns modernes : DI, Decoration, Repository
- Penser en événements plutôt qu'en hooks
- Écrire du code testable dès le départ
- Utiliser Composer pour gérer les dépendances
- Suivre les standards PSR (PSR-4, PSR-12, etc.)
Ressources pour approfondir
Formation Symfony
- Symfony Documentation : https://symfony.com/doc/current/index.html
- SymfonyCasts : https://symfonycasts.com/
- Formation certifiante Symfony
Documentation Sylius
- Sylius Documentation : https://docs.sylius.com/
- Sylius Cookbook : recettes pour cas spécifiques
- Sylius Plus : version entreprise avec fonctionnalités avancées
Communauté
- Sylius Slack : échanges avec la communauté
- GitHub Discussions : questions techniques
- Sylius France : meetups et conférences
Dans notre dernier article, on détaille comment migrer ses données de PrestaShop vers Sylius, pas à pas.
Sources et références
- Sylius Architecture Documentation
- Symfony Best Practices
- Doctrine ORM Documentation
- API Platform Documentation
- PrestaShop Developer Documentation