symfony
An Open-Source Framework
     for Professionals
         Fabien Potencier
      Stefan Koopmanschap
Before we begin



     How many have already
    used symfony for a project,
even a very small personal project?
Who are we?
•  Fabien Potencier
  –  Founder of Sensio
     •  Web Agency
     •  Since 1998
     •  45 people
     •  Open-Source Specialists
     •  Big corporate customers
  –  Creator and lead developer of symfony


•  Stefan Koopmanschap
  –  Consultant at Ibuildings
  –  Initiator of symfony-framework.nl and symfonyCamp
  –  symfony developer for 2 years
symfony
•  PHP Web framework
•  Based on
   –  10 years of Sensio experience
   –  Existing Open-Source projects


•  Built for :
   –  Professional websites
   –  Complex needs
   –  Demanding environments
Framework
Whatever the application, a
  framework is build to ease
development by providing tools
for recurrent and boring tasks.
Maintainability & Evolutivity
Structure & Standardisation
MVC
Model
View
Controller
1



                 Internet

             2

           Controleur             6

      3                 5

  Modèle                    Vue

  4

BDD
Develop Faster & Better
Write less code


                          less code
                              
                       less complexity
                              
                          less bugs
                              
                      more productivity
                              
                          more time


More time for edge cases, business rules, …
Each line of code has an initial cost

                     Costinitial = Costdeveloppement + Costtests


… and there is a cost to maintain the line


                           Costmaintenance >> Costinitial




    Costmaintenance = Costunderstanding + Costchange + Costtests + Costdeployment




                          Kent Beck (based on Yourdon and Constantine)
symfony
An Open-Source Framework
MIT Licence


  « It is a permissive license, meaning that it permits
   reuse within proprietary software on the condition
   that the license is distributed with that software. »
An Open-Source Documentation
•  Open-Source documentation
  –  The book (450 pages - GFDL)
  –  Askeet Tutorial (250 pages)


•  Translation in 12 langages
  –     (Chinese)      –  Polski
  –  Deutsch           –  Português
  –  Español           –  Russian
  –  Français          –  Ukrainian
  –  Italiano          –  Čeština
  –       (Japanese)
                       –  Nederlands
A great Community
Mailing-list support / forums / IRC

240 available plugins

300k unique visitors per month on the official
  website www.symfony-project.org
« Entreprise » Version
Version 1.0 released early 2007

  – Maintained for 3 years (early 2010)
  – ~1 release a month (1.0.16 now)
    • Bug and security fixes, compatibility with
      new PHP versions fixes
    • No new features (even small ones)
    • Upgrading is simple and safe
Version 1.1 to be released this month
  – Maintained for 1 year
  – Same release cycle as 1.0


Roadmap
  – Version 1.2 Q4 2008
  – Version 1.3 Q1 2009
symfony is a set of cohesive
  but decoupled classes
symfony platform
sfEventDispatcher
// sfUser!
$event = new sfEvent($this, ‘user.change_culture’,
   array(‘culture’ => $culture));!
$dispatcher->notify($event);!

// sfI18N!
$callback = array($this, ‘listenToChangeCultureEvent’);!
$dispatcher->connect(‘user.change_culture’, $callback);!


•  sfI18N and sfUser are decoupled
•  « Anybody » can listen to any event
•  You can notify existing events or create new ones
the symfony MVC framework
         is based on
    the symfony platform
Let’s start a Project
The Project
•  A simple blog system
  –  Posts
  –  Categories
  –  Authors
  –  Comments
•  Requirements
  –  Maintainable
  –  Customizable
  –  Secure
•  Use symfony 1.1
List of recent posts


             Excerpt



                                Categories
             Post information
Sidebar customization


List of comments




Add a comment
YUI stylesheets

                          homepage



Famfamfam icons



             post




  http://www.symfony-project.org/get/design.tgz
Project Initialization
Bootstrap a symfony Project

