PageRenderTime 43ms CodeModel.GetById 2ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/jobeet/fr/14.markdown

https://github.com/rafaelgou/symfony1-docs
Markdown | 414 lines | 344 code | 70 blank | 0 comment | 0 complexity | acaa185ee3ecacc8abab09a08dc2558b MD5 | raw file
  1Jour 14 : Les Flux
  2==================
  3
  4Hier, vous avez commencé à développer votre première application symfony. Ne vous arrêtez
  5pas maintenant. Car vous en apprendrez davantage sur symfony, essayez d'ajouter de nouvelles
  6fonctionnalités à votre application, l'héberger quelque part, et la partager avec la communauté. 
  7
  8Passons à quelque chose de complètement différent aujourd'hui.
  9
 10Si vous êtes à la recherche d'un emploi, vous aurez probablement besoin d'être informé
 11dès qu'un nouveau poste est affiché. Parce qu'il n'est pas très pratique de vérifier le
 12site web toutes les heures, nous allons ajouter plusieurs flux d'emploi aujourd'hui pour
 13que nos utilisateurs Jobeet soient mis au courant.
 14
 15Les formats
 16-----------
 17
 18Le framework symfony a un support natif pour les ~formats|Formats~ et les
 19~mime-types|Mime Types~. Cela signifie que le même modèle et contrôleur peut
 20avoir différents ~Templates|Templates~ basés sur le format requêté. Le
 21format par défaut est HTML, mais symfony  supporte ~plusieurs autres formats|Formats
 22intégrés~ comme `txt`, `js`, `css`, `json`, `xml`, `rdf`, ou
 23`atom`.
 24
 25Le format peut être définie en utilisant la méthode `setRequestFormat()` de l'objet de
 26la ~requête|Requête HTTP~ :
 27
 28    [php]
 29    $request->setRequestFormat('xml');
 30
 31Mais la plupart du temps, le format est incorporé dans l'URL. Dans ce cas, symfony
 32va le mettre pour vous, si la variable spéciale ~`sf_format`~ est utilisé dans la route
 33correspondante. Pour la liste des emplois, l'URL de la liste est :
 34
 35    http://jobeet.localhost/frontend_dev.php/job
 36
 37Cette URL est équivalent à :
 38
 39    http://jobeet.localhost/frontend_dev.php/job.html
 40
 41Les deux URL sont équivalentes car les routes générés par la classe
 42`sfPropelRouteCollection` ont le `sf_format` comme extension et parce
 43que le HTML est le format par défaut. Vous pouvez le vérifier vous-même en
 44exécutant la tâche `app:routes` :
 45
 46![Cli](http://www.symfony-project.org/images/jobeet/1_4/15/cli.png)
 47
 48Les flux
 49--------
 50
 51### Le flux du dernier emploi
 52
 53Le support de différents formats est aussi facile que la création de Templates différents.
 54Pour créer un [flux Atom](http://en.wikipedia.org/wiki/Atom_(standard)) pour les derniers
 55emplois, créez un Template `indexSuccess.atom.php` :
 56
 57    [php]
 58    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
 59    <?xml version="1.0" encoding="utf-8"?>
 60    <feed xmlns="http://www.w3.org/2005/Atom">
 61      <title>Jobeet</title>
 62      <subtitle>Latest Jobs</subtitle>
 63      <link href="" rel="self"/>
 64      <link href=""/>
 65      <updated></updated>
 66      <author><name>Jobeet</name></author>
 67      <id>Unique Id</id>
 68
 69      <entry>
 70        <title>Job title</title>
 71        <link href="" />
 72        <id>Unique id</id>
 73        <updated></updated>
 74        <summary>Job description</summary>
 75        <author><name>Company</name></author>
 76      </entry>
 77    </feed>
 78
 79>**SIDEBAR**
 80>Les noms des Templates
 81>
 82>Comme `html` est le format le plus couramment utilisé pour les applications web, il peut être
 83>omis du nom du Template. Les deux Templates `indexSuccess.php` et `indexSuccess.html.php`
 84>sont équivalents et symfony utilise le premier qu'il trouve.
 85>
 86>Pourquoi les Templates par défaut sont suffixés avec `Success` ? Une action ne peut
 87>retourner une valeur pour indiquer le Template à rendre. Si l'action renvoie rien, il
 88>est équivalent au code suivant :
 89>
 90>     [php]
 91>     return sfView::SUCCESS; // == 'Success'
 92>
 93>Si vous voulez changer le suffixe, retournez simplement autre chose :
 94>
 95>     [php]
 96>     return sfView::ERROR; // == 'Error'
 97>
 98>     return 'Foo';
 99>
100>Comme nous l'avons vu dans la journée précédente, le nom du Template peut
101>également être modifié en utilisant la méthode `setTemplate()` :
102>
103>     [php]
104>     $this->setTemplate('foo');
105
106Par défaut, symfony va changer le `~Content-Type~` de la réponse en fonction du
107format, et pour tous les formats non-HTML, le layout est désactivé. Pour un flux Atom,
108symfony change le `Content-Type` en `application/atom+xml;
109charset=utf-8`.
110
111Dans le pied de page de Jobeet, mettez à jour le lien vers le flux :
112
113    [php]
114    <!-- apps/frontend/templates/layout.php -->
115    <li class="feed">
116      <a href="<?php echo url_for('@job?sf_format=atom') ?>">Full feed</a>
117    </li>
118
119L'~URI interne|URI interne~ est la même que pour la liste `job` avec le
120`sf_format` ajouté comme une variable.
121
122Ajoutez un balise `<link>` dans la section d'entête du layout pour permettre
123de découvrir par le navigateur automatiquement notre flux :
124
125    [php]
126    <!-- apps/frontend/templates/layout.php -->
127    <link rel="alternate" type="application/atom+xml" title="Latest Jobs"
128      href="<?php echo url_for('@job?sf_format=atom', true) ?>" />
129
130Pour l'attribut `href` du lien, une ~URL (Absolue)~ est utilisée grâce au second
131argument du helper `url_for()`.
132
133Remplacer l'entête du Template Atom avec le code suivant :
134
135    [php]
136    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
137    <title>Jobeet</title>
138    <subtitle>Latest Jobs</subtitle>
139    <link href="<?php echo url_for('@job?sf_format=atom', true) ?>" rel="self"/>
140    <link href="<?php echo url_for('@homepage', true) ?>"/>
141<propel>
142    <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', JobeetJobPeer::getLatestPost()->getCreatedAt('U')) ?></updated>
143</propel>
144<doctrine>
145    <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', Doctrine::getTable('JobeetJob')->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
146</doctrine>
147    <author>
148      <name>Jobeet</name>
149    </author>
150    <id><?php echo sha1(url_for('@job?sf_format=atom', true)) ?></id>
151
152<propel>
153Notez l'utilisation du `U` comme un argument pour `getCreatedAt()` pour obtenir
154la date comme un timestamp. Pour obtenir la date du dernier post, créez la méthode
155`getLatestPost()` :
156</propel>
157<doctrine>
158Notez l'utilisation du `U` comme un argument pour `format()` pour obtenir la date
159comme un timestamp. Pour obtenir la date du dernier post, créez la méthode
160`getLatestPost()` :
161</doctrine>
162
163<propel>
164    [php]
165    // lib/model/JobeetJobPeer.php
166    class JobeetJobPeer extends BaseJobeetJobPeer
167    {
168      static public function getLatestPost()
169      {
170        $criteria = new Criteria();
171        self::addActiveJobsCriteria($criteria);
172
173        return JobeetJobPeer::doSelectOne($criteria);
174      }
175
176      // ...
177    }
178</propel>
179<doctrine>
180    [php]
181    // lib/model/doctrine/JobeetJobTable.class.php
182    class JobeetJobTable extends Doctrine_Table
183    {
184      public function getLatestPost()
185      {
186        $q = Doctrine_Query::create()
187          ->from('JobeetJob j');
188        $this->addActiveJobsQuery($q);
189
190        return $q->fetchOne();
191      }
192
193      // ...
194    }
195</doctrine>
196
197Les entrées du flux peuvent être générées par le code suivant :
198
199    [php]
200    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
201    <?php use_helper('Text') ?>
202    <?php foreach ($categories as $category): ?>
203      <?php foreach ($category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')) as $job): ?>
204        <entry>
205          <title>
206            <?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)
207          </title>
208          <link href="<?php echo url_for('job_show_user', $job, true) ?>" />
209          <id><?php echo sha1($job->getId()) ?></id>
210<propel>
211          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getCreatedAt('U')) ?></updated>
212</propel>
213<doctrine>
214          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getDateTimeObject('created_at')->format('U')) ?></updated>
215</doctrine>
216          <summary type="xhtml">
217           <div xmlns="http://www.w3.org/1999/xhtml">
218             <?php if ($job->getLogo()): ?>
219               <div>
220                 <a href="<?php echo $job->getUrl() ?>">
221                   <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>"
222                     alt="<?php echo $job->getCompany() ?> logo" />
223                 </a>
224               </div>
225             <?php endif; ?>
226
227             <div>
228               <?php echo simple_format_text($job->getDescription()) ?>
229             </div>
230
231             <h4>How to apply?</h4>
232
233             <p><?php echo $job->getHowToApply() ?></p>
234           </div>
235          </summary>
236          <author>
237            <name><?php echo $job->getCompany() ?></name>
238          </author>
239        </entry>
240      <?php endforeach; ?>
241    <?php endforeach; ?>
242
243La méthode `getHost()` de l'objet de la requête (`$sf_request`) retourne
244l'hôte actuel, qui est très pratique pour créer un lien absolu pour le logo
245de l'entreprise.
246
247![Flux](http://www.symfony-project.org/images/jobeet/1_4/15/feed.png)
248
249>**TIP**
250>Lors de la création d'un flux, le ~débogage|Deboguer~ est plus facile si vous utilisez
251>des outils en ligne de commande comme [`curl`](http://curl.haxx.se/) ou
252>[`wget`](http://www.gnu.org/software/wget/), car vous voyez le contenu actuel
253>du flux.
254
255### Les derniers emplois dans le flux de la catégorie
256
257L'un des objectifs de Jobeet est d'aider les gens à trouver un emploi plus ciblées. Donc,
258nous devons fournir un flux pour chaque catégorie.
259
260D'abord, nous allons mettre à jour la route `category` pour ajouter le support de différents formats :
261
262    [yml]
263    // apps/frontend/config/routing.yml
264    category:
265      url:     /category/:slug.:sf_format
266      class:   sfPropelRoute
267      param:   { module: category, action: show, sf_format: html }
268      options: { model: JobeetCategory, type: object }
269      requirements:
270        sf_format: (?:html|atom)
271
272Maintenant, la route `category` comprend à la fois les formats `html` et `atom`.
273Mettez à jour les flux de la catégorie dans les ~Templates|Templates~ :
274
275    [php]
276    <!-- apps/frontend/modules/job/templates/indexSuccess.php -->
277    <div class="feed">
278      <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a>
279    </div>
280
281    <!-- apps/frontend/modules/category/templates/showSuccess.php -->
282    <div class="feed">
283      <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a>
284    </div>
285
286La dernière étape consiste à créer le Template `showSuccess.atom.php`. Mais comme ce
287flux sera également la liste des emplois, nous pouvons ~refactoriser|Refactorisation~ le
288code qui génère les entrées du flux en créant un partial `_list.atom.php`. Comme pour le
289format `html`, les ~partials|Templates Partial~ ont un format spécifique :
290
291    [php]
292    <!-- apps/frontend/modules/job/templates/_list.atom.php -->
293    <?php use_helper('Text') ?>
294
295    <?php foreach ($jobs as $job): ?>
296      <entry>
297        <title><?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)</title>
298        <link href="<?php echo url_for('job_show_user', $job, true) ?>" />
299        <id><?php echo sha1($job->getId()) ?></id>
300<propel>
301          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getCreatedAt('U')) ?></updated>
302</propel>
303<doctrine>
304          <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $job->getDateTimeObject('created_at')->format('U')) ?></updated>
305</doctrine>
306        <summary type="xhtml">
307         <div xmlns="http://www.w3.org/1999/xhtml">
308           <?php if ($job->getLogo()): ?>
309             <div>
310               <a href="<?php echo $job->getUrl() ?>">
311                 <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>"
312                   alt="<?php echo $job->getCompany() ?> logo" />
313               </a>
314             </div>
315           <?php endif; ?>
316
317           <div>
318             <?php echo simple_format_text($job->getDescription()) ?>
319           </div>
320
321           <h4>How to apply?</h4>
322
323           <p><?php echo $job->getHowToApply() ?></p>
324         </div>
325        </summary>
326        <author>
327          <name><?php echo $job->getCompany() ?></name>
328        </author>
329      </entry>
330    <?php endforeach; ?>
331
332Vous pouvez utiliser le partial `_list.atom.php` pour simplifier le Template du flux emploi :
333
334    [php]
335    <!-- apps/frontend/modules/job/templates/indexSuccess.atom.php -->
336    <?xml version="1.0" encoding="utf-8"?>
337    <feed xmlns="http://www.w3.org/2005/Atom">
338      <title>Jobeet</title>
339      <subtitle>Latest Jobs</subtitle>
340      <link href="<?php echo url_for('@job?sf_format=atom', true) ?>" rel="self"/>
341      <link href="<?php echo url_for('@homepage', true) ?>"/>
342<propel>
343      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', JobeetJobPeer::getLatestPost()->getCreatedAt('U')) ?></updated>
344</propel>
345<doctrine>
346      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', Doctrine::getTable('JobeetJob')->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
347</doctrine>
348      <author>
349        <name>Jobeet</name>
350      </author>
351      <id><?php echo sha1(url_for('@job?sf_format=atom', true)) ?></id>
352
353    <?php foreach ($categories as $category): ?>
354      <?php include_partial('job/list', array('jobs' => $category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')))) ?>
355    <?php endforeach; ?>
356    </feed>
357
358Enfin, créez le Template `showSuccess.atom.php` :
359
360    [php]
361    <!-- apps/frontend/modules/category/templates/showSuccess.atom.php -->
362    <?xml version="1.0" encoding="utf-8"?>
363    <feed xmlns="http://www.w3.org/2005/Atom">
364      <title>Jobeet (<?php echo $category ?>)</title>
365      <subtitle>Latest Jobs</subtitle>
366      <link href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom'), true) ?>" rel="self" />
367      <link href="<?php echo url_for('category', array('sf_subject' => $category), true) ?>" />
368<propel>
369      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $category->getLatestPost()->getCreatedAt('U')) ?></updated>
370</propel>
371<doctrine>
372      <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', $category->getLatestPost()->getDateTimeObject('created_at')->format('U')) ?></updated>
373</doctrine>
374      <author>
375        <name>Jobeet</name>
376      </author>
377      <id><?php echo sha1(url_for('category', array('sf_subject' => $category), true)) ?></id>
378
379      <?php include_partial('job/list', array('jobs' => $pager->getResults())) ?>
380    </feed>
381
382Quant au flux principal des emplois, nous avons besoin de la date du dernier emploi pour une catégorie :
383
384    [php]
385<propel>
386    // lib/model/JobeetCategory.php
387</propel>
388<doctrine>
389    // lib/model/doctrine/JobeetCategory.class.php
390</doctrine>
391    class JobeetCategory extends BaseJobeetCategory
392    {
393      public function getLatestPost()
394      {
395        $jobs = $this->getActiveJobs(1);
396
397        return $jobs[0];
398      }
399
400      // ...
401    }
402
403![Flux de la catégorie](http://www.symfony-project.org/images/jobeet/1_4/15/category_feed.png)
404
405À demain
406--------
407
408Comme avec de nombreuses fonctionnalités de symfony, le support du format natif vou
409permet d'ajouter des flux à vos sites Web sans effort.
410 
411Aujourd'hui, nous avons amélioré l'expérience du demandeur d'emploi. Demain, nous allons
412voir comment assurer une plus grande exposition aux annonceurs en leur fournissant un service Web.
413
414__ORM__