Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour à tous,
Ma petite présentation :
Il y'a 1 ans je me suis aventuré dans la développement en mode procédurale d'un site web sous php 5 "accès - news - forums - gestion de droits - admins - css+html - accès base de donnée avec easyphp. Je découvre le développement en générale, je me suis donc appuyé sur les tutoriels de sdz qui m'ont beaucoup appris.
je suis clairement un novice sur la création de site web en général. Il est évident que je vais dire des erreurs que je vais faire des erreurs de code, je serais surement très sujet à la critique et c'est là tout l'intérêt.
Je souhaite poster tout le code de mon projet afin de le commenter et surtout de le retravailler si besoin. Mon objectif à long terme est de maitriser l'environnement zend sous toutes ces formes. Je souhaite devenir autonome, il va me falloir être armé de patience car zend n'est pas simple du tout. Au temps suivre des tutoriaux de "sdz" est relativement simple et l'on obtient un résultat assez rapidement. Au temps les tutoriaux Zf sont plus tôt orienté pour les amateurs qui ont déjà des connaissances sur le dév en objet.
J'ai donc commencé par le tutoriel général de Rob "débuter-avec-zend-framework-1-10" qui est très bien fait.
Mais pour déjà réussir ce tutoriel, il faut commencer par configurer Easyphp.
Voici une partie du fichier httpd.conf avec les quelques modifications nécessaires:
// j'ai décommenté le module rewrite qui permet la réecriture d'url si j'ai bien compris #LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule setenvif_module modules/mod_setenvif.so #LoadModule speling_module modules/mod_speling.so // j'ai initialisé la fonction "AllowOverride sur All pour redéfinir les droits d'accès via un fichier htaccess. <Directory /> Options FollowSymLinks AllowOverride All Order deny,allow Deny from all </Directory> Puis j'ai configuré mon virtual host: <VirtualHost *:80> ServerAdmin webmaster@dummy-host.localhost DocumentRoot "C:/Program Files/EasyPHP-5.3.3/www/breakeven/public" ServerName breakeven.int ServerAlias www.breakeven.int # ErrorLog "logs/dummy-host.localhost-error.log" # CustomLog "logs/dummy-host.localhost-access.log" common </VirtualHost> J'ai modifié mon fichier "host" pour accéder directement au site www.breakeven.int
Mon projet se nomme "breakeven", j 'ai ajouté à la racine de ce dossier ma librairie zend.
J'ai modifié l'include path de php pour qu'il pointe sur cette librairie et cela marche.
Ps: j'ai aussi modifier mon fichier host pour qu'il pointe sur www.breakeven.int lorsque l'on accède à l'ip locale
Dernière modification par lalwende (28-02-2011 12:21:15)
Hors ligne
J'ai structuré mon projet sous cette forme:
- www - breakeven - application - configs "application.ini" - controllers - forms - layouts - scripts - models - DbTable - views - helpers - scripts - error - index - auth - register bootstrap.php - data - docs - library - public index.php .htaccess - css - images - tests
Désoler la présentation de ma structure des dossiers n'est pas très belle, mais bon elle est assez clair.
Dernière modification par lalwende (28-02-2011 11:34:40)
Hors ligne
je vais commencer par vous présenter mon fichier "index.php":
Si il y'a des erreurs dans les différents fichiers que je vous présente, n'hésitez à me le dire.
<?php // Define path to application directory defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); // Define application environment defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production')); /** Zend_Application */ require_once 'Zend/Application.php'; set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../library'), realpath(APPLICATION_PATH . '/models'), get_include_path(), ))); // Create application, bootstrap, and run $application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); // Initialize and retrieve DB resource $bootstrap = $application->getBootstrap(); $bootstrap->bootstrap('db'); $dbAdapter = $bootstrap->getResource('db'); //Setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setControllerDirectory('../application/controllers'); Zend_layout::startMvc(array('layoutPath'=>'../application/layouts')); $application->bootstrap() ->run();
Hors ligne
Voici mon fichier "application.ini". Je n'utiliserais pas de module pour le moment trop complexe pour moi. J'essaie seulement de comprendre le fonctionnement et de bien l'assimiler. Alors je commence par quelque chose de simple.
[production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 resources.view.doctype = "XHTML1_STRICT" includePaths.library = APPLICATION_PATH "/../library/" ;définition du bootstrapp bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" ;initialisation du contrôleur frontal resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.frontController.params.displayExceptions = 1 ;initialize front controller resource ;resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" ;resources.frontController.defaultControllerName = "index" ;resources.frontController.defaultAction = "index" ;resources.frontController.defaultModule = "Frontend" ;layout resources.layout.layoutpath = APPLICATION_PATH "\layouts\scripts\" resources.layout.layout = "layout" resources.view[] = ;definition de la timezone phpSettings.date.timezone = "Europe/Paris" ;Espaces de nom: les espaces de noms utilisées dans l’application :Zend pour la librairie ZF - Lib pour notre librairie personnalisée autoloadernamespaces[] = "Zend_" appnamespace = "Application" ;acces a la base resources.db.adapter = "PDO_MYSQL" resources.db.params.host = "localhost" resources.db.params.username = "******" resources.db.params.password = "******" resources.db.params.dbname = "breakeven" resources.db.params.date_format = "YYYY-MM-ddTHH:mm:ss" ;pour la version 1.10 de zend qui automatise resources.db.isDefaultTableAdapter = "true" [staging : production] [testing : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 ;acces a la base resources.db.adapter = "PDO_MYSQL" resources.db.params.host = "localhost" resources.db.params.username = "******" resources.db.params.password = "*******" resources.db.params.dbname = "breakeven" resources.db.params.date_format = "YYYY-MM-ddTHH:mm:ss" ;pour la version 1.10 de zend qui automatise resources.db.isDefaultTableAdapter = "true" [development : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 resources.frontController.params.displayExceptions = 1 ;acces a la base resources.db.adapter = "PDO_MYSQL" resources.db.params.host = "localhost" resources.db.params.username = "******" resources.db.params.password = "******" resources.db.params.dbname = "breakeven" resources.db.params.date_format = "YYYY-MM-ddTHH:mm:ss" ;pour la version 1.10 de zend qui automatise resources.db.isDefaultTableAdapter = "true"
Hors ligne
Voilà maintenant le fichier bootstrap.php.
<?php class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { public function run() { // Cela permet d'avoir le fichier de configuration disponible depuis n'importe ou dans l'application. Zend_Registry::set('config', new Zend_Config($this->getOptions())); parent::run(); } //Pour initialiser les modules - a voir plus tard si besoin de module - pour l'instant sans module protected function _initAutoload() { $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => '', 'basePath' => APPLICATION_PATH, )); //rajouter ces deux lignes pour que ce connard de zend pointe bien sur mes dossiers model et form car sinon class not //found j'espere que cela va marcher cette fois connard de zend. $autoloader->addResourceType('model', 'application/models', 'Model'); $autoloader->addResourceType('form', 'application/forms', 'Form'); return $autoloader; } //pour initialiser la base de donnée protected function _initDb() { //on charge notre fichier de configuration $config = new Zend_Config($this->getOptions()); //On essaye de faire une connection a la base de donnee. try { $db = Zend_Db::factory($config->resources->db); //on test si la connection se fait $db->getConnection(); } catch ( Exception $e ) { exit( $e -> getMessage() ); } // on stock notre dbAdapter dans le registre Zend_Registry::set('dbAdapter', $db); Zend_Db_Table::setDefaultAdapter($db); return $db; } protected function _initView() { // Initialisons la vue $view = new Zend_View(); $view->doctype('XHTML1_STRICT'); $view->headTitle('Respirons Zend'); // Ajoutons là au ViewRenderer $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer'); $viewRenderer->setView($view); // Retourner la vue pour qu'elle puisse être stockée par le bootstrap return $view; } //pour initialiser la session protected function _initSession() { // On initialise la session $session = new Zend_Session_Namespace('breakeven', true); return $session; } protected function _initDoctype() { $this->bootstrap('view'); $view = $this->getResource('view'); $view->doctype('XHTML1_STRICT'); } }
Hors ligne
Voilà je viens de vous présenter mes différents fichiers de configuration. Il me reste une petite chose à vous présenter avant de rentrer dans le vif du sujet.
Le fichier .htaccess qui est dans public.
SetEnv APPLICATION_ENV production RewriteEngine On RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L]
Hors ligne
Maintenant que la structure est prête.
Je vais commencer par le tutoriel de rob allen "debuter-avec-zend-framework-1-10".
J'ai aussi travaillé sur le tutoriel "Débuter avec Zend auth" afin de comprendre le fonctionnement de cet outil.
Quand je dis "outil" c'est peut être une erreur de prononciation.
Objectif:
- Comprendre la structure MVC "Model vue controleur".
- Comprendre l'accès à une base de donnée en mode "ecriture - lecture - enregistrement - effacer".
- Comprendre "Zend Form".
- Comprendre l'écriture de code façon zend.
- obtenir une application simple mais qui marche "étape par étape".
L'application: elle fait quoi!
Pour l'instant je veux afficher sur la page d'accueil "index.phtml" la liste des news renseignées sur une base de données "easyphp". La table qui contient ces données s'appelle "news". Elle possède 5 champs.
champs de la table news: id - title - author - date - content
J'ai commencé par travailler mon "IndexController" pour afficher le contenu de mon tableau news, je me suis appuyé sur ce bout de code : "$this->view->news = $news->fetchAll();"
<?php class IndexController extends Zend_Controller_Action { public function init() { //initialisation du controller index $this->initView(); $this->view->baseUrl = $this->_request->getBaseUrl(); $this->view->user = Zend_Auth::getInstance()->getIdentity(); } /** * L'action par defaut est d'afficher la page d'accueil - index */ public function predispatch() { $auth = Zend_Auth::getInstance(); if (!$auth->hasIdentity()) { $this->_redirect('auth/login'); } } public function indexAction() { $news =new Application_Model_DbTable_News(); $this->view->news = $news->fetchAll(); }
Ok mais sans le fichier "news.php" qui est stocké dans "models/DbTable" on ne va pas afficher grand chose:
Voici le bout de code concerné:
<?php class Application_Model_DbTable_News extends Zend_Db_Table_Abstract { protected $_name = 'news'; public function obtenirNews($id) { $id = (int)$id; $row = $this->fetchRow('id= ' . $id); if (!$row) { throw new Exception ("Impossible de trouver les donnees $id"); } RETURN $row->toArray(); }
Hors ligne
Et la vue dans tout çà !
Dans mon fichier index.phtml, je présente un tableau avec toutes les news.
Je fais appelle à "zend date" juste pour m'assurer que ma librarie "Zend" est bien vue.
<?php $this->title = 'Les News'; $this->headTitle($this->title); ?> <div> <p> <?php //Affichage de la date du jour //Require ‘Zend/Date.php’ ; // pas de besoin d'effectuer un require de la méthode date de la library car elle est inclue par default via l'include path $date = new Zend_Date() ; echo $date; ?> </p> <p> <a href="<?php echo $this->url(array('controller'=>'index','action'=>'ajouter'));?>">Ajouter une news</a> </p> <table> <tr> <th>Titre</th> <th>Author</th> <th>date</th> <th>Content</th> </tr> <?php foreach($this->news as $news) : ?> <tr> <td><?php echo $this->escape($news->title);?></td> <td><?php echo $this->escape($news->author);?></td> <td><?php echo $this->escape($news->date);?></td> <td><?php echo $this->escape($news->content);?></td> <td> <a href="<?php echo $this->url(array('controller'=>'index','action'=>'modifier', 'id'=>$news->id));?>"> Modifier</a> <a href="<?php echo $this->url(array('controller'=>'index','action'=>'supprimer', 'id'=>$news->id));?>">Supprimer</a> </td> </tr> <?php endforeach; ?> </table> </div>
Hors ligne
Ok maintenant nous avons sur notre page d'accueil un tableau avec toutes les news, ouah je suis fier de moi.
Très bien tout çà, mais il faut désormais pouvoir ajouter une news.
Je reprend donc notre "IndexController" afin d'ajouter une action qui se nomme "ajouter". Je sais je n'ai pas beaucoup d'imagination.
public function ajouterAction() { $form = new Application_Form_News(); $form->envoyer->setLabel('Ajouter'); $this->view->form = $form; //Nous instancions notre Application_Form_News, nous affectons au bouton d'envoi le libellé "Ajouter" puis nous //assignons le formulaire à la vue pour affichage. if ($this->getRequest()->isPost()) { $formData = $this->getRequest()->getPost(); if ($form->isValid($formData)) //Si la méthode isPost() de l'objet de requête renvoie true, alors le formulaire a été envoyé. Nous récupérons alors les données de la requête avec la méthode getPost() et nous vérifions qu'elles sont valides avec la méthode membre isValid(). { $title = $form->getValue('title'); $author = $form->getValue('author'); $date = $form->getValue('date'); $content = $form->getValue('content'); $news = new Application_Model_DbTable_News(); $news->ajouterNews($title, $author, $date, $content); //Si le formulaire est valide, nous instancions la classe modèle Application_Model_DbTable_News et nous //utilisons la méthode ajouterNews() que nous avons créée plus tôt pour créer un nouvel enregistrement dans la //base de données. $this->_helper->redirector('index'); //on redirige vers l'inde si le form est valide avec l'aide d'action redirector } else { $form->populate($formData); } //si c'est pas valide on affiche à nouveau le formulaire avec les données déja mises. } }
Ne me faites pas confiance si je vous dit que j'ai codé cela tout seul, c'est pas vrai j'ai ponctionné ce code comme tout bon novice qui se respecte .
Hors ligne
Ok maintenant que notre action est disponible dans notre controller, on doit faire deux choses.
- Ajouter l'action dans notre fichier "news.php" qui permet l'accès à la base.
- Créer un fichier "ajouter.phtml" pour donner un rendu de l'action.
news.php
public function ajouterNews($title, $author, $date, $content) { $data = array( 'title' =>$title, 'author' =>$author, 'date' =>$date, 'content' =>$content, ); $this->insert($data); }
ajouter.phtml
<?php $this->title = "Ajouter une nouvelle news"; $this->headTitle($this->title); echo $this->form; ?>
Hors ligne
Ok tout ça c'est bien, mais il te manque pas quelque chose guignol. Heu oueh mon formulaire pour ajouter des données. Eureka, je suis trop null non tout simplement un novice.
Dans le dossier "\application\forms\News.php"
<?php class Application_Form_News extends Zend_Form { public function init() { $this->setName('news'); //l'id est autoincrémenter on utilise Hidden pour dire que c'est caché mais il faut le référencer $id = new Zend_Form_Element_Hidden('id'); $id->addFilter('Int'); $title = new Zend_Form_Element_Text('title'); $title->setLabel('Title') ->setRequired(true) ->addFilter('StripTags') ->addFilter('StringTrim') ->addValidator('NotEmpty'); $author = new Zend_Form_Element_Text('author'); $author->setLabel('Author') ->setRequired(true) ->addFilter('StripTags') ->addFilter('StringTrim') ->addValidator('NotEmpty'); $date = new Zend_Form_Element_Text('date'); $date->setLabel('Date') ->setRequired(true) ->addFilter('StripTags') ->addFilter('StringTrim') ->addValidator('NotEmpty'); $content = new Zend_Form_Element_Text('content'); $content->setLabel('Content') ->setRequired(true) ->addFilter('StripTags') ->addFilter('StringTrim') ->addValidator('NotEmpty'); $envoyer = new Zend_Form_Element_Submit('envoyer'); $envoyer->setAttrib('id', 'boutonenvoyer'); $this->addElements(array($id, $title, $author, $date, $content, $envoyer)); } }
Hors ligne
Maintenant j'arrive à intégrer des news dans ma base de donnée. Ces news s'affichent sur la page d'accueil. Cool, je suis une vrai bête, lol je m'enflamme après avoir copié deux bouts de code d'un génie et je me prend pour une vedette, trop null le mec.
En tout cas, j'arrive maintenant à lire et écrire des données. C'est ti pas beau. La suite au prochain épisode.
- Modifier des news.
- Supprimer des news.
Dernière modification par lalwende (28-02-2011 12:26:59)
Hors ligne
J'ai oublié de vous parler de mon layout. J'ai quelques liens href qui ne sont pas utilisé pour le moment.
Seuls les liens "s'identifier" et "s'inscrire" seront disponibles pour la partie authentification. Pour les autres j'en serai plus bientôt.
<?php $this->headMeta()->appendHttpEquiv('Content-Type', 'text/html;charset=utf-8'); $this->headTitle()->setSeparator(' - '); $this->headTitle('Breakeven'); echo $this->doctype(); ?> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <?php echo $this->headMeta(); ?> <?php echo $this->headTitle(); ?> <?php echo $this->headLink()->prependStylesheet($this->baseUrl().'css/style.css'); ?> </head> <body> <div id="left"> <h2> Application Web</h2> </div> <div id="right"> <h3>Authentification</h3> <br/> <?php if($this->user) : ?> <p id="logged-in">Logged in as <?php echo $this->escape($this->user->real_name);?>. <a href="<?php echo $this->baseUrl ?>/auth/logout">Logout</a></p> <?php endif; ?> </div> <div id="menu"> <ul> <li> <a href="<?php echo $this->url(array('controller'=>'auth', 'action'=>'login'), 'default', true) ?>">S'identifier</a> </li> <li> <a href="<?php echo $this->url(array('controller'=>'register', 'action'=>'creation'), 'default', true) ?>">S'inscrire</a> </li> <li> <a href="<?php echo $this->url(array('controller'=>'forum', 'action'=>'voirforum'), 'default', true) ?>">Forum</a> </li> <li> <a href="<?php echo $this->url(array('controller'=>'news'), 'default', true) ?>">News</a> </li> </ul> </div> <div id="content"> <h1><?php echo $this->escape($this->title); ?></h1> <?php echo $this->layout()->content; ?> </div> </body> </html>
Hors ligne
Revenons à notre sujet:
On souhaite maintenant "modifier" et "supprimer" des news.
Il faut que j'ajoute deux nouvelles actions dans mon controlleur "IndexController".
IndexController:
L'action "modifier":
public function modifierAction() { $form = new Application_Form_News(); $form->envoyer->setLabel('Sauvegarder'); //assigne le formulaire à la vue $this->view->form = $form; //si la page est posté - formulaire envoyé if ($this->getRequest()->isPost()) { //alors on récupére les données envoyé par le formulaire $formData = $this->getRequest()->getPost(); if ($form->isValid($formData)) { $id = $form->getValue('id'); $title = $form->getValue('title'); $author = $form->getValue('author'); $date = $form->getValue('date'); $content = $form->getValue('content'); $news = new Application_Model_DbTable_News(); $news->modifierNews($id, $title, $author, $date, $content); $this->_helper->redirector('index'); } else { $form->populate($formData); } } else { $id = $this->_getParam('id', 0); if ($id > 0) { $news = new Application_Model_DbTable_News(); //assignation des valeurs de l'entrée dans un tableau //tableau utilisé pour la méthode populate() qui va remplir le champs du formulaire //avec les valeurs du tableau $form->populate($news->obtenirNews($id)); //Notez que ce n'est exécuté que si la requête n'est pas de type POST, puisqu'un POST implique que le formulaire //a été rempli et que nous voulons le traiter. //Pour l'affichage initial du formulaire, nous récupérons l'id de la requête //en utilisant la méthode _getParam(). Nous utilisons ensuite le modèle pour récupérer l'enregistrement de la // base de données et remplir le formulaire directement avec les données de l'enregistrement (maintenant vous //savez pourquoi la méthode obtenirAlbum() du modèle retourne un tableau !). } } }
L'action "supprimer":
public function supprimerAction() { if ($this->getRequest()->isPost()) { $supprimer = $this->getRequest()->getPost('supprimer'); if ($supprimer == 'Oui') { $id = $this->getRequest()->getPost('id'); $news = new Application_Model_DbTable_News(); $news->supprimerNews($id); } $this->_helper->redirector('index'); } else { $id = $this->_getParam('id', 0); $news = new Application_Model_DbTable_News(); $this->view->news = $news->obtenirNews($id); } //Comme pour l'ajout et la modification, nous utilisons la méthode isPost() de la requête pour savoir si nous devons //afficher le formulaire ou bien effectuer la suppression. Nous utilisons le modèle Application_Model_DbTable_Albums //pour réellement supprimer l'enregistrement en utilisant la méthode supprimerAlbum(). Si la requête n'est pas de type //POST, alors nous recherchons un paramètre id, récupérons le bon enregistrement de base de données et l'assignonsla vue. } }
Il faut aussi que j'initialise ces 2 actions pour l'accès à la base dans mon dossier "Models/DbTable/news.php"
public function modifierNews($id, $title, $author, $date, $content) { $data = array( 'title' =>$title, 'author' =>$author, 'date' =>$date, 'content' =>$content, ); $this->update($data, 'id = '. (int)$id); } public function supprimerNews($id) { $this->delete('id =' . (int)$id); } } ?>
Hors ligne
Maintenant voici les deux vues correspondantes à ces deux actions:
Ces 2 fichiers sont dans \views\scripts\index
modifier.phtml - ressemble au fichier ajouter.phtml.
<?php $this->title = "Modifier une news"; $this->headTitle($this->title); echo $this->form; ?>
supprimer.phtml - un peu plus complexe.
<?php $this->title = "Supprimer une news"; $this->headTitle($this->title); ?> <p>Êtes-vous sûr de vouloir supprimer '<?php echo $this->escape($this->news['title']); ?>' de '<?php echo $this->escape($this->news['author']); ?>' '<?php echo $this->escape($this->news['date']); ?>'creé le '<?php echo $this->escape($this->news['content']); ?>'contenant ? </p> <form action="<?php echo $this->url(array('action'=>'supprimer')); ?>" method="post"> <div> <input type="hidden" name="id" value="<?php echo $this->news['id']; ?>" /> <input type="submit" name="supprimer" value="Oui" /> <input type="submit" name="supprimer" value="Non" /> </div> </form>
Hors ligne
Bon c'est un peu difficile d'être propre sur ma façon de travailler sur mon projet. Je suis désolé si tout cela n'est pas clair. Je tiens à préciser que je ne suis pas là pour vous aider, je suis trop mauvais pour çà lol. Je souhaite juste être remis dans le droit chemin au cas ou je m'égare. J'écris ce pseudo blog afin de poser les choses pour mieux les comprendre et pour que vous puissez répondre à mes prochaines interrogations.
Merci pour votre compréhension, merci pour les efforts fournis sur la lecture de ce projet.
Je continue dans la lancée.
Nous avons en page d'accueil un tableau de news qui ne ressemble pas à grand chose
On peut voir, ajouter, modifier et supprimer des news. On peut faire ces 4 actions en anonyme sans connexion.
On va donc se mettre sur le tutoriel " Débuter avec Zend Auth".
Règles:
1. Je dois m'inscrire via un formulaire d'inscription.
2. je peux modifier mon profil utilisateur.
3. Je dois m'identifier pour accéder aux news de la page d'accueil.
4. Je ne peux pas modifier ou supprimer les news de mon voisin - sinon message d'alerte.
5. Si j'ajoute une news, pendant l'ajout cela prend en compte mon nom de connexion et la date du jour.
Bon si j'arrive à appliquer ces 5 règles cela sera déjà très bien.
Dernière modification par lalwende (28-02-2011 15:37:52)
Hors ligne
Avant tout, voici les 2 fichiers complets - IndexController - news.php "accès à la base"
IndexController.php
<?php class IndexController extends Zend_Controller_Action { public function init() { //initialisation du controller index $this->initView(); $this->view->baseUrl = $this->_request->getBaseUrl(); $this->view->user = Zend_Auth::getInstance()->getIdentity(); } /** * L'action par defaut est d'afficher la page d'accueil - index */ public function predispatch() { $auth = Zend_Auth::getInstance(); if (!$auth->hasIdentity()) { $this->_redirect('auth/login'); } } public function indexAction() { $news =new Application_Model_DbTable_News(); $this->view->news = $news->fetchAll(); } public function ajouterAction() { $form = new Application_Form_News(); $form->envoyer->setLabel('Ajouter'); $this->view->form = $form; //Nous instancions notre Application_Form_News, nous affectons au bouton d'envoi le libellé "Ajouter" puis nous //assignons le formulaire à la vue pour affichage. if ($this->getRequest()->isPost()) { $formData = $this->getRequest()->getPost(); if ($form->isValid($formData)) //Si la méthode isPost() de l'objet de requête renvoie true, alors le formulaire a été envoyé. Nous récupérons alors les données de la requête avec la méthode getPost() et nous vérifions qu'elles sont valides avec la méthode membre isValid(). { $title = $form->getValue('title'); $author = $form->getValue('author'); $date = $form->getValue('date'); $content = $form->getValue('content'); $news = new Application_Model_DbTable_News(); $news->ajouterNews($title, $author, $date, $content); //Si le formulaire est valide, nous instancions la classe modèle Application_Model_DbTable_News et nous //utilisons la méthode ajouterNews() que nous avons créée plus tôt pour créer un nouvel enregistrement dans la //base de données. $this->_helper->redirector('index'); //on redirige vers l'inde si le form est valide avec l'aide d'action redirector } else { $form->populate($formData); } //si c'est pas valide on affiche à nouveau le formulaire avec les données déja mises. } } public function modifierAction() { $form = new Application_Form_News(); $form->envoyer->setLabel('Sauvegarder'); //assigne le formulaire à la vue $this->view->form = $form; //si la page est posté - formulaire envoyé if ($this->getRequest()->isPost()) { //alors on récupére les données envoyé par le formulaire $formData = $this->getRequest()->getPost(); if ($form->isValid($formData)) { $id = $form->getValue('id'); $title = $form->getValue('title'); $author = $form->getValue('author'); $date = $form->getValue('date'); $content = $form->getValue('content'); $news = new Application_Model_DbTable_News(); $news->modifierNews($id, $title, $author, $date, $content); $this->_helper->redirector('index'); } else { $form->populate($formData); } } else { $id = $this->_getParam('id', 0); if ($id > 0) { $news = new Application_Model_DbTable_News(); //assignation des valeurs de l'entrée dans un tableau //tableau utilisé pour la méthode populate() qui va remplir le champs du formulaire //avec les valeurs du tableau $form->populate($news->obtenirNews($id)); //Notez que ce n'est exécuté que si la requête n'est pas de type POST, puisqu'un POST implique que le formulaire //a été rempli et que nous voulons le traiter. //Pour l'affichage initial du formulaire, nous récupérons l'id de la requête //en utilisant la méthode _getParam(). Nous utilisons ensuite le modèle pour récupérer l'enregistrement de la // base de données et remplir le formulaire directement avec les données de l'enregistrement (maintenant vous //savez pourquoi la méthode obtenirAlbum() du modèle retourne un tableau !). } } } public function supprimerAction() { if ($this->getRequest()->isPost()) { $supprimer = $this->getRequest()->getPost('supprimer'); if ($supprimer == 'Oui') { $id = $this->getRequest()->getPost('id'); $news = new Application_Model_DbTable_News(); $news->supprimerNews($id); } $this->_helper->redirector('index'); } else { $id = $this->_getParam('id', 0); $news = new Application_Model_DbTable_News(); $this->view->news = $news->obtenirNews($id); } //Comme pour l'ajout et la modification, nous utilisons la méthode isPost() de la requête pour savoir si nous devons //afficher le formulaire ou bien effectuer la suppression. Nous utilisons le modèle Application_Model_DbTable_Albums //pour réellement supprimer l'enregistrement en utilisant la méthode supprimerAlbum(). Si la requête n'est pas de type //POST, alors nous recherchons un paramètre id, récupérons le bon enregistrement de base de données et l'assignonsla vue. } }
news.php - DbTable
<?php class Application_Model_DbTable_News extends Zend_Db_Table_Abstract { protected $_name = 'news'; public function obtenirNews($id) { $id = (int)$id; $row = $this->fetchRow('id= ' . $id); if (!$row) { throw new Exception ("Impossible de trouver les donnees $id"); } RETURN $row->toArray(); } public function ajouterNews($title, $author, $date, $content) { $data = array( 'title' =>$title, 'author' =>$author, 'date' =>$date, 'content' =>$content, ); $this->insert($data); } public function modifierNews($id, $title, $author, $date, $content) { $data = array( 'title' =>$title, 'author' =>$author, 'date' =>$date, 'content' =>$content, ); $this->update($data, 'id = '. (int)$id); } public function supprimerNews($id) { $this->delete('id =' . (int)$id); } } ?>
Si cela peut être utile à la compréhension de mon code.
Hors ligne
Ok, on passe à l'authentification.
Tout d'abord je vais partir d'une table "users" très légère ->id - username - password - real_name.
On commence par créer notre formulaire d'authentification. Ce formulaire est directement accessible sur le fichier "login.phtml". Ce formulaire permet la reconnaissance de l'utilisateur.
Dernière modification par lalwende (28-02-2011 15:43:51)
Hors ligne
Mon controlleur se nomme "AuthController.php"
Ce controlleur a deux actions -> login ->logout. Il me faut donc créer les vues correspondantes dans un dossier "auth".
<?php class AuthController extends Zend_Controller_Action { public function init() { $this->initView(); $this->view->baseUrl = $this->_request->getBaseUrl(); } public function indexAction() { $this->_redirect('/'); } public function loginAction() { $this->view->message = ''; // traitement des donnees du formulaire if ($this->_request->isPost()) { // collect the data from the user Zend_Loader::loadClass('Zend_Filter_StripTags'); $f = new Zend_Filter_StripTags(); $username = $f->filter($this->_request->getPost('username')); $password = $f->filter($this->_request->getPost('password')); if (empty($username)) { $this->view->message = 'Please provide a username.'; } else { // setup Zend_Auth adapter for a database table Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable'); $dbAdapter = Zend_Registry::get('dbAdapter'); $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter); $authAdapter->setTableName('users'); $authAdapter->setIdentityColumn('username'); $authAdapter->setCredentialColumn('password'); // Set the input credential values to authenticate against $authAdapter->setIdentity($username); $authAdapter->setCredential($password); // do the authentication $auth = Zend_Auth::getInstance(); $result = $auth->authenticate($authAdapter); if ($result->isValid()) { // success: store database row to auth's storage // system. (Not the password though!) $data = $authAdapter->getResultRowObject(null, 'password'); $auth->getStorage()->write($data); $this->_redirect('/'); } else { // failure: clear database row from session $this->view->message = 'Login failed.'; } } } $this->view->title = ""; $this->render(); } public function logoutAction() { Zend_Auth::getInstance()->clearIdentity(); $this->_redirect('/'); } }
Hors ligne
voici le fichier "login.phtml" qui se trouve dans le dossier \views\scripts\auth.
<h1><?php echo $this->escape($this->title); ?></h1> <?php if(!empty($this->message)) :?> <div id="message"> <?php echo $this->escape($this->message);?> </div> <?php endif; ?> <h3>Identifiez vous:</h3> <form action="<?php echo $this->baseUrl ?>/auth/login" method="post"> <div> <label for="username">Username</label> <input type="text" name="username" value=""/> </div> <div> <label for="password">Password</label> <input type="password" name="password" value=""/> </div> <div id="formbutton"> <input type="submit" name="login" value="Login" /> </div> </form>
le fichier logout.phtml est bien créé mais il ne contient rien car c'est juste un clear de l'identity. voir le tuto de rob.
Dernière modification par lalwende (28-02-2011 15:28:06)
Hors ligne
Il me manque un fichier pour que l'identification fonctionne.
Le fichier d'interaction avec la base qui se nomme: \application\models\DbTable\users.php
<?php class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract { protected $_name = 'users'; public function obtenirUsers($id) { $id = (int)$id; $row = $this->fetchRow('id= ' . $id); if (!$row) { throw new Exception ("Impossible de trouver les donnees $id"); } RETURN $row->toArray(); } public function creationUsers($username, $password, $real_name) { $data = array( 'username' =>$username, 'password' =>$password, 'real_name' =>$real_name, ); $this->insert($data); } public function modifierUsers($id, $username, $password, $real_name) { $data = array( 'username' =>$username, 'password' =>$password, 'real_name' =>$real_name, ); $this->update($data, 'id = '. (int)$id); } }
Hors ligne
Ok on peut s'identifier sur le site.
Je n'ai toujours pas de formulaire d'inscription. J'ai repris la même méthode que les "news".
On retrouve deux actions qui seront utiles "creation - modifier" dans notre fichier DbTable/Users.php
Dernière modification par lalwende (28-02-2011 16:12:20)
Hors ligne
Je vais exploiter ces deux actions via un controller qui se nomme "RegisterController". C'est là ou les choses se compliquent pour mon petit cerveau. Dois je utilisé un controller indépendant "Register" ou bien exploiter celui déjà utilisé "AuthController".
voici le code "RegisterController". Pour simplifier les choses, on ne retrouve que l'action creation. Je n'arrive pas a faire fonctionner l'action "modifier". J'ai essayé de reprendre la même méthode que pour les news mais l'appli n'a pas l'air de comprendre. Je n'ai pas de message d'erreur qui en résulte.
<?php class RegisterController extends Zend_Controller_Action { public function init() { $this->initView(); $this->view->baseUrl = $this->_request->getBaseUrl(); } public function indexAction() { $this->_redirect('/'); } public function creationAction() { $form = new Application_Form_Users(); $form->envoyer->setLabel('Creation'); $this->view->form = $form; //Nous instancions notre Application_Form_Users, nous affectons au bouton d'envoi le libellé "Creation" puis nous //assignons le formulaire à la vue pour affichage. if ($this->getRequest()->isPost()) { $formData = $this->getRequest()->getPost(); if ($form->isValid($formData)) //Si la méthode isPost() de l'objet de requête renvoie true, alors le formulaire a été envoyé. Nous récupérons alors les données de la requête avec la méthode getPost() et nous vérifions qu'elles sont valides avec la méthode membre isValid(). { $username = $form->getValue('username'); $password = $form->getValue('password'); $real_name = $form->getValue('real_name'); $users = new Application_Model_DbTable_Users(); $users->creationUsers($username, $password, $real_name); //Si le formulaire est valide, nous instancions la classe modèle Application_Model_DbTable_Users et nous //utilisons la méthode creationUsers() que nous avons créée plus tôt pour créer un nouvel enregistrement dans la //base de données. $this->_helper->redirector('index'); //on redirige vers l'inde si le form est valide avec l'aide d'action redirector } else { $form->populate($formData); } //si c'est pas valide on affiche à nouveau le formulaire avec les données déja mises. } } }
Pour récupérer des données liés à l'utilisateur qui s'est connecté cela passe par l'id. Sauf que c'est une méthode surement différente des news?
Si il y'avait une âme charitable pour m'expliquer cela, je serais fan.
Dernière modification par lalwende (28-02-2011 16:24:09)
Hors ligne
J'ai tenté de faire ceci :
public function modifierAction() { $form = new Application_Form_Users(); $form->envoyer->setLabel('Sauvegarder'); //assigne le formulaire à la vue $this->view->form = $form; //si la page est posté - formulaire envoyé if ($this->getRequest()->isPost()) { //alors on récupére les données envoyé par le formulaire $formData = $this->getRequest()->getPost(); if ($form->isValid($formData)) { $username = $form->getValue('username'); $password = $form->getValue('password'); $real_name = $form->getValue('real_name'); $users = new Application_Model_DbTable_Users(); $users->modifierUsers($username, $password, $real_name); $this->_helper->redirector('index'); } else { $form->populate($formData); } } else { $id = $this->_getParam('id', 0); if ($id > 0) { $users = new Application_Model_DbTable_Users(); //assignation des valeurs de l'entrée dans un tableau //tableau utilisé pour la méthode populate() qui va remplir le champs du formulaire //avec les valeurs du tableau déjà donner. $form->populate($news->obtenirUsers($id)); } } }
J'ai donc repris la méthode pour modifier une "news" et je l'ai adapté pour modifier un user.
J'ai ajouté ce bout de code dans mon layout pour que lorsque je suis connecté je peux modifier mon profil.
<h3>Authentification</h3> <br/> <?php if($this->user) : ?> <p id="logged-in">Logged in as <?php echo $this->escape($this->user->real_name);?>. <a href="<?php echo $this->baseUrl ?>/auth/logout">Logout</a> <a href="<?php echo $this->baseUrl ?>/register/modifier">Modifier</a> Modifier</a>
C'est bon je suis dans la brume, je ne vois pas à plus d'1 mètre. Arff dure dure zend.
A mon avis il y'a une histoire d'id qui n'est pas pris en compte et ne peux donc pas remontée sur le formulaire les infos afin de les modifier.
Si j'ai une réponse à ce pseudo blog, je serais ravi vue le pavé indigeste que je vous ai écris.
Dernière modification par lalwende (28-02-2011 16:45:17)
Hors ligne
En faite je suis une grosse bille. Si je veux modifier les infos du profil. C'est certainnement dans mon controller "AuthController" que cela se passe. J'imagine que je dois utiliser un truc du genre:
"Zend_Auth::getInstance()->updateIdentity"
Sinon je sèche.
Hors ligne