SlideShare une entreprise Scribd logo
1  sur  46
Télécharger pour lire hors ligne
One hour application
                            with symfony




vendredi 13 novembre 2009                  1
Aim



                 • Present symfony in an original way
                 • Make an application in one hour




vendredi 13 novembre 2009                               2
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
Questions?


                            ?
       Please wait at the
         end, we don’t
        have much time



vendredi 13 novembre 2009       4
The application


                 • Blog
                        • Comments
                        • Clean URLs




vendredi 13 novembre 2009                      5
Install symfony

         http://www.symfony-project.org/installation
                 • Source
                 • Sandbox
                 • PEAR
                 • SVN
                 • Linux Package (Debian and SUSE)

vendredi 13 novembre 2009                              6
Install using PEAR
      pear channel-discover pear.symfony-project.com
                            pear install symfony/symfony-1.2.4




vendredi 13 novembre 2009                                        7
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
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
http://blog.local/frontend_dev.php/


vendredi 13 novembre 2009                                10
Activating sfDoctrine
                      // config/ProjectConfiguration.class.php
                      public function setup()
                      {
                        $this->enableAllPluginsExcept(
                          array('sfPropelPlugin',
                                'sfCompat10Plugin'));
                      }




vendredi 13 novembre 2009                                        11
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
Plugins
                 • Installing plugins
             http://www.symfony-project.org/plugins/
                 • sfDoctrineGuardPlugin
                       $ symfony plugin:install /
                         sfDoctrineGuardPlugin /
                         --release=3.0.0




vendredi 13 novembre 2009                              13
The database diagram




vendredi 13 novembre 2009                   14
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
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
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
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
Create the tables
                 • Create the tables and load all fixtures
                       $ symfony doctrine:build-all-load




vendredi 13 novembre 2009                                   19
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
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
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
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
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
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
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
Add comments
                 • Use the code generator
                       $ symfony doctrine:generate-crud /
                         frontend comment BlogComment
                 • Copy the code you’ll need




vendredi 13 novembre 2009                                   27
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
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
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
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
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
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
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
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
Backend creation
              • Create an application
                     $ symfony generate:app /
                       --escaping-strategy=on /
                       --csrf-secret=UniqueSecret /
                       backend




vendredi 13 novembre 2009                             36
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
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
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
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
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
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
Backend creation
              • Edit myUser.class.php
                        class myUser extends sfGuardSecurityUser
                        {
                        }




vendredi 13 novembre 2009                                          43
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
Questions?

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


vendredi 13 novembre 2009                45
vendredi 13 novembre 2009   46

Contenu connexe

Tendances

Composer
ComposerComposer
Composer
cmodijk
 
Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)
LumoSpark
 

Tendances (20)

Symfony and eZ Publish
Symfony and eZ PublishSymfony and eZ Publish
Symfony and eZ Publish
 
TTW FTW: Plone as the new wordpress
TTW FTW: Plone as the new wordpressTTW FTW: Plone as the new wordpress
TTW FTW: Plone as the new wordpress
 
Ezobject wrapper workshop
Ezobject wrapper workshopEzobject wrapper workshop
Ezobject wrapper workshop
 
Composer
ComposerComposer
Composer
 
Transforming WebSockets
Transforming WebSocketsTransforming WebSockets
Transforming WebSockets
 
Plone pwns
Plone pwnsPlone pwns
Plone pwns
 
Heroku
HerokuHeroku
Heroku
 
Take Command of WordPress With WP-CLI
Take Command of WordPress With WP-CLITake Command of WordPress With WP-CLI
Take Command of WordPress With WP-CLI
 
Nashville Php Symfony Presentation
Nashville Php Symfony PresentationNashville Php Symfony Presentation
Nashville Php Symfony Presentation
 
I'm the butcher would you like some BeEF
I'm the butcher would you like some BeEFI'm the butcher would you like some BeEF
I'm the butcher would you like some BeEF
 
Pragmatic plone projects
Pragmatic plone projectsPragmatic plone projects
Pragmatic plone projects
 
Contributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonContributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter Wilson
 
Funnelweb ploneconf2010
Funnelweb ploneconf2010Funnelweb ploneconf2010
Funnelweb ploneconf2010
 
