SlideShare a Scribd company logo
1 of 44
Download to read offline
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

http://www.symfony-project.org/installation
  • Source
  • Bac à sable
  • Installation via PEAR
  • Installation via SVN
  • Installation Linux (Debian et SUSE)

                                              6
Création du projet
• Installation de symfony
  $ mkdir -p blogue/lib/vendor
  $ cd blogue/lib/vendor
• Créer le répertoire du projet
  $ svn checkout
    http://svn.symfony-project.com/tags/
    RELEASE_1_4_0
• Vérifier la version de symfony
  $ symfony -V


                                           7
Création du projet
• Créer un projet
  $ symfony generate:project blogue
• Créer une application
  $ symfony generate:app /
    --escaping-strategy=on /
    --csrf-secret=Unique$ecr3t1 /
    frontend
• Ajuster votre serveur web


                                      8
http://blog.local/frontend_dev.php/


                                      9
La base de données
• Créer la base de données
 $ mysqladmin -uroot -pmYsEcret /
   create blog
• Configurer le projet
 $ symfony configure:database /
   --name=doctrine /
   --class=sfDoctrineDatabase /
   "mysql:host=localhost;dbname=blog" /
   root mYsEcret



                                          10
Plugiciels
 • Installer les plugiciels
http://www.symfony-project.org/plugins/
 • sfDoctrineGuardPlugin
  $ symfony plugin:install /
    sfDoctrineGuardPlugin /
    --release=4.0.1




                                          11
Le modèle




            12
Le schéma
# 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




                                                                 13
Données de tests
# 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


                                                14
Données de tests
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
...


                                                                                     15
Données de tests
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.




                                                                                     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
 $ symfony doctrine:generate-module /
    frontend post BlogPost
• Effacer les actions inutiles
  • executeNew()
  • executeEdit()
  • executeUpdate()
  • executeDelete()
  • processForm()

                                    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
 <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>


• Modifier web/css/main.css




                                                               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
   public function getContentSummary()
   {
     $out = explode('<', nl2br(substr($this->getcontent(), 0, 500)));
     return $out[0] . '...';
   }


• Modifier routing.yml
 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
 $ symfony doctrine:generate-module /
   frontend comment BlogComment
• Copier le code dont vous aurez besoin




                                          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
   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'));
     }
   }

• Ajouter a routing.yml
 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
 ...
   <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; ?>


• Déplacer _form.php




                                                                      31
Ajouter les
            commentaires
• Modifier 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>
 ...

• Garder que
  • author_name
  • author_email
  • author_url
  • content

                                                        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.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 }




                                                       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
  ...
  all:
    .actions:
       login_module:       sfGuardAuth
       login_action:       signin

      secure_module:       sfGuardAuth
      secure_action:       secure
    .settings:
      enabled_modules:   [default, sfGuardAuth]
  ...

• Modifier security.yml
  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.php
  class 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?

philippe.gamache@symfony-project.com
              info@ph-il.ca
     http://www.symfoy-project.org
  http://www.ph-il.ca/fr/conferences


                                       43
44

More Related Content

Similar to Une application en une heure avec symfony - Collège de Mainsonneuve

04 practical symfony 4дөх
04 practical symfony 4дөх04 practical symfony 4дөх
04 practical symfony 4дөхtuvshinmgl
 
20100925 sola-android
20100925 sola-android20100925 sola-android
20100925 sola-androidandroid sola
 
Komplexe Sites sauber aufbauen
Komplexe Sites sauber aufbauenKomplexe Sites sauber aufbauen
Komplexe Sites sauber aufbauenJens Grochtdreis
 
Social networks analisys - github API
Social networks analisys - github APISocial networks analisys - github API
Social networks analisys - github APIbaturin
 
初学者向けセミナー資料
初学者向けセミナー資料初学者向けセミナー資料
初学者向けセミナー資料Kenichi Kanai
 
Fatih BAZMAN CodeIgniter Sunumu
Fatih BAZMAN CodeIgniter SunumuFatih BAZMAN CodeIgniter Sunumu
Fatih BAZMAN CodeIgniter SunumuFatih Bazman
 

Similar to Une application en une heure avec symfony - Collège de Mainsonneuve (9)

04 practical symfony 4дөх
04 practical symfony 4дөх04 practical symfony 4дөх
04 practical symfony 4дөх
 
20100925 sola-android
20100925 sola-android20100925 sola-android
20100925 sola-android
 
Komplexe Sites sauber aufbauen
Komplexe Sites sauber aufbauenKomplexe Sites sauber aufbauen
Komplexe Sites sauber aufbauen
 
Social networks analisys - github API
Social networks analisys - github APISocial networks analisys - github API
Social networks analisys - github API
 
Clase5_Python-CTIC
Clase5_Python-CTICClase5_Python-CTIC
Clase5_Python-CTIC
 
BDD no mundo real
BDD no mundo realBDD no mundo real
BDD no mundo real
 
Wordpress avançat
Wordpress avançatWordpress avançat
Wordpress avançat
 
初学者向けセミナー資料
初学者向けセミナー資料初学者向けセミナー資料
初学者向けセミナー資料
 