1.  Install symfony

2.  Initialize a new project

3.  Configure the Web Server

4.  Start coding
Installing symfony

Sandbox: Ready-to-run symfony application

PEAR: Install symfony globally on your machine

Subversion: Be free to have several versions around
symfony CLI
$ symfony!
Create a new Project

$ mkdir blog!
$ cd blog!
$ symfony generate:project blog!
Create a new Application
./symfony help generate:app!
Create a new secure Application
   ./symfony generate:app frontend !
             --escaping-strategy=on !
             --csrf-secret=A$ecret!
Project, Application, Module, Action
Which symfony Version?

./symfony -V!




config/ProjectConfiguration.class.php!
Configure the Web Server
<VirtualHost *:80>
  ServerName myapp.example.com
  DocumentRoot "/path/to/blog/web"
  DirectoryIndex index.php

  <Directory "/path/to/blog/web">
    AllowOverride All
    Allow from All                   Web root directory is web/
  </Directory>
</VirtualHost>
symfony Assets
Used by the default pages and the Web Debug Toolbar

Configure the Web Server to serve symfony assets
            <VirtualHost *:80>
              …
              Alias /sf /$sf_symfony_data_dir/web/sf
              <Directory "/$sf_symfony_data_dir/web/sf">
                AllowOverride All
                Allow from All
              </Directory>
            </VirtualHost>


Or, create a symlink
         $ cd web/
         $ ln -sf ../lib/vendor/symfony/data/web/sf sf
Environments
developers   customers     end users




development     staging      production
environment   environment   environment
cache        cache         cache

   debug        debug         debug

    logs         logs          logs

                              stats
    stats        stats


development     staging      production
environment   environment   environment
Try a 404
dev environment!
                               prod environment!
Front Controllers
dev environment!




                                 environment


                                       prod environment!




                                    environment
Environment Configuration
apps/frontend/config/settings.yml!

      environment




           Web debug toolbar
Web Debug Toolbar

      Web debug toolbar
Create a Module for Posts
Create a new ‘post’ module in the ‘frontend’
  application

      $ php symfony generate:module frontend post!
Project, Application, Module, Action
Action and Template Naming
/frontend_dev.php/blog/index


                 module action

// in apps/frontend/modules/blog/actions/actions.class.php
<?php

class blogActions extends sfActions
{
  public function executeIndex()
  {
    // do things
  }
}

// in apps/frontend/modules/blog/templates/indexSuccess.php
<!–- do things -->
Browse
/frontend_dev.php/post/index!
Create the Blog Homepage
apps/frontend/modules/post/templates/indexSuccess.php!

•  Copy homepage.html into indexSuccess.php
•  Copy the images/ and css/ under web/
•  Add the base.css CSS in view.yml
•  Fix images and css paths
                                /frontend_dev.php/post/index!
Create an Action to show a Post
apps/frontend/modules/post/actions/actions.class.php!

•  Create an empy executeShow() action
•  Copy post.html into showSuccess.php
•  Fix images and css paths
                                /frontend_dev.php/post/show!
Project, Application, Module, Action
Extract common Code

                            Post page specific content




Homepage specific content
The Layout
   A layout wraps the template content

          header.php
                                   page content
                         include

                                      decoration

          page content


include


           footer.php
                                           layout.php
The Layout
Move the common code from homepage and post to
  the layout

         apps/frontend/templates/layout.php!
Customize the Sidebar and the Title
                            The title depends on the page




         The sidebar depends on the page
Layout with Several "holes"
A slot content depends on the template context


           Slot1
                          Main
                         content
 Slot 2




           Main     +                =
          content
                          Slot 1
                          Slot 2


    Layout              Template         Rendered
                        with slots         Page
Create Slots for Title and Sidebar
apps/frontend/templates/layout.php!
Fill the Slots
apps/frontend/modules/blog/templates/showSuccess.php!
Passing Data from Action to Template
apps/frontend/modules/blog/actions/actions.class.php!




    apps/frontend/modules/blog/templates/indexSuccess.php!
