moduler son application

a marqué ce sujet comme résolu.

Bonsoir,

Je travail sur un projet utilisant Symfony 3 et je souhaiterai moduler mon application.

Concrètement j'ai un Bundle de base fournissant les controller et entité de base, et je souhaiterai pouvoir via un fichier de configuration étendre ce Bundle en en incluant d'autre qui apporteront d'autres fonctionnalité.

Mon problème est d'étendre la base de données, concrètement j'ai dans mon bundle de base une entité. Dans un bundle complémentaire une nouvelle entité fait son apparition mais l'entité dans le module de base détient une relation sur cette nouvelle entité.

Ce que je souhaiterai c'est via ce bundle pouvoir décrire cette liaison.

Comment dois-je m'y prendre ?

Merci d'avance pour votre aide.
Cordialement, La source

+0 -1

Je n’ai pas l’impression que tu puisses encore vraiment exprimer des dépendances entre Bundles dans Symfony, même s’ils semblent en parler dans leur repo.

La question qui se pose, c’est pourquoi tu veux séparer les deux, en fait ?

+0 -0

Pour des questions de maintenabilité et de séparation des fonctions.

Le but est de distribuer l'application, chaque client ayant le choix d'activer ou non tel ou tel module. L'avantage c'est que l'application de base reste le plus simple possible, et en cas de bug il sera plus facile de cibler le problème.

Tu as raison de parler de dépendances, j'ai établis la liste des Bundle (des groupe de fonctionnalité) et c'est même carrément un arbre de dépendance puisque tout les Bundle on besoin du Bundle de base, mais des Bundle d'extension peuvent dépendre d'autre Bundle d'extension.

Je sais comment étendre une classe d'un autre Bundle mais j'ignore comment faire pour dans le core bundle utiliser les classes potentiellement étendue.

+0 -0

Je sais comment étendre une classe d'un autre Bundle mais j'ignore comment faire pour dans le core bundle utiliser les classes potentiellement étendue.

Par agrégation plutôt que par héritage ? Ou en définissant des interfaces ? Je dois avouer que ça sort de mon domaine de compétences, désolé.

+0 -0

Mon problème est d'étendre la base de données, concrètement j'ai dans mon bundle de base une entité. Dans un bundle complémentaire une nouvelle entité fait son apparition mais l'entité dans le module de base détient une relation sur cette nouvelle entité.

Si j'ai bien saisi, tu as une entité Doctrine dans ton bundle principal et tu veux que celle-ci puisse avoir des relations avec des entités Doctrine d'autres bundles sans que celles-ci soit déclarées au sein du bundle principal ?

Pour faire cela, tu peux créer une entité dans tes bundles complémentaires qui étendent l'entité de ton bundle principal. Doctrine possède un mécanisme d'héritage extrêmement souple, je t'invite à en lire la documentation : http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#class-table-inheritance

Ensuite, au sein de ces nouvelles entités - qui sont donc spécifiques à chaque bundle complémentaire - tu peux créer une ou plusieurs relations vers d'autres entités de ce bundle.

J'espère avoir répondu à ta question.

+0 -0

Merci pour vos réponses.

@Ekron, effectivement l'idée de base est bonne, sauf qu'en l'état ce n'est pas exactement ce que je recherche (et je commence sérieusement à me demander si ce que je recherche existe).

Dans les modes d'héritage proposé, soit on doit hériter d'une classe abstraite (sous entendu pas une entité) soit on doit préciser un critère discriminant pour que Doctrine sache dans quel cas il est.

Sauf que ce n'est pas vraiment cela que je recherche, l'idée est que si l'héritage est définit (de par l'inclusion même du Bundle d'extension) alors sa sera toujours l'objet étendu qui doit être manipuler et sauvegardé.

Je vais prendre un exemple concret:

J'ai mon Bundle de base qui contient une entité Product, dans ce Bundle évidement elle est manipulée correctement.

J'ai un Bundle d'extension qui définit une entité Model, l'entité Product devant être étendue pour tenir une relation ManyToOne vers cette nouvelle entité.

A partir de là, il est évident que si on manipule une entité Product sa doit toujours être l'entité complète, ce n'est pas parceque le Bundle de base n'utilise pas cette relation qu'elle n'existe concrètement pas, le seul fait que le Bundle d'extension existe dans le projet signifie qu'il faut manipuler l'entité complète.

Mon but avec ce découpage c'est vraiment de simplifier le travail au moment de l'ajout de la maintenant et du développement de nouvelles fonctions. Si on place tout dans un seul Bundle on se retrouve avec des entités avec 12 relations et des conditions dans tout les sens, dans le temps la maintenabilité est grandement amoindrie.

+0 -0

Si j'ai bien compris ce que tu demandes, a priori la solution que je te propose pourrait convenir.

Je reprends ton exemple :

  • l'entité Model du bundle complémentaire ;
  • l'entité Product du bundle principal qui n'a aucune relation avec Model ;
  • l'entité ProductExtended, située dans le bundle complémentaire, héritée de Product et possédant une relation avec Model.

Maintenant mettons que dans le bundle principal tu récupères la liste des Product parmi lesquels certains sont des ProductExtended. Eh bien sur les ProductExtended tu peux quand même utiliser ta relation (avec un méthode du style getModel()). Le contenant a beau être un Product, le contenu reste un ProductExtended et tu peux parfaitement utiliser toutes les méthodes de cette classe.

