Aujourd'hui, nous allons encore avoir un peu de travail...et ce n'est pas peu dire.
Pour ce jour 10, nous allons nous intéresser à la gestion des utilisateurs et à la gestion des ACL: nous verrons pour cela de nouveaux modules (ZfcUser et BjyAuthorize).
Nous serons amenés à toucher à la fois au module Front et au module Admin.
Modification du 16/09/2013:
Après plusieurs commentaires m'indiquant un problème avec BjyAuthorize (modification du fichier schema.sql), je vous recommande d'utiliser pour le moment une ancienne version de ce module.
Pour cela, modifier le fichier composer.json:
Chercher la ligne "bjyoungblood/bjy-authorize": "dev-master"
Remplacer-la par "bjyoungblood/bjy-authorize": "1.3.*"
Cela permettra d'utiliser la même version de BjyAuthorize que j'utilise dans ce tuto...
Nous pourrions très bien développer nous-même la gestion des utilisateurs et des droits d'accès (ZF2 fournit des classes pour les ACL), mais il existe des modules (très pratique) qui nous ferons gagner du temps.
Installation des modules ZfcUser et BjyAuthorize
ZfcUser est un module d'enregistrement et d'authentification d'utilisateur pour ZF2. Ce module fonctionne, de base, avec \Zend\Db. Mais il permet aussi d'utiliser d'autres adaptateurs de connexion (ex Doctrine).BjyAuthorize est un module fournissant une façade pour Zend\Permissions\Acl qui facilitera son utilisation avec des modules et des applications. Par défaut, il offre une configuration simple via des fichiers de configuration ou en utilisant Zend\Db ou Doctrine (via ZfcUserDoctrineORM).
Le module ZfcUser
Commençons par installer le module ZfcUser. Nous allons utiliser composer:
Cette commande va rajouter le module dans composer.json et installer ce nouveau module dans vendor/zf-commons/zfc-user.
En parallèle, le module ZfcBase sera installé: ce module est une dépendance nécessaire pour ZfcUser (et d'autres modules) et contient une suite de classes.
Il faut ensuite déclarer ces deux modules (ZfcBase et ZfcUser) dans notre fichier application.config.php:
Les données de ZfcUser seront stockées dans notre base de données. Le module fournit les schémas pour différentes base de données. Les scripts sont disponibles dans vendor/zf-commons/zfc-user/data. Nous allons utiliser la version MySQL pour créer la table 'user' qui sera utilisée par ZfcUser:
Le module ZfcUser a quelques options qui nous autorise une personnalisation rapide des fonctionnalités principales. Après linstallation du module, copier le fichier vendor/zf-commons/zfc-user/config/zfcuser.global.php.dist vers config/autoload/zfcuser.global.php et modifier les valeurs désirées. Plus d'informations sur ces options sont disponibles sur le compte github du module.
Voici la config de mon fichier zfcuser.global.php:
Allez voir dans le navigateur jobeet.lxc/user:
Si vous avez un formulaire de connexion: bravo! L'installation et la configuration sont correctes.
Pour le moment, le design n'est pas terrible, mais nous y remédierons plus tard.
Activez le module dans le fichier application.config.php:
Le module BjyAuthorize fournit, lui-aussi, un fichier SQL à exécuter pour stocker ses données. Le fichier se trouve dans vendor/bjyoungblood/bjy-authorize/data/schema.sql
Copiez ensuite le fichier vendor/BjyAuthorize/config/module.config.php vers config/autoload/module.bjyauthorize.global.php
Je vous ajoute la configuration de ce fichier.
Dans ce fichier de configuration, nous indiquons les différentes routes ainsi que les rôles permettant d'y accéder.
J'ai aussi inséré quelques données dans la base de données. J'ai inséré 3 rôles et un utilisateur admin (login: admin, password: jobeet):
Accéder à l'administration sans être connecté (jobeet.lxc/admin):
Nous n'avons plus accès à notre administration: nous avons indiqué qu'il fallait le rôle admin pour accéder à notre route admin...
Allez maintenant sur http://jobeet.lxc/user/login, connectez-vous avec l'utilisateur admin / jobeet (vous serez redirigés sur la page user). Puis retourner sur la page d'administration: vous avez accès à l'administration, car vous êtes connectés avec l'utilisateur admin, qui a le rôle admin.
Cela fonctionne a peu près: nous pouvons nous connecter, accéder ou non à certaines pages...
Mais il serait intéressant de pousser un peu plus la personnalisation.
php composer.phar require zf-commons/zfc-user:dev-master
Cette commande va rajouter le module dans composer.json et installer ce nouveau module dans vendor/zf-commons/zfc-user.
En parallèle, le module ZfcBase sera installé: ce module est une dépendance nécessaire pour ZfcUser (et d'autres modules) et contient une suite de classes.
Il faut ensuite déclarer ces deux modules (ZfcBase et ZfcUser) dans notre fichier application.config.php:
return array( 'modules' => array( 'BjyProfiler', 'ZendDeveloperTools', 'ZfcAdmin', 'Jobeet', 'Front', 'Admin', 'ZfcBase', 'ZfcUser', ), 'module_listener_options' => array( 'config_glob_paths' => array( 'config/autoload/{,*.}{global,local}.php', ), 'module_paths' => array( './module', './vendor', ), ), );
Les données de ZfcUser seront stockées dans notre base de données. Le module fournit les schémas pour différentes base de données. Les scripts sont disponibles dans vendor/zf-commons/zfc-user/data. Nous allons utiliser la version MySQL pour créer la table 'user' qui sera utilisée par ZfcUser:
mysql -u jobeet -p jobeet < schema.mysql.sql
Le module ZfcUser a quelques options qui nous autorise une personnalisation rapide des fonctionnalités principales. Après linstallation du module, copier le fichier vendor/zf-commons/zfc-user/config/zfcuser.global.php.dist vers config/autoload/zfcuser.global.php et modifier les valeurs désirées. Plus d'informations sur ces options sont disponibles sur le compte github du module.
Voici la config de mon fichier zfcuser.global.php:
<?php $settings = array( 'zend_db_adapter' => 'Zend\Db\Adapter\Adapter', 'user_entity_class' => 'ZfcUser\Entity\User', 'enable_registration' => true, 'enable_username' => true, 'auth_adapters' => array( 100 => 'ZfcUser\Authentication\Adapter\Db' ), 'enable_display_name' => true, 'auth_identity_fields' => array('email', 'username'), 'login_form_timeout' => 300, 'user_form_timeout' => 600, 'login_after_registration' => false, 'use_registration_form_captcha' => false, 'use_redirect_parameter_if_present' => true, //'user_login_widget_view_template' => 'zfc-user/user/login.phtml', //'login_redirect_route' => 'zfcuser', //'logout_redirect_route' => 'zfcuser/login', //'password_cost' => 14, //'enable_user_state' => true, //'default_user_state' => 1, //'allowed_login_states' => array( null, 1 ), 'table_name' => 'user', ); /** * You do not need to edit below this line */ return array( 'zfcuser' => $settings, 'service_manager' => array( 'aliases' => array( 'zfcuser_zend_db_adapter' => (isset($settings['zend_db_adapter'])) ? $settings['zend_db_adapter']: 'Zend\Db\Adapter\Adapter', ), ), );
Allez voir dans le navigateur jobeet.lxc/user:
Si vous avez un formulaire de connexion: bravo! L'installation et la configuration sont correctes.
Pour le moment, le design n'est pas terrible, mais nous y remédierons plus tard.
Le module BjyAuthorize
Ajoutons maintenant le module BjyAuthorize pour gérer les droits d'accès.php composer.phar require bjyoungblood/bjy-authorize:1.3.*
Activez le module dans le fichier application.config.php:
<?php return array( 'modules' => array( 'BjyProfiler', 'ZendDeveloperTools', 'ZfcAdmin', 'Jobeet', 'Front', 'Admin', 'ZfcBase', 'ZfcUser', 'BjyAuthorize', ), 'module_listener_options' => array( 'config_glob_paths' => array( 'config/autoload/{,*.}{global,local}.php', ), 'module_paths' => array( './module', './vendor', ), ), );
Le module BjyAuthorize fournit, lui-aussi, un fichier SQL à exécuter pour stocker ses données. Le fichier se trouve dans vendor/bjyoungblood/bjy-authorize/data/schema.sql
mysql -u jobeet -p jobeet < schema.sql
Copiez ensuite le fichier vendor/BjyAuthorize/config/module.config.php vers config/autoload/module.bjyauthorize.global.php
Je vous ajoute la configuration de ce fichier.
<?php <?php /** * BjyAuthorize Module (https://github.com/bjyoungblood/BjyAuthorize) * * @link https://github.com/bjyoungblood/BjyAuthorize for the canonical source repository * @license http://framework.zend.com/license/new-bsd New BSD License */ return array( 'bjyauthorize' => array( // default role for unauthenticated users 'default_role' => 'guest', // identity provider service name 'identity_provider' => 'BjyAuthorize\Provider\Identity\ZfcUserZendDb', // Role providers to be used to load all available roles into Zend\Permissions\Acl\Acl // Keys are the provider service names, values are the options to be passed to the provider 'role_providers' => array( 'BjyAuthorize\Provider\Role\ZendDb' => array( 'table' => 'user_role', 'role_id_field' => 'role_id', 'parent_role_field' => 'parent' ) ), // Guard listeners to be attached to the application event manager 'guards' => array( 'BjyAuthorize\Guard\Route' => array( array('route' => 'zfcadmin', 'roles' => array('admin')), array('route' => 'zfcadmin/logout', 'roles' => array('user', 'admin')), array('route' => 'zfcadmin/login', 'roles' => array('guest', 'user', 'admin')), array('route' => 'zfcadmin/authenticate', 'roles' => array( 'guest', 'user', 'admin')), array('route' => 'zfcadmin/register', 'roles' => array('guest')), array('route' => 'zfcadmin/category', 'roles' => array('admin')), array('route' => 'zfcadmin/category/action', 'roles' => array('admin')), array('route' => 'zfcadmin/job', 'roles' => array('admin')), array('route' => 'zfcadmin/job/action', 'roles' => array('admin')), array('route' => 'home', 'roles' => array('guest', 'user', 'admin')), array('route' => 'home/logout', 'roles' => array('user', 'admin')), array('route' => 'home/add_job', 'roles' => array('user', 'admin')), array('route' => 'home/login', 'roles' => array('guest', 'user', 'admin')), array('route' => 'home/authenticate', 'roles' => array('guest', 'user', 'admin')), array('route' => 'home/register', 'roles' => array('guest')), array('route' => 'home/list_category_page', 'roles' => array('guest', 'user', 'admin')), array('route' => 'home/get_job', 'roles' => array('guest', 'user', 'admin')) ) ) ) );
Dans ce fichier de configuration, nous indiquons les différentes routes ainsi que les rôles permettant d'y accéder.
J'ai aussi inséré quelques données dans la base de données. J'ai inséré 3 rôles et un utilisateur admin (login: admin, password: jobeet):
INSERT INTO `user`('user_id', 'username', 'email', 'display_name', 'password', 'state') VALUES (1, 'admin', 'admin@admin.fr', 'Admin', '$2y$14$PScxr/eNq9CLsjWiTogYXeTpoYa3jrO7S3wXyQPm5.AOQA8KQQYdW', null); INSERT INTO user_role VALUES ('guest', 1, null); INSERT INTO user_role VALUES ('user', 0, 'guest'); INSERT INTO user_role VALUES ('admin', 0, 'user'); INSERT INTO user_role_linker VALUES (1, 'admin');
Accéder à l'administration sans être connecté (jobeet.lxc/admin):
Nous n'avons plus accès à notre administration: nous avons indiqué qu'il fallait le rôle admin pour accéder à notre route admin...
Allez maintenant sur http://jobeet.lxc/user/login, connectez-vous avec l'utilisateur admin / jobeet (vous serez redirigés sur la page user). Puis retourner sur la page d'administration: vous avez accès à l'administration, car vous êtes connectés avec l'utilisateur admin, qui a le rôle admin.
Cela fonctionne a peu près: nous pouvons nous connecter, accéder ou non à certaines pages...
Mais il serait intéressant de pousser un peu plus la personnalisation.
Personnalisation de ZfcUser / BjyAuthorize
Ce que nous pourrions faire, pour améliorer un peu notre application Jobeet:
- avoir 2 pages de connexion (1 pour l'admin et 1 pour le front)
- ne pas être redirigé vers la page 403 lorsque l'on accède à une page nécessitant un rôle particulier (autre que Guest), mais être redirigé vers la bonne page de login (page de login de l'admin si l'on souhaite accéder à une page protégée de l'admin, page de login du front si l'on souhaite accéder à une page protégé du front)
Pour le premier point, c'est assez simple. Je ne rentrerais pas trop dans les détails (vous trouverez les sources dans l'archive à la fin de l'article).
Copiez le répertoire vendor/zf-commons/zfc-user/view/zfc-user dans les répertoires view des modules Admin et Front. Personnalisez ensuite les pages module/Front/view/zfc-user/user/login.phtml et module/Admin/view/zfc-user/user/login.phtml.
Le seconde point m'a posé quelques problèmes. Je voulais que l'appel aux pages protégées des modules Admin et Front redirige sur le formulaire de login du module appelé.
Après quelques recherches et quelques essaies, j'ai finalement trouvé une solution.
Le module BjyAuthorize utilise une classe UnauthorizedStrategy qui gère la redirection vers la page "403 Forbidden : you are not authorized to access ...". Je me suis donc intéressé à cette classe, et je l'ai surchargé dans le module Jobeet.
Modifions d'abord le fichier module.config.php du module Jobeet:
Maintenant, le code de notre classe UnauthorizedStrategy (module/Jobeet/src/Jobeet/View/UnauthorizedStrategy.php):
Si je n'ai rien oublié, si vous tentez d'accéder à une page nécessitant un rôle particulier (autre que Guest), vous serez redirigé vers une fenêtre de login (front ou admin). Sinon, vous trouverez le code complet dans l'archive en fin d'article :-)
Le seconde point m'a posé quelques problèmes. Je voulais que l'appel aux pages protégées des modules Admin et Front redirige sur le formulaire de login du module appelé.
Après quelques recherches et quelques essaies, j'ai finalement trouvé une solution.
Le module BjyAuthorize utilise une classe UnauthorizedStrategy qui gère la redirection vers la page "403 Forbidden : you are not authorized to access ...". Je me suis donc intéressé à cette classe, et je l'ai surchargé dans le module Jobeet.
Modifions d'abord le fichier module.config.php du module Jobeet:
<?php namespace Jobeet; return array( // On indique ici les routes 'principales' de nos modules et les pages login correspondantes __NAMESPACE__ => array( 'options' => array( 'routes' => array( 'backend' => 'zfcadmin', 'backend-login' => 'zfcadmin/login', 'frontend' => 'home', 'frontend-login' => 'home/login' ) ) ), 'jobeet' => array( 'nb_job_by_category' => 10, 'nb_job_pagination' => 4, 'job_nb_valid_days' => 30 ), // C'est ici que l'on surcharge la classe UnauthorizedStrategy du module BjyAuthorize // Notre classe sera utilisée à la place de celle de BjyAuthorize 'bjyauthorize' => array( 'unauthorized_strategy' => 'Jobeet\View\UnauthorizedStrategy' ), 'service_manager' => array( 'factories' => array( 'BjyAuthorize\View\UnauthorizedStrategy' => 'Jobeet\View\UnauthorizedStrategy' ) ) );
Maintenant, le code de notre classe UnauthorizedStrategy (module/Jobeet/src/Jobeet/View/UnauthorizedStrategy.php):
<?php namespace Jobeet\View; use Zend\EventManager\EventManagerInterface; use Zend\EventManager\ListenerAggregateInterface; use Zend\Http\Response as HttpResponse; use Zend\Mvc\MvcEvent; use Zend\Stdlib\ResponseInterface as Response; class UnauthorizedStrategy implements ListenerAggregateInterface { /** * * @var \Zend\Stdlib\CallbackHandler[] */ protected $listeners = array(); public function attach(EventManagerInterface $events) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, array( $this, 'onDispatchError' ), - 5000); } public function detach(EventManagerInterface $events) { foreach ($this->listeners as $index => $listener) { if ($events->detach($listener)) { unset($this->listeners[$index]); } } } public function onDispatchError(MvcEvent $e) { // Do nothing if the result is a response object $result = $e->getResult(); if ($result instanceof Response) { return; } $app = $e->getTarget(); $serviceManager = $app->getServiceManager(); $router = $e->getRouter(); $match = $e->getRouteMatch(); $routeName = $match->getMatchedRouteName(); $module = $serviceManager->get('ModuleManager')->getModule('Jobeet'); $adminRoute = $module->getOption('routes.backend'); $adminLoginRoute = $module->getOption('routes.backend-login'); $frontRoute = $module->getOption('routes.frontend'); $frontLoginRoute = $module->getOption('routes.frontend-login'); if ($routeName === $adminLoginRoute || $routeName === $frontLoginRoute) { return; } if (strpos($routeName, $adminRoute) === 0) { $loginRoute = $adminLoginRoute; } elseif (strpos($routeName, $frontRoute) === 0) { $loginRoute = $frontLoginRoute; } else { return; } // get url to the zfcuser/login route $options['name'] = $loginRoute; $url = $router->assemble(array(), $options); // Work out where were we trying to get to $options['name'] = $match->getMatchedRouteName(); $redirect = $router->assemble($match->getParams(), $options); // set up response to redirect to login page $response = $e->getResponse(); if (! $response) { $response = new HttpResponse(); $e->setResponse($response); } $response->getHeaders()->addHeaderLine('Location', $url . '?redirect=' . $redirect); $response->setStatusCode(302); } }
Si je n'ai rien oublié, si vous tentez d'accéder à une page nécessitant un rôle particulier (autre que Guest), vous serez redirigé vers une fenêtre de login (front ou admin). Sinon, vous trouverez le code complet dans l'archive en fin d'article :-)
Pour finir
Nous allons terminer ce tutoriel en ajoutant une exigence, que nous n'avions pas prévu précédemment : pour faciliter la navigation, les trois derniers emplois vus par l'utilisateur doivent être affiché avec des liens pour revenir à la page des emplois par la suite.
Pour cela, nous allons voir comment gérer les sessions. Je vais traiter ce point de façon très simple, nous ne devons pas stocker d'autres données. On peut configurer un manager de session, via la configuration mais j'ai fait plus simple...
Dans un premier temps, nous devons stocker les emplois consultés par l'utilisateur. Nous allons donc ajouter le stockage dans le controller Job (dans l'action get):
Ces 3 jobs devront être visibles dans le layout du front. Nous allons donc modifier le fichier layout.phtml (module/Front/view/layout/layout.phtml): Recherchez la chaîne "Recent viewed jobs" et modifiez le code comme suit
Pour la clarté du code HTML du layout, j'ai créé une aide de vue (pour voir comment faire).
Créons l'aide de vue. Elle doit étendre AbstractHelper et implémenter la méthode __invoke():
Dernière étape: il faut déclarer notre aide de vue comme "invokables" dans le fichier Module.php du module Front
Naviguez sur le site, consultez quelques offres et vous devriez voir les offres consultées:
Nous en avons fini pour le jour 10. Nous avons vu comment ajouter simplement une authentification et un système de gestion des droits à l'aide des modules ZfcUser et BjyAuthorize. Nous avons aussi vu comment surcharger le comportement du module BjyAuthorize pour rediriger vers la page de login plutot qu'afficher la page 403. Finalement, nous avons traité, brièvement, les sessions. Consulter la documentation officielle pour approfondir les sessions (Session Manager, Container, etc).
Comme d'habitude, vous trouverez le code sur mon compte Github.
Si vous avez des questions sur ce jour 10, n'hésitez pas à poster un commentaire ici, ou sur la communauté ZF2 France sur GooglePlus
// module/Front/src/Front/Controller/JobController.php use Zend\Session\Container; // Déclarer ce namespace class JobController extends JobeetController { [...] public function getAction() { $id_job = $this->params()->fromRoute('id', null); if (! is_null($id_job)) { $job = $this->jobTable->getJob($id_job); $category = $this->categoryTable->getCategoryById($job->id_category); // Nous créons notre container $job_sessions = new Container('jobs'); // et nous enregistrons le job consulté if (isset($job_sessions->jobs)) { if (!in_array($job->id_job, $job_sessions->jobs)) { array_unshift($job_sessions->jobs, $job->id_job); $job_sessions->jobs = array_slice($job_sessions->jobs, 0, 3); } } else { $job_sessions->jobs = array(); $job_sessions->jobs[] = $job->id_job; } return new ViewModel( array( 'job' => $job, 'category' => $category ) ); } else { $this->getResponse()->setStatusCode(404); return; } } }
Ces 3 jobs devront être visibles dans le layout du front. Nous allons donc modifier le fichier layout.phtml (module/Front/view/layout/layout.phtml): Recherchez la chaîne "Recent viewed jobs" et modifiez le code comme suit
<div id="job_history">Recent viewed jobs:<?php echo $this->jobSessions(); ?></div>
Pour la clarté du code HTML du layout, j'ai créé une aide de vue (pour voir comment faire).
Créons l'aide de vue. Elle doit étendre AbstractHelper et implémenter la méthode __invoke():
// module/Front/src/Front/View/Helper/JobSessions.php <?php namespace Front\View\Helper; use \Jobeet\Filter\Slugify as Slugify; use Zend\ServiceManager\ServiceLocatorAwareInterface; use Zend\Session\Container; use Zend\View\Helper\AbstractHelper;
class JobSessions extends AbstractHelper implements ServiceLocatorAwareInterface { public function __invoke() { $slug = new Slugify(); $job_sessions = new Container('jobs'); $html = ''; if (isset($job_sessions->jobs)) { $html .= '<ul>'; $jobTable = $this->serviceLocator->getServiceLocator()->get('Jobeet\Model\JobTable'); $getUrl = $this->getView()->plugin('url'); foreach ($job_sessions->jobs as $key => $idJob) { $currentJob = $jobTable->getJob((int)$idJob); if (!is_null($currentJob)) { $url = $getUrl( 'home/get_job', array( 'company' => $slug->filter($currentJob->company), 'position' => $slug->filter($currentJob->position), 'location' => $slug->filter($currentJob->location), 'id' => $currentJob->id_job ), false, false ); $html .= '<li><a href="' . $url . '">' . $currentJob->position . ' - ' . $currentJob->company . '</a></li>'; } } $html .= '<ul>'; } return $html; } public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) { $this->serviceLocator = $serviceLocator; return $this; } public function getServiceLocator() { return $this->serviceLocator; } }
Dernière étape: il faut déclarer notre aide de vue comme "invokables" dans le fichier Module.php du module Front
// Méthode à ajouter dans module/Front/Module.php public function getViewHelperConfig() { return array( 'invokables' => array( 'jobsessions' => 'Front\View\Helper\JobSessions', ), ); }
Naviguez sur le site, consultez quelques offres et vous devriez voir les offres consultées:
Nous en avons fini pour le jour 10. Nous avons vu comment ajouter simplement une authentification et un système de gestion des droits à l'aide des modules ZfcUser et BjyAuthorize. Nous avons aussi vu comment surcharger le comportement du module BjyAuthorize pour rediriger vers la page de login plutot qu'afficher la page 403. Finalement, nous avons traité, brièvement, les sessions. Consulter la documentation officielle pour approfondir les sessions (Session Manager, Container, etc).
Comme d'habitude, vous trouverez le code sur mon compte Github.
Si vous avez des questions sur ce jour 10, n'hésitez pas à poster un commentaire ici, ou sur la communauté ZF2 France sur GooglePlus
Bonsoir,
RépondreSupprimerj'essaie d'intégrer BjyAuthorize et je me suis heurté à un problème : lors de l'enregistrement d'un utilisateur via zfcuser, BjyAuthorize ne devrait pas insérer une ligne dans user_role_linker ?
comment cela ce passe pour vous ?
cordialement
Oui, c'est un point que je voudrais résoudre aussi (sans utiliser de module tier si possible)...
RépondreSupprimerJe completerais l'article dès que j'aurais trouver une bonne solution
Sinon, tu peux regarder ce module https://github.com/darkmatus/roleuserbridge => a priori, ca reglerais le pb
Bonjour,
SupprimerC'est bien ce qu'il me semblait en feuilletant les sources que je n'arrivais pas à trouver ce qu'il me fallait.
Du coup, j'ai fait un mapper comme darkmatus mais j'ai préféré binder sur l'event 'register.post' plutôt que de surcharger la classe.
C'ets bête que ce ne soit pas prévu de base.
je pense que l'utilisation de l'event est la bonne solution justement :-)
SupprimerBonjour, tout d'abord super tuto !!
SupprimerSerait il possible d'avoir un exemple de code de la methode utilisé par Gowser ?
Merci
excusez moi d'y revenir encore mais j'ai un serieux probleme au jour 4:
RépondreSupprimerFile:
C:\wamp\www\zf2-tutorial.com\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:496
Message:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Db\Adapter\Adapter
comment je regle ce probleme merci
Je répond un peu tard, mais tu trouveras une réponse de Fadel dans le jour 4 => http://php-underground.blogspot.com/2012/10/jobeet-zf2-jour-4-controller-et-vue.html?showComment=1375898989284#c4935711804067426710
SupprimerBonjour,
SupprimerJ'ai le même problème et je n'arrive pas à trouver.
Merci pour votre réponse.
La reponse ici :)
Supprimerhttp://php-underground.blogspot.com/2012/10/jobeet-zf2-jour-4-controller-et-vue.html?showComment=1375898989284#c4935711804067426710
Bonjour,
RépondreSupprimerTout d'abord, Merci beaucoup pour cette belle série de tutos , c'est du très bon travail.
j'ai rencontré quelques petits problèmes avec la partie Gestion des ACL ( dixième tuto).
1 - Page blanche jusqu'à ce que j'ai changé les noms des colonnes 'roleId' et 'parent_id' par 'role_id' et 'parent' dans la table user_role car j'ai vu qu'ils étaient déclarés comme ceci dans le fichier ZendDB.php (vendor/biyougblood/bjy-autorized/src/BjyAuthoriz/Provider/Role/ ). pourtant à la base j'avais utilisé le fichier sql fournis dans le module (.../data/)....
2- lors de l'authentification , j'avais une exception "role '3' not found" générée par la classe Registry.php (z**f/library/Zend/Permissions/Acl/Role/*), j'ai donc modifié la colonne 'role_id' de la table user_role_linker en varchar(255) au lieu de int(11) et j'y ai mis 'admin' au lieu de '3' qui est l'ID du role 'admin'... et ça a marché ..
je voulais savoir si vous avez été confrontés aux mêmes problèmes que moi, et si oui, quelles sont les solutions que vous avez adopté.
Merci pour vos réponses.
Bonjour Youssef, t merci pour ton comm :-)
Supprimer1 - Bizarrement, dans la table user_role, j'ai les colonne suivante:
role_id varchar(255)
is_default tinyint(1)
parent varchar(255)
=> ca correspond bien aux changement que tu as fait...J'avais aussi utilisé le fichier .sql présent dans le module BjyAuthorize
2 - Dans user_role_admin, j'ai bien les valeurs id_user=1 et role_id=admin.
Je vais vérifié si le module BjyAuthorize n'a pas été mis à jour entre le tuto et maintenant...Je ne me souviens pas avoir modifié ça...
En tout cas, ta réponse pourra servir si d'autres personnes ont le même problème plus tard.
Youssef, je confirme qu'il y a eu quelques changements sur le fichier .sql du module BjyAuthorize...
Supprimerhttps://github.com/bjyoungblood/BjyAuthorize/commits/master/data/schema.sql
Romain, merci pour ta réponse rapide :).
RépondreSupprimerEn effet, en suivant le lien j'ai constaté les modifications apporté au module.
Par contre , en allant dans le fichier vendor/biyougblood/bjy-autorized/src/BjyAuthoriz/Provider/Role/ZendDb.php je vois que la variable protected $roleIdFieldName est toujours à 'role_id' OR 'role_id' n'existe plus dans la table 'user_role'.
Je vais regarder ça un peu plus en détail et je referai un Post.
par ailleurs, est ce que tu as prévu d'autre tutos ou est ce la fin de la série ?
Il y a encore plusieurs tutos prévus :-)
Supprimergood course
RépondreSupprimerBjyAuthorize\Exception\UnAuthorizedException
RépondreSupprimerFile:
jobeet/vendor/bjyoungblood/bjy-authorize/src/BjyAuthorize/Guard/Route.php:133
Message:
You are not authorized to access zfcuser/register
A quand un nouveau tuto?????
RépondreSupprimerBonsoir, merci pour ce tuto, cependant j'ai un petit probleme, les options de Zfcuser ne sont pas prise en compte.
RépondreSupprimerMerci d'avance pour votre aide
une absence se fait longue, on attend la suite
RépondreSupprimerMerci
Une partie Internationnalisation serait intéressante pour le Jour 11. ( Avec l'utilisation de Poedit =) pour un gain de temps )
RépondreSupprimerLa partie Internationnalisation est prevue pour le jour 16...Mais ca peut être plus interessant que le jour 11 (sur les flux, que j'ai commencé).
SupprimerMais je vais changer l'ordre. J'attaquerais le tuto sur l'internationnalisation pour le jour 11 ce soir, en esperant pouvoir le publier rapidement
et une partie Responsive Design pour le Jour 12
RépondreSupprimerBonjour,
SupprimerIl existe deja de nombreuses ressources pour le responsive design. De plus, cela n'a rien a voir avec ZF2 ;-)
Donc je ne traiterais pas cette partie :-)
Cordialement,
Romain
2-3 liens:
Supprimerhttp://objetdirect.developpez.com/tutoriels/css/responsive-design/
http://paulgruson.fr/2013/01/22/responsive-design-10-conseils-pour-reussir/
http://lehollandaisvolant.net/?d=2012/11/24/20/37/08-css-faire-un-theme-mobile-avec-html5-et-responsive-design
Bonjour, ai je le droit de modifier directement les fichiers du module de ZfcUser ? (UserController et les vues)
RépondreSupprimerIl ne faut JAMAIS modifier directement les fichiers des modules présents dans vendor => en cas de mise a jour du module, tu perdrais tes modifs.
SupprimerSi tu veux modifier les vues: il faut copier les vues du module ZfcUser dans ton propre module, (en conservant l'arborescence), et indiquer dans la conf que tu souhaite utiliser tes vues custom Zfcuser. Regarde dans le code, il me semble avoir fait ca pour le module Admin (surcharger ed la vue login), ainsi que dans le module Front il me semble.
Pour modifier le UserController, il me semble qu'il va te falloir faire ton propre controller (soit un nouveau, soit qui etends ZfcUser\UserController) et indiquer dans la conf de zfcuser du'tiliser ton controller plutot que celui de zfcuser => Je te confirme ça dans la semaine, je n'aurais pas le temps de regarder ce soir
Pour les vues, tu trouveras des explications sur le wiki du module ZfcUser
Supprimerhttps://github.com/ZF-Commons/ZfcUser/wiki
Cordialement,
Romain
d'accord merci beaucoup.
RépondreSupprimerPar contre j'ai un problème :
Lorsque je crée un utilisateur, celui ci est bien enregistré dans la table user. Cependant aucun rôle ne lui ai attribué par défaut. (la ligne dans la table user_role_linker n'est pas créée automatiquement).
Comment y remédier ? car ça pause un gros problème, si l'utilisateur se connecte alors qu'il n'a pas de role, il ne peux accèder à aucune page.
Bonjour,
RépondreSupprimerje me permet de faire une petite remarque en passant , ça concerne la classe UnauthorizedStrategy.
j'ai réussi à reproduire le fonctionnement souhaité en utilisant le code présenté plus haut, sauf que lorsque j'essaie d'aller sur une route non existante, j'ai l'erreur suivante :
Fatal error: Call to a member function getMatchedRouteName() on a non-object in C:\xampp\htdocs\Trilab\test\module\Test\src\Test\View\UnauthorizedStrategy.php on line 50
ce qui est normale car la variable manipulée à la ligne 50 est null quand la route est inexistante ..
pour ma part je souhaitais qu'une page d'erreur 404 soit affiché dans ce cas .. j'ai alors mis à la ligne 49 ;
if(!$match) return ; .
si ça peut servir à quelqu'un ...
Bonjour,
SupprimerMerci pour ton commentaire, je corrigerais ça dans le code de la prochaine journée :-)
Je viens de rechercher une configuration pour utiliser la version 1.4 de BjyAuthorize.
RépondreSupprimerVoici les modifications que j’ai apportées pour que ça fonctionne :
1. Dans la table user_role_linker, colonne role_id, il faut indiquer l’id du rôle (colonne id de la table user_role) à la place du label du rôle. Ainsi, sur cet exemple, si admin a pour id 3 dans la table user_role, il faut insérer :
INSERT INTO user_role_linker VALUES (1, 3);
On doit pouvoir modifier le type de la colonne role_id mais ce n'est pas indispensable.
2. Ensuite, pour la configuration de BjyAuthorize dans le fichier config/autoload/module.bjyauthorize.global.php :
'role_providers' => array(
'BjyAuthorize\Provider\Role\ZendDb' => array(
'table' => 'user_role',
'identifier_field_name' => 'role_id',
'role_id_field' => 'role_id',
'parent_role_field' => 'parent_id'
)
),
3. Enfin, pour la configuration de zfc-user, dans le fichier config/autoload/zfcuser.global.php :
'use_redirect_parameter_if_present' => true,
'login_redirect_route' => 'zfcadmin',
'logout_redirect_route' => 'home/login',
Il y a peut-être mieux mais chez moi ça fonctionne.
J'ai mis pas mal de temps pour comprendre comment le bon formulaire de login se met en place : Romain a passé sous silence l'adaptation qu'il a faite dans Front\Module.
RépondreSupprimerDans la méthode onBootstrap(MvcEvent $e) de cette classe, il attache une fonction de rappel (méthode de cette classe Front\Module nommée onDispatch) qui va rajouter le path __DIR__ . '/view' à la pile des TemplatePath de l'application. Cette fonction de rappel étant appelée après le chargement des modules, une fois que la pile de TemplatePath a été constituée en fonction de l'ordre de déclaration des modules dans application.config.php, on est ainsi certain qu'en haut de la pile se trouve le bon chemin pour accéder à zfc-user.
Attention, si le module Admin est déclaré avant le module Front dans application.config.php, c'est la classe Admin\Module qu'il faudra modifier.
A noter, Romain, qu'il n'est pas utile de déclarer onBootstrap dans init puisque la méthode onBootstrap est appelée automatiquement après le chargement lorsqu'elle est implémentée.
En tout cas, merci et bravo pour ce tutoriel.
Bonsoir Loguit,
SupprimerMerci pour ton commentaire et tes précisions :-)
Effectivement, le tuto manque un peu d'explication sur ce point. Je te remercie pour l'eclaircissement (en espérant que les lecteurs liront aussi les différents commentaires des articles ^^)
Pour la méthode onBootstrap, il me semble que j'avais vu ça quelque part. J'en prend note, et je corrigerais ça pour la suite des tutos
svp j veux savoir comment ajouter le module zfcuser pour chaque module sachant que j'ai 3 modules (Administrateur,camion,chauffeur) et comment je peux rediriger l'utilisateur a chaque login et merci d'avance ;)
RépondreSupprimerBonjour quelqu'un a t-il trouvé une solution pour l'ajout automatique de l'user lors de sa création dans la table role_linker ?
RépondreSupprimerJ'ai essayé d'utiliser https://github.com/darkmatus/roleuserbridge, mais rien n'y fait, rien a changé.
Merci
Bonjour j'essai de suivre le tuto, mais je bloque quand il s'agit de definir la strategie utuliser lors d'un acces sur une page interdite
RépondreSupprimerj'ai bien cree le fichier module/Application/src/Application/View/UnauthorizedStrategy.php
j'ai copier coller le code de module/Jobeet/src/Jobeet/View/UnauthorizedStrategy.php
en cheangeant le namespace a l'interieur du fichier a la place de "namespace Jobeet\View;" j'ai "namespace Application\View;"
j'ai ajouter dans le tableau des service_manager/factories comme indiquer en mettant
'BjyAuthorize\View\UnauthorizedStrategy' => 'Application\View\UnauthorizedStrategy'
j'ai ajouter egalement dans le tableau de bjyauthorize 'unauthorized_strategy' => 'Application\View\UnauthorizedStrategy',
mais j'ai un message d'erreur qui me dit
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Application\View\UnauthorizedStrategy