quickstart-create-model.xml 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="learning.quickstart.create-model">
  5. <title>Créer un modèle et une table en base de données</title>
  6. <para>
  7. Avant de démarrer, considérons ceci: où vont se trouver ces classes et comment les retrouver?
  8. Le projet par défaut que nous avons conçu instancie un autoloader. Nous pouvons lui attacher
  9. d'autres autoloaders pour qu'il puisse trouver des classes différentes. Typiquement nous
  10. voulons que nos classes MVC soient groupées sous une même arborescence -- dans ce cas,
  11. <filename>application/</filename> -- et nous utiliserons un préfixe commun.
  12. </para>
  13. <para>
  14. <classname>Zend_Controller_Front</classname> a une notion de "modules", qui sont des
  15. mini-applications individuelles. Les modules reflètent la structure de répertoires que la
  16. commande <command>zf</command> crée sous <filename>application/</filename>, et toutes les
  17. classes à l'intérieur sont supposées commencer par un préfixe étant le nom du module.
  18. <filename>application/</filename> est lui-même un module -- le module "default" ou
  19. "application". Ainsi, nous allons vouloir configurer un autoload pour les ressources sous
  20. ce dossier.
  21. </para>
  22. <para>
  23. <classname>Zend_Application_Module_Autoloader</classname> propose la fonctionnalité nécessaire
  24. à la correspondance entre les ressources d'un module et ses dossiers, il propose pour cela
  25. un mécanisme de nommage standard. Une instance de la classe est créee par défaut pendant
  26. l'initialisation de l'objet de bootstrap et utilisera le préfixe de module "Application".
  27. De ce fait, nos classes de modèles, formulaires, et tables commenceront toutes par le préfixe
  28. de classe "Application_".
  29. </para>
  30. <para>
  31. Maintenant voyons de quoi est fait un livre d'or. Typiquement il existe simplement une liste
  32. d'entrées avec un <emphasis>commentaire</emphasis>, <emphasis>timestamp</emphasis>, et souvent
  33. une <emphasis>adresse email</emphasis>. En supposant que nous stockons cela dans une base de
  34. données, nous aurons aussi besoin d'un <emphasis>identifiant unique</emphasis> pour chaque
  35. entrée. Nous voudrons aussi sauvegarder une entrée, récupérer une entrée individuelle ou encore
  36. récupérer toutes les entrées. De ce fait, l'<acronym>API</acronym> du modèle d'un simple livre
  37. d'or ressemblerait à ceci:
  38. </para>
  39. <programlisting language="php"><![CDATA[
  40. // application/models/Guestbook.php
  41. class Application_Model_Guestbook
  42. {
  43. protected $_comment;
  44. protected $_created;
  45. protected $_email;
  46. protected $_id;
  47. public function __set($name, $value);
  48. public function __get($name);
  49. public function setComment($text);
  50. public function getComment();
  51. public function setEmail($email);
  52. public function getEmail();
  53. public function setCreated($ts);
  54. public function getCreated();
  55. public function setId($id);
  56. public function getId();
  57. }
  58. class Application_Model_GuestbookMapper
  59. {
  60. public function save(Application_Model_Guestbook $guestbook);
  61. public function find($id);
  62. public function fetchAll();
  63. }
  64. ]]></programlisting>
  65. <para>
  66. <methodname>__get()</methodname> et <methodname>__set()</methodname> nous simpliferons l'accès
  67. aux attributs et proxieront vers les autres getters et setters. Ils nous permettront de même
  68. de nous assurer que seuls les attributs que nous avons définis seront accessibles dans l'objet.
  69. </para>
  70. <para>
  71. <methodname>find()</methodname> et <methodname>fetchAll()</methodname> permettent de récupérer
  72. une seule entrée ou toutes les entrées alors que <methodname>save()</methodname> offrira la
  73. possibilité de stocker une entrée dans le support de stockage.
  74. </para>
  75. <para>
  76. Maintenant à partir de là, nous pouvons commecer à penser en terme de base de données.
  77. </para>
  78. <para>
  79. Nous devons d'abord intialiser une ressource <classname>Db</classname>. Comme pour les
  80. ressources <classname>Layout</classname> et <classname>View</classname>, nous pouvons utiliser
  81. de la configuration pour <classname>Db</classname>. Cela est possible au moyen de la commande
  82. <command>zf configure db-adapter</command>:
  83. </para>
  84. <programlisting language="shell"><![CDATA[
  85. % zf configure db-adapter \
  86. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
  87. > production
  88. A db configuration for the production has been written to the application config file.
  89. % zf configure db-adapter \
  90. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' \
  91. > testing
  92. A db configuration for the production has been written to the application config file.
  93. % zf configure db-adapter \
  94. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' \
  95. > development
  96. A db configuration for the production has been written to the application config file.
  97. ]]></programlisting>
  98. <para>
  99. Editez maintenant le fichier <filename>application/configs/application.ini</filename>, vous
  100. verrez que les lignes suivantes ont été ajoutées dans les sections appropriées:
  101. </para>
  102. <programlisting language="ini"><![CDATA[
  103. ; application/configs/application.ini
  104. [production]
  105. ; ...
  106. resources.db.adapter = "PDO_SQLITE"
  107. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
  108. [testing : production]
  109. ; ...
  110. resources.db.adapter = "PDO_SQLITE"
  111. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
  112. [development : production]
  113. ; ...
  114. resources.db.adapter = "PDO_SQLITE"
  115. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
  116. ]]></programlisting>
  117. <para>
  118. Votre fichier de configuration final devrait ressembler à ceci:
  119. </para>
  120. <programlisting language="ini"><![CDATA[
  121. ; application/configs/application.ini
  122. [production]
  123. phpSettings.display_startup_errors = 0
  124. phpSettings.display_errors = 0
  125. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  126. bootstrap.class = "Bootstrap"
  127. appnamespace = "Application"
  128. resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
  129. resources.frontController.params.displayExceptions = 0
  130. resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
  131. resources.view[] =
  132. resources.db.adapter = "PDO_SQLITE"
  133. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
  134. [staging : production]
  135. [testing : production]
  136. phpSettings.display_startup_errors = 1
  137. phpSettings.display_errors = 1
  138. resources.db.adapter = "PDO_SQLITE"
  139. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
  140. [development : production]
  141. phpSettings.display_startup_errors = 1
  142. phpSettings.display_errors = 1
  143. resources.db.adapter = "PDO_SQLITE"
  144. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
  145. ]]></programlisting>
  146. <para>
  147. Notez que la/les base(s) de données seront stockées sous <filename>data/db/</filename>. Créez ces dossiers
  148. et affectez leur les bons droits. Sur les systèmes Unix utilisez:
  149. </para>
  150. <programlisting language="shell"><![CDATA[
  151. % mkdir -p data/db; chmod -R a+rwX data
  152. ]]></programlisting>
  153. <para>
  154. Sur Windows, vous devrez créer le dossier avec l'explorateur et lui donner les bonnes permissions pour que
  155. tout le monde puisse y écrire.
  156. </para>
  157. <para>
  158. Dès lors, nous possédons une connexion à une base de données, dans notre cas il s'agit de Sqlite et la base
  159. est placée sous le dossier <filename>application/data/</filename>. Créons maintenant une table pour
  160. stocker nos entrées de livre d'or.
  161. </para>
  162. <programlisting language="sql"><![CDATA[
  163. -- scripts/schema.sqlite.sql
  164. --
  165. -- You will need load your database schema with this SQL.
  166. CREATE TABLE guestbook (
  167. id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  168. email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
  169. comment TEXT NULL,
  170. created DATETIME NOT NULL
  171. );
  172. CREATE INDEX "id" ON "guestbook" ("id");
  173. ]]></programlisting>
  174. <para>
  175. Puis pour ne pas travailler dans le vide, créons quelques enregistrements de départ.
  176. </para>
  177. <programlisting language="sql"><![CDATA[
  178. -- scripts/data.sqlite.sql
  179. --
  180. -- You can begin populating the database with the following SQL statements.
  181. INSERT INTO guestbook (email, comment, created) VALUES
  182. ('ralph.schindler@zend.com',
  183. 'Hello! Hope you enjoy this sample zf application!',
  184. DATETIME('NOW'));
  185. INSERT INTO guestbook (email, comment, created) VALUES
  186. ('foo@bar.com',
  187. 'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
  188. DATETIME('NOW'));
  189. ]]></programlisting>
  190. <para>
  191. Maintenant que nous avons la définition de la base de données ainsi que des données, créons un
  192. script qui pourra être lancé pour entièrement initialiser la base de données de manière
  193. autonomme. Bien sûr cela ne sera pas nécessaire en production. Créez le script
  194. <filename>scripts/load.sqlite.php</filename> avec le contenu suivant:
  195. </para>
  196. <programlisting language="php"><![CDATA[
  197. // scripts/load.sqlite.php
  198. /**
  199. * Script pour créer et charger la base
  200. */
  201. // Initialise le chemin vers l'application et l'autoload
  202. defined('APPLICATION_PATH')
  203. || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
  204. set_include_path(implode(PATH_SEPARATOR, array(
  205. APPLICATION_PATH . '/../library',
  206. get_include_path(),
  207. )));
  208. require_once 'Zend/Loader/Autoloader.php';
  209. Zend_Loader_Autoloader::getInstance();
  210. // Definit des options CLI
  211. $getopt = new Zend_Console_Getopt(array(
  212. 'withdata|w' => 'Load database with sample data',
  213. 'env|e-s' => 'Application environment for which to create database (defaults to development)',
  214. 'help|h' => 'Help -- usage message',
  215. ));
  216. try {
  217. $getopt->parse();
  218. } catch (Zend_Console_Getopt_Exception $e) {
  219. // Mauvaises options passées: afficher l'aide
  220. echo $e->getUsageMessage();
  221. return false;
  222. }
  223. // Si l'aid eest demandée, l'afficher
  224. if ($getopt->getOption('h')) {
  225. echo $getopt->getUsageMessage();
  226. return true;
  227. }
  228. // Initialise des valeurs selon la présence ou absence d'options CLI
  229. $withData = $getopt->getOption('w');
  230. $env = $getopt->getOption('e');
  231. defined('APPLICATION_ENV')
  232. || define('APPLICATION_ENV', (null === $env) ? 'development' : $env);
  233. // Initialise Zend_Application
  234. $application = new Zend_Application(
  235. APPLICATION_ENV,
  236. APPLICATION_PATH . '/configs/application.ini'
  237. );
  238. // Initialise et récupère la ressoucre DB
  239. $bootstrap = $application->getBootstrap();
  240. $bootstrap->bootstrap('db');
  241. $dbAdapter = $bootstrap->getResource('db');
  242. // Informons l'utilisateur de ce qui se passe (nous créons une base de données
  243. // ici)
  244. if ('testing' != APPLICATION_ENV) {
  245. echo 'Writing Database Guestbook in (control-c to cancel): ' . PHP_EOL;
  246. for ($x = 5; $x > 0; $x--) {
  247. echo $x . "\r"; sleep(1);
  248. }
  249. }
  250. // Vérifions si un fichier pour la base existe déja
  251. $options = $bootstrap->getOption('resources');
  252. $dbFile = $options['db']['params']['dbname'];
  253. if (file_exists($dbFile)) {
  254. unlink($dbFile);
  255. }
  256. // Chargement du fichier de la base de données.
  257. try {
  258. $schemaSql = file_get_contents(dirname(__FILE__) . '/schema.sqlite.sql');
  259. // utilise la connexion directement pour charger le sql
  260. $dbAdapter->getConnection()->exec($schemaSql);
  261. chmod($dbFile, 0666);
  262. if ('testing' != APPLICATION_ENV) {
  263. echo PHP_EOL;
  264. echo 'Database Created';
  265. echo PHP_EOL;
  266. }
  267. if ($withData) {
  268. $dataSql = file_get_contents(dirname(__FILE__) . '/data.sqlite.sql');
  269. // utilise la connexion directement pour charger le sql
  270. $dbAdapter->getConnection()->exec($dataSql);
  271. if ('testing' != APPLICATION_ENV) {
  272. echo 'Data Loaded.';
  273. echo PHP_EOL;
  274. }
  275. }
  276. } catch (Exception $e) {
  277. echo 'AN ERROR HAS OCCURED:' . PHP_EOL;
  278. echo $e->getMessage() . PHP_EOL;
  279. return false;
  280. }
  281. // Ce script sera lancé depuis la ligne de commandes
  282. return true;
  283. ]]></programlisting>
  284. <para>
  285. Exécutons ce script. Depuis un terminal ou un invite DOS, effectuez:
  286. </para>
  287. <programlisting language="shell"><![CDATA[
  288. % php scripts/load.sqlite.php --withdata
  289. ]]></programlisting>
  290. <para>
  291. Vous devriez voir ceci:
  292. </para>
  293. <programlisting language="text"><![CDATA[
  294. path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
  295. Writing Database Guestbook in (control-c to cancel):
  296. 1
  297. Database Created
  298. Data Loaded.
  299. ]]></programlisting>
  300. <para>
  301. Nous avons maintenant une base de données et une table pour notre application de livre d'or.
  302. Les prochaines étapes seront de créer le code applicatif. Ceci incluera une source de données
  303. (dans notre cas nous utiliserons <classname>Zend_Db_Table</classname>), un datamapper pour
  304. connecter cette source à notre modèle et enfin un contrôleur pour intéragir avec le modèle
  305. et afficher du contenu divers.
  306. </para>
  307. <para>
  308. Nous allons utiliser un <ulink url="http://martinfowler.com/eaaCatalog/tableDataGateway.html">Table
  309. Data Gateway</ulink> pour se connecter à notre source de données; <classname>Zend_Db_Table</classname>
  310. propose cette fonctionnalité. Créons les classes basées sur <classname>Zend_Db_Table</classname>.
  311. Comme nous avons opéré pour les layouts ou la base, nous pouvons utiliser la commande
  312. <command>zf</command> pour nous aider, avec la commande complète
  313. <command>create db-table</command>. Celle-ci prend deux arguments au minimum, le nom de la classe à
  314. créer et la table qui y fera référence.
  315. </para>
  316. <programlisting language="shell"><![CDATA[
  317. % zf create db-table Guestbook guestbook
  318. Creating a DbTable at application/models/DbTable/Guestbook.php
  319. Updating project profile 'zfproject.xml'
  320. ]]></programlisting>
  321. <para>
  322. En regardant l'orborescence du projet, un nouveau dossier
  323. <filename>application/models/DbTable/</filename> a été crée contenant le fichier
  324. <filename>Guestbook.php</filename>. Si vous ouvrez ce fichier, vous y verrez le contenu suivant:
  325. </para>
  326. <programlisting language="php"><![CDATA[
  327. // application/models/DbTable/Guestbook.php
  328. /**
  329. * This is the DbTable class for the guestbook table.
  330. */
  331. class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
  332. {
  333. /** Table name */
  334. protected $_name = 'guestbook';
  335. }
  336. ]]></programlisting>
  337. <para>
  338. Notez le préfixe de classe: <classname>Application_Model_DbTable</classname>. Le premier segment
  339. est "Application", le nom du module, puis vient le nom du composant "Model_DbTable" qui est lié
  340. au dossier <filename>models/DbTable/</filename> du module.
  341. </para>
  342. <para>
  343. Pour étendre <classname>Zend_Db_Table</classname>, seuls un nom de table et éventuellement un
  344. nom de clé primaire (si ce n'est pas "id") sont nécessaires.
  345. </para>
  346. <para>
  347. Créons maintenant un <ulink url="http://martinfowler.com/eaaCatalog/dataMapper.html">Data
  348. Mapper</ulink>. Un <emphasis>Data Mapper</emphasis> fait correspondre un objet métier à la
  349. base de données. Dans notre cas <classname>Application_Model_Guestbook</classname> vers la
  350. source de données <classname>Application_Model_DbTable_Guestbook</classname>. Une
  351. <acronym>API</acronym> typique pour un data mapper est:
  352. </para>
  353. <programlisting language="php"><![CDATA[
  354. // application/models/GuestbookMapper.php
  355. class Application_Model_GuestbookMapper
  356. {
  357. public function save($model);
  358. public function find($id, $model);
  359. public function fetchAll();
  360. }
  361. ]]></programlisting>
  362. <para>
  363. En plus de ces méthodes nous allons ajouter des méthodes pour affecter/récupérer l'objet
  364. Table Data Gateway. Pour créer la classe initiale, utilsez l'outil CLI
  365. <command>zf</command>:
  366. </para>
  367. <programlisting language="shell"><![CDATA[
  368. % zf create model GuestbookMapper
  369. Creating a model at application/models/GuestbookMapper.php
  370. Updating project profile '.zfproject.xml'
  371. ]]></programlisting>
  372. <para>
  373. Maintenant, éditez la classe <classname>Application_Model_GuestbookMapper</classname> dans
  374. <filename>application/models/GuestbookMapper.php</filename> pour y voir ceci:
  375. </para>
  376. <programlisting language="php"><![CDATA[
  377. // application/models/GuestbookMapper.php
  378. class Application_Model_GuestbookMapper
  379. {
  380. protected $_dbTable;
  381. public function setDbTable($dbTable)
  382. {
  383. if (is_string($dbTable)) {
  384. $dbTable = new $dbTable();
  385. }
  386. if (!$dbTable instanceof Zend_Db_Table_Abstract) {
  387. throw new Exception('Invalid table data gateway provided');
  388. }
  389. $this->_dbTable = $dbTable;
  390. return $this;
  391. }
  392. public function getDbTable()
  393. {
  394. if (null === $this->_dbTable) {
  395. $this->setDbTable('Application_Model_DbTable_Guestbook');
  396. }
  397. return $this->_dbTable;
  398. }
  399. public function save(Application_Model_Guestbook $guestbook)
  400. {
  401. $data = array(
  402. 'email' => $guestbook->getEmail(),
  403. 'comment' => $guestbook->getComment(),
  404. 'created' => date('Y-m-d H:i:s'),
  405. );
  406. if (null === ($id = $guestbook->getId())) {
  407. unset($data['id']);
  408. $this->getDbTable()->insert($data);
  409. } else {
  410. $this->getDbTable()->update($data, array('id = ?' => $id));
  411. }
  412. }
  413. public function find($id, Application_Model_Guestbook $guestbook)
  414. {
  415. $result = $this->getDbTable()->find($id);
  416. if (0 == count($result)) {
  417. return;
  418. }
  419. $row = $result->current();
  420. $guestbook->setId($row->id)
  421. ->setEmail($row->email)
  422. ->setComment($row->comment)
  423. ->setCreated($row->created);
  424. }
  425. public function fetchAll()
  426. {
  427. $resultSet = $this->getDbTable()->fetchAll();
  428. $entries = array();
  429. foreach ($resultSet as $row) {
  430. $entry = new Application_Model_Guestbook();
  431. $entry->setId($row->id)
  432. ->setEmail($row->email)
  433. ->setComment($row->comment)
  434. ->setCreated($row->created);
  435. $entries[] = $entry;
  436. }
  437. return $entries;
  438. }
  439. }
  440. ]]></programlisting>
  441. <para>
  442. Maintenant il faut créer la classe de modèle. Une fois de plus, nous utiliserons la commande
  443. <command>zf create model</command>:
  444. </para>
  445. <programlisting language="shell"><![CDATA[
  446. % zf create model Guestbook
  447. Creating a model at application/models/Guestbook.php
  448. Updating project profile '.zfproject.xml'
  449. ]]></programlisting>
  450. <para>
  451. Nous allons modifier cette classe <acronym>PHP</acronym> vide pour simplifier le remplissage
  452. du modèle via un tableau dans le constructeur ou une méthode
  453. <methodname>setOptions()</methodname>. Le code final de la classe de modèle stockée dans
  454. <filename>application/models/Guestbook.php</filename> devrait ressembler à ceci:
  455. </para>
  456. <programlisting language="php"><![CDATA[
  457. // application/models/Guestbook.php
  458. class Application_Model_Guestbook
  459. {
  460. protected $_comment;
  461. protected $_created;
  462. protected $_email;
  463. protected $_id;
  464. public function __construct(array $options = null)
  465. {
  466. if (is_array($options)) {
  467. $this->setOptions($options);
  468. }
  469. }
  470. public function __set($name, $value)
  471. {
  472. $method = 'set' . $name;
  473. if (('mapper' == $name) || !method_exists($this, $method)) {
  474. throw new Exception('Invalid guestbook property');
  475. }
  476. $this->$method($value);
  477. }
  478. public function __get($name)
  479. {
  480. $method = 'get' . $name;
  481. if (('mapper' == $name) || !method_exists($this, $method)) {
  482. throw new Exception('Invalid guestbook property');
  483. }
  484. return $this->$method();
  485. }
  486. public function setOptions(array $options)
  487. {
  488. $methods = get_class_methods($this);
  489. foreach ($options as $key => $value) {
  490. $method = 'set' . ucfirst($key);
  491. if (in_array($method, $methods)) {
  492. $this->$method($value);
  493. }
  494. }
  495. return $this;
  496. }
  497. public function setComment($text)
  498. {
  499. $this->_comment = (string) $text;
  500. return $this;
  501. }
  502. public function getComment()
  503. {
  504. return $this->_comment;
  505. }
  506. public function setEmail($email)
  507. {
  508. $this->_email = (string) $email;
  509. return $this;
  510. }
  511. public function getEmail()
  512. {
  513. return $this->_email;
  514. }
  515. public function setCreated($ts)
  516. {
  517. $this->_created = $ts;
  518. return $this;
  519. }
  520. public function getCreated()
  521. {
  522. return $this->_created;
  523. }
  524. public function setId($id)
  525. {
  526. $this->_id = (int) $id;
  527. return $this;
  528. }
  529. public function getId()
  530. {
  531. return $this->_id;
  532. }
  533. }
  534. ]]></programlisting>
  535. <para>
  536. Enfin, pour connecter tous ces éléments ensemble, créons un contrôleur qui listera les entrées
  537. de la base de données.
  538. </para>
  539. <para>
  540. Pour créer le nouveau contrôleur, utilisez la commande <command>zf create controller</command>:
  541. </para>
  542. <programlisting language="shell"><![CDATA[
  543. % zf create controller Guestbook
  544. Creating a controller at
  545. application/controllers/GuestbookController.php
  546. Creating an index action method in controller Guestbook
  547. Creating a view script for the index action method at
  548. application/views/scripts/guestbook/index.phtml
  549. Creating a controller test file at
  550. tests/application/controllers/GuestbookControllerTest.php
  551. Updating project profile '.zfproject.xml'
  552. ]]></programlisting>
  553. <para>
  554. Ceci va créer <classname>GuestbookController</classname> dans
  555. <filename>application/controllers/GuestbookController.php</filename>, avec une seule action
  556. <methodname>indexAction()</methodname>. Un script de vue sera aussi crée pour ce contrôleur,
  557. il sera logé dans <filename>application/views/scripts/guestbook/</filename>, avec une vue
  558. pour l'action index.
  559. </para>
  560. <para>
  561. Nous allons utiliser l'action "index" pour lister toutes les entrées du livre d'or.
  562. </para>
  563. <para>
  564. Un aterrissage sur <methodname>indexAction()</methodname> devra lister toutes les
  565. entrées du livre d'or. Ceci ressemblera à ce qui suit:
  566. </para>
  567. <programlisting language="php"><![CDATA[
  568. // application/controllers/GuestbookController.php
  569. class GuestbookController extends Zend_Controller_Action
  570. {
  571. public function indexAction()
  572. {
  573. $guestbook = new Application_Model_GuestbookMapper();
  574. $this->view->entries = $guestbook->fetchAll();
  575. }
  576. }
  577. ]]></programlisting>
  578. <para>
  579. Et bien sûr un script de vue sera nécessaire. Editez
  580. <filename>application/views/scripts/guestbook/index.phtml</filename> pour y
  581. inclure ceci:
  582. </para>
  583. <programlisting language="php"><![CDATA[
  584. <!-- application/views/scripts/guestbook/index.phtml -->
  585. <p><a href="<?php echo $this->url(
  586. array(
  587. 'controller' => 'guestbook',
  588. 'action' => 'sign'
  589. ),
  590. 'default',
  591. true) ?>">Sign Our Guestbook</a></p>
  592. Guestbook Entries: <br />
  593. <dl>
  594. <?php foreach ($this->entries as $entry): ?>
  595. <dt><?php echo $this->escape($entry->email) ?></dt>
  596. <dd><?php echo $this->escape($entry->comment) ?></dd>
  597. <?php endforeach ?>
  598. </dl>
  599. ]]></programlisting>
  600. <note>
  601. <title>Checkpoint</title>
  602. <para>
  603. Naviguez maintenant vers "http://localhost/guestbook". Vous devriez voir ceci
  604. apparaitre dans votre navigateur:
  605. </para>
  606. <para>
  607. <inlinegraphic width="525" scale="100" align="center" valign="middle"
  608. fileref="figures/learning.quickstart.create-model.png" format="PNG" />
  609. </para>
  610. </note>
  611. <note>
  612. <title>Utiliser le script de chargement des données</title>
  613. <para>
  614. Le script de chargement des données montré dans la section en question
  615. (<filename>scripts/load.sqlite.php</filename>) peut être utilisé pour créer une base
  616. de données pour chaque environnement défini et la remplir de données d'exemple. En
  617. interne, il utilise <classname>Zend_Console_Getopt</classname>, qui permet de préciser
  618. des options à la commande. Si vous passez "-h" ou "--help", toutes les options
  619. disponibles seront affichées:
  620. </para>
  621. <programlisting language="php"><![CDATA[
  622. Usage: load.sqlite.php [ options ]
  623. --withdata|-w Load database with sample data
  624. --env|-e [ ] Application environment for which to create database
  625. (defaults to development)
  626. --help|-h Help -- usage message)]]
  627. ]]></programlisting>
  628. <para>
  629. L'option "-e" permet de préciser la valeur de la constante
  630. <constant>APPLICATION_ENV</constant> -- ce qui en effet permet de créer une base de
  631. données SQLite pour chaque environnement défini. N'oubliez pas l'envrionnement
  632. lorsque vous utilisez ce script.
  633. </para>
  634. </note>
  635. </sect1>