Une application en une heure avec symfony - Collège de Mainsonneuve
-
Upload
philippe-gamache -
Category
Technology
-
view
754 -
download
1
Transcript of Une application en une heure avec symfony - Collège de Mainsonneuve
Une application en une heure
avec symfony
1
Objectif
• Présenter symfony d’une façon originale
• Faire une application en une heure
2
Qui suis-je?
•Philippe Gamache
•Expert en sécurité PHP chez Parler Haut, Interagir Librement
•Auteur du livre « Sécurité PHP 5 et MySQL » avec Damien Seguy, chez Eyrolles
•http://www.ph-il.ca•http://lapageamelkor.org•naheulbeukauquebec.ca
3
Des questions?
N’attendez à la fin ?
4
L’application
• Blogue
• Commentaires
• URLs propres
5
Installer symfony
• Source
• Bac à sable
• Installation via PEAR
• Installation via SVN
• Installation Linux (Debian et SUSE)
http://www.symfony-project.org/installation
6
Création du projet
• Installation de symfony
• Créer le répertoire du projet
• Vérifier la version de symfony
$ mkdir -p blogue/lib/vendor$ cd blogue/lib/vendor
$ symfony -V
$ svn checkout http://svn.symfony-project.com/tags/ RELEASE_1_4_0
7
Création du projet
• Créer un projet
• Créer une application
• Ajuster votre serveur web
$ symfony generate:app / --escaping-strategy=on / --csrf-secret=Unique$ecr3t1 / frontend
$ symfony generate:project blogue
8
http://blog.local/frontend_dev.php/
9
La base de données
• Créer la base de données
• Configurer le projet$ symfony configure:database / --name=doctrine / --class=sfDoctrineDatabase / "mysql:host=localhost;dbname=blog" / root mYsEcret
$ mysqladmin -uroot -pmYsEcret / create blog
10
Plugiciels
• Installer les plugiciels
• sfDoctrineGuardPluginhttp://www.symfony-project.org/plugins/
$ symfony plugin:install / sfDoctrineGuardPlugin / --release=4.0.1
11
Le modèle
12
Le schéma # config/doctrine/schema.ymlactAs: [Timestampable]
BlogPost: actAs: Timestampable: ~ Sluggable: fields: [title] unique: true columns: is_published: type: boolean default: false allow_comments: type: boolean default: true author_id: integer(4) title: type: string(255) notnull: true content: type: string(500000) notnull: true published_at: date
relations: Author: class: sfGuardUser local: author_id foreign: id type: one BlogComment: columns: blog_post_id: integer author_name: type: string(255) notnull: true author_email: string(255) author_url: string(255) content: type: string(5000) notnull: true relations: BlogPost: local: blog_post_id foreign: id type: one foreignAlias: Comments
13
Données de tests# data/fixtures/fixtures.ymlsfGuardUser: philippeg: username: Philippe Gamache password: password is_super_admin: true
sfGuardPermission: sgp_admin: name: admin description: Administrator permission
sfGuardGroup: sgg_admin: name: admin description: Administrator group
sfGuardGroupPermission: sggp_admin: sfGuardGroup: sgg_admin sfGuardPermission: sgp_admin
sfGuardUserGroup: sgug_admin: sfGuardGroup: sgg_admin sfGuardUser: philippeg
14
Données de testsBlogPost: post_1: Author: philippeg title: Lorem ipsum dolor sit amet content: | <p>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut...</p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do...</p> is_published: true published_at: 09-01-07 post_2: Author: philippeg title: Ut enim ad minim veniam content: | <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p> <p>Duis aute irure dolor in reprehenderit in voluptate velit esse...</p> is_published: true published_at: 09-01-07 post_3: Author: philippeg title: Duis aute irure dolor in reprehenderit in voluptate content: | <p>Duis aute irure dolor in reprehenderit in voluptate velit esse...</p> <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p> is_published: true published_at: 09-01-07...
15
Données de testsBlogComment: comment_1: BlogPost: post_1 author_name: lorem content: Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. comment_2: BlogPost: post_1 author_name: elit content: Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. comment_3: BlogPost: post_3 author_name: aute content: Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. comment_4: BlogPost: post_3 author_name: aute content: ESunt in culpa qui officia deserunt mollit anim id est laborum.
16
Creation Doctrine
• Creation des tables, des modèles, des formulaires, monter de test $ symfony doctrine:build --all --and-load
17
Création du code
• Utiliser le générateur de code
• Effacer les actions inutiles
• executeNew()• executeEdit()• executeUpdate()• executeDelete()• processForm()
$ symfony doctrine:generate-module / frontend post BlogPost
18
Création du code
• Effacer les fichiers inutiles
• templates/_form.php• templates/editSuccess.php• templates/newSuccess.php
• Effacer les liens vers les autres fonctions
19
Création du code
• Modifier templates/indexSuccess.php<?php foreach ($blog_post_list as $blog_post): ?> <h2><?php echo link_to($blog_post->gettitle(), '@post_show?slug=' . $blog_post->getslug()) ?></h2> <div>Par <?php echo $blog_post->getAuthor() ?> le <?php echo $blog_post->getpublished_at() ?></div> <p> <?php echo $blog_post->getContentSuccess() ?> </p> <p><?php echo link_to('Voir plus...', '@post_show?slug=' . $blog_post->getslug()) ?></p> <br /><br /><?php endforeach; ?>
20
Création du code
• Modifier templates/showSuccess.php<h2><?php echo $blog_post->gettitle() ?></h2><div>Par <?php echo $blog_post->getAuthor() ?> le <?php echo $blog_post->getpublished_at() ?></div>
<p><?php echo nl2br($blog_post->getcontent()) ?></p>
<hr /><br /><br />
<?php echo link_to('Liste', '@homepage') ?>
21
Création du code
• Ajouter au templates/layout.php
• Modifier web/css/main.css
<div id="header"> <h1><?php echo link_to('Mon Blogue', '@homepage') ?></h1></div>
<div id="content"> <?php echo $sf_data->getRaw('sf_content') ?></div><div id="footer"></div>
22
Création du code
• Modifier actions.class.php public function executeIndex(sfWebRequest $request) { $this->blog_post_list = Doctrine::getTable('BlogPost') ->createQuery('a') ->where('a.is_published = 1') ->execute(); }
public function executeShow(sfWebRequest $request) { $this->blog_post = Doctrine::getTable('BlogPost') ->findOneBySlug($request->getParameter('slug')); $this->forward404Unless($this->blog_post); }
23
Création du code
• Ajouter à BlogPost.class.php
• Modifier routing.yml
public function getContentSummary() { $out = explode('<', nl2br(substr($this->getcontent(), 0, 500))); return $out[0] . '...'; }
homepage: url: / param: { module: post, action: index }
post_show: url: /:slug param: { module: post, action: show }
24
Ajouter les commentaires
• Utiliser le générateur de code
• Copier le code dont vous aurez besoin
$ symfony doctrine:generate-module / frontend comment BlogComment
25
Ajouter les commentaires
• Modifier le code dans actions.class.php public function executeIndex(sfWebRequest $request) { $this->blog_post_list = Doctrine::getTable('BlogPost') ->createQuery('p') ->groupBy('p.published_at, p.id') ->where('p.is_published = 1') ->execute(); }
public function executeShow(sfWebRequest $request) { $this->blog_post = Doctrine::getTable('BlogPost') ->findOneBySlug($request->getParameter('slug')); $this->forward404Unless($this->blog_post);
$this->form = new BlogCommentForm(); }
26
Ajouter les commentaires
• Modifier le code dans actions.class.php public function executeCreate(sfWebRequest $request) { $this->forward404Unless($request->isMethod(sfRequest::POST)); $this->blog_post = Doctrine::getTable('BlogPost') ->findOneBySlug($request->getParameter('slug')); $this->forward404Unless($this->blog_post);
$comment = new BlogComment(); $comment->setBlogPost($this->blog_post);
$this->form = new BlogCommentForm($comment); $this->processForm($request, $this->form);
$this->setTemplate('show'); }
27
Ajouter les commentaires
• Modifier le code dans actions.class.php
• Ajouter a routing.yml
public function processForm(sfWebRequest $request, sfForm $form) { $form->bind($request->getParameter($form->getName())); if ($form->isValid()) { $blog_comment = $form->save(); $this->redirect('@post_show?slug=' . $request->getParameter('slug')); } }
comment: url: /comment/:slug param: { module: post, action: create }
28
Ajouter les commentaires
• Modifier templates/showSuccess.php...<p><?php echo nl2br($blog_post->getcontent()) ?></p><?php if (count($blog_post->getComments())): ?> <ul id="comments"> <?php foreach ($blog_post->getComments() as $comment): ?> <li class="comments"> <br /> <div class="bold">Poster <?php echo $comment->getcreated_at() ?> par <?php echo $comment->getauthor_name() ?> le </div> <p> <?php echo $comment->getcontent() ?> </p> </li> <?php endforeach; ?> </ul><?php endif ?><br />...
29
Ajouter les commentaires
• Modifier templates/showSuccess.php...
<p class="bold">Ajouter votre commentaire</p><br /><?php include_partial('form', array('form' => $form, 'blog_post' => $blog_post)) ?><hr /><br /><br />
<?php echo link_to('Liste', '@homepage') ?>
30
Ajouter les commentaires
• Modifier templates/indexSuccess.php
• Déplacer _form.php
... <p> <?php echo $blog_post->getContentSummary() ?> </p> <p>Comments (<?php echo count($blog_post->getComments()) ?>) : <?php echo link_to('Show more', '@post_show?slug=' . $blog_post->getslug()) ?></p> <br /><br /><?php endforeach; ?>
31
Ajouter les commentaires
• Modifier templates/_form.php
• Garder que• author_name• author_email• author_url• content
...<form action="<?php echo url_for('@comment?slug=' . $blog_post->getSlug()) ?>" method="POST"><?php if (!$form->getObject()->isNew()): ?><input type="hidden" name="sf_method" value="PUT" /><?php endif; ?> <table>...
32
Ajouter les commentaires
• Modifier BlogCommentForm.class.php public function configure() { $this->useFields(array('author_email', 'author_name', 'author_url', 'content' )); $this->validatorSchema['author_email'] = new sfValidatorEmail(array('required' => false)); $this->validatorSchema['author_url'] = new sfValidatorUrl(array('required' => false)); $this->widgetSchema->setLabels(array( 'author_email' => 'Votre courriel ', 'author_name' => 'Votre nom ', 'author_url' => 'Site Web ', 'content' => 'Commentaire ', )); }
33
Création du Backend
• Créer une application$ symfony generate:app / --escaping-strategy=on / --csrf-secret=UniqueSecret / backend
34
Création du Backend
• Créer les modules$ symfony doctrine:generate-admin / --module=post backend BlogPost$ symfony doctrine:generate-admin / --module=comment backend / BlogComment
35
Création du Backend
• Modifier routing.ymlsf_guard_signin: url: /login param: { module: sfGuardAuth, action: signin }
sf_guard_signout: url: /logout param: { module: sfGuardAuth, action: signout }
sf_guard_password: url: /request_password param: { module: sfGuardAuth, action: password }
# default ruleshomepage: url: / param: { module: post, action: index }
36
Création du Backend
• Ajouter au templates/layout.php<div id="header"> <h1><?php echo link_to('Mon Blogue', '@homepage') ?></h1></div>
<div id="menu"> <ul> <li><?php echo link_to('Poste', '@blog_post') ?></li> <li><?php echo link_to('Commentaire', '@blog_comment') ?></li> </ul></div>
<div id="content"> <?php echo $sf_data->getRaw('sf_content') ?></div>
<div id="footer"></div>
37
Création du Backend
• Modifier setting.yml
• Modifier security.yml
...all: .actions: login_module: sfGuardAuth login_action: signin
secure_module: sfGuardAuth secure_action: secure .settings: enabled_modules: [default, sfGuardAuth]...
default: is_secure: on
38
Création du Backend
• Modifier post generator.yml... config: actions: ~ fields: ~ list: title: Liste de message display: [is_published, author_id, =title, published_at] filter: display: [is_published] form: ~ edit: title: Modifier le message "%%title%%" display: [is_published, author_id, title, content, published_at] new: title: Nouveau message display: [is_published, author_id, title, content, published_at]
39
Création du Backend
• Modifier comment generator.yml... config: actions: _delete: ~ _list: ~ fields: ~ list: object_actions: _delete: ~ actions: __: ~ title: Liste des commentaires display: [blog_post_id, =author_name, =content] filter: display: [blog_post_id] form: ~ edit: ~ new: ~
40
Création du Backend
• Modifier myUser.class.phpclass myUser extends sfGuardSecurityUser{}
41
Pour aller plus loins
• Ajouter étiquettes (tags)
• Ajouter un mini-calendrier
• Mettre les billets par mois
• Ajouter recherche par date
• Ajouter des flux de données (RSS, ATOM) via sfFeed2plugins
42
Questions?
[email protected]@ph-il.ca
http://www.symfoy-project.orghttp://www.ph-il.ca/fr/conferences
43
44