Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour,
Je possède un système de membre grâce au module ZfcUser.
J'ai ajouté un système ACL grâce au module BjyAuthorize.
ZfcUser ajoute 1 nouvelle table :
- user
BjyAuthorize ajoute 2 nouvelles tables :
- user_role : j'ai ajouté 3 rôle (guest < user < admin)
- user_role_linker : permet de lier un user à un rôle
Problème : lorsque je créer un nouvel utilisateur, celui-ci est bien ajouté à la table User, mais il n'y a aucun ajout qui est fait automatiquement dans la table user_role_linker afin que celui-ci se voit affecter un rôle "user" lors de sa création.
Je suis obligé d'ajouté la ligne dans user_role_linker via phpMyAdmin.
J'ai trouvé sur le net d'utiliser le module : https://github.com/darkmatus/roleuserbridge, mais rien ne change, l'ajout ne se fait toujours pas.
Est ce que quelqu'un à trouvé une solution ?
Merci de votre aide.
Hors ligne
Salut, je ne connais pas très bien ces modules mais tu peux regarder pour lancer un évènement à l'inscription d'un utilisateur pour lui affecter un rôle par défaut.
Hors ligne
Oui mais dans ce cas je devrais modifier directement les fichiers du module ZfcUser.
Hors ligne
Non pas du tout, BjyAuthorize et ZfcUser ont des évenements built-in !
ZfcUserServiceUser, lignes 73 à 75
[lang=php] $events->trigger(__FUNCTION__, $this, compact('user', 'form')); $this->getUserMapper()->insert($user); $events->trigger(__FUNCTION__.'.post', $this, compact('user', 'form'));
Tu remarqueras donc un évènement avant et un après l'enregistrement, les deux ayant l'objet user.
Il faut donc aller dans ton Module.php et ajouter un listener qui va récupérer l'évènement "register", ajouter le role par défaut à l'utilisateur, puis reprendre le cours normal et faire l'insert de l'utilisateur en DB.
Tout est bien indiqué dans cette page : How to perform a custom action when a new user account is created
Hors ligne
Je ne peux pas ajouter le rôle de l'utilisateur avant d'ajouter l'utilisateur en BDD car user_role_linker demande l'id de l'utilisateur.
je dois d'abord, ajouter l'utilisateur dans la table User, récupérer l'id de l'utilisateur qui vient d'être enregistré, puis ajouter une entrée dans la table user_role_linker (id_user, id_role).
Mais comment faire ceci
Hors ligne
Je t'avais écris tout le détail, il suffit de lire !
Cette ligne en question t'intéresse :
[lang=php] $events->trigger(__FUNCTION__.'.post', $this, compact('user', 'form'));
Tu as donc un évènement register.post qui contient ton user en premier paramètre, qui est lancé après insertion... As-tu lu le lien en bas de mon post précédent ? (la doc officielle)
Hors ligne
oui oui, j'ai fais ceci :
[lang=php] $em = \Zend\EventManager\StaticEventManager::getInstance(); $em->attach('ZfcUser\Service\User', 'register.post', function($e) { $user = $e->getParam('user'); // User account object $form = $e->getParam('form'); // Form object print_r($user->getId()); exit(); });
mon print_r($user->getId()), m'affiche bien l'id de l'utilisateur (ici 26)
Mais maintenant je dois faire l'insertion dans user_role_linker (26, 2) ou user_id = 26, role_id = 2
Mais comment faire une requête dans le bootstrap ?
Hors ligne
Bah c'est pareil qu'ailleurs. Tu injectes ton service et tu fais l'insertion, ça c'est à toi de savoir quoi faire.
Hors ligne
j'ai essayé ceci dans mon module.php
[lang=php] class Module { protected $roleTable; public function getRoleTable() { if (!$this->roleTable) { $sm = $this->getServiceLocator(); $this->roleTable = $sm->get('Application\Model\RoleTable'); } return $this->roleTable; } public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); $translator = $e->getApplication()->getServiceManager()->get('translator'); \Zend\Validator\AbstractValidator::setDefaultTranslator( $translator, 'val' ); $em = \Zend\EventManager\StaticEventManager::getInstance(); $em->attach('ZfcUser\Service\User', 'register.post', function($e) { $user = $e->getParam('user'); // User account object $form = $e->getParam('form'); // Form object /* TEST 1 : $userRoleService = $e->getApplication()->getServiceManager()->get('Application\Model\RoleTable'); $userRoleService->saveRole($user->getId(), 2); */ /* TEST 2 : $sm = $e->getApplication()->getServiceLocator(); $toto = $sm->get('Application\Model\RoleTable'); $toto->saveRole($user->getId(), 2); */ // TEST 3 : $this->getRoleTable()->saveRole($user->getId(), 2); }); } }
( ! ) Fatal error: Call to undefined method Application\Module::getServiceLocator() in C:\wamp\www\zf2test\module\Application\Module.php on line 48
Je n'arrive pas à récupérer le serviceLocator ou serviceManager
Dernière modification par romsVLM (24-11-2014 17:16:14)
Hors ligne
Relis toi un peu ... Tu appels une fonction qui n'existe pas donc c'est normal que ça ne fonctionne pas. En plus tu le récupère le service locator (service manager) dans ton module. Donc relis toi, prends du temps au calme pour bien comprendre ce que tu fais .
Hors ligne
Orkin a écrit:
Bah c'est pareil qu'ailleurs. Tu injectes ton service et tu fais l'insertion, ça c'est à toi de savoir quoi faire.
Non ce n'est pas pareil qu'ailleur, vu qu'ailleur j'appel mon modèle via mon controleur. Et la je suis dans le fichier Module.php dans la méthode bootstrap.
Je ne vois vraiment pas comment faire une requête dans le module.php
Hors ligne
Je sais pas si Orkin est d'accord avec moi, mais pour pas m'enbêter je passerais juste le service manager à la fonction anonyme triggered par l'event...:
[lang=php] class Module { protected $roleTable; public function getRoleTable() { if (!$this->roleTable) { $sm = $this->getServiceLocator(); $this->roleTable = $sm->get('Application\Model\RoleTable'); } return $this->roleTable; } public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); //////////////////////////////////////////////////////////////////////// $serviceManager = $e->getApplication()->getServiceManager(); // on récupère le service manager //////////////////////////////////////////////////////////////////////// $translator = $serviceManager()->get('translator'); \Zend\Validator\AbstractValidator::setDefaultTranslator( $translator, 'val' ); $em = \Zend\EventManager\StaticEventManager::getInstance(); //////////////////////////////////////////////////////////////////////// $em->attach('ZfcUser\Service\User', 'register.post', function($e) use ($serviceManager) { // on passe le SM dans la fonction anonyme //////////////////////////////////////////////////////////////////////// $user = $e->getParam('user'); // User account object $form = $e->getParam('form'); // Form object //////////////////////////////////////////////////////////////////////// $userRoleService = $serviceManager()->get('Application\Model\RoleTable'); $userRoleService->saveRole($user->getId(), 2); //////////////////////////////////////////////////////////////////////// }); } }
J'ai mis des // autour des lignes modifiées.
Hors ligne
Je ne sais pas si Orkin sera d'accord aussi, mais ton code fonctionne en tout cas.
J'y étais presque, je récupéré mal le service.
Merci de votre aide
Hors ligne
Oui le code fonctionne et c'est ce que j'utilises en général, mais Orkin est ZCA... Donc si tu veux, ce qu'il dit te permettra d'obtenir quelque chose de plus maintenable et plus testable...
J'avoue que son avis m'intéresse particulièrement car je commence à réviser pour passer la certification l'an prochain
Hors ligne
Vous me mettez pas du tout la pression :p.
Moi j'utiliserais un listener ce qui évite d'utiliser les fonctions anonymes même si c'est très pratique. Dans le listener on écoute l'évènement et on peut via une factory y injecter les services dont on a besoin et du coup plus besoin d'avoir le service manager. En soit c'est une mauvaise pratique d'utiliser les service manager dans nos classes. Dans le ZF3 par exemple il ne sera plus possible de l'utiliser dans nos contrôleur (il ne sera plus injecté par le framework) et l'interface ServiceLocatorAwareInterface sera normalement retirée pour éviter de l'injecter partout facilement. Le but c'est justement d'utiliser des dépendances fortes via des fabriques.
romsVLM a écrit:
Non ce n'est pas pareil qu'ailleur, vu qu'ailleur j'appel mon modèle via mon controleur. Et la je suis dans le fichier Module.php dans la méthode bootstrap.
Je ne vois vraiment pas comment faire une requête dans le module.php
Justement ce que tu fais dans ton contrôleur n'est pas propre. Tu devrais avoir une couche service. Tu ne dois pas manipuler tes modèles dans ton contrôleur. Ton contrôleur est juste censé récupérer le modèle via un service et le retourner à la vue c'est tout.
Hors ligne
Pages: 1