Plone: The CMS that hits above it's weight
Plone: The CMS that hits above it's weightPlone: The CMS that hits above it's weight
Plone: The CMS that hits above it's weight
 
20110606 e z_flow_gig_v1
20110606 e z_flow_gig_v120110606 e z_flow_gig_v1
20110606 e z_flow_gig_v1
 
Immutant
ImmutantImmutant
Immutant
 
Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)
 
Software livre e padrões abertos no desenvolvimento Web
Software livre e padrões abertos no desenvolvimento WebSoftware livre e padrões abertos no desenvolvimento Web
Software livre e padrões abertos no desenvolvimento Web
 
May The Nodejs Be With You
May The Nodejs Be With YouMay The Nodejs Be With You
May The Nodejs Be With You
 
Take Command of WordPress With WP-CLI at WordCamp Long Beach
Take Command of WordPress With WP-CLI at WordCamp Long BeachTake Command of WordPress With WP-CLI at WordCamp Long Beach
Take Command of WordPress With WP-CLI at WordCamp Long Beach
 

En vedette

ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...
ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...
ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...
Joan Celma
 
Fotosíntesis J G O
Fotosíntesis  J G OFotosíntesis  J G O
Fotosíntesis J G O
jortega
 
Trujillo (padilla abraham 3ero a)
Trujillo (padilla abraham 3ero a)Trujillo (padilla abraham 3ero a)
Trujillo (padilla abraham 3ero a)
abrahampadilla30
 
Wise 2013 oct 31 anil gupta frugal, flexible and friendly innovations for i...
Wise 2013  oct 31  anil gupta frugal, flexible and friendly innovations for i...Wise 2013  oct 31  anil gupta frugal, flexible and friendly innovations for i...
Wise 2013 oct 31 anil gupta frugal, flexible and friendly innovations for i...
Dr Anil Gupta
 
UCLA SOD Annual Report_spread_11.5.15
UCLA SOD Annual Report_spread_11.5.15UCLA SOD Annual Report_spread_11.5.15
UCLA SOD Annual Report_spread_11.5.15
Brianna Aldrich
 
Caballos de fuerza HP
Caballos de fuerza HPCaballos de fuerza HP
Caballos de fuerza HP
Mike Coral
 

En vedette (20)

User and behavioural data in recommendation system - Asta Bäck
User and behavioural data in recommendation system - Asta BäckUser and behavioural data in recommendation system - Asta Bäck
User and behavioural data in recommendation system - Asta Bäck
 
Xquizzit
XquizzitXquizzit
Xquizzit
 
Els Castellers De Vilafrancanuevo
Els Castellers De VilafrancanuevoEls Castellers De Vilafrancanuevo
Els Castellers De Vilafrancanuevo
 
ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...
ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...
ESCUELA DE ADMINISTRACIÓN DE EMPRESAS. EAE BARCELONA. MBA SPORT MANAGEMENT. J...
 
Fotosíntesis J G O
Fotosíntesis  J G OFotosíntesis  J G O
Fotosíntesis J G O
 
Trujillo (padilla abraham 3ero a)
Trujillo (padilla abraham 3ero a)Trujillo (padilla abraham 3ero a)
Trujillo (padilla abraham 3ero a)
 
ASERTIVIDAD
ASERTIVIDADASERTIVIDAD
ASERTIVIDAD
 
Hackability: Free/Open Source Assistive Tech
Hackability: Free/Open Source Assistive TechHackability: Free/Open Source Assistive Tech
Hackability: Free/Open Source Assistive Tech
 
Wise 2013 oct 31 anil gupta frugal, flexible and friendly innovations for i...
Wise 2013  oct 31  anil gupta frugal, flexible and friendly innovations for i...Wise 2013  oct 31  anil gupta frugal, flexible and friendly innovations for i...
Wise 2013 oct 31 anil gupta frugal, flexible and friendly innovations for i...
 
Curso italiano para dependientes comercio A2
Curso italiano para dependientes comercio A2Curso italiano para dependientes comercio A2
Curso italiano para dependientes comercio A2
 
Wc Triptico.Ndd
Wc Triptico.NddWc Triptico.Ndd
Wc Triptico.Ndd
 