Fatih BAZMAN CodeIgniter Sunumu
Fatih BAZMAN CodeIgniter SunumuFatih BAZMAN CodeIgniter Sunumu
Fatih BAZMAN CodeIgniter Sunumu
 

More from Philippe Gamache

Cryptographie 101 Pour les programmeurs (PHP)
Cryptographie 101 Pour les programmeurs (PHP)Cryptographie 101 Pour les programmeurs (PHP)
Cryptographie 101 Pour les programmeurs (PHP)Philippe Gamache
 
Content-Security-Policy 2018.0
Content-Security-Policy 2018.0Content-Security-Policy 2018.0
Content-Security-Policy 2018.0Philippe Gamache
 
Multi Factor Authetification - ZendCon 2017
Multi Factor Authetification - ZendCon 2017Multi Factor Authetification - ZendCon 2017
Multi Factor Authetification - ZendCon 2017Philippe Gamache
 
Browser Serving Your We Application Security - ZendCon 2017
Browser Serving Your We Application Security - ZendCon 2017Browser Serving Your We Application Security - ZendCon 2017
Browser Serving Your We Application Security - ZendCon 2017Philippe Gamache
 
Browser Serving Your Web Application Security - Madison PHP 2017
Browser Serving Your Web Application Security - Madison PHP 2017Browser Serving Your Web Application Security - Madison PHP 2017
Browser Serving Your Web Application Security - Madison PHP 2017Philippe Gamache
 
OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017
OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017 OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017
OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017 Philippe Gamache
 
Browser Serving Your Web Application Security - NorthEast PHP 2017
Browser Serving Your Web Application Security - NorthEast PHP 2017Browser Serving Your Web Application Security - NorthEast PHP 2017
Browser Serving Your Web Application Security - NorthEast PHP 2017Philippe Gamache
 
OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017
OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017
OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017Philippe Gamache
 
Kaizen ou l'amélioration continue
Kaizen ou l'amélioration continueKaizen ou l'amélioration continue
Kaizen ou l'amélioration continuePhilippe Gamache
 
Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009
Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009
Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009Philippe Gamache
 
One hour application - PHP Quebec Conference 2009
One hour application - PHP Quebec Conference 2009One hour application - PHP Quebec Conference 2009
One hour application - PHP Quebec Conference 2009Philippe Gamache
 
Une application en deux heure - PHP Québec Janvier 2009
Une application en deux heure - PHP Québec Janvier 2009Une application en deux heure - PHP Québec Janvier 2009
Une application en deux heure - PHP Québec Janvier 2009Philippe Gamache
 
Audit de code PHP - PHP Code Audit - HackFest.ca 2009
Audit de code PHP - PHP Code Audit - HackFest.ca 2009Audit de code PHP - PHP Code Audit - HackFest.ca 2009
Audit de code PHP - PHP Code Audit - HackFest.ca 2009Philippe Gamache
 
Auditing and securing PHP applications - FRHACK 2009
Auditing and securing PHP applications - FRHACK 2009Auditing and securing PHP applications - FRHACK 2009
Auditing and securing PHP applications - FRHACK 2009Philippe Gamache
 

More from Philippe Gamache (15)

Cryptographie 101 Pour les programmeurs (PHP)
Cryptographie 101 Pour les programmeurs (PHP)Cryptographie 101 Pour les programmeurs (PHP)
Cryptographie 101 Pour les programmeurs (PHP)
 
Content-Security-Policy 2018.0
Content-Security-Policy 2018.0Content-Security-Policy 2018.0
Content-Security-Policy 2018.0
 
Mentor et votre équipe
Mentor et votre équipeMentor et votre équipe
Mentor et votre équipe
 
Multi Factor Authetification - ZendCon 2017
Multi Factor Authetification - ZendCon 2017Multi Factor Authetification - ZendCon 2017
Multi Factor Authetification - ZendCon 2017
 
Browser Serving Your We Application Security - ZendCon 2017
Browser Serving Your We Application Security - ZendCon 2017Browser Serving Your We Application Security - ZendCon 2017
Browser Serving Your We Application Security - ZendCon 2017
 
Browser Serving Your Web Application Security - Madison PHP 2017
Browser Serving Your Web Application Security - Madison PHP 2017Browser Serving Your Web Application Security - Madison PHP 2017
Browser Serving Your Web Application Security - Madison PHP 2017
 
OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017
OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017 OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017
OWASP Top 10 Proactive Controls 2016 - NorthEast PHP 2017
 
Browser Serving Your Web Application Security - NorthEast PHP 2017
Browser Serving Your Web Application Security - NorthEast PHP 2017Browser Serving Your Web Application Security - NorthEast PHP 2017
Browser Serving Your Web Application Security - NorthEast PHP 2017
 
OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017
OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017
OWASP Top 10 Proactive Controls 2016 - PHP Québec August 2017
 
Kaizen ou l'amélioration continue
Kaizen ou l'amélioration continueKaizen ou l'amélioration continue
Kaizen ou l'amélioration continue
 
Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009
Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009
Laboratoire sécurité : audit de code PHP - Conférence PHP Québec 2009
 