Make the Counter dynamic
Database Schema


A post has an author

A post can be in a category

A post can have comments
Propel : The symfony ORM
ORM = Object-Relational Mapping
Mapping a relational database to an object-oriented
  model
Database Abstraction

            Relational    Object-Oriented
         table            class
         row, record      object
         field, column    proterty
Schema Conventions
post:
  id:           #   primary key, autoincrement integer
  author_id:    #   foreign key to Author
  created_at:   #   timestamp, set to current time on creation
  updated_at:   #   timestamp, set to current time on update

 # column types
 published_at: timestamp
 title:         varchar(255)
 content:       longvarchar
 is_spam:       boolean

 # complex column definitions
 last_name:   { type: varchar(100), index: true, required: true }
 category_id:     { type: integer, foreignTable: category,
    foreignReference: id, required: false, onDelete: setnull }
Database Schema
config/schema.yml!
Build the Model Classes
./symfony propel:build-model!
From Schema to Object Model

             $ ./symfony propel:build-model!

propel:                               lib/
  post:                                 model/
    id:   ~                                om/
    name: varchar(255)                       BasePost.php
                                             BasePostPeer.php
                                           Post.php
                                           PostPeer.php




                         1 table > 4 classes?
Base and Custom Classes
lib/
  model/
                          Base classes
     om/                     Under model/om/, prefixed by Base
       BasePost.php
       BasePostPeer.php      Generated by Propel
     Post.php                Overwritten each time the schema
     PostPeer.php
                               changes and the model is
                               generated
                             Never edit these files!
lib/                       Custom classes
  model/
     om/                      Under model/, no prefix
       BasePost.php
                              Inherit from Base classes
       BasePostPeer.php
     Post.php                 Never overwritten
     PostPeer.php
                              Put custom methods here
                              Override base methods here
Peer and Object Classes
lib/                      Peer classes
  model/
     om/                     Suffixed by Peer
       BasePost.php          Useful to retrieve a collection of objects
       BasePostPeer.php
    Post.php                 Methods return objects
     PostPeer.php            Only static methods (::, self)


lib/                      Object classes
  model/
     om/
                             No suffix
       BasePost.php          Useful to create / inspect / update
       BasePostPeer.php       records
     Post.php                Methods return column values
    PostPeer.php             Only object methods (->, $this)
Database Initialization



mysqladmin create dutchconference!
./symfony configure:database mysql://localhost/dutchconference!
Build the SQL queries
./symfony propel:build-sql!




./symfony propel:insert-sql!
Shortcut for all the previous Tasks



          ./symfony propel:build-all!
Initial Data
data/fixtures/01-data.yml!


             Define PKs with names




             Use names instead of Pks

                            Dynamic values
Load Data
$ ./symfony propel:data-load frontend!
Summary of Code Generation

           2                     Object model
           propel:build-model!   Base, Custom,
                                 Peer and object classes

1
 schema.yml

       3   propel:build-sql!
           propel:insert-sql!
                                 Relational database
                                 Tables, columns, keys, indexes
If the Database preexists the Project

           3                      Object model
            propel:build-model!   Base, Custom,
                                  Peer and object classes

2
 schema.yml

       1
           propel:build-schema!
                                  Relational database
                                  Tables, columns, keys, indexes
Generated Methods of Object Classes
Getter for columns
  $title     = $post->getTitle();           CamelCase version
  $content   = $post->getContent();         of the column name
  $createdAt = $post->getCreatedAt();


Some getters have special options
  $date      = $post->getCreatedAt($dateFormat);


Getter by name
  $title     = $post->getByName('title');
Generated Methods of Object Classes
Manipulate primary keys
   $commentId = $comment->getId();
   // for composite keys, prefer
   $commentId = $comment->getPrimaryKey();


