Bernhard Schussek                        Leveraging Symfony2 Forms     Symfony Live Conference, March 03rd 2011
About myself Software Architect in Vienna Student of Software  Engineering Symfony since 2006 Outdoor and music junkie
Agenda Introductory example The Form Config class Form processing Fields Useful features
The Symfony2 Form     component
The Symfony2 Form component Evolution of symfony1 sfForm 2.5 years development Fixes most of its problems   Reusable widge...
Why 2.5 years?
"It takes a long time to make somthing complicated simple, but if you do, it will work without problems for a long time."–...
Service Oriented Architecture Applications provide services Services are exchangable These services can be consumed by dif...
Forms dont contain    business logic
Services do
Example: Online sausage shop
Example: Online sausage shop        You              Request              Response
Example: Online sausage shopConsumer                       Service           You                 Request                 R...
Example: Online sausage shopConsumer                       Service              Request             Response
Example: Online sausage shopConsumer                       Service              Request             Response
Service implementation  class Order  {      function setName($name);      function setAddress($address);      function set...
Flow of information                      I am Max!
Flow of information                                  I am Max!         $order->setName(Max)
Flow of information   Order formName:    MaxAddress: Sensio Labs,         ParisSausage: BratwurstAmount: 5
Flow of information   Order form                        $orderName:    Max            ->setName(Max)Address: Sensio Labs, ...
Flow of information                          Existing order $order ->getName()          Name:     Bob ->getAddress()      ...
The Form Config class
Form definition                   PHP class  class OrderFormConfig extends AbstractConfig  {    public function configure(...
Form definition                   PHP class  class OrderFormConfig extends AbstractConfig  {    public function configure(...
Form definition                     PHP class  class OrderFormConfig extends AbstractConfig  {      ...      public functi...
Why not a simple OrderForm class?
Why we need Config classes OrderForm cannot be put into the Dependency  Injection Container ... ... but OrderFormConfig can!
Dependency Injection Container <service id="form.order" class="OrderFormConfig">   <tag name="form.config" alias="form.ord...
Form processing
Form processing                        Form identifier  $factory = $this->get(form.factory);  $form = $factory->getInstanc...
Form processing  $factory = $this->get(form.factory);  $form = $factory->getInstance(form.order);  $form->setData($order);...
Form processing  $factory = $this->get(form.factory);  $form = $factory->getInstance(form.order);  $form->setData($order);...
Form processing  $factory = $this->get(form.factory);  $form = $factory->getInstance(form.order);  $form->setData($order);...
Form rendering                   In the action  return $this->render(      HelloBundle:Hello:index.twig.html,      array(f...
Form rendering                 In the template  <form action="#" method="post">    {{ form.widget }}  </form>             ...
Form rendering                           "fields" is a view variable  <form action="#" method="post">    {{ form.errors }}...
Form rendering  <form action="#" method="post">    {{ form.errors }}    {{ form.name.errors }}    {{ form.name.label }}   ...
Form rendering  {{ form.rest }} Renders all fields that werent rendered before   ... fields that you forgot to render manu...
What about validation?
Form validation uses the Symfony2 Validator "Constraints" are put onto your PHP classes  (services, entities etc.)
Validation constraints  class Order  {      /**       * @check:NotNull       * @check:AssertType("string")       * @check:...
Fields
Text input      Title:      $form->add(text, title);
Textarea   Content:      $form->add(textarea, content);
Date selector                           Mmmh localized!     Publish at:     $form->add(date, publishAt);
Country selector                         Localized too! Yummy!        Nationality:    $form->add(country, nationality);
File upload Profile picture:      $form->add(file, profilePicture);                    Remembers uploaded files on errors!
Repeated input           Email:    Email (again):       $form->add(repeated, email);
Core fields               entity  birthday                password               file  checkbox                percent    ...
Field architecture  Filters  Value transformers
Filters  modify a value  uni­directional  Example: FixUrlProtocolFilter  symfony-project.com      http://symfony-project.com
Value Transformers convert values between two representations bi­directional Example: DateTimeToArrayTransformer          ...
Example: Entity fieldThe user sees:Symfony sees:    Entity field       Checkbox    Checkbox   Checkbox   Checkbox         ...
Tag IDsarray("0" => "0", "1" => "1", "2" => "1", ...)  "0"          "1"          "0"          "0"Checkbox    Checkbox     ...
Tag IDsarray("0" => "0", "1" => "1", "2" => "1", ...)  "0"          "1"          "0"          "0"Checkbox    Checkbox     ...
Checkbox      Checkbox     Checkbox     Checkbox     "0"           "1"          "2"          "3"    false         true    ...
Checkbox      Checkbox     Checkbox     Checkbox     "0"           "1"          "2"          "3"    false         true    ...
Checkbox      Checkbox     Checkbox     Checkbox     "0"           "1"          "2"          "3"    false         true    ...
CSRF protection Cross­Site Request Forgery A form is submitted using the session of another  person All kinds of misuse Bu...
CSRF protection              app/config/config.yml  framework:      csrf_protection:          enabled: true          secre...
Field creation  Manual  Automatic    Symfony2 looks at metadata of the domain class to     "guess" the correct field type ...
Manual field creation  public function configure(       FieldInterface $form, array $options)  {    $form->add(entity, sau...
Automatic field creation  public function configure(       FieldInterface $form, array $options)  {    $form->setDataClass...
Automatic with options overriding  public function configure(       FieldInterface $form, array $options)  {    $form->set...
Embedded forms Symfony2 allows to embed forms into another very  easily Fields and forms implement FieldInterface "A form ...
Embedded to­one forms  public function configure(       FieldInterface $form, array $options)  {    $form->add(form.sausag...
Embedded to­many forms  public function configure(        FieldInterface $form, array $options)  {    $form->add(collectio...
Config options Options for influencing the fields/forms creation  class ConcealedFieldConfig extends Abstract..  {    publ...
Config inheritance Dynamic inheritance from other forms/fields  class ConcealedFieldConfig extends Abstract..  {    public...
Form themes Are normal Twig templates Blocks for each field type  {% block textarea__widget %}    <textarea {{ block(attri...
Form themes Can specify widget, errors, label and row  templates for specific field types  {% block textarea__row %}    <t...
Form themes Core themes:   TwigBundle::div_layout.html.twig   TwigBundle::table_layout.html.twig Configuration in the DI p...
Questions?                 Thanks for listening!              Code can currently be found onhttps://github.com/bschussek/s...
The EndCopyright"dog window" by Larry Wentzelhttp://www.flickr.com/photos/wentzelepsy"Symfony Live 2011 Logo" by Sensio La...
Upcoming SlideShare
Loading in …5
×

Leveraging Symfony2 Forms

43,175 views

Published on

This session will introduce you to the new Form component in Symfony2. With the new domain-driven paradigma and its flexible design, the component opens a door to a wide range of possibilities. The brand new architecture makes creating complex forms easier and faster than ever before. This talk will teach you today what you need to know to build powerful forms tomorrow.

3 Comments
57 Likes
Statistics
Notes
No Downloads
Views
Total views
43,175
On SlideShare
0
From Embeds
0
Number of Embeds
894
Actions
Shares
0
Downloads
503
Comments
3
Likes
57
Embeds 0
No embeds

No notes for slide

Leveraging Symfony2 Forms

  1. 1. Bernhard Schussek  Leveraging Symfony2 Forms  Symfony Live Conference, March 03rd 2011
  2. 2. About myself Software Architect in Vienna Student of Software  Engineering Symfony since 2006 Outdoor and music junkie
  3. 3. Agenda Introductory example The Form Config class Form processing Fields Useful features
  4. 4. The Symfony2 Form  component
  5. 5. The Symfony2 Form component Evolution of symfony1 sfForm 2.5 years development Fixes most of its problems Reusable widgets Embedded forms
  6. 6. Why 2.5 years?
  7. 7. "It takes a long time to make somthing complicated simple, but if you do, it will work without problems for a long time."– F. Andy Seidl, http://faseidl.com
  8. 8. Service Oriented Architecture Applications provide services Services are exchangable These services can be consumed by different actors Humans Machines
  9. 9. Forms dont contain  business logic
  10. 10. Services do
  11. 11. Example: Online sausage shop
  12. 12. Example: Online sausage shop You Request Response
  13. 13. Example: Online sausage shopConsumer Service You Request Response
  14. 14. Example: Online sausage shopConsumer Service Request Response
  15. 15. Example: Online sausage shopConsumer Service Request Response
  16. 16. Service implementation class Order { function setName($name); function setAddress($address); function setSausage($sausage); function setAmount($amount); }
  17. 17. Flow of information I am Max!
  18. 18. Flow of information I am Max! $order->setName(Max)
  19. 19. Flow of information Order formName: MaxAddress: Sensio Labs, ParisSausage: BratwurstAmount: 5
  20. 20. Flow of information Order form $orderName: Max ->setName(Max)Address: Sensio Labs, ->setAddress( Sensio Labs, Paris Paris)Sausage: Bratwurst ->setSausage( Bratwurst)Amount: 5 ->setAmount(5);
  21. 21. Flow of information Existing order $order ->getName() Name: Bob ->getAddress() Address: Liip Office Zurich ->getSausage() Sausage: Cervelat ->getAmount(); Amount: 10
  22. 22. The Form Config class
  23. 23. Form definition PHP class class OrderFormConfig extends AbstractConfig { public function configure( FieldInterface $form, array $options) { } }
  24. 24. Form definition PHP class class OrderFormConfig extends AbstractConfig { public function configure( FieldInterface $form, array $options) { $form->add(text, name) ->add(text, address) ->add(text, sausage) ->add(integer, amount); } }
  25. 25. Form definition PHP class class OrderFormConfig extends AbstractConfig { ... public function getIdentifier() { return form.order; } }
  26. 26. Why not a simple OrderForm class?
  27. 27. Why we need Config classes OrderForm cannot be put into the Dependency  Injection Container ... ... but OrderFormConfig can!
  28. 28. Dependency Injection Container <service id="form.order" class="OrderFormConfig"> <tag name="form.config" alias="form.order" /> <argument type="service" id="form.factory" /> </service> Tag alias == form identifier public function getIdentifier() { return form.order; }
  29. 29. Form processing
  30. 30. Form processing Form identifier $factory = $this->get(form.factory); $form = $factory->getInstance(form.order); $form->setData($order); if ($request->getMethod() === POST) { $form->bindRequest($request); if ($form->isValid()) { $order->send(); return new RedirectResponse(...); } }
  31. 31. Form processing $factory = $this->get(form.factory); $form = $factory->getInstance(form.order); $form->setData($order); Service object if ($request->getMethod() === POST) { $form->bindRequest($request); if ($form->isValid()) { $order->send(); return new RedirectResponse(...); } }
  32. 32. Form processing $factory = $this->get(form.factory); $form = $factory->getInstance(form.order); $form->setData($order); if ($request->getMethod() === POST) { $form->bindRequest($request); if ($form->isValid()) { Calls setters $order->send(); return new RedirectResponse(...); } }
  33. 33. Form processing $factory = $this->get(form.factory); $form = $factory->getInstance(form.order); $form->setData($order); if ($request->getMethod() === POST) { $form->bindRequest($request); if ($form->isValid()) { $order->send(); return new RedirectResponse(...); } } $order now contains submitted data!
  34. 34. Form rendering In the action return $this->render( HelloBundle:Hello:index.twig.html, array(form => $form->getRenderer())); Contains view variables and methods
  35. 35. Form rendering In the template <form action="#" method="post"> {{ form.widget }} </form> "widget" is a view method
  36. 36. Form rendering "fields" is a view variable <form action="#" method="post"> {{ form.errors }} {% for field in form.vars.fields %} {{ field.errors }} {{ field.label }} {{ field.widget }} {% endfor %} {{ form.rest }} </form>
  37. 37. Form rendering <form action="#" method="post"> {{ form.errors }} {{ form.name.errors }} {{ form.name.label }} {{ form.name.widget }} {{ form.rest }} </form>
  38. 38. Form rendering {{ form.rest }} Renders all fields that werent rendered before ... fields that you forgot to render manually ... hidden fields
  39. 39. What about validation?
  40. 40. Form validation uses the Symfony2 Validator "Constraints" are put onto your PHP classes  (services, entities etc.)
  41. 41. Validation constraints class Order { /** * @check:NotNull * @check:AssertType("string") * @check:MaxLength(50, message= * "Long name, dude...") */ private $name; }
  42. 42. Fields
  43. 43. Text input Title: $form->add(text, title);
  44. 44. Textarea Content: $form->add(textarea, content);
  45. 45. Date selector Mmmh localized! Publish at: $form->add(date, publishAt);
  46. 46. Country selector Localized too! Yummy! Nationality: $form->add(country, nationality);
  47. 47. File upload Profile picture: $form->add(file, profilePicture); Remembers uploaded files on errors!
  48. 48. Repeated input Email: Email (again): $form->add(repeated, email);
  49. 49. Core fields entity birthday password file checkbox percent hidden choice repeated integer collection textarea language country text locale date timezone money datetime url number
  50. 50. Field architecture Filters Value transformers
  51. 51. Filters modify a value uni­directional Example: FixUrlProtocolFilter symfony-project.com http://symfony-project.com
  52. 52. Value Transformers convert values between two representations bi­directional Example: DateTimeToArrayTransformer array( year => 2011, object(DateTime) month => 5, day => 1, )
  53. 53. Example: Entity fieldThe user sees:Symfony sees: Entity field Checkbox Checkbox Checkbox Checkbox "0" "1" "2" "3" Tag IDs
  54. 54. Tag IDsarray("0" => "0", "1" => "1", "2" => "1", ...) "0" "1" "0" "0"Checkbox Checkbox Checkbox Checkbox "0" "1" "2" "3"
  55. 55. Tag IDsarray("0" => "0", "1" => "1", "2" => "1", ...) "0" "1" "0" "0"Checkbox Checkbox Checkbox Checkbox "0" "1" "2" "3"
  56. 56. Checkbox Checkbox Checkbox Checkbox "0" "1" "2" "3" false true true falsearray("0" => false, "1" => true, "2" => true, ...) ArrayCollection($securityTag, $validatorTag)
  57. 57. Checkbox Checkbox Checkbox Checkbox "0" "1" "2" "3" false true true false ChoicesToArrayTransformerarray("0" => false, "1" => true, "2" => true, ...) ArrayCollection($securityTag, $validatorTag)
  58. 58. Checkbox Checkbox Checkbox Checkbox "0" "1" "2" "3" false true true falsearray("0" => false, "1" => true, "2" => true, ...) ArrayToEntitiesTransformer ArrayCollection($securityTag, $validatorTag)
  59. 59. CSRF protection Cross­Site Request Forgery A form is submitted using the session of another  person All kinds of misuse Built­in protection in Symfony2
  60. 60. CSRF protection app/config/config.yml framework: csrf_protection: enabled: true secret: 30665e19ef0010d5620553
  61. 61. Field creation Manual Automatic Symfony2 looks at metadata of the domain class to  "guess" the correct field type and settings E.g. Validator metadata, Doctrine2 metadata
  62. 62. Manual field creation public function configure( FieldInterface $form, array $options) { $form->add(entity, sausage, array( class => Sausage, )); } but Doctrine already knows, that "sausage" is a  To­One relationship to the Sausage class!
  63. 63. Automatic field creation public function configure( FieldInterface $form, array $options) { $form->setDataClass(Order); $form->add(sausage); }
  64. 64. Automatic with options overriding public function configure( FieldInterface $form, array $options) { $form->setDataClass(Order) ->add(sausage, array( required => false, )); }
  65. 65. Embedded forms Symfony2 allows to embed forms into another very  easily Fields and forms implement FieldInterface "A form is a field"
  66. 66. Embedded to­one forms public function configure( FieldInterface $form, array $options) { $form->add(form.sausage, sausage); } Identifier of SausageFormConfig
  67. 67. Embedded to­many forms public function configure( FieldInterface $form, array $options) { $form->add(collection, sausages, array( identifier => form.sausage )); } Identifier of SausageFormConfig
  68. 68. Config options Options for influencing the fields/forms creation class ConcealedFieldConfig extends Abstract.. { public function getDefaultOptions($options) { return array( concealed => true, ); } }
  69. 69. Config inheritance Dynamic inheritance from other forms/fields class ConcealedFieldConfig extends Abstract.. { public function getParent(array $options) { return $options[concealed] ? password : text; } }
  70. 70. Form themes Are normal Twig templates Blocks for each field type {% block textarea__widget %} <textarea {{ block(attributes) }}> {{ value }} </textarea> {% endblock textarea__widget %}
  71. 71. Form themes Can specify widget, errors, label and row  templates for specific field types {% block textarea__row %} <tr><td colspan="2"> {{ this.errors }} {{ this.widget }} </td></tr> {% endblock textarea__row %}
  72. 72. Form themes Core themes: TwigBundle::div_layout.html.twig TwigBundle::table_layout.html.twig Configuration in the DI parameter  "form.theme.template" More flexible configuration options coming soon
  73. 73. Questions? Thanks for listening! Code can currently be found onhttps://github.com/bschussek/symfony/tree/experimental Bernhard Schussek Twitter: @webmozart
  74. 74. The EndCopyright"dog window" by Larry Wentzelhttp://www.flickr.com/photos/wentzelepsy"Symfony Live 2011 Logo" by Sensio Labshttp://www.sensiolabs.com

×