Davin Skonberg - Creative Director & Design Portfolio
Davin Skonberg - Creative Director & Design PortfolioDavin Skonberg - Creative Director & Design Portfolio
Davin Skonberg - Creative Director & Design Portfolio
 
Catalunya Papers nº 151 Juny 2012
Catalunya Papers  nº 151 Juny 2012Catalunya Papers  nº 151 Juny 2012
Catalunya Papers nº 151 Juny 2012
 
UCLA SOD Annual Report_spread_11.5.15
UCLA SOD Annual Report_spread_11.5.15UCLA SOD Annual Report_spread_11.5.15
UCLA SOD Annual Report_spread_11.5.15
 
Persönlichkeitsrechte und Datenschutz in der Wolke?
Persönlichkeitsrechte und Datenschutz in der Wolke?Persönlichkeitsrechte und Datenschutz in der Wolke?
Persönlichkeitsrechte und Datenschutz in der Wolke?
 
La gestión del conocimiento desde la perspectiva personal en un entorno en r...
La gestión del conocimiento desde la perspectiva personal en un entorno en r...La gestión del conocimiento desde la perspectiva personal en un entorno en r...
La gestión del conocimiento desde la perspectiva personal en un entorno en r...
 
Caballos de fuerza HP
Caballos de fuerza HPCaballos de fuerza HP
Caballos de fuerza HP
 
Glosari
GlosariGlosari
Glosari
 
Herramientas para el Diseño de Exámenes en Línea
Herramientas para el Diseño de Exámenes en LíneaHerramientas para el Diseño de Exámenes en Línea
Herramientas para el Diseño de Exámenes en Línea
 
Magdy Hussine CV
Magdy Hussine CVMagdy Hussine CV
Magdy Hussine CV
 

Similaire à One hour application - PHP Quebec Conference 2009

Noseevich, petukhov no locked doors no windows barred. hacking open am infr...
Noseevich, petukhov   no locked doors no windows barred. hacking open am infr...Noseevich, petukhov   no locked doors no windows barred. hacking open am infr...
Noseevich, petukhov no locked doors no windows barred. hacking open am infr...
DefconRussia
 
Virtualization and automation of library software/machines + Puppet
Virtualization and automation of library software/machines + PuppetVirtualization and automation of library software/machines + Puppet
Virtualization and automation of library software/machines + Puppet
Omar Reygaert
 
Using puppet
Using puppetUsing puppet
Using puppet
Alex Su
 

Similaire à One hour application - PHP Quebec Conference 2009 (20)

Symfony 4 & Flex news
Symfony 4 & Flex newsSymfony 4 & Flex news
Symfony 4 & Flex news
 
Welcome to the Symfony2 World - FOSDEM 2013
 Welcome to the Symfony2 World - FOSDEM 2013 Welcome to the Symfony2 World - FOSDEM 2013
Welcome to the Symfony2 World - FOSDEM 2013
 
JRubyConf 2009
JRubyConf 2009JRubyConf 2009
JRubyConf 2009
 
Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"
 
Symfony finally swiped right on envvars
Symfony finally swiped right on envvarsSymfony finally swiped right on envvars
Symfony finally swiped right on envvars
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrb
 
Plone on Amazon EC2
Plone on Amazon EC2Plone on Amazon EC2
Plone on Amazon EC2
 
What to do when things go wrong
What to do when things go wrongWhat to do when things go wrong
What to do when things go wrong
 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19
 
GR8Conf 2009: Groovy Usage Patterns by Dierk König
GR8Conf 2009: Groovy Usage Patterns by Dierk KönigGR8Conf 2009: Groovy Usage Patterns by Dierk König
GR8Conf 2009: Groovy Usage Patterns by Dierk König
 
Noseevich, petukhov no locked doors no windows barred. hacking open am infr...
Noseevich, petukhov   no locked doors no windows barred. hacking open am infr...Noseevich, petukhov   no locked doors no windows barred. hacking open am infr...
Noseevich, petukhov no locked doors no windows barred. hacking open am infr...
 
Doctrine 2: Enterprise Persistence Layer for PHP
Doctrine 2: Enterprise Persistence Layer for PHPDoctrine 2: Enterprise Persistence Layer for PHP
Doctrine 2: Enterprise Persistence Layer for PHP
 