Alors ton IDE ne va pas forcément les reconnaître parce qu'au moment de l'écriture du code il ne peut pas savoir si ton Product est un Product ou un ProductExtended mais au moment de l'exécution, si c'est bien un ProductExtended (ce qu'on peut vérifier avec instanceof), PHP va appeler la méthode sans aucun problème.

J'espère que j'ai bien compris ton problème et que je n'ai pas répondu à côté, mes excuses si ce n'est pas le cas. :/

+0 -0

Doctrine ne risque t'il pas de faire des bétises ?

Si dans le Bundle de base j'ajoute/modifie une entité, que du point de vue de l'entité de base tout va bien mais si on prend en compte le point de vue de l'entité étendue cela ne va pas car la relation ManyToOne qu'elle tient n'est pas nullable…

Faudrai que je fasse le test mais j'imagine que doctrine construit ses requête select en fonction du schéma de l'entité dans le code source, donc un select dans le bundle de base ne récupérera pas les extensions fournie dans les Bundle complémentaire…

Bref, je crains vraiment que mon idée de séparer les différentes fonctionnalités dans des Bundle distinct est une mauvaise idée en pratique.

Merci de t'être pencher sur le problème, cependant j'ai peur que pour Symfony ce ne soie pas possible.

+0 -0

Salut,

Je travaille sur un truc d'un peu similaire en ce moment sur Symfony. J'ai été étonné en découvrant certains mécanismes qui, bien que complexes, sont très utiles et puissants.

Si l'on en croit la doc, ce que tu cherches à faire est impossible. Ceci étant dit, je pense qu'avec de la config c'est possible.

Tu as tes deux bundles. Le bundle de base fait son job, l'autre aussi, en redéclarant les classes et le mapping. Mais c'est avec une config dans app/config.yml que tu donnes la classe à utiliser :

1
2
3
#app/config.yml
my_bundle:
    product.entity: My/Extended/Bundle/Entity/MyEntity

Par défaut, le bundle de base déclare une config qui prend sa propre entité. En revanche, si tu déclares l'entité présente dans le bundle étendu, alors le travail se fera sur cette dernière.

Je ne sais pas si j'ai été très clair. A mon avis tu peux t'en tirer avec ce genre de méthode. Si ce n'est pas déjà fait, je t'invite à lire le deuxième lien donné et à regarder ceux donnés en fin de page sur la doc. Il y a moyen d'aller assez loin avec cette approche. Un peu complexe au début certes, mais vraiment très puissante.

Bon courage !

+0 -0

Um… alors oui tu as été clair et je te remercie pour ta réponse.

Je me pose une question, écrire un fichier de config avec comme clé dans my_bundle product.entity est-il lu par doctrine ?

Je veux dire, dans le bundle de base j'ai ma classe Product avec mon annotation @Entity et dans le Bundle extension on a une classe ProductExtend qui elle aussi à une annotation @Entity. Donc déjà ce que tu me conseille c'est de ne pas hériter de Product (et donc devoir redéfinir l'ensemble des propriété de la classe de base) ?

Parceque dans le cas contraire, si j'en hérite Doctrine me rouspète dessus en me disant que l'entité a déjà été définie.

+0 -0

Doctrine ne risque t'il pas de faire des bétises ?

Si dans le Bundle de base j'ajoute/modifie une entité, que du point de vue de l'entité de base tout va bien mais si on prend en compte le point de vue de l'entité étendue cela ne va pas car la relation ManyToOne qu'elle tient n'est pas nullable…

Faudrai que je fasse le test mais j'imagine que doctrine construit ses requête select en fonction du schéma de l'entité dans le code source, donc un select dans le bundle de base ne récupérera pas les extensions fournie dans les Bundle complémentaire…

Bref, je crains vraiment que mon idée de séparer les différentes fonctionnalités dans des Bundle distinct est une mauvaise idée en pratique.

Merci de t'être pencher sur le problème, cependant j'ai peur que pour Symfony ce ne soie pas possible.

La source

Ne confonds pas le stockage de l'entité avec son utilisation. Tu configures la façon dont Doctrine va comprendre ton héritage, mais derrière il va se démerder avec le stockage. Toi tu fais du PHP et en PHP tu peux parfaitement appeler n'importe quelle méthode d'un objet même si cet objet est placé dans un contenant qui n'a pas ces méthodes.

Doctrine va s'occuper de charger les données tout seul et il le fait très bien : il chargera toutes les données dont tu as besoin pour travailler de manière aussi naturelle que possible avec ton objet, en pur PHP.

+0 -0

Um… alors oui tu as été clair et je te remercie pour ta réponse.

Je me pose une question, écrire un fichier de config avec comme clé dans my_bundle product.entity est-il lu par doctrine ?

Je veux dire, dans le bundle de base j'ai ma classe Product avec mon annotation @Entity et dans le Bundle extension on a une classe ProductExtend qui elle aussi à une annotation @Entity. Donc déjà ce que tu me conseille c'est de ne pas hériter de Product (et donc devoir redéfinir l'ensemble des propriété de la classe de base) ?

Parceque dans le cas contraire, si j'en hérite Doctrine me rouspète dessus en me disant que l'entité a déjà été définie.

La source

Non, Doctrine ne pourra pas lire directement dans ton fichier de config. La conf permet juste de facilement spécifier sur quelle entité tu bosses (encore que dans ton cas je ne suis même pas sûr que ce soit obligatoire).

A priori, tu peux étendre ton entité sans problème, sans champ discriminatoire.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte