Tutorials

Crédit photo : pxfuel.com

Comment surcharger la configuration d'un Bundle avec Symfony 5

on Tuesday 16 March 2021

La possibilité de surcharger un fichier de configuration d'un bundle a été dépréciée en Symfony 4.4 puis supprimée en Symfony 5.0 sans donner de piste de remplacement. Voici une façon testée par nos soins pour remplacer ce comportement dans votre projet.

Point sur la situation

Dans un bundle Symfony, il est possible de configurer le conteneur mais également d'autres bundles.

Dans ce post, j'illustrerai mon propos en me basant sur la configuration du framework dans l'application e-commerce Sylius.

Le bundle utilisé pour gérer les workflows est Winzou StateMachineBundle. Il autorise la personnalisation des workflows en utilisant un fichier de configuration à placer dans config/packages .

Aïe Symfony 5

Cependant, il y a un gros problème. Impossible d'écraser la configuration d'une transition ou supprimer un état possible dans le graphe.

Le cas le plus courant est le tunnel de commande. Vous réalisez le tunnel de commande sur une seule page, il faut donc supprimer les étapes inutiles et tout rassembler dans une seule étape.

Avec Symfony 4.4, c'était fait en copiant le fichier de configuration du CoreBundle de Sylius (vendor/sylius/sylius/src/Sylius/Bundle/CoreBundle/Resources/config/app/state_machine/sylius_order_checkout.yml ) dans le dossier src/Resources/SyliusCoreBundle/config/app/state_machine

Mais lors de la mise à jour vers Sylius 1.9 basé sur Symfony 5, impossible de reproduire le comportement. Le fichier présent dans le dossier src/Resources  n'était pas utilisé/appelé par Symfony 5.

J'ai cherché une bonne journée avant de me tourner vers mes pairs et demander conseil. Pas de réaction sur les slacks communautaire Symfony ni Sylius... Personne n'a rencontré ce problème ? Personne n'est passé sur Symfony 5 avec Sylius ?

La solution m'a été proposée par mon collègue Jérémy et je vous livre le résultat testé !

Solution

La première chose à faire est d'ajouter le dossier config/override . Son fonctionnement sera le même que celui de Symfony 4.

Si vous avez du contenu dans src/Resources , déplacez le dans config/override

Maintenant modifier votre Kernel pour charger le fichier présent dans le dossier config/override à la place du fichier d'origine:

 

   

public function locateResource(string $name)
{
    if ('@' !== $name[0]) {
        throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name));
    } 
    if (false !== strpos($name, '..')) {
        throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
    }
    $bundleName = substr($name, 1);
    $path = '';
    if (false !== strpos($bundleName, '/')) {
        [$bundleName, $path] = explode('/', $bundleName, 2);
    } 
    $overrideFolderPath = $this->getProjectDir() . '/config/override'; 
    $bundleOverrideFolder = sprintf('%s/%s', $overrideFolderPath, $bundleName);
    if (is_dir($overrideFolderPath) && 0 === strpos($path, 'Resources')) {
        $overrideFilePath = sprintf('%s/%s', $bundleOverrideFolder, str_replace('Resources/', '', $path));
        if (is_file($overrideFilePath)) {
            return $overrideFilePath;
        }
    } 
    return parent::locateResource($name);
} 
   

Dites-moi dans les commentaires si cette cela vous a aidé ? Avez-vous fait autrement ?