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 :

Service Encoder [2.x]


Sujet :

Symfony PHP

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 6
    Points
    6
    Par défaut Service Encoder
    Bonsoir à tous,

    J'ai à nouveau des ennuis avec le méchant Symfony2 ! Nen je rigole il est très gentil, mais parfois capricieux.

    J'ai créé un formulaire (en trois parties avec le handler et le type et le reste dans le contrôleur ) et je dois aller chercher le service encoder factory pour encoder mes mots de passe. Quand mon formulaire était en une seule partie, tout fonctionnait bien et la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $factory = $this->get('security.encoder_factory');
    fonctionnait très bien !

    Mais la, j'ai un soucis c'est que quand j'appelle le service au sein de mon FormHandler, ça ne fonctionne plus ! J'ai une belle erreur.

    Voici les codes de mes formulaires :

    RegisterHandler :
    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
    50
    51
    52
    53
    <?php
     
    namespace AudioSuivi\UserBundle\Form\Handler;
     
    use Symfony\Component\Form\Form;
    use Symfony\Component\HttpFoundation\Request;
    use Doctrine\ORM\EntityManager;
    use AudioSuivi\UserBundle\Entity\User;
     
    class RegisterHandler
    {
        protected $form;
        protected $request;
        protected $em;
     
        public function __construct(Form $form, Request $request, EntityManager $em)
        {
            $this->form    = $form;
            $this->request = $request;
            $this->em      = $em;
        }
     
        public function process()
        {
            if( $this->request->getMethod() == 'POST' )
            {
                $this->form->bindRequest($this->request);
                if( $this->form->isValid() )
                {
                    $this->onSuccess($this->form->getData());
                    return true;
                }
            }
            return false;
        }
     
        public function onSuccess(User $user)
        {
    		// Appelle du service encoder_factory
    		$factory = $this->get('security.encoder_factory');
    		// Récupération du mot de passe entré par l'utilisateur dans le formulaire
    		$password = $user->getPassword();
    		// Lie l'objet $user à l'encoder
    		$encoder = $factory->getEncoder($user);
    		// Encodage du mot de passe en sha512 (précisé dans le security.yml
    		$password_encode = $encoder->encodePassword($password, $user->getSalt());
    		// Hydratation de l'utilisateur avec le password encodé
    		$user->setPassword($password_encode);
    		// Création de l'utilisateur
            $this->em->persist($user);
            $this->em->flush();
        }
    }

    RegisterType :
    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
    <?php
     
    namespace AudioSuivi\UserBundle\Form\Type;
     
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilder;
     
    class RegisterType extends AbstractType
    {
        public function buildForm(FormBuilder $builder, array $options)
        {
    	    $builder
                ->add('username',  'text')
    			->add('email',     'text')
    			->add('password',  'repeated', array('type' => 'password', 'invalid_message' => 'Mot de passe incorrect, veuillez vérifier', 'first_name' => 'Mot de passe', 'second_name' => 'Vérification',));
        }
     
        public function getName()
        {
            return 'audiosuivi_userbundle_registertype';
        }
     
    	public function getDefaultOptions(array $options)
        {
            return array(
                'data_class' => 'AudioSuivi\UserBundle\Entity\User',
            );
        }
    }
    Le contrôleur est tout à fait classique :
    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
    <?php
     
    namespace AudioSuivi\UserBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use AudioSuivi\UserBundle\Entity\User;
    use AudioSuivi\UserBundle\Entity\Group;
    use Audiosuivi\UserBundle\Form\Type\RegisterType;
    use AudioSuivi\UserBundle\Form\Handler\RegisterHandler;
     
     
    class RegisterController extends Controller
    {
        public function registerAction()
        {
    		// Création de l'objet User
    		$user = New User;
     
    		// Appelle du service encoder_factory
    		$factory = $this->get('security.encoder_factory');
     
    		// On appelle le formulaire RegisterType.php
    		$form = $this->createForm(new RegisterType, $user);
     
    		// Appelle de RegisterHandler pour gérer le traitement du formulaire
    		$formHandler = new RegisterHandler($form, $this->get('request'), $this->getDoctrine()->getEntityManager());
     
    		// Execution du traitement du formulaire
    		if( $formHandler->process() )
            {
    			// Redirection vers la page d'accueil, pour l'instant
                return $this->redirect( $this->generateUrl('_welcome') );
            }
     
    		// Création de la vue du formulaire avec createView
            return $this->render('AudioSuiviUserBundle:Register:register.html.twig', array('form' => $form->createView()));
        }
    }

    Et donc quand j'essaye d'inscrire un membre, j'ai cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fatal error: Call to undefined method AudioSuivi\UserBundle\Form\Handler\RegisterHandler::get() in D:\wamp\www\Audiosuivi\src\AudioSuivi\UserBundle\Form\Handler\RegisterHandler.php on line 40

    Je ne comprends pas du tout pourquoi ! Alors que quand j'appelais le service dans le contrôleur tout allait bien.. Sauriez-vous pourquoi ?

  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
    c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $factory = $this->get('security.encoder_factory');
    Il faut passer le encoder_factory dans le constructeur via ton service
    D'ailleurs pour ne pas avoir fait un service ?

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2011
    Messages : 34
    Points : 30
    Points
    30
    Par défaut ContainerInterface
    Possible que tu as besoin utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Symfony\Component\DependencyInjection\ContainerInterface;
    par la suite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $encoder = $this->container->get('security.encoder_factory');

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    @stealth35 : et bien tout simplement parce que je ne maîtrise pas bien cette notion de service encore ! Et surtout parce que quand je tapais cette ligne dans le contrôleur avant de diviser mon formulaire en trois parties (handler, type, etc.) ça fonctionnait sans que je déclare quoi que ce soit ! Donc la je comprends pas pourquoi le simple fait de déplacer la ligne de code dans un autre fichier.php ça ne fonctionne plus... Sinon, peux-tu m'indiquer la démarche à suivre (une doc ou je ne sais pas ?) pour déclarer le service encoder ? Merci !

    @ziemelitis : j'ai cru lire que cette méthode du container c'était pour des loader en fixture ! Mais bon, comme j'avais rien à perdre, j'ai essayé, mais ça ne fonctionne quand même pas j'ai cette erreur de la part de symfony2 (et non plus d'apache !) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Notice: Undefined property: AudioSuivi\UserBundle\Form\Handler\RegisterHandler::$container in D:\wamp\www\Audiosuivi\src\AudioSuivi\UserBundle\Form\Handler\RegisterHandler.php line 43

  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

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Bon, je viens d'essayer de lire la doc mais j'ai encore beaucoup de mal à comprendre ! En fait Symfony2 à déjà des services intégrés comme $session = $this->get('session'); ou encore pour envoyer des mails avec SfwiftMailer par exemple. Dans un contrôleur je peux y accéder directement sans problèmes, mais dans le Handler, peu importe le use XX/XX/XX que j'utilise, il ne trouve aucun des services ! Que ça soit l'encoder ou le mail ou même accéder à doctrine... C'est ce point la que je ne comprends pas ?

    Pourquoi je dois créer un service alors qu'il existe déjà dans Symfony2 ? Mais que je n'arrive pas à y accéder dans le FormHandler ?

    En tous cas, merci de vos réponses !

  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
    Citation Envoyé par Styblue Voir le message
    Pourquoi je dois créer un service alors qu'il existe déjà dans Symfony2 ? Mais que je n'arrive pas à y accéder dans le FormHandler ?
    Pour ça justement, les services sont la pour l'injection de dépendance.
    Mais en lisant ton code, t'as pas a faire tout ça, si ton User implémente UserIterface le password se fera tout seul,
    Pourquoi ne pas mettre ça dans le controller ?

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    En fait je voulais respecter l'architecture Handler / Type / Controler pour pouvoir réutiliser mes formulaires (par exemple pour modification du profil). A priori, c'est ce qu'il faut faire pour avoir quelque chose de propre.

    Donc la si je veux absolument l'utiliser dans un Handler, c'est à dire pas dans un controler, il faut déclarer le service, c'est bien ça ?

    Oui, j'implémente bien UserInterface, mais le password n'est pas encodé du coup ! Mais j'y pense.. peut être que je peux encoder directement dans l'entité User ?

    Je vais tester tout ça !

    Merci

  9. #9
    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
    fait juste ç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
    22
    23
    24
    public function registerAction()
    {
        $user = New User;
        $form = $this->createForm(new RegisterType, $user);
     
        if( $this->request->getMethod() == 'POST' ) {
            $form->bindRequest($this->request);
     
            if($this->form->isValid()) {
                $em = $this->getDoctrine()->getEntityManager();
     
                $encoder = $factory->getEncoder($user);
                $password = $encoder->encodePassword($user->getPassword(), $user->getSalt());
                $user->setPassword($password);
     
                $em->persist($user);
                $em->flush();
     
                return $this->redirect( $this->generateUrl('_welcome'));
            }
        }
     
        return  array('form' => $form->createView()));
    }
    et puis le Handler c'est avec le FOSUserBundle, c'est pas natif de Symfony

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    D'accord, donc j'enlève simplement le Handler et je le met dans le Controler ! Oui, la ça fonctionne !

    Merci pour tes conseils !

  11. #11
    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
    Citation Envoyé par Styblue Voir le message
    D'accord, donc j'enlève simplement le Handler et je le met dans le Controler ! Oui, la ça fonctionne !

    Merci pour tes conseils !
    t'utilises le FOSUserBundle ?

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Non non ! En fait j'ai suivi le cookbook de symfony2 a propos de l'entity provider et j'ai donc créé une Entité User ou j'ai étendu AdvanceUserInterface, j'y ai rajouté mes méthodes et j'ai changé l'encoder dans security.yml pour du sha512.

    Donc tout se passe bien, mais évidemment il faut encoder le mot de passe pour qu'il soit hasher en sha512.

    J'avais testé FosUserBundle mais comme je suis curieux, j'ai voulu le faire moi-même pour comprendre comment cela fonctionnait . Mais, loin d'être un professionnel en langage informatique, je rencontre souvent des petits obstacles comme ceux-la.

    En ce qui concerne les formulaires et pourquoi j'avais créé un fichier de type FormHandler, c'est tout simplement parceque j'ai suivi plusieurs tutoriels et qu'il était conseillé de l'utiliser.

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

Discussions similaires

  1. appel web service soap rpc-encoded multi-ref
    Par arnaud.b dans le forum Pentaho
    Réponses: 0
    Dernier message: 18/01/2010, 15h33
  2. [Dojo] Service JSON->encode de dojox grid
    Par Loloperso dans le forum Bibliothèques & Frameworks
    Réponses: 6
    Dernier message: 17/09/2009, 19h56
  3. Web Service RPC/Encoded (IsNullable Attribute)
    Par AKANDOUCH dans le forum Services Web
    Réponses: 1
    Dernier message: 04/01/2007, 01h34
  4. Encoding Style - web services
    Par senga82 dans le forum Services Web
    Réponses: 1
    Dernier message: 18/07/2006, 12h36
  5. Service de nommage java C++
    Par Anonymous dans le forum CORBA
    Réponses: 3
    Dernier message: 15/04/2002, 12h48

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