Virtualization and automation of library software/machines + Puppet
Virtualization and automation of library software/machines + PuppetVirtualization and automation of library software/machines + Puppet
Virtualization and automation of library software/machines + Puppet
 
Zimbra scripting with python
Zimbra scripting with pythonZimbra scripting with python
Zimbra scripting with python
 
Followup Session in Asia-Pacific Geant4 Workshop and Training Course 2009 hel...
Followup Session in Asia-Pacific Geant4 Workshop and Training Course 2009 hel...Followup Session in Asia-Pacific Geant4 Workshop and Training Course 2009 hel...
Followup Session in Asia-Pacific Geant4 Workshop and Training Course 2009 hel...
 
Using puppet
Using puppetUsing puppet
Using puppet
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Deep dive into Verdaccio - NodeTLV 2022 - Israel
Deep dive into Verdaccio - NodeTLV 2022 - IsraelDeep dive into Verdaccio - NodeTLV 2022 - Israel
Deep dive into Verdaccio - NodeTLV 2022 - Israel
 
CloudInit Introduction
CloudInit IntroductionCloudInit Introduction
CloudInit Introduction
 

Plus de Philippe Gamache

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

Plus de Philippe Gamache (18)

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
 
Entreprise Security API - OWASP Montreal
Entreprise Security API - OWASP MontrealEntreprise Security API - OWASP Montreal
Entreprise Security API - OWASP Montreal
 
Entreprise Security API - ConFoo 2011
Entreprise Security API - ConFoo 2011Entreprise Security API - ConFoo 2011
Entreprise Security API - ConFoo 2011
 
Strong authetification - ConFoo 2011
Strong authetification - ConFoo 2011Strong authetification - ConFoo 2011
Strong authetification - ConFoo 2011
 
Une application en une heure avec symfony - Collège de Mainsonneuve
Une application en une heure avec symfony - Collège de MainsonneuveUne application en une heure avec symfony - Collège de Mainsonneuve
Une application en une heure avec symfony - Collège de Mainsonneuve
 
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
 
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
 

Dernier

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Dernier (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 

One hour application - PHP Quebec Conference 2009

  • 1. One hour application with symfony vendredi 13 novembre 2009 1
  • 2. Aim • Present symfony in an original way • Make an application in one hour vendredi 13 novembre 2009 2
  • 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. Questions? ? Please wait at the end, we don’t have much time vendredi 13 novembre 2009 4
  • 5. The application • Blog • Comments • Clean URLs vendredi 13 novembre 2009 5
  • 6. Install symfony http://www.symfony-project.org/installation • Source • Sandbox • PEAR • SVN • Linux Package (Debian and SUSE) vendredi 13 novembre 2009 6
  • 7. Install using PEAR pear channel-discover pear.symfony-project.com pear install symfony/symfony-1.2.4 vendredi 13 novembre 2009 7
  • 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. 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
  • 11. Activating sfDoctrine // config/ProjectConfiguration.class.php public function setup() { $this->enableAllPluginsExcept( array('sfPropelPlugin', 'sfCompat10Plugin')); } vendredi 13 novembre 2009 11
  • 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. Plugins • Installing plugins http://www.symfony-project.org/plugins/ • sfDoctrineGuardPlugin $ symfony plugin:install / sfDoctrineGuardPlugin / --release=3.0.0 vendredi 13 novembre 2009 13
  • 14. The database diagram vendredi 13 novembre 2009 14
  • 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. 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. 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. 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. Create the tables • Create the tables and load all fixtures $ symfony doctrine:build-all-load vendredi 13 novembre 2009 19
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Backend creation • Create an application $ symfony generate:app / --escaping-strategy=on / --csrf-secret=UniqueSecret / backend vendredi 13 novembre 2009 36
  • 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. 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. 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. 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. 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. 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. Backend creation • Edit myUser.class.php class myUser extends sfGuardSecurityUser { } vendredi 13 novembre 2009 43
  • 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. Questions? philippe.gamache@symfony-project.com info@ph-il.ca http://www.symfoy-project.org http://www.phportail.net vendredi 13 novembre 2009 45