Je partage aujourd’hui un concept pas nouveau, mais souvent oublié par les développeurs.

Dans le cadre de notre travail, il nous a été demandé de développer des bundles qui vont être réutilisés sur d’autres projets et utiliser par d’autres boîtes qui bossent pour le même client.

Le challenge ici était de sortir ce qui a été fait et le mettre dans un bundle dédié, donc pas mal de factorisation du code, le rendre plus générique, ….

Au lieu d’aller créer un dépôt et commencer de développer ou mettre le code déjà implémenté, nous avons profité du composer, tout en créant un dossier package qui va contenir le bundle

Voici un exemple de comment faire :

Dans votre fichier composer.json

....
"autoload": {
    "psr-4": {
       "App\\": "src/",
       "Bundle\\TrackingBundle\\":   
          "./packages/TrackingBundle/src"
      }
},
....

Le dossier package va contenir votre bundle avec son premier fichier README et son fichier composer.json dédié

Je parle ici dans un contexte (Ibexa3/Symfony5). Ibexa est DXP, CMS qui se base sur Symfony 5, donc coder avec Ibexa veut dire coder avec Symfony 5.

Parmi les premières choses qu’on a fait est utiliser la fonctionnalité

ça permet d’utiliser de la configuration par siteAccess. Comme vous le savez un CMS fournit cette fonctionnalité par défaut, siteAccess, afin d’avoir plusieurs sites sur la même instance. Du coup chaque site peut avoir sa propre configuration.

Ensuite au niveau du code du bundle. Ce dernier propose des services, le challenge ici, c’est que ces services devront proposer le max possible du besoin, mais ce qui n’est pas toujours le cas. Pour faire simple, nous avons créé des interfaces pour chaque service avec une implémentation par défaut. Si le besoin d’une boîte donnée qui va utiliser le bundle ne colle pas avec le service proposé, tout simplement ils peuvent implémenter l’interface afin de coder leur propre besoin. Ceci normalement on doit le faire sans attende une demande du client ou un développement dans un bundle spécifique, mais ce n’est pas toujours le cas

Voici quelques exemples

  • Services
    • Contracts
      • InterfaceA
      • InterfaceB
    • ServiceA (implements InterfaceA)
    • ServiceB (implements InterfaceB)

Avec la configuration par défaut du Symfony, tout rentre dans l’ordre

Rien du nouveau, mais juste il faut vraiment prendre le temps pour la conception car c’est la clé.