Manipulate foreign keys
   $postId = $comment->getPostId();
   // in practice, these methods are not used much
   // use getter for foreign objects instead
   $post    = $comment->getPost();     // Post object
   // as the result is an object, you can chain method calls
   $content = $comment->getPost()->getContent();


One-to-Many smart getters
   $comments   = $post->getCommments();   // Array of Comments
   $nb         = $post->countCommments(); // Integer
Get the Posts from the Database
What the Model Layer does
Action                Model                     Database


    PostPeer::doSelect(new Criteria())!

                           Criteria to SQL translation
                           SELECT * FROM post!


                                                         Query execution
                                        resultset!


                           Object hydrating
  Array of Post objects!
What the Model Layer does
Template                Model                   Database


   $post->getTitle()!

                            Looking up internal attribute
           String!
Make the Post show Page dynamic

/frontend_dev.php/post/show?id=1!
Make the Post show Page dynamic




           Display a 404 error if the post does not exist
Change the Date Format
getPublishedAt() first argument accepts the date()
  format or the strftime() format

symfony format_date() helper is i18n aware
Helper Groups
•  Tag
•  URLs
•  Assets (images, JavaScript, CSS, …)
•  Subtemplate inclusion (slot, partial, component)
•  Links
•  Form
•  Javascript and Ajax
•  Text, number, date manipulation
•  I18N
•  …
Permalinks
•  Many applications provide an alternative to
   functional URLs
•  Permalinks look like links to permanent content
   while the resource they reference is dynamically
   generated
•  Primarily focused at search engines, permalink
   often carry more readable data for end users

http://www.symfony-project.org/blog/2008/05/21/new-symfony-security-policy
Links to the Post Page
apps/frontend/config/routing.yml!




                                   lib/modełPost.php!
Links to the Post Page

apps/frontend/modules/post/templates/indexSuccess.php!




        apps/frontend/modules/post/actions/actions.class.php!
Link to the Homepage
Add the Comments
apps/frontend/modules/post/templates/showSuccess.php!
What the Model Layer does
Template              Model                  Database


    $post->getComments()!


                            SELECT * FROM comment!
                            WHERE comment.post_id= ?!


                                                    Query execution!
                                       resultset!


Array of Comment objects!
                            Object hydrating!
Comment Form
$ ./symfony propel:build-forms!
Base and Custom Classes
lib/                              Base classes
  form/
     base/
                                     Under form/base/, prefixed by Base
       BasePostForm.class.php        Generated by symfony
     PostForm.class.php
                                     Overwritten when the schema
                                       changes and the forms are
                                       generated
                                     Never edit these files!
 lib/                              Custom classes
   form/
      base/                           Under form/, no prefix
        BasePost.Form.class.php
                                      Inherit from Base classes
      PostForm.class.php
                                      Never overwritten
                                      Put custom methods here
                                      Override base methods here
Create a Comment Form
apps/frontend/modules/post/actions/actions.class.php!




apps/frontend/modules/post/templates/showSuccess.php!
Create a Comment Form
Propel Forms
•  Generated by propel:build-forms
•  1 table = 1 form
•  Model introspection to determine
  –  The widget
  –  The validation rules
•  Automatically converts a form to a Propel object
   and save it to the database
•  Extensible
Bind The Form to the Post
Customize the Form
lib/form/CommentForm.class.php!
Form Life Cycle
Comments
Security: XSS
Security: CSRF
Create the Category Page
lib/modełPostPeer.class.php!




         apps/frontend/modules/blog/actions/actions.class.php!
Create the Category Page
apps/frontend/config/routing.yml!




                           apps/frontend/templates/layout.php!
Create a Partial for the List
apps/frontend/modules/blog/templates/_list.php!




apps/frontend/modules/blog/templates/listByCategorySuccess.php!
Create a Component
apps/frontend/modules/post/actions/components.class.php!




