IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Créer un Service Factory via Entity


Sujet :

Symfony PHP

  1. #1
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut Créer un Service Factory via Entity
    Bonjour à tous,
    pour une fois c'est moi qui pose une question (en attendant ma formation Sf2 )

    J'ai un Entity appelé Module, elle contient deux champs :

    'type' : le type correspond à un Bundle.
    'id' : l'id est l'id interne au type

    Exemple :
    Dans ma page j'ai 3 Modules :

    • type TextBundle, id 5
    • type LinkBundle, id 7
    • type ImageBundle, id 8


    pour afficher (dans twig) ces Bundles j'ai besoin de deux chose :
    un titre, un lien

    ces informations font parties des Bundles et sont liés a l'id d'un Entity des bundles (ex : TextBundle utilisera l'Entity Text)

    j'aimerai utiliser les services (sans doute schema .xsd a faire aussi) pour faire ça mais c'est le flou total pour ce genre de chose, ainsi que pour l'affichage (qui est ducoup dans le même style le WebProfilerBundle)

    Au final j'aimerai dans ma vue avoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <a href="text/5">Le titre du text 5</a>
    <a href="link/7">Le titre du lien 7</a>
    <a href="image/8">Le titre de l'image 8</a>
    pour rappel le bundle Module ne connais ni le lien, ni le titre

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    rien n’empêche, que comme les DataCollector du WebProfilerBundle,
    on fasse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //  /src/TextBundle/Resources/view/Module/text.html.twig
    {% include 'ModuleBundle:Profiler:module_item.html.twig' with { 'link': text.link, 'title' :text.title }
    puisqu'au final dans la vue j'ai que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    {% for module in modules %}
    ???
    {% endfor %}
    Controller

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $repository = $this->getDoctrine()->getRepository('PageBundle:Modules');
    $modules= $repository->findByPage($id);
     
    return array('modules' => $modules);

  3. #3
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Bon j'ai réussi,

    Dans la bundle (ModuleBundle), il passer par la méthode build et lui rajouter un Compiler

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class ModuleBundle extends Bundle
    {
        public function build(ContainerBuilder $container)
        {
            parent::build($container);
     
            $container->addCompilerPass(new ModuleCompilerPass());
        }
    }
    le compiler va permettre de recupere tout les services tag du type : module

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    namespace ModuleBundle\DependencyInjection\Compiler;
     
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\Reference;
     
    class ModuleCompilerPass implements CompilerPassInterface
    {
        public function process(ContainerBuilder $container)
        {
            if (false === $container->hasDefinition('module.factory')) {
                return;
            }
     
            $definition = $container->getDefinition('module.factory');
     
            foreach ($container->findTaggedServiceIds('module') as $id => $attributes) {
                $definition->addMethodCall('addModule', array(new Reference($id)));
            }
        }
    }
    voici le factory qui va géré ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    namespace ModuleBundle\Service;
     
    class ModuleFactory
    {
        private $modules;
     
        public function getModule($module)
        {
            return $this->modules[$module];
        }
     
        public function hasModule($module)
        {
            return isset($this->modules[$module]);
        }
     
        public function addModule($modules)
        {
            $this->modules[$modules->getName()] = $modules;
        }
    }
    Maintenant pour les modules, c'est simple dans la condf du service i lfaudra lui mettre le tag "module"
    Exemple pour TextModule

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?xml version="1.0" ?>
     
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
     
        <parameters>
            <parameter key="module.text.class">TextBundle\Module\ForumModule</parameter>
            <parameter key="module.text.entity">TextBundle:Text</parameter>
        </parameters>
     
        <services>
            <service id="module.module.text" class="%module.text.class%">
                <tag name="module" template="TextBundle:Module:text" id="text" />
                <argument type="service" id="doctrine.orm.entity_manager" />
                <argument>%moodle.text.entity%</argument>
            </service>
        </services>
    </container>
    Et la classe du Module

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <?php
     
    namespace textBundle\Module;
     
    use Moodle\ModuleBundle\Service\ModuleInterface;
    use Doctrine\ORM\EntityManager;
     
    class TextModule implements ModuleInterface
    {
        protected $em;
        protected $entity;
     
        private $forum;
     
        public function __construct(EntityManager $em, $entity)
        {
            $this->em = $em;
            $this->entity = $entity;
        }
     
        public function get($id)
        {
            $this->text= $this->em->find($this->entity, $id);
     
            return $this->text;
        }
     
        public function getTitle()
        {
            return $this->text->name;
        }
     
        public function getLink()
        {
            return $this->text->id;
        }
     
        public function getName()
        {
            return 'text';
        }
    }
    ensuite dans la vue on fera (pour le moment j'ai pas finis pour les templates) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $module = $this->get('module.factory')->get('text')->get(5);

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bon, c'est bien mignon tout ça mais s'agirait de voter un peu pour tes propres réponses

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut


    Ouai c'est nul, j'ouvre mon premier sujet, et c'est moi qui trouve
    (c'est possible que j'explique mal mon problème)

  6. #6
    Membre habitué Avatar de FrontLine
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2008
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2008
    Messages : 173
    Points : 134
    Points
    134
    Par défaut
    Merci pour ton auto-réponse bien utile

    Dans ta définition du container (xml) tu charges le template module.text, connaîtrais-tu un moyen de rendre ça plus générique (dynamique) par hasard ?

    Genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <tag name="tpl" template="TplBundle:UserBundle:*" id="{$1}" />
    $1 est la valeur de * (comme avec les REGEX).

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    alors enfaite j'avais mis ça mais dans mon exemple je m'en sert pas, si tu veux t'en servir

    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <tag name="module" template="TextBundle:Module:text" id="text" />
    a chaque fois qu'il check le tag il appelle la méthode addModule avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $definition->addMethodCall('addModule', array(new Reference($id)));
    si tu regardes bien dans la boucle y'a $id mais aussi $arguments

    et ici argument est égale à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    array(
        'template' => 'TextBundle:Module:text',
        'id' => 'text'
    );
    donc fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $definition->addMethodCall('addModule', array(new Reference($id), $arguments));
    et avec ces infos t'en fais ce que tu veux dans addModule

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public function addModule($modules, $arguments)
    {
     
    }

  8. #8
    Membre habitué Avatar de FrontLine
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2008
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2008
    Messages : 173
    Points : 134
    Points
    134
    Par défaut
    Super, merci pour l'explication !
    Je suis également en train de me farcir la doc, ça rentre au fur et à mesure ... Pas évident

Discussions similaires

  1. [Service] Créer un service manuellement
    Par thomas_strass dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 03/08/2016, 23h05
  2. [Delphi 2005 Personal] Créer un service NT
    Par dorian833 dans le forum EDI
    Réponses: 26
    Dernier message: 29/08/2005, 14h15
  3. Peut-on créer une page internet via JBuilder?
    Par Xavier dans le forum JBuilder
    Réponses: 2
    Dernier message: 17/02/2005, 21h21
  4. Réponses: 3
    Dernier message: 21/09/2003, 15h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo