| 1 |
Calendrier de l?avent cinqui� jour: formulaire et pagineur |
|---|
| 2 |
============================================================ |
|---|
| 3 |
|
|---|
| 4 |
Pr�demment dans Symfony |
|---|
| 5 |
------------------------- |
|---|
| 6 |
|
|---|
| 7 |
Durant ce long [quatri� jour] (4.txt), nous avons refactoriser notre application en d�a�t des bouts de codes dans des fichiers plus relatifs �eur nature. Vous avez �lement apprit �odifier le mod� de sorte que des fonctions li� aux donn�, puissent �e mises hors du code de l?action. |
|---|
| 8 |
|
|---|
| 9 |
Le d�loppement est propre, mais le nombre de fonctionnalit�est un peu pauvre. Il est temps de permettre un peu plus d?interactivit�ntre le site askeet et ses utilisateurs. Et les origines de l?interactivit�u HTML ? apr�les liens hypertextes ? sont les formulaires. |
|---|
| 10 |
|
|---|
| 11 |
Les objectifs d?aujourd?hui sont de permettre �?utilisateur de s?identifier et de mettre en forme la liste des questions de la page d?accueil. Cela sera rapide ��lopper, mais vous permettra de r�p�r d?hier. |
|---|
| 12 |
|
|---|
| 13 |
Formulaire login |
|---|
| 14 |
---------------- |
|---|
| 15 |
Des utilisateurs sont pr�nts dans les donn� de test, mais l?application ne peut pas les identifier. Donnons acc��n formulaire de login depuis n?importe quelle page de l?application. Ouvrez le layout global `askeet/apps/frontend/templates/layout.php` et ajoutez la ligne suivante avant le lien `about`�: |
|---|
| 16 |
|
|---|
| 17 |
[php] |
|---|
| 18 |
<li><?php echo link_to('sign in', 'user/login') ?></li> |
|---|
| 19 |
|
|---|
| 20 |
>**Note**: le layout courant place ce lien juste derri� la barre d?outils de d�gage. Pour la voir, cachez la barre d?outils en cliquant sur l?ic�?Sf?. |
|---|
| 21 |
|
|---|
| 22 |
Il est temps de cr� le module `user`. Tandis que le module `question` a � g�r�ors du deuxi� jour, cette fois nous allons juste demander �ymfony de cr� le squelette du module, et nous allons �ire le code nous m�. |
|---|
| 23 |
|
|---|
| 24 |
$ symfony init-module frontend user |
|---|
| 25 |
|
|---|
| 26 |
>**Note**: le squelette contient une action `index` par d�ut et un template `indexSuccess.php`. D�rrassons-nous en, puisque nous n?en aurons pas besoin. |
|---|
| 27 |
|
|---|
| 28 |
### Cr� l?action user/login |
|---|
| 29 |
|
|---|
| 30 |
Dans le fichier `user/actions/action.class.php` (du nouveau r�rtoire `askeet/apps/frontend/modules/`), ajoutez l?action `login`�: |
|---|
| 31 |
|
|---|
| 32 |
[php] |
|---|
| 33 |
public function executeLogin() |
|---|
| 34 |
{ |
|---|
| 35 |
$this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer()); |
|---|
| 36 |
|
|---|
| 37 |
return sfView::SUCCESS; |
|---|
| 38 |
} |
|---|
| 39 |
|
|---|
| 40 |
L?action sauvegarde la page appelante dans un attribut de requ�. Il sera ensuite possible au template de le mettre dans un champ cach�de sorte que l'action cible du formulaire puisse rediriger vers la page appelant, apr�une authentification r�sie. |
|---|
| 41 |
|
|---|
| 42 |
Le `return sfView::SUCCESS` passe le r�ltat de l?action au template `loginSuccess.php`. Cette instruction est implicite dans les actions qui ne contiennent pas d?instruction de retour, c?est pourquoi le template par d�ut d?une action est appel�actionnameSuccess.php`. |
|---|
| 43 |
|
|---|
| 44 |
Avant de poursuivre cette l?action, jetons un ?il au template. |
|---|
| 45 |
|
|---|
| 46 |
### Cr� le template `loginSuccess.php` |
|---|
| 47 |
|
|---|
| 48 |
Sur internet beaucoup d?interactions homme-machine utilisent les formulaires, et Symfony facilite la cr�ion et le management de ces derniers en fournissant un ensemble **d?assistants**. |
|---|
| 49 |
Dans le r�rtoire `askeet/apps/frontend/modules/user/templates/`, cr� le template `loginSuccess.php`: |
|---|
| 50 |
|
|---|
| 51 |
[php] |
|---|
| 52 |
<?php echo form_tag('user/login') ?> |
|---|
| 53 |
|
|---|
| 54 |
<fieldset> |
|---|
| 55 |
|
|---|
| 56 |
<div class="form-row"> |
|---|
| 57 |
<label for="nickname">nickname:</label> |
|---|
| 58 |
<?php echo input_tag('nickname', $sf_params->get('nickname')) ?> |
|---|
| 59 |
</div> |
|---|
| 60 |
|
|---|
| 61 |
<div class="form-row"> |
|---|
| 62 |
<label for="password">password:</label> |
|---|
| 63 |
<?php echo input_password_tag('password') ?> |
|---|
| 64 |
</div> |
|---|
| 65 |
|
|---|
| 66 |
</fieldset> |
|---|
| 67 |
|
|---|
| 68 |
<?php echo input_hidden_tag('referer', $sf_request->getAttribute('referer')) ?> |
|---|
| 69 |
<?php echo submit_tag('sign in') ?> |
|---|
| 70 |
|
|---|
| 71 |
</form> |
|---|
| 72 |
|
|---|
| 73 |
Ce template est votre premi� introduction aux assistants de formulaires. Ces fonctions Symfony aident �utomatiser l?�iture des formulaires. L?assistant `form_tag()` ouvre un formulaire avec le comportement POST par d�ut, et pointe vers l?action pass�en argument. L?assistant `input_tag()` produit une balise `<input>` (c?est une suprise) en ajoutant automatiquement l?attribut `id` dont la valeur est �le au premier argument�; la valeur par d�ut est donn�par le second argument. Vous pouvez en apprendre plus sur les assistants et sur le code HTML qu?ils g�rent dans le [chapitre relatif] (http://www.symfony-project.com/content/book/page/templating_form_helpers.html) du livre Symfony. |
|---|
| 74 |
|
|---|
| 75 |
La chose essentielle ici est que l?action appel�quand le formulaire est envoy�l?argument de `form_tag()`) est la m� action `login` que pour l?afficher. Ainsi revenons �?action. |
|---|
| 76 |
|
|---|
| 77 |
### Traiter l?envoie du formulaire login |
|---|
| 78 |
|
|---|
| 79 |
Remplacez l?action `login` que nous venons d?�ire par le code suivant�: |
|---|
| 80 |
|
|---|
| 81 |
[php] |
|---|
| 82 |
public function executeLogin() |
|---|
| 83 |
{ |
|---|
| 84 |
if ($this->getRequest()->getMethod() != sfRequest::POST) |
|---|
| 85 |
{ |
|---|
| 86 |
// display the form |
|---|
| 87 |
$this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer()); |
|---|
| 88 |
} |
|---|
| 89 |
else |
|---|
| 90 |
{ |
|---|
| 91 |
// handle the form submission |
|---|
| 92 |
$nickname = $this->getRequestParameter('nickname'); |
|---|
| 93 |
|
|---|
| 94 |
$c = new Criteria(); |
|---|
| 95 |
$c->add(UserPeer::NICKNAME, $nickname); |
|---|
| 96 |
$user = UserPeer::doSelectOne($c); |
|---|
| 97 |
|
|---|
| 98 |
// nickname exists? |
|---|
| 99 |
if ($user) |
|---|
| 100 |
{ |
|---|
| 101 |
// password is OK? |
|---|
| 102 |
if (true) |
|---|
| 103 |
{ |
|---|
| 104 |
$this->getUser()->setAuthenticated(true); |
|---|
| 105 |
$this->getUser()->addCredential('subscriber'); |
|---|
| 106 |
|
|---|
| 107 |
$this->getUser()->setAttribute('subscriber_id', $user->getId(), 'subscriber'); |
|---|
| 108 |
$this->getUser()->setAttribute('nickname', $user->getNickname(), 'subscriber'); |
|---|
| 109 |
|
|---|
| 110 |
// redirect to last page |
|---|
| 111 |
return $this->redirect($this->getRequestParameter('referer', '@homepage')); |
|---|
| 112 |
} |
|---|
| 113 |
} |
|---|
| 114 |
} |
|---|
| 115 |
} |
|---|
| 116 |
|
|---|
| 117 |
L?action login sera utilis�pour afficher le formulaire login et pour le traiter. Par cons�ent, elle doit savoir dans quel contexte elle est appel� Si l?action n?est pas appel�en mode POST, c?est parce qu?elle est appel�depuis un lien�: c'est ce dont nous avons parl�r�demment. Si la demande est en mode POST, l?action est appel�par un formulaire et il est temps de le traiter. |
|---|
| 118 |
|
|---|
| 119 |
L?action prend la valeur du champ `nickname` des param�es de la requ�, et requiert la table `User` pour voir si cet utilisateur existe. |
|---|
| 120 |
|
|---|
| 121 |
Il y aura, dans un avenir proche, un contr�du mot de passe qui accordera des droits d?acc��'utilisateur. Pour le moment, la seule chose que cette action fasse est de stoker dans un attribut de session `l?id`et le `nickname` de l?utilisateur. Eventuellement, l?action redirige �a page appelante gr� au champ cach�referer` du formulaire, pass�omme un param�e de requ�. Si le champ est vide, la valeur par d�ut (`@homepage`, qui est le nom de la r�e de routage pour `question/list`) est utilis��a place. |
|---|
| 122 |
|
|---|
| 123 |
Notez la diff�nce entre les deux types d?attribut dans cet exemple�: les **request attributes** (`$this->getRequest()->setAttribute()`) sont gard�pour le template et perdus d�que la r�nse est envoy��a page appelante. Les **session attributes** (`$this->getUser()->setAttribute()`) sont gard�le temps de la dur�de vie de la session utilisateur, et d?autres actions pourront encore y acc�r dans le future. Si vous voulez en savoir plus sur les attributs, vous pouvez jeter un ?il au [chapitre de support des param�es] (http://www.symfony-project.com/content/book/page/parameter_holder.html) du livre Symfony. |
|---|
| 124 |
|
|---|
| 125 |
### Accorder des privil�s |
|---|
| 126 |
|
|---|
| 127 |
C?est une bonne chose que les utilisateurs puissent s?identifier sur le site web askeet, mais ils ne le feront pas juste pour s?amuser. S?identifier sera exiger pour poster une nouvelle question, se d�arer int�ss�ar une question, et pour �luer un commentaire. Toutes les autres actions seront accessibles aux utilisateurs non identifi� |
|---|
| 128 |
Pour mettre un utilisateur comme authentifi�vous avez besoin d?appeler la fonction `->setAuthenticated()` de l?objet `sfUser`. Cet objet fournit aussi un m�nisme de droits d?acc�(`->addCredential()`), pour affiner la restriction d?acc�selon les profiles. Le [chapitre sur les droits d?acc�utilisateur](http://www.symfony-project.com/content/book/page/security.html) du livre Symfony explique tout ca en d�ils. |
|---|
| 129 |
|
|---|
| 130 |
|
|---|
| 131 |
That's the purpose of the two lines: |
|---|
| 132 |
|
|---|
| 133 |
[php] |
|---|
| 134 |
$this->getContext()->getUser()->setAuthenticated(true); |
|---|
| 135 |
$this->getContext()->getUser()->addCredential('subscriber'); |
|---|
| 136 |
|
|---|
| 137 |
Quand le nom d?utilisateur est identifi�non seulement les donn� utilisateurs seront mises en variables de session, mais l?acc�aux parties r�rv� sera attribu� l?utilisateur. Nous verrons demain comment restreindre l?acc��ertaines parties de l?application aux utilisateurs authentifi� |
|---|
| 138 |
|
|---|
| 139 |
|
|---|
| 140 |
### Ajouter l?action user/logout |
|---|
| 141 |
|
|---|
| 142 |
Il y a une derni� astuce �ropos de la fonction `->setAttribute()`: le dernier argument (`subscriber` dans l?exemple pr�dent) d�ni l?espace de noms ou l?attribut sera stock�Non seulement un espace de noms autorise un nom d� existant dans un autre espace de noms, mais il autorise �lement la suppression rapide de tous les attributs avec la simple commande�: |
|---|
| 143 |
|
|---|
| 144 |
[php] |
|---|
| 145 |
public function executeLogout() |
|---|
| 146 |
{ |
|---|
| 147 |
$this->getUser()->setAuthenticated(false); |
|---|
| 148 |
$this->getUser()->clearCredentials(); |
|---|
| 149 |
|
|---|
| 150 |
$this->getUser()->getAttributeHolder()->removeNamespace('subscriber'); |
|---|
| 151 |
|
|---|
| 152 |
$this->redirect('@homepage'); |
|---|
| 153 |
} |
|---|
| 154 |
|
|---|
| 155 |
Employer des espaces de noms nous a �t�'enlever les attributs un �n�: c?est une ligne de code en moins. Parlez de paresse�! |
|---|
| 156 |
|
|---|
| 157 |
### Mettre �our le layout |
|---|
| 158 |
|
|---|
| 159 |
Le layout montre toujours un lien 'login' m� si un utilisateur est d� logg�Corrigeons vite cela. Dans `askeet/apps/frontend/templates/layout.php`, changez la ligne que nous venons d?ajouter au d�t du tutorial d?aujourd?hui par�: |
|---|
| 160 |
|
|---|
| 161 |
[php] |
|---|
| 162 |
<?php if ($sf_user->isAuthenticated()): ?> |
|---|
| 163 |
<li><?php echo link_to('sign out', 'user/logout') ?></li> |
|---|
| 164 |
<li><?php echo link_to($sf_user->getAttribute('nickname', '', 'subscriber').' profile', 'user/profile') ?></li> |
|---|
| 165 |
<?php else: ?> |
|---|
| 166 |
<li><?php echo link_to('sign in/register', 'user/login') ?></li> |
|---|
| 167 |
<?php endif ?> |
|---|
| 168 |
|
|---|
| 169 |
Il est temps de tester tout ca en affichant quelques pages de l?application. Cliquez sur le lien ?login?, entrez un pseudo valide (?anonymous? devrai faire l?affaire) et valider le. Si le lien ?login? en haut de la fen�e change en ?sign out?, vous avez tout fait correctement. Eventuellement, essayez de vous d�nnecter pour v�fier si le lien ?login? apparait de nouveau. |
|---|
| 170 |
|
|---|
| 171 |
 |
|---|
| 172 |
|
|---|
| 173 |
Vous trouverez plus d?informations �ropos de la manipulation des attributs de sessions utilisateurs dans le [chapitre sur les sessions utilisateurs](http://www.symfony-project.com/content/book/page/user_session.html) du livre Symfony. |
|---|
| 174 |
|
|---|
| 175 |
Pagineur de question |
|---|
| 176 |
-------------------- |
|---|
| 177 |
|
|---|
| 178 |
Car des milliers de fans de Symfony se pr�piteront sur le site web d'askeet, il est tr�probable que la liste de questions affich� sur la page d?accueil, va beaucoup s?allonger. Pour �ter les requ�s lentes et le scrolling excessif, il est n�ssaire de mettre en page la liste des questions. |
|---|
| 179 |
Symfony fournit un objet dans ce but: le `sfPropelPager`. Il encapsule la requ� �a base de donn� de sorte que seuls les enregistrements �fficher sur la page courante soient exig� Par exemple, si un pagineur est initialis�our afficher 10 enregistrements par page, la requ� �a base de donn� sera limit��0 r�ltats, et l?offset est mit pour marquer la page. |
|---|
| 180 |
|
|---|
| 181 |
### Modifier l?action `question/list` |
|---|
| 182 |
|
|---|
| 183 |
Pendant le [troisi� jour] (3.txt), nous avons vu que l?action `list` du module `question` �it tout �ait restreint�: |
|---|
| 184 |
|
|---|
| 185 |
[php] |
|---|
| 186 |
public function executeList () |
|---|
| 187 |
{ |
|---|
| 188 |
$this->questions = QuestionPeer::doSelect(new Criteria()); |
|---|
| 189 |
} |
|---|
| 190 |
|
|---|
| 191 |
Nous allons modifier cette action, pour passer au template un objet `sfPropelPager` au lieu d?un tableau. Dans le m� temps, nous allons classer les questions par nombre d?int�ss� |
|---|
| 192 |
|
|---|
| 193 |
[php] |
|---|
| 194 |
public function executeList () |
|---|
| 195 |
{ |
|---|
| 196 |
$pager = new sfPropelPager('Question', 2); |
|---|
| 197 |
$c = new Criteria(); |
|---|
| 198 |
$c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS); |
|---|
| 199 |
$pager->setCriteria($c); |
|---|
| 200 |
$pager->setPage($this->getRequestParameter('page', 1)); |
|---|
| 201 |
$pager->setPeerMethod('doSelectJoinUser'); |
|---|
| 202 |
$pager->init(); |
|---|
| 203 |
|
|---|
| 204 |
$this->question_pager = $pager; |
|---|
| 205 |
} |
|---|
| 206 |
|
|---|
| 207 |
L?initialisation de l?objet `sfPropelPager` permet d?indiquer quelle classe il contiendra, et le nombre maximum d?objet qu?il est possible de mettre dans une page (deux dans cet exemple). La fonction `->setPage()` utilise un param�e pour afficher la page courante. Par exemple, si ce param�e `page` a la valeur `2`, le `sfPropelPager` retournera les r�ltats 3 �. La valeur par d�ut du param�e de requ� `page` �nt `1`, ce pagineur retournera les r�ltats 1 � par d�ut. Vous pouvez trouver plus d?informations �ropos de l?objet `sfPropelPager` et ses fonctions dans le [chapitre sur la mise en page](http://www.symfony-project.com/content/book/page/pager.html) du livre Symfony. |
|---|
| 208 |
|
|---|
| 209 |
### Utiliser un param�e personnalis� |
|---|
| 210 |
C'est toujours une bonne id�de mettre les constantes que vous utilisez dans des fichiers de configuration. Par exemple, le nombre de r�ltats par page (`2` dans cet exemple) pourrait �e remplac�ar un param�e, d�ni dans la configuration personnalis�de votre application. Changer la ligne de `new sfPropelPager` ci-dessus par : |
|---|
| 211 |
|
|---|
| 212 |
[php] |
|---|
| 213 |
... |
|---|
| 214 |
$pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max')); |
|---|
| 215 |
|
|---|
| 216 |
Ouvrez le fichier de configuration personnalis�`askeet/apps/frontend/config/app.yml`) de votre application et ajoutez-y�: |
|---|
| 217 |
|
|---|
| 218 |
all: |
|---|
| 219 |
pager: |
|---|
| 220 |
homepage_max: 2 |
|---|
| 221 |
|
|---|
| 222 |
Ici, la cl�pager` est utilis�comme un espace de nom, c?est pourquoi il apparait �lement dans le nom du param�e. Vous pouvez trouver plus d?informations �ropos des configurations personnalis� et les r�es pour appeler des param�es faits sur commande dans le [chapitre de configuration](http://www.symfony-project.com/content/book/page/configuration.html) du livre Symfony. |
|---|
| 223 |
|
|---|
| 224 |
### Modifier le template `listSuccess.php` |
|---|
| 225 |
|
|---|
| 226 |
Dans le template `listSuccess.php`, remplacez juste la ligne�: |
|---|
| 227 |
|
|---|
| 228 |
[php] |
|---|
| 229 |
<?php foreach($questions as $question): ?> |
|---|
| 230 |
|
|---|
| 231 |
par |
|---|
| 232 |
|
|---|
| 233 |
[php] |
|---|
| 234 |
<?php foreach($question_pager->getResults() as $question): ?> |
|---|
| 235 |
|
|---|
| 236 |
de sorte que la page affiche la liste de r�ltats stock� dans le pagineur. |
|---|
| 237 |
|
|---|
| 238 |
### Ajouter une page de navigation |
|---|
| 239 |
|
|---|
| 240 |
Il y a une chose de plus �jouter �e template�: la page de navigation. Pour le moment, tout ce que fait le template est d?afficher les deux premi�s questions, mais nous devrions ajouter la possibilit�?aller aux pages suivantes, et ensuite de revenir aux pages pr�dentes. Pour faire cela, ajoutez �a fin du template�: |
|---|
| 241 |
|
|---|
| 242 |
[php] |
|---|
| 243 |
<div id="question_pager"> |
|---|
| 244 |
<?php if ($question_pager->haveToPaginate()): ?> |
|---|
| 245 |
<?php echo link_to('«', 'question/list?page=1') ?> |
|---|
| 246 |
<?php echo link_to('<', 'question/list?page='.$question_pager->getPreviousPage()) ?> |
|---|
| 247 |
|
|---|
| 248 |
<?php foreach ($question_pager->getLinks() as $page): ?> |
|---|
| 249 |
<?php echo link_to_unless($page == $question_pager->getPage(), $page, 'question/list?page='.$page) ?> |
|---|
| 250 |
<?php echo ($page != $question_pager->getCurrentMaxLink()) ? '-' : '' ?> |
|---|
| 251 |
<?php endforeach; ?> |
|---|
| 252 |
|
|---|
| 253 |
<?php echo link_to('>', 'question/list?page='.$question_pager->getNextPage()) ?> |
|---|
| 254 |
<?php echo link_to('»', 'question/list?page='.$question_pager->getLastPage()) ?> |
|---|
| 255 |
<?php endif; ?> |
|---|
| 256 |
</div> |
|---|
| 257 |
|
|---|
| 258 |
Ce code tire l?avantage des diff�ntes fonctions de l?objet `sfPropelPager`, parmi lesquelles `->haveToPaginate()`, qui retourne `true` seulement si le nombre de r�ltats de la requ� exc� la taille de la page�; `->getPreviousPage()`, `->getNextPage()` et `->getLastPage()`, qui ont des significations �dentes�;�`->getLinks()`, fournit un tableau des num�s des pages; et `->getCurrentMaxLink()`, qui renvoie le dernier num� de page. |
|---|
| 259 |
|
|---|
| 260 |
Cette exemple montre �lement un assistant maniable de liens�: link_to_unless()` fera un simple `link_to()` si le test donn�omme premier argument est `false`, autrement le texte sera produit sans lien, encapsul�ans un simple `<span>`. |
|---|
| 261 |
|
|---|
| 262 |
Avez-vous testez le pagineur�? Vous devriez. La modification n?est pas effective tant que vous ne l?avez pas valid�avec vos propres yeux. Pour cela, ouvrez juste le fichier de donn� de test cr�lors du troisi� jour, et ajoutez quelques questions pour que la navigation de page apparaisse. Relancez le batch d?importation des donn� et rafraichissez la page d?accueil. Voila. |
|---|
| 263 |
|
|---|
| 264 |
 |
|---|
| 265 |
|
|---|
| 266 |
### Ajoutez une r�e de routage pour les pages suivantes |
|---|
| 267 |
|
|---|
| 268 |
Par d�ut, les urls des pages ressembleront � |
|---|
| 269 |
|
|---|
| 270 |
http://askeet/frontend_dev.php/question/list/page/XX |
|---|
| 271 |
|
|---|
| 272 |
Tirons profit des r�es de routage pour que ces pages soient interpr�es�: |
|---|
| 273 |
|
|---|
| 274 |
http://askeet/frontend_dev.php/index/XX |
|---|
| 275 |
|
|---|
| 276 |
Ouvrez juste le fichier `apps/frontend/config/routing.yml` et ajoutez au d�t�: |
|---|
| 277 |
|
|---|
| 278 |
popular_questions: |
|---|
| 279 |
url: /index/:page |
|---|
| 280 |
param: { module: question, action: list } |
|---|
| 281 |
|
|---|
| 282 |
Tant que l?on y est, ajoutez une autre r�e de routage pour la page de login�: |
|---|
| 283 |
|
|---|
| 284 |
login: |
|---|
| 285 |
url: /login |
|---|
| 286 |
param: { module: user, action: login } |
|---|
| 287 |
|
|---|
| 288 |
Refactorisation |
|---|
| 289 |
--------------- |
|---|
| 290 |
|
|---|
| 291 |
### Mod� |
|---|
| 292 |
|
|---|
| 293 |
L?action question/list` ex�te du code qui est �oitement li�u mod�, c?est pourquoi nous allons le d�acer dans le mod�. Remplacez le code de l?action `question/list` par�: |
|---|
| 294 |
|
|---|
| 295 |
[php] |
|---|
| 296 |
public function executeList () |
|---|
| 297 |
{ |
|---|
| 298 |
$this->question_pager = QuestionPeer::getHomepagePager($this->getRequestParameter('page', 1)); |
|---|
| 299 |
} |
|---|
| 300 |
|
|---|
| 301 |
?et ajoutez la fonction suivante dans la classe `QuestionPeer.php` situ�dans `lib/model`�: |
|---|
| 302 |
|
|---|
| 303 |
[php] |
|---|
| 304 |
public static function getHomepagePager($page) |
|---|
| 305 |
{ |
|---|
| 306 |
$pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max')); |
|---|
| 307 |
$c = new Criteria(); |
|---|
| 308 |
$c->addDescendingOrderByColumn(self::INTERESTED_USERS); |
|---|
| 309 |
$pager->setCriteria($c); |
|---|
| 310 |
$pager->setPage($page); |
|---|
| 311 |
$pager->setPeerMethod('doSelectJoinUser'); |
|---|
| 312 |
$pager->init(); |
|---|
| 313 |
|
|---|
| 314 |
return $pager; |
|---|
| 315 |
} |
|---|
| 316 |
|
|---|
| 317 |
La m� id�appliqu��?action `question/show`, �ite hier�: l?utilisation des objets Propel pour rechercher une question par son titre d�uill�evrait appartenir au mod�. Donc changez l?action `question/show` par: |
|---|
| 318 |
|
|---|
| 319 |
[php] |
|---|
| 320 |
public function executeShow() |
|---|
| 321 |
{ |
|---|
| 322 |
$this->question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title')); |
|---|
| 323 |
|
|---|
| 324 |
$this->forward404Unless($this->question); |
|---|
| 325 |
} |
|---|
| 326 |
|
|---|
| 327 |
Ajoutez �QuestionPeer.php`: |
|---|
| 328 |
|
|---|
| 329 |
[php] |
|---|
| 330 |
public static function getQuestionFromTitle($title) |
|---|
| 331 |
{ |
|---|
| 332 |
$c = new Criteria(); |
|---|
| 333 |
$c->add(QuestionPeer::STRIPPED_TITLE, $title); |
|---|
| 334 |
|
|---|
| 335 |
return self::doSelectOne($c); |
|---|
| 336 |
} |
|---|
| 337 |
|
|---|
| 338 |
### Templates |
|---|
| 339 |
|
|---|
| 340 |
La liste des questions affich� dans `question/templates/listSuccess.php` sera r�ilis�ailleurs dans le future. Donc nous allons d�acer le code du template pour afficher une liste de question dans le fragment `_list.php` et remplacer le contenu de `listSuccess.php` par un simple�: |
|---|
| 341 |
|
|---|
| 342 |
[php] |
|---|
| 343 |
<h1>popular questions</h1> |
|---|
| 344 |
|
|---|
| 345 |
<?php echo include_partial('list', array('question_pager' => $question_pager)) ?> |
|---|
| 346 |
|
|---|
| 347 |
Le contenu du fragment `_list.php` peut �e vu dans [l?espace de stockage SVN d?akeet](http://svn.askeet.com/tags/release_day_5/). |
|---|
| 348 |
|
|---|
| 349 |
A demain |
|---|
| 350 |
-------- |
|---|
| 351 |
|
|---|
| 352 |
Les formulaires de login et les pagineurs de liste sont utilis�dans la plupart des applications web de nos jours. Vous avez vu aujourd?hui qu?il �it facile de d�lopper avec Symfony. |
|---|
| 353 |
Une nouvelle fois, le tutorial finit par un peu de refactorisation. C?est le prix �ayer quand vous d�loppez une application petit �etit, sans la concevoir en entier avant. |
|---|
| 354 |
Demain, nous continuerons de travailler sur le processus d?authentification, en limitant l?acc��uelques parties du site aux utilisateurs enregistr� et nous ferons quelques validations de formulaire pour �ter les soumissions incorrectes. |
|---|
| 355 |
|
|---|