Symfony2 Forms: Past, Present, Future

Symfony2 Forms: Past, Present, Future

Held at the SymfonyCon 2013 in Warsaw, Poland.

The Symfony2 Form component is a critical part for many Symfony2 applications. As such, we have been constantly improving the component to handle the many different use cases of our users and to lower the barrier to entry for newcomers. As seasoned Symfony2 developer, all these changes can be sometimes hard to track. What about backwards compatibility? Will your business-critical applications break? And the questions don't stop there. How can you get up to scratch with the latest best practices? What can you expect from future versions? And how can you get involved to help things move faster? I will try to answer these and many other questions in my talk.

24d20907afea0f684e62d620b886af16?s=128

Bernhard Schussek

December 13, 2013
Tweet

Transcript

  1. Bernhard Schussek @webmozart 1/89 Symfony2 Forms Symfony2 Forms Past, Present,

    Future Past, Present, Future Bernhard Bernhard Schussek aka @webmozart Schussek aka @webmozart SymfonyCon Warsaw 2013 SymfonyCon Warsaw 2013 http://www.flickr.com/photos/94334088@N03/11339593125/
  2. Bernhard Schussek @webmozart 2/89 Bernhard Schussek Not: Bernard Bernhart Bernardt

    Bernharth Also Wrong: Schusseck Schusek Shusseck Scussek Shcusek Schuseck Shusek Schuhsek Shuhseck Shushek Shuseck Shusec Shushek Shushek Shushec Sussek Shussec Schußeck Scusek Shußec Schuhsec Shußec Schushek Schusheck
  3. Bernhard Schussek @webmozart 3/89 Bernard @webmozart "that Forms guy"

  4. Bernhard Schussek @webmozart 4/89 http://commons.wikimedia.org/wiki/File%3AAustralia-New_Guinea_(orthographic_projection).svg

  5. Bernhard Schussek @webmozart 5/89 http://upload.wikimedia.org/wikipedia/commons/b/b3/Blank_map_of_Europe.svg

  6. Austria

  7. Bernhard Schussek @webmozart 7/89 flag of Austria not the flag

    of Austria http://en.wikipedia.org/wiki/File:Flag_of_Austria.svg http://en.wikipedia.org/wiki/File:Zeichen_267.svg
  8. Bernhard Schussek @webmozart 8/89 Form Form Evolution Evolution http://www.flickr.com/photos/jurvetson/2490285058/

  9. Bernhard Schussek @webmozart 9/89 1.1 June 29, 2008

  10. Bernhard Schussek @webmozart 10/89 Symfony 1.1 Forms sfForm ContactForm sfValidatorSchema

    sfWidgetSchema sfValidator sfWidget * *
  11. Bernhard Schussek @webmozart 11/89 2.0 July 28, 2010

  12. Bernhard Schussek @webmozart 12/89 Symfony 2.0 Forms FormTypeInterface ContactType Form

    FormBuilder configures produces
  13. Bernhard Schussek @webmozart 13/89 Form Growth 19/02/07 19/02/08 19/02/09 19/02/10

    19/02/11 19/02/12 19/02/13 0 5000 10000 15000 20000 25000 30000 35000 40000 0 5000 10000 15000 20000 25000 30000 35000 40000 NCLOC 2.0 1.1 1.4 2.1 2.2 2.4
  14. Bernhard Schussek @webmozart 14/89 2.3 LTS June 3, 2013

  15. Bernhard Schussek @webmozart 15/89 Immutable To-Many Relations v2.3.7+ v2.2.10+

  16. Bernhard Schussek @webmozart 16/89 Immutable To-Many (2.2.10+) public function getTags()

    { return $this->tags->toArray(); }
  17. Bernhard Schussek @webmozart 17/89 Button Support v2.3+

  18. Bernhard Schussek @webmozart 18/89 Button Support (2.3+) $builder->add('create', 'submit'); $builder->add('reset',

    'reset'); $builder->add('delete', 'button');
  19. Bernhard Schussek @webmozart 19/89 Checking Clicked Buttons if ($form->get('create')->isClicked()) {

    ... }
  20. Bernhard Schussek @webmozart 20/89 Disabled Validation $builder->add('update', 'submit', array( 'validation_groups'

    => false, )); also possible in forms now
  21. Bernhard Schussek @webmozart 21/89 Simplified Request Handling v2.3+

  22. Bernhard Schussek @webmozart 22/89 Request Handling (<2.3) $form = $this->createForm('task',

    $task); if ($request->isMethod('POST')) { $form->bind($request); if ($form->isValid()) { ... } }
  23. Bernhard Schussek @webmozart 23/89 Request Handling (<2.3) <form action="{{ path('task_new')

    }}" method="post" {{ form_enctype(form) }}> {{ form_widget(form) }} <input type="submit" /> </form>
  24. Bernhard Schussek @webmozart 24/89 Request Handling (2.3+) $form = $this->createForm('task',

    $task, array( 'action' => $this->generateUrl('task_new'), )); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { ... }
  25. Bernhard Schussek @webmozart 25/89 Request Handling (2.3+) {{ form_start(form) }}

    {{ form_widget(form) }} <input type="submit" /> {{ form_end(form) }}
  26. Bernhard Schussek @webmozart 26/89 Request Handling (2.3+) {{ form(form) }}

  27. Bernhard Schussek @webmozart 27/89 Non-POST Requests $form = $this->createForm('task', $task,

    array( 'action' => $this->generateUrl('task_new'), 'method' => 'PATCH', )); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { ... }
  28. Bernhard Schussek @webmozart 28/89 Fluid FormBuilder Interface $form = $this->createFormBuilder($task)

    ->setAction($this->generateUrl('task_new')) ->setMethod('PUT') ... ->getForm();
  29. Bernhard Schussek @webmozart 29/89 More Powerful Dynamic Forms v2.3+

  30. Bernhard Schussek @webmozart 30/89 Dynamic Forms (2.3+) $addProvince = function

    (FormEvent $event) { $form = $event->getForm()->getParent(); $country = $event->getForm()->getData(); $form->add('province', 'entity', array( ... )); }; $builder->get('country')->addEventListener( FormEvents::POST_SET_DATA, $addProvince );
  31. Bernhard Schussek @webmozart 31/89 province POST_SET_DATA add('province', 'entity', ...) Dynamic

    Forms (2.3+) form country setData( ) object (Shop) object (Shop) object (Country) setData($shop->getCountry()) object (Province) setData($shop->getProvince()) POST_SET_DATA POST_SET_DATA
  32. Bernhard Schussek @webmozart 32/89 Dynamic Forms (2.3+) $builder->get('country')->addEventListener( FormEvents::POST_SUBMIT, $addProvince

    );
  33. Bernhard Schussek @webmozart 33/89 province province POST_SUBMIT add('province', 'entity', ...)

    Dynamic Forms (2.3+) form country submit(array(...)) submit("23") submit("17") POST_SUBMIT POST_SUBMIT object (Shop) object (Country) object (Province)
  34. Bernhard Schussek @webmozart 34/89 2.4 December 3, 2013

  35. Bernhard Schussek @webmozart 35/89 New Form Debugger v2.4+

  36. Bernhard Schussek @webmozart 36/89

  37. Bernhard Schussek @webmozart 37/89 Security Subtree Split v2.4+

  38. Bernhard Schussek @webmozart 38/89 Security Core ACL CSRF

  39. Bernhard Schussek @webmozart 39/89 composer.json { "require": { "symfony/security-csrf": "~2.4"

    } }
  40. Bernhard Schussek @webmozart 40/89 Creating a CSRF Token (2.3+) use

    Symfony\Component\Security\Csrf\CsrfTokenManager; $tokenManager = new CsrfTokenManager(); $token = $tokenManager->getToken('shoppingCart'); echo $url.'&token='.$token->getValue();
  41. Bernhard Schussek @webmozart 41/89 CSRF Token Verification (2.3+) use Symfony\Component\Security\Csrf\CsrfToken;

    $userToken = new CsrfToken( 'shoppingCart', $request->query->get('token') ); if (!$tokenManager->isTokenValid($userToken)) { throw new SecurityException('CSRF attack!'); }
  42. Bernhard Schussek @webmozart 42/89 Better Callback Constraint v2.4+

  43. Bernhard Schussek @webmozart 43/89 Callback Constraint (<2.3) /** * @Assert\Callback(methods={"validateTotalPrice"})

    */ class ShoppingCart { public function validateTotalPrice($context) ... }
  44. Bernhard Schussek @webmozart 44/89 Callback Constraint (<2.3) use Symfony\Component\Validator\ ExecutionContextInterface;

    public function validateTotalPrice( ExecutionContextInterface $context) { if ($this->totalPrice > $this->calculateTotal()) { $context->addViolationAt( 'totalPrice', 'The total price is incorrect.' ); } }
  45. Bernhard Schussek @webmozart 45/89 Callback Constraint (2.3+) class ShoppingCart {

    /** * @Assert\Callback */ public function validateTotalPrice($context) ... }
  46. Bernhard Schussek @webmozart 46/89 Future? http://www.flickr.com/photos/visualpanic/2271636207/

  47. Bernhard Schussek @webmozart 47/89

  48. Bernhard Schussek @webmozart 48/89 Claim 1 Claim 1 "Constant Change"

    "Constant Change" http://www.flickr.com/photos/nanagyei/6636632951/
  49. Bernhard Schussek @webmozart 49/89 19/02/07 19/02/08 19/02/09 19/02/10 19/02/11 19/02/12

    19/02/13 0 5000 10000 15000 20000 25000 30000 35000 40000 0 100 200 300 400 500 600 700 800 900 NCLOC Commit Count 2.0 1.1 1.4 2.1 2.2 2.4 Commit Count
  50. Bernhard Schussek @webmozart 50/89 Symfony 2.1 Promise: No More BC

    Breaks
  51. Bernhard Schussek @webmozart 51/89 class PropertyPathMapper implements DataMapperInterface { ...

    + /** + * Creates a new property path mapper. + * + * @param PropertyAccessorInterface $propertyAccessor + */ + public function __construct(PropertyAccessorInterface + $propertyAccessor = null) + { + $this->propertyAccessor = $propertyAccessor + ?: PropertyAccess::createPropertyAccessor(); + } ... }
  52. Bernhard Schussek @webmozart 52/89 class CustomMapper extends PropertyPathMapper { public

    function __construct() { $this->initialized = false; } } broken!
  53. Bernhard Schussek @webmozart 53/89 class CustomMapper extends PropertyPathMapper { public

    function __construct() { + parent::__construct(); $this->initialized = false; } }
  54. Bernhard Schussek @webmozart 54/89 Enhancements May Break BC!

  55. Bernhard Schussek @webmozart 55/89 No More BC Breaks When Using

    the Documented API
  56. Bernhard Schussek @webmozart 56/89 2.0 2.1 2.2 2.3 2.4 0

    5 10 15 20 25 30 BC Breaks Deprecations 2.1 2.1 2.2 2.3 2.4 BC Breaks and Deprecations
  57. Bernhard Schussek @webmozart 57/89 Claim 2 Claim 2 "Basic Features

    Are Missing" "Basic Features Are Missing" http://www.flickr.com/photos/annagaycoan/3834802666/
  58. Bernhard Schussek @webmozart 58/89 CAPTCHA GenemuFormBundle

  59. Bernhard Schussek @webmozart 59/89 Dependent Select Fields Event Listeners...

  60. Bernhard Schussek @webmozart 60/89 Multi-Step Forms CraueFormFlowBundle

  61. Bernhard Schussek @webmozart 61/89 JavaScript Validation APYJsFormValidationBundle?

  62. Bernhard Schussek @webmozart 62/89 The The Community Community Can Easily

    Add Features Can Easily Add Features http://www.flickr.com/photos/gulsenozcan/9323768024/
  63. Bernhard Schussek @webmozart 63/89 ... thanks to Composer ... thanks

    to Composer
  64. Bernhard Schussek @webmozart 64/89 Features Features Are Are Missing… Missing…

    http://www.flickr.com/photos/31246066@N04/6365239995/
  65. Bernhard Schussek @webmozart 65/89 03/07/10 03/01/11 03/07/11 03/01/12 03/07/12 03/01/13

    03/07/13 0 50 100 150 200 250 Bug Enhancement Feature Unlabeled 2.1 2.2 2.3 2.4 2.0 Form Issues+PRs
  66. Bernhard Schussek @webmozart 66/89 We Need We Need Your Your

    Help! Help! http://www.flickr.com/photos/59949757@N06/10822072804
  67. Bernhard Schussek @webmozart 67/89 http://www.flickr.com/photos/99314200@N04/11339612014/ Claim 3 Claim 3 "No

    Defined Roadmap" "No Defined Roadmap"
  68. Bernhard Schussek @webmozart 68/89

  69. Bernhard Schussek @webmozart 69/89

  70. Bernhard Schussek @webmozart 70/89 Bugs Enhancements Features Priority Pyramid

  71. Bernhard Schussek @webmozart 71/89 Roadmap? Roadmap? http://www.flickr.com/photos/99314200@N04/11339612014/

  72. Bernhard Schussek @webmozart 72/89 Priority 1: Simplified Dependent Fields difficult!

    #5807
  73. Bernhard Schussek @webmozart 73/89 Priority 2: Simplified Theming #9371 #8733

  74. Bernhard Schussek @webmozart 74/89 Priority 3+: Many Small Enhancements see

    GitHub
  75. Bernhard Schussek @webmozart 75/89 Claim 4 Claim 4 "No Community

    Support" "No Community Support" http://www.flickr.com/photos/jonathankosread/9283478903/
  76. Bernhard Schussek @webmozart 76/89 19/02/07 19/02/08 19/02/09 19/02/10 19/02/11 19/02/12

    19/02/13 0 100 200 300 400 500 600 700 800 900 0 10 20 30 40 50 60 70 80 90 100 Authors Commit Count 2.0 2.1 2.2 2.4 Number of Commit Authors
  77. Bernhard Schussek @webmozart 77/89 How To Get How To Get

    Involved Involved? ? http://www.flickr.com/photos/pagedooley/3258088498/
  78. Bernhard Schussek @webmozart 78/89 Easy: Create An Issue

  79. Bernhard Schussek @webmozart 79/89 Hard: Implement Fix/Feature

  80. Bernhard Schussek @webmozart 80/89 contribute experiment learn

  81. Bernhard Schussek @webmozart 81/89 Learning Learning By Reproducing By Reproducing

  82. Bernhard Schussek @webmozart 82/89 Reproduce Issue Fork Symfony Standard Reproduce

    Upload Create PR/Issue Comment 1 contribute
  83. Bernhard Schussek @webmozart 83/89 and if you have time… and

    if you have time… http://www.flickr.com/photos/see-through-the-eye-of-g/6268973351/
  84. Bernhard Schussek @webmozart 84/89 Understand Try to Understand the Problem

    Source 2 experiment
  85. Bernhard Schussek @webmozart 85/89 Fix Attempt a Fix 3 learn

  86. Bernhard Schussek @webmozart 86/89 Actual Core Development reproduce #1234 not

    reproducible reproduce #5678 not fixable attempt fix reproduce #9123 implement fix
  87. Bernhard Schussek @webmozart 87/89 Ideal Core Development #5678 #7856 not

    fixable attempt fix #9123 implement fix implement feature attempt fix not fixable #4321
  88. Bernhard Schussek @webmozart 88/89 http://www.flickr.com/photos/59949757@N06/10822072804 Join The Join The Hackday

    Hackday! !
  89. Bernhard Schussek @webmozart 89/89 Questions? Questions? http://joind.in/talk/view/10362 http://joind.in/talk/view/10362 Thank you!

    Thank you! Bernhard Schussek Bernhard Schussek @webmozart @webmozart http://www.flickr.com/photos/59949757@N06/10822072804