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 :

Formulaire imbriqué et dataTransformer [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2009
    Messages : 82
    Points : 63
    Points
    63
    Par défaut Formulaire imbriqué et dataTransformer
    Bonjour à tous, je n'arrive pas à comprends pourquoi mon DataTransformer fonctionne dans un cas et pas dans l'autre

    dans ce cas la ca fonctionne, mais si j'utilise un type pour subject ca ne fonctionne pas :

    TicketType:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $builder
     
       ->add($builder->create('subject', 'choice', array(
            'label' => 'form.contact.label.subject',
            'empty_value' => 'choice.empty.value',
            'required' => true,
            'multiple' => false,
            'choices' => $this->subjectRepository->findSubjectToArray()
        ))->addModelTransformer($this->subjectDataTransformer))
    dans ce cas la ca fonctionne plus :

    TicketType:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ->add('subject', 'help_desk_subject_form_type', array(
          'data_class' => 'F\HelpDeskBundle\Entity\Subject',
          'required' => false,
          'mapped' => true
      ))
    SubjecType

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add($builder->create('subject', 'choice', array(
                'label' => 'form.contact.label.subject',
                'empty_value' => 'choice.empty.value',
                'mapped' => false,
                'required' => true,
                'multiple' => false,
                'choices' => $this->subjectRepository->findSubjectToArray()
            ))->addModelTransformer($this->subjectDataTransformer))
        ;
    }
    Merci d'avance de votre aide.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Bonjour,

    une premiere piste,
    dans le premier cas, l'arborescence du formulaire est
    • subject (classe Subject, type entity)

    c'est cohérent avec ton modele de donné je suppose

    dans le deuxieme cas
    • subject (classe Subject, type SubjectType)
      • subject (classe Subject, type entity)

    ce qui voudrait dire que tu aie un attribut subject dans l'entité Subject elle-même


    ca ne fonctionne pas
    Il faut être plus précis !!! un message d'erreur est affiché peut-être ?

    A quoi sert le DataTransformer? tu n'as pas fourni son code

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2009
    Messages : 82
    Points : 63
    Points
    63
    Par défaut
    Salut arnooo999 et merci de ta réponse, je vais essayer de te répondre

    déja voici le code de mon DataTransformer

    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
    43
    44
    45
    46
    47
    48
    49
    class SubjectToNumberTransformer implements DataTransformerInterface
    {
        /**
         * @var SubjectManager F\HelpDeskBundle\Manager\SubjectManager
         */
        private $subjectManager;
     
        /**
         * @param \F\HelpDeskBundle\Manager\SubjectManager $subjectManager
         */
        public function __construct($subjectManager)
        {
            $this->subjectManager = $subjectManager;
        }
     
        /**
         * Transforms an object (Subject) to a string (number).
         *
         * @param  \F\HelpDeskBundle\Entity\Subject|null $subject
         * @return string
         */
        public function transform($subject)
        {
            //debug_r('transform . ' . $subject);
     
            if (null === $subject) {
                return "";
            }
     
            return $subject->getId();
        }
     
        /**
         * Transforms a string (number) to an object (Subject).
         *
         * @param  string $subjectId
         * @return Subject|null
         */
        public function reverseTransform($subjectId)
        {
            debug_r('new request , reverseTransof : ' . $subjectId);
     
            if (!$subjectId) {
                return null;
            }
     
            return $this->subjectManager->load($subjectId);
        }
    }
    Il me sert à convertir un ID de subject en entity subject, car dans mon formulaire qui fonctionne j'utilise un type choice que je remplis avec un array. je n'utilise pas entity car sinon avec les tradutions ca me bouffe un max de requêtes.

    Donc dans le formulaire 'TicketType' j'ajoute un champ subject (qui existe dans mon entity ticket) de type choice et je lui donne un array, (le dataTransformer fonctionne ici) et je peux enregistrer une entity subject dans mon attributs subject de mon "ticket", mais dans mon 'TicketType' j'injecte un SubjectRepository et un subjectDataTransformer que j'aurais voulu plutôt injecter dans un SubjectType, et c'est la que je commence à me perdre. exemple dans mon TicketType:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ->add('subject', 'help_desk_subject_form_type', array(
                   'data_class' => 'F\HelpDeskBundle\Entity\Subject',
                   'required' => false,
                   'mapped' => true
               ))
    En fait je viens de refaire un test, et je sais pas vraiment comment expliquer..

    dans mon ticket handler dans la methode onSuccess()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    debug_r('$ticket->getSubject()->getId() = ' . $ticket->getSubject()->getId());
    je ne retrouve pas l'id de mon subject et du coup j'ai et c'est logique cette erreur :

    A new entity was found through the relationship 'F\HelpDeskBundle\Entity\Ticket#subject' that was not configured to cascade persist operations for entity: . To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"})
    Erreur que je comprends et que je ne veux pas corriger comme indiqué dans l'exemple car je ne veux pas persister un nouveau sujet

    Je suis pas sur d'être clair..

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Concernant ma premiere remarque concernant l'incohérence entre modele de donnée et arborescence du formulaire.
    Il faudrait plutot faire un héritage
    NB héritage au sens du Composant Form (méthode getParent) et non héritage de classe
    Quelque chose comme cela:
    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
     
    class SubjectChoiceType extends AbstractType
    {
     
         public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->addModelTransformer($this->subjectDataTransformer))
        }
     
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'choices' => $this->subjectRepository->findSubjectToArray()
            ));
        }
     
        public function getParent()
        {
            return 'choice';
        }
     
        public function getName()
        {
            return 'subject_choice';
        }
    je ne retrouve pas l'id de mon subject
    Vu que tu met une option "data_class", ton subjectType essaie probablement d'instancier de lui-même cet objet

    je n'utilise pas entity car sinon avec les tradutions ca me bouffe un max de requêtes.
    Ne peux tu pas utiliser l'option "query_builder" pour optimiser cette requete (quitte à passer une option "locale" au FormType)?

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2009
    Messages : 82
    Points : 63
    Points
    63
    Par défaut
    Et bin voila tout fonctionne, je ne connaissais pas l'héritage du composant form ;-)

    Tout fonctionne correctement, mes validations, mon dataTransformer, bref le top.

    Concernant la requête, elle est mise en cache qui est invalidé si un admin rajoute un sujet

    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
        public function findSubjectToArray()
        {
            $qb = $this
                ->createQueryBuilder('s')
                ->select('s, t')
                ->join('s.translations', 't')
                ->where('t.locale = :locale')
                    ->setParameter('locale', $this->getLocale())
            ;
     
            $query = $qb->getQuery();
            $query->setResultCacheId('test');
     
            $data = $query->getResult();
     
            $subjects = array();
            foreach($data as $subject){
                $subjects[$subject->getId()] = $subject->getTitle();
            }
     
            return $subjects;
        }
    Si j'ai bien compris mon incohérence venait du faite d'ajouter un sujet dans un sujet et cela m'a pas percuté quand j'ai vu dans la requette post:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [
      subject => [subject => 3] 
    ]
    au lieu de

    Un grand merci pour ton aide.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Une derniere précision, le type "entity" héritant du type "choice",
    on peut également utiliser l'option "choices" sur un champ "entity" ( si l'option "query_builder" n'est pas suffisante pour ce que tu veux faire).
    Il prend simplement un tableau d'entités (récupéré du cache Doctrine dans ton cas).

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2009
    Messages : 82
    Points : 63
    Points
    63
    Par défaut
    Merci pour cette précision, je vais regarder ça. merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Struts] - Déclenchement d'une action dans un formulaire imbriqué
    Par Dabat dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 19/03/2009, 15h14
  2. Parcour des getElementById dans un formulaire imbriqué ?
    Par DrySs dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/10/2007, 19h03
  3. formulaire imbriquer + popup
    Par luan220 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 09/10/2007, 12h11
  4. Probleme Formulaire imbriques
    Par gloglo dans le forum Struts 1
    Réponses: 10
    Dernier message: 30/08/2006, 20h30
  5. formulaire imbriqué
    Par jani dans le forum Langage
    Réponses: 9
    Dernier message: 18/01/2006, 15h40

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