apps/frontend/modules/post/templates/_categories.php!




                              apps/frontend/templates/layout.php!
Create a Web Service for Posts
apps/frontend/config/routing.yml!




  apps/frontend/modules/post/templates/indexSuccess.xml.php!
If we have time…
•  Functional Tests

•  Cache

•  CRUD to manage posts
Sensio S.A.
                     26, rue Salomon de Rothschild
                         92 286 Suresnes Cedex
                                FRANCE
                         Tél. : +33 1 40 99 80 80

                                Contact
                           Fabien Potencier
                     fabien.potencier@sensio.com




http://www.sensiolabs.com/                http://www.symfony-project.com/

symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)

  • 1.
    symfony An Open-Source Framework for Professionals Fabien Potencier Stefan Koopmanschap
  • 2.
    Before we begin How many have already used symfony for a project, even a very small personal project?
  • 3.
    Who are we? • Fabien Potencier –  Founder of Sensio •  Web Agency •  Since 1998 •  45 people •  Open-Source Specialists •  Big corporate customers –  Creator and lead developer of symfony •  Stefan Koopmanschap –  Consultant at Ibuildings –  Initiator of symfony-framework.nl and symfonyCamp –  symfony developer for 2 years
  • 4.
    symfony •  PHP Webframework •  Based on –  10 years of Sensio experience –  Existing Open-Source projects •  Built for : –  Professional websites –  Complex needs –  Demanding environments
  • 5.
  • 6.
    Whatever the application,a framework is build to ease development by providing tools for recurrent and boring tasks.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
    1 Internet 2 Controleur 6 3 5 Modèle Vue 4 BDD
  • 14.
  • 15.
    Write less code less code  less complexity  less bugs  more productivity  more time More time for edge cases, business rules, …
  • 16.
    Each line ofcode has an initial cost Costinitial = Costdeveloppement + Costtests … and there is a cost to maintain the line Costmaintenance >> Costinitial Costmaintenance = Costunderstanding + Costchange + Costtests + Costdeployment Kent Beck (based on Yourdon and Constantine)
  • 17.
  • 18.
  • 19.
    MIT Licence « It is a permissive license, meaning that it permits reuse within proprietary software on the condition that the license is distributed with that software. »
  • 20.
  • 21.
    •  Open-Source documentation –  The book (450 pages - GFDL) –  Askeet Tutorial (250 pages) •  Translation in 12 langages –  (Chinese) –  Polski –  Deutsch –  Português –  Español –  Russian –  Français –  Ukrainian –  Italiano –  Čeština –  (Japanese) –  Nederlands
  • 23.
  • 24.
    Mailing-list support /forums / IRC 240 available plugins 300k unique visitors per month on the official website www.symfony-project.org
  • 25.
  • 26.
    Version 1.0 releasedearly 2007 – Maintained for 3 years (early 2010) – ~1 release a month (1.0.16 now) • Bug and security fixes, compatibility with new PHP versions fixes • No new features (even small ones) • Upgrading is simple and safe
  • 27.
    Version 1.1 tobe released this month – Maintained for 1 year – Same release cycle as 1.0 Roadmap – Version 1.2 Q4 2008 – Version 1.3 Q1 2009
  • 28.
    symfony is aset of cohesive but decoupled classes
  • 29.
  • 35.
    sfEventDispatcher // sfUser! $event =new sfEvent($this, ‘user.change_culture’, array(‘culture’ => $culture));! $dispatcher->notify($event);! // sfI18N! $callback = array($this, ‘listenToChangeCultureEvent’);! $dispatcher->connect(‘user.change_culture’, $callback);! •  sfI18N and sfUser are decoupled •  « Anybody » can listen to any event •  You can notify existing events or create new ones
  • 36.
    the symfony MVCframework is based on the symfony platform
  • 40.
  • 41.
    The Project •  Asimple blog system –  Posts –  Categories –  Authors –  Comments •  Requirements –  Maintainable –  Customizable –  Secure •  Use symfony 1.1
  • 42.
    List of recentposts Excerpt Categories Post information
  • 43.
    Sidebar customization List ofcomments Add a comment
  • 44.
    YUI stylesheets homepage Famfamfam icons post http://www.symfony-project.org/get/design.tgz
  • 45.
  • 46.
    Bootstrap a symfonyProject 1.  Install symfony 2.  Initialize a new project 3.  Configure the Web Server 4.  Start coding
  • 47.
    Installing symfony Sandbox: Ready-to-runsymfony application PEAR: Install symfony globally on your machine Subversion: Be free to have several versions around
  • 48.
  • 49.
    Create a newProject $ mkdir blog! $ cd blog! $ symfony generate:project blog!
  • 50.
    Create a newApplication ./symfony help generate:app!
  • 51.
    Create a newsecure Application ./symfony generate:app frontend ! --escaping-strategy=on ! --csrf-secret=A$ecret!
  • 52.
  • 53.
    Which symfony Version? ./symfony-V! config/ProjectConfiguration.class.php!
  • 54.
    Configure the WebServer <VirtualHost *:80> ServerName myapp.example.com DocumentRoot "/path/to/blog/web" DirectoryIndex index.php <Directory "/path/to/blog/web"> AllowOverride All Allow from All Web root directory is web/ </Directory> </VirtualHost>
  • 55.
    symfony Assets Used bythe default pages and the Web Debug Toolbar Configure the Web Server to serve symfony assets <VirtualHost *:80> … Alias /sf /$sf_symfony_data_dir/web/sf <Directory "/$sf_symfony_data_dir/web/sf"> AllowOverride All Allow from All </Directory> </VirtualHost> Or, create a symlink $ cd web/ $ ln -sf ../lib/vendor/symfony/data/web/sf sf
  • 56.
  • 57.
    developers customers end users development staging production environment environment environment
  • 58.
    cache cache cache debug debug debug logs logs logs stats stats stats development staging production environment environment environment
  • 59.
    Try a 404 devenvironment! prod environment!
  • 60.
    Front Controllers dev environment! environment prod environment! environment
  • 61.
  • 62.
    Web Debug Toolbar Web debug toolbar
  • 63.
    Create a Modulefor Posts Create a new ‘post’ module in the ‘frontend’ application $ php symfony generate:module frontend post!
  • 64.
  • 65.
    Action and TemplateNaming /frontend_dev.php/blog/index module action // in apps/frontend/modules/blog/actions/actions.class.php <?php class blogActions extends sfActions { public function executeIndex() { // do things } } // in apps/frontend/modules/blog/templates/indexSuccess.php <!–- do things -->
  • 66.
  • 67.
    Create the BlogHomepage apps/frontend/modules/post/templates/indexSuccess.php! •  Copy homepage.html into indexSuccess.php •  Copy the images/ and css/ under web/ •  Add the base.css CSS in view.yml •  Fix images and css paths /frontend_dev.php/post/index!
  • 68.
    Create an Actionto show a Post apps/frontend/modules/post/actions/actions.class.php! •  Create an empy executeShow() action •  Copy post.html into showSuccess.php •  Fix images and css paths /frontend_dev.php/post/show!
  • 69.
  • 70.
    Extract common Code Post page specific content Homepage specific content
  • 71.
    The Layout A layout wraps the template content header.php page content include decoration page content include footer.php layout.php
  • 72.
    The Layout Move thecommon code from homepage and post to the layout apps/frontend/templates/layout.php!
  • 73.
    Customize the Sidebarand the Title The title depends on the page The sidebar depends on the page
  • 74.
    Layout with Several"holes" A slot content depends on the template context Slot1 Main content Slot 2 Main + = content Slot 1 Slot 2 Layout Template Rendered with slots Page
  • 75.
    Create Slots forTitle and Sidebar apps/frontend/templates/layout.php!
  • 76.
  • 77.
    Passing Data fromAction to Template apps/frontend/modules/blog/actions/actions.class.php! apps/frontend/modules/blog/templates/indexSuccess.php!
  • 78.
  • 79.
    Database Schema A posthas an author A post can be in a category A post can have comments
  • 80.
    Propel : Thesymfony ORM ORM = Object-Relational Mapping Mapping a relational database to an object-oriented model Database Abstraction Relational Object-Oriented table class row, record object field, column proterty
  • 81.
    Schema Conventions post: id: # primary key, autoincrement integer author_id: # foreign key to Author created_at: # timestamp, set to current time on creation updated_at: # timestamp, set to current time on update # column types published_at: timestamp title: varchar(255) content: longvarchar is_spam: boolean # complex column definitions last_name: { type: varchar(100), index: true, required: true } category_id: { type: integer, foreignTable: category, foreignReference: id, required: false, onDelete: setnull }
  • 82.
  • 83.
    Build the ModelClasses ./symfony propel:build-model!
  • 84.
    From Schema toObject Model $ ./symfony propel:build-model! propel: lib/ post: model/ id: ~ om/ name: varchar(255) BasePost.php BasePostPeer.php Post.php PostPeer.php 1 table > 4 classes?
  • 85.
    Base and CustomClasses lib/ model/ Base classes om/ Under model/om/, prefixed by Base BasePost.php BasePostPeer.php Generated by Propel Post.php Overwritten each time the schema PostPeer.php changes and the model is generated Never edit these files! lib/ Custom classes model/ om/ Under model/, no prefix BasePost.php Inherit from Base classes BasePostPeer.php Post.php Never overwritten PostPeer.php Put custom methods here Override base methods here
  • 86.
    Peer and ObjectClasses lib/ Peer classes model/ om/ Suffixed by Peer BasePost.php Useful to retrieve a collection of objects BasePostPeer.php Post.php Methods return objects PostPeer.php Only static methods (::, self) lib/ Object classes model/ om/ No suffix BasePost.php Useful to create / inspect / update BasePostPeer.php records Post.php Methods return column values PostPeer.php Only object methods (->, $this)
  • 87.
    Database Initialization mysqladmin createdutchconference! ./symfony configure:database mysql://localhost/dutchconference!
  • 88.
    Build the SQLqueries ./symfony propel:build-sql! ./symfony propel:insert-sql!
  • 89.
    Shortcut for allthe previous Tasks ./symfony propel:build-all!
  • 90.
    Initial Data data/fixtures/01-data.yml! Define PKs with names Use names instead of Pks Dynamic values
  • 91.
    Load Data $ ./symfonypropel:data-load frontend!
  • 92.
    Summary of CodeGeneration 2 Object model propel:build-model! Base, Custom, Peer and object classes 1 schema.yml 3 propel:build-sql! propel:insert-sql! Relational database Tables, columns, keys, indexes
  • 93.
    If the Databasepreexists the Project 3 Object model propel:build-model! Base, Custom, Peer and object classes 2 schema.yml 1 propel:build-schema! Relational database Tables, columns, keys, indexes
  • 94.
    Generated Methods ofObject Classes Getter for columns $title = $post->getTitle(); CamelCase version $content = $post->getContent(); of the column name $createdAt = $post->getCreatedAt(); Some getters have special options $date = $post->getCreatedAt($dateFormat); Getter by name $title = $post->getByName('title');
  • 95.
    Generated Methods ofObject Classes Manipulate primary keys $commentId = $comment->getId(); // for composite keys, prefer $commentId = $comment->getPrimaryKey(); Manipulate foreign keys $postId = $comment->getPostId(); // in practice, these methods are not used much // use getter for foreign objects instead $post = $comment->getPost(); // Post object // as the result is an object, you can chain method calls $content = $comment->getPost()->getContent(); One-to-Many smart getters $comments = $post->getCommments(); // Array of Comments $nb = $post->countCommments(); // Integer
  • 96.
    Get the Postsfrom the Database
  • 97.
    What the ModelLayer does Action Model Database PostPeer::doSelect(new Criteria())! Criteria to SQL translation SELECT * FROM post! Query execution resultset! Object hydrating Array of Post objects!
  • 98.
    What the ModelLayer does Template Model Database $post->getTitle()! Looking up internal attribute String!
  • 99.
    Make the Postshow Page dynamic /frontend_dev.php/post/show?id=1!
  • 100.
    Make the Postshow Page dynamic Display a 404 error if the post does not exist
  • 101.
    Change the DateFormat getPublishedAt() first argument accepts the date() format or the strftime() format symfony format_date() helper is i18n aware
  • 102.
    Helper Groups •  Tag • URLs •  Assets (images, JavaScript, CSS, …) •  Subtemplate inclusion (slot, partial, component) •  Links •  Form •  Javascript and Ajax •  Text, number, date manipulation •  I18N •  …
  • 103.
    Permalinks •  Many applicationsprovide an alternative to functional URLs •  Permalinks look like links to permanent content while the resource they reference is dynamically generated •  Primarily focused at search engines, permalink often carry more readable data for end users http://www.symfony-project.org/blog/2008/05/21/new-symfony-security-policy
  • 104.
    Links to thePost Page apps/frontend/config/routing.yml! lib/modełPost.php!
  • 105.
    Links to thePost Page apps/frontend/modules/post/templates/indexSuccess.php! apps/frontend/modules/post/actions/actions.class.php!
  • 106.
    Link to theHomepage
  • 107.
  • 108.
    What the ModelLayer does Template Model Database $post->getComments()! SELECT * FROM comment! WHERE comment.post_id= ?! Query execution! resultset! Array of Comment objects! Object hydrating!
  • 109.
    Comment Form $ ./symfonypropel:build-forms!
  • 110.
    Base and CustomClasses lib/ Base classes form/ base/ Under form/base/, prefixed by Base BasePostForm.class.php Generated by symfony PostForm.class.php Overwritten when the schema changes and the forms are generated Never edit these files! lib/ Custom classes form/ base/ Under form/, no prefix BasePost.Form.class.php Inherit from Base classes PostForm.class.php Never overwritten Put custom methods here Override base methods here
  • 111.
    Create a CommentForm apps/frontend/modules/post/actions/actions.class.php! apps/frontend/modules/post/templates/showSuccess.php!
  • 112.
  • 113.
    Propel Forms •  Generatedby propel:build-forms •  1 table = 1 form •  Model introspection to determine –  The widget –  The validation rules •  Automatically converts a form to a Propel object and save it to the database •  Extensible
  • 114.
    Bind The Formto the Post
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
    Create the CategoryPage lib/modełPostPeer.class.php! apps/frontend/modules/blog/actions/actions.class.php!
  • 121.
    Create the CategoryPage apps/frontend/config/routing.yml! apps/frontend/templates/layout.php!
  • 122.
    Create a Partialfor the List apps/frontend/modules/blog/templates/_list.php! apps/frontend/modules/blog/templates/listByCategorySuccess.php!
  • 123.
  • 124.
    Create a WebService for Posts apps/frontend/config/routing.yml! apps/frontend/modules/post/templates/indexSuccess.xml.php!
  • 125.
    If we havetime… •  Functional Tests •  Cache •  CRUD to manage posts
  • 126.
    Sensio S.A. 26, rue Salomon de Rothschild 92 286 Suresnes Cedex FRANCE Tél. : +33 1 40 99 80 80 Contact Fabien Potencier fabien.potencier@sensio.com http://www.sensiolabs.com/ http://www.symfony-project.com/