PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jobeet/fr/14.markdown

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