One hour application - PHP Quebec Conference 2009
One hour application - PHP Quebec Conference 2009One hour application - PHP Quebec Conference 2009
One hour application - PHP Quebec Conference 2009
 
Une application en deux heure - PHP Québec Janvier 2009
Une application en deux heure - PHP Québec Janvier 2009Une application en deux heure - PHP Québec Janvier 2009
Une application en deux heure - PHP Québec Janvier 2009
 
Audit de code PHP - PHP Code Audit - HackFest.ca 2009
Audit de code PHP - PHP Code Audit - HackFest.ca 2009Audit de code PHP - PHP Code Audit - HackFest.ca 2009
Audit de code PHP - PHP Code Audit - HackFest.ca 2009
 
Auditing and securing PHP applications - FRHACK 2009
Auditing and securing PHP applications - FRHACK 2009Auditing and securing PHP applications - FRHACK 2009
Auditing and securing PHP applications - FRHACK 2009
 

Une application en une heure avec symfony - Collège de Mainsonneuve

  • 1. Une application en une heure avec symfony 1
  • 2. Objectif • Présenter symfony d’une façon originale • Faire une application en une heure 2
  • 3. 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
  • 4. Des questions? ? N’attendez à la fin 4
  • 5. L’application • Blogue • Commentaires • URLs propres 5
  • 6. Installer symfony http://www.symfony-project.org/installation • Source • Bac à sable • Installation via PEAR • Installation via SVN • Installation Linux (Debian et SUSE) 6
  • 7. Création du projet • Installation de symfony $ mkdir -p blogue/lib/vendor $ cd blogue/lib/vendor • Créer le répertoire du projet $ svn checkout http://svn.symfony-project.com/tags/ RELEASE_1_4_0 • Vérifier la version de symfony $ symfony -V 7
  • 8. Création du projet • Créer un projet $ symfony generate:project blogue • Créer une application $ symfony generate:app / --escaping-strategy=on / --csrf-secret=Unique$ecr3t1 / frontend • Ajuster votre serveur web 8
  • 10. La base de données • Créer la base de données $ mysqladmin -uroot -pmYsEcret / create blog • Configurer le projet $ symfony configure:database / --name=doctrine / --class=sfDoctrineDatabase / "mysql:host=localhost;dbname=blog" / root mYsEcret 10
  • 11. Plugiciels • Installer les plugiciels http://www.symfony-project.org/plugins/ • sfDoctrineGuardPlugin $ symfony plugin:install / sfDoctrineGuardPlugin / --release=4.0.1 11
  • 13. Le schéma # 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 13
  • 14. Données de tests # 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 14
  • 15. Données de tests 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 ... 15
  • 16. Données de tests 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. 16
  • 17. Creation Doctrine • Creation des tables, des modèles, des formulaires, monter de test $ symfony doctrine:build --all --and-load 17
  • 18. Création du code • Utiliser le générateur de code $ symfony doctrine:generate-module / frontend post BlogPost • Effacer les actions inutiles • executeNew() • executeEdit() • executeUpdate() • executeDelete() • processForm() 18
  • 19. 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
  • 20. 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
  • 21. 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
  • 22. Création du code • Ajouter au templates/layout.php <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> • Modifier web/css/main.css 22
  • 23. 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
  • 24. Création du code • Ajouter à BlogPost.class.php public function getContentSummary() { $out = explode('<', nl2br(substr($this->getcontent(), 0, 500))); return $out[0] . '...'; } • Modifier routing.yml homepage: url: / param: { module: post, action: index } post_show: url: /:slug param: { module: post, action: show } 24
  • 25. Ajouter les commentaires • Utiliser le générateur de code $ symfony doctrine:generate-module / frontend comment BlogComment • Copier le code dont vous aurez besoin 25
  • 26. 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
  • 27. 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
  • 28. Ajouter les commentaires • Modifier le code dans 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')); } } • Ajouter a routing.yml comment: url: /comment/:slug param: { module: post, action: create } 28
  • 29. 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
  • 30. 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
  • 31. Ajouter les commentaires • Modifier 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; ?> • Déplacer _form.php 31
  • 32. Ajouter les commentaires • Modifier 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> ... • Garder que • author_name • author_email • author_url • content 32
  • 33. 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
  • 34. Création du Backend • Créer une application $ symfony generate:app / --escaping-strategy=on / --csrf-secret=UniqueSecret / backend 34
  • 35. 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
  • 36. Création du Backend • Modifier 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 } 36
  • 37. 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
  • 38. Création du Backend • Modifier setting.yml ... all: .actions: login_module: sfGuardAuth login_action: signin secure_module: sfGuardAuth secure_action: secure .settings: enabled_modules: [default, sfGuardAuth] ... • Modifier security.yml default: is_secure: on 38
  • 39. 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
  • 40. 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
  • 41. Création du Backend • Modifier myUser.class.php class myUser extends sfGuardSecurityUser { } 41
  • 42. 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
  • 43. Questions? philippe.gamache@symfony-project.com info@ph-il.ca http://www.symfoy-project.org http://www.ph-il.ca/fr/conferences 43
  • 44. 44