One hour application - PHP Quebec Conference 2009

11,793 views

Published on

Making a complete (but simple) application in one hour? I must be made! But with symfony it's possible!

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
11,793
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
25
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

One hour application - PHP Quebec Conference 2009

  1. 1. One hour application with symfony vendredi 13 novembre 2009 1
  2. 2. Aim • Present symfony in an original way • Make an application in one hour vendredi 13 novembre 2009 2
  3. 3. Who am I? • Philippe Gamache •PHP security expert at Parler Haut, Interagir Librement •Author of the book « Sécurité PHP 5 et MySQL » with Damien Seguy, at Eyrolles •http://www.ph-il.ca •http://www.phportail.net •http://lapageamelkor.org •naheulbeukauquebec.ca vendredi 13 novembre 2009 3
  4. 4. Questions? ? Please wait at the end, we don’t have much time vendredi 13 novembre 2009 4
  5. 5. The application • Blog • Comments • Clean URLs vendredi 13 novembre 2009 5
  6. 6. Install symfony http://www.symfony-project.org/installation • Source • Sandbox • PEAR • SVN • Linux Package (Debian and SUSE) vendredi 13 novembre 2009 6
  7. 7. Install using PEAR pear channel-discover pear.symfony-project.com pear install symfony/symfony-1.2.4 vendredi 13 novembre 2009 7
  8. 8. Create the project • Create directory project $ mkdir -p blog $ cd blog • Check symfony’s version $ symfony -V • Create project $ symfony generate:project blog vendredi 13 novembre 2009 8
  9. 9. Create the project • Create an application $ symfony generate:app / --escaping-strategy=on / --csrf-secret=Unique$ecr3t1 / frontend • Adjust your web server vendredi 13 novembre 2009 9
  10. 10. http://blog.local/frontend_dev.php/ vendredi 13 novembre 2009 10
  11. 11. Activating sfDoctrine // config/ProjectConfiguration.class.php public function setup() { $this->enableAllPluginsExcept( array('sfPropelPlugin', 'sfCompat10Plugin')); } vendredi 13 novembre 2009 11
  12. 12. The database • Creating the database $ mysqladmin -uroot -pmYsEcret / create blog • Configure the project $ symfony configure:database / --name=doctrine / --class=sfDoctrineDatabase / "mysql:host=localhost;dbname=blog" / root mYsEcret • Clear Propel connection vendredi 13 novembre 2009 12
  13. 13. Plugins • Installing plugins http://www.symfony-project.org/plugins/ • sfDoctrineGuardPlugin $ symfony plugin:install / sfDoctrineGuardPlugin / --release=3.0.0 vendredi 13 novembre 2009 13
  14. 14. The database diagram vendredi 13 novembre 2009 14
  15. 15. The databade model # config/doctrine/schema.yml actAs: [Timestampable] relations: BlogPost: Author: actAs: class: sfGuardUser Timestampable: ~ local: author_id Sluggable: foreign: id fields: [title] type: one BlogComment: unique: true columns: columns: blog_post_id: integer is_published: author_name: type: boolean type: string(255) default: false notnull: true allow_comments: author_email: string(255) type: boolean author_url: string(255) default: true content: author_id: integer(4) type: string(5000) title: notnull: true type: string(255) relations: notnull: true BlogPost: content: local: blog_post_id type: string(500000) foreign: id notnull: true type: one published_at: date foreignAlias: Comments vendredi 13 novembre 2009 15
  16. 16. Database fixtures # data/fixtures/fixtures.yml sfGuardUser: 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 vendredi 13 novembre 2009 16
  17. 17. Database fixtures BlogPost: 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 ... vendredi 13 novembre 2009 17
  18. 18. Database fixtures BlogComment: 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. vendredi 13 novembre 2009 18
  19. 19. Create the tables • Create the tables and load all fixtures $ symfony doctrine:build-all-load vendredi 13 novembre 2009 19
  20. 20. Creating the code • Use the code generator $ symfony doctrine:generate-crud / --with-show frontend post BlogPost • Delete unnecessary actions • executeNew() • executeEdit() • executeUpdate() • executeDelete() • processForm() vendredi 13 novembre 2009 20
  21. 21. Creating the code • Delete unnecessary files • templates/_form.php • templates/editSuccess.php • templates/newSuccess.php • Clear links to other functions vendredi 13 novembre 2009 21
  22. 22. Creating the code • Edit 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>By <?php echo $blog_post->getAuthor() ?> on <?php echo $blog_post- >getpublished_at() ?></div> <p> <?php echo $blog_post->getContentSuccess() ?> </p> <p><?php echo link_to('Show more...', '@post_show?slug=' . $blog_post- >getslug()) ?></p> <br /><br /> <?php endforeach; ?> vendredi 13 novembre 2009 22
  23. 23. Creating the code • Edit templates/showSuccess.php <h2><?php echo $blog_post->gettitle() ?></h2> <div>By <?php echo $blog_post->getAuthor() ?> on <?php echo $blog_post- >getpublished_at() ?></div> <p><?php echo nl2br($blog_post->getcontent()) ?></p> <hr /><br /><br /> <?php echo link_to('List', '@homepage') ?> vendredi 13 novembre 2009 23
  24. 24. Creating the code • Add to templates/layout.php <div id="header"> <h1><?php echo link_to('My blog', '@homepage') ?></h1> </div> <div id="content"> <?php echo $sf_data->getRaw('sf_content') ?> </div> <div id="footer"></div> • Modify web/css/main.css with blog.css vendredi 13 novembre 2009 24
  25. 25. Creating the code • Edit 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); } vendredi 13 novembre 2009 25
  26. 26. Creating the code • Edit BlogPost.class.php public function getContentSummary() { $out = explode('<', nl2br(substr($this->getcontent(), 0, 500))); return $out[0] . '...'; } • Modify to routing.yml homepage: url: / param: { module: post, action: index } post_show: url: /:slug param: { module: post, action: show } vendredi 13 novembre 2009 26
  27. 27. Add comments • Use the code generator $ symfony doctrine:generate-crud / frontend comment BlogComment • Copy the code you’ll need vendredi 13 novembre 2009 27
  28. 28. Add comments • Edit code in 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(); } vendredi 13 novembre 2009 28
  29. 29. Add comments • Add the code in actions.class.php public function executeCreate(sfWebRequest $request) { $this->forward404Unless($request->isMethod('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'); } vendredi 13 novembre 2009 29
  30. 30. Add comments • Add the code in actions.class.php 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')); } } • Add to routing.yml comment: url: /comment/:slug param: { module: post, action: create } vendredi 13 novembre 2009 30
  31. 31. Add comments • Edit 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">Posted on <?php echo $comment->getcreated_at() ?> by <?php echo $comment->getauthor_name() ?> </div> <p> <?php echo $comment->getcontent() ?> </p> </li> <?php endforeach; ?> </ul> <?php endif ?> <br /> ... vendredi 13 novembre 2009 31
  32. 32. Add comments • Edit templates/showSuccess.php ... <p class="bold">Add your comment</p> <br /> <?php include_partial('form', array('form' => $form, 'blog_post' => $blog_post)) ?> <hr /><br /><br /> <?php echo link_to('List', '@homepage') ?> vendredi 13 novembre 2009 32
  33. 33. Add comments • Edit templates/indexSuccess.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; ?> • Move _form.php vendredi 13 novembre 2009 33
  34. 34. Add comments • Edit templates/_form.php ... <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> ... • Keep only • author_name • author_email • author_url • content vendredi 13 novembre 2009 34
  35. 35. Add comments • Edit BlogCommentForm.class.php public function configure() { unset( $this['created_at'], $this['updated_at'], $this['blog_post_id'] ); $this->validatorSchema['author_email'] = new sfValidatorEmail(array('required' => false)); $this->validatorSchema['author_url'] = new sfValidatorUrl(array('required' => false)); $this->widgetSchema->setLabels(array( 'author_email' => 'Your email ', 'author_name' => 'Your name ', 'author_url' => 'Web site ', 'content' => 'Comment ', )); } vendredi 13 novembre 2009 35
  36. 36. Backend creation • Create an application $ symfony generate:app / --escaping-strategy=on / --csrf-secret=UniqueSecret / backend vendredi 13 novembre 2009 36
  37. 37. Backend creation • Create modules $ symfony doctrine:generate-admin / --module=post backend BlogPost $ symfony doctrine:generate-admin / --module=comment backend / BlogComment vendredi 13 novembre 2009 37
  38. 38. Backend creation • Edit routing.yml sf_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 rules homepage: url: / param: { module: post, action: index } vendredi 13 novembre 2009 38
  39. 39. Backend creation • Add to templates/layout.php <div id="header"> <h1><?php echo link_to('My blog', '@homepage') ?></h1> </div> <div id="menu"> <ul> <li><?php echo link_to('Posts', '@blog_post_post') ?></li> <li><?php echo link_to('Comments', '@blog_comment_comment') ?></li> </ul> </div> <div id="content"> <?php echo $sf_data->getRaw('sf_content') ?> </div> <div id="footer"></div> • Edit apps/frontend/config/view.yml vendredi 13 novembre 2009 39
  40. 40. Backend creation • Edit setting.yml ... all: .actions: login_module: sfGuardAuth login_action: signin secure_module: sfGuardAuth secure_action: secure .settings: enabled_modules: [default, sfGuardAuth] ... • Edit security.yml default: is_secure: on vendredi 13 novembre 2009 40
  41. 41. Backend creation • Edit post generator.yml ... config: actions: ~ fields: ~ list: title: Message list display: [is_published, author_id, =title, published_at] filter: display: [is_published] form: ~ edit: title: Edit post : "%%title%%" display: [is_published, author_id, title, content, published_at] new: title: New post display: [is_published, author_id, title, content, published_at] vendredi 13 novembre 2009 41
  42. 42. Backend creation • Edit comment generator.yml ... config: actions: ~ _delete: ~ _list: ~ fields: ContentSummary: label: Comments list: object_actions: _delete: ~ actions: __: ~ title: Comments list display: [blog_post_id, =author_name, =ContentSummary] filter: display: [blog_post_id] form: ~ edit: ~ new: ~ vendredi 13 novembre 2009 42
  43. 43. Backend creation • Edit myUser.class.php class myUser extends sfGuardSecurityUser { } vendredi 13 novembre 2009 43
  44. 44. To go further • Add tags • Add a mini-calendar • Display posts per month • Add search • Add feeds (RSS, ATOM) via sfFeed2plugins vendredi 13 novembre 2009 44
  45. 45. Questions? philippe.gamache@symfony-project.com info@ph-il.ca http://www.symfoy-project.org http://www.phportail.net vendredi 13 novembre 2009 45
  46. 46. vendredi 13 novembre 2009 46

×