Slide 1

Slide 1 text

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/

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Bernhard Schussek @webmozart 3/89 Bernard @webmozart "that Forms guy"

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Austria

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Bernhard Schussek @webmozart 8/89 Form Form Evolution Evolution http://www.flickr.com/photos/jurvetson/2490285058/

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Bernhard Schussek @webmozart 10/89 Symfony 1.1 Forms sfForm ContactForm sfValidatorSchema sfWidgetSchema sfValidator sfWidget * *

Slide 11

Slide 11 text

Bernhard Schussek @webmozart 11/89 2.0 July 28, 2010

Slide 12

Slide 12 text

Bernhard Schussek @webmozart 12/89 Symfony 2.0 Forms FormTypeInterface ContactType Form FormBuilder configures produces

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Bernhard Schussek @webmozart 14/89 2.3 LTS June 3, 2013

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Bernhard Schussek @webmozart 16/89 Immutable To-Many (2.2.10+) public function getTags() { return $this->tags->toArray(); }

Slide 17

Slide 17 text

Bernhard Schussek @webmozart 17/89 Button Support v2.3+

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Bernhard Schussek @webmozart 19/89 Checking Clicked Buttons if ($form->get('create')->isClicked()) { ... }

Slide 20

Slide 20 text

Bernhard Schussek @webmozart 20/89 Disabled Validation $builder->add('update', 'submit', array( 'validation_groups' => false, )); also possible in forms now

Slide 21

Slide 21 text

Bernhard Schussek @webmozart 21/89 Simplified Request Handling v2.3+

Slide 22

Slide 22 text

Bernhard Schussek @webmozart 22/89 Request Handling (<2.3) $form = $this->createForm('task', $task); if ($request->isMethod('POST')) { $form->bind($request); if ($form->isValid()) { ... } }

Slide 23

Slide 23 text

Bernhard Schussek @webmozart 23/89 Request Handling (<2.3) {{ form_widget(form) }}

Slide 24

Slide 24 text

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()) { ... }

Slide 25

Slide 25 text

Bernhard Schussek @webmozart 25/89 Request Handling (2.3+) {{ form_start(form) }} {{ form_widget(form) }} {{ form_end(form) }}

Slide 26

Slide 26 text

Bernhard Schussek @webmozart 26/89 Request Handling (2.3+) {{ form(form) }}

Slide 27

Slide 27 text

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()) { ... }

Slide 28

Slide 28 text

Bernhard Schussek @webmozart 28/89 Fluid FormBuilder Interface $form = $this->createFormBuilder($task) ->setAction($this->generateUrl('task_new')) ->setMethod('PUT') ... ->getForm();

Slide 29

Slide 29 text

Bernhard Schussek @webmozart 29/89 More Powerful Dynamic Forms v2.3+

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Bernhard Schussek @webmozart 32/89 Dynamic Forms (2.3+) $builder->get('country')->addEventListener( FormEvents::POST_SUBMIT, $addProvince );

Slide 33

Slide 33 text

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)

Slide 34

Slide 34 text

Bernhard Schussek @webmozart 34/89 2.4 December 3, 2013

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

Bernhard Schussek @webmozart 36/89

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Bernhard Schussek @webmozart 38/89 Security Core ACL CSRF

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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();

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Bernhard Schussek @webmozart 42/89 Better Callback Constraint v2.4+

Slide 43

Slide 43 text

Bernhard Schussek @webmozart 43/89 Callback Constraint (<2.3) /** * @Assert\Callback(methods={"validateTotalPrice"}) */ class ShoppingCart { public function validateTotalPrice($context) ... }

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Bernhard Schussek @webmozart 45/89 Callback Constraint (2.3+) class ShoppingCart { /** * @Assert\Callback */ public function validateTotalPrice($context) ... }

Slide 46

Slide 46 text

Bernhard Schussek @webmozart 46/89 Future? http://www.flickr.com/photos/visualpanic/2271636207/

Slide 47

Slide 47 text

Bernhard Schussek @webmozart 47/89

Slide 48

Slide 48 text

Bernhard Schussek @webmozart 48/89 Claim 1 Claim 1 "Constant Change" "Constant Change" http://www.flickr.com/photos/nanagyei/6636632951/

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

Bernhard Schussek @webmozart 50/89 Symfony 2.1 Promise: No More BC Breaks

Slide 51

Slide 51 text

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(); + } ... }

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Bernhard Schussek @webmozart 54/89 Enhancements May Break BC!

Slide 55

Slide 55 text

Bernhard Schussek @webmozart 55/89 No More BC Breaks When Using the Documented API

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

Bernhard Schussek @webmozart 57/89 Claim 2 Claim 2 "Basic Features Are Missing" "Basic Features Are Missing" http://www.flickr.com/photos/annagaycoan/3834802666/

Slide 58

Slide 58 text

Bernhard Schussek @webmozart 58/89 CAPTCHA GenemuFormBundle

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

Bernhard Schussek @webmozart 61/89 JavaScript Validation APYJsFormValidationBundle?

Slide 62

Slide 62 text

Bernhard Schussek @webmozart 62/89 The The Community Community Can Easily Add Features Can Easily Add Features http://www.flickr.com/photos/gulsenozcan/9323768024/

Slide 63

Slide 63 text

Bernhard Schussek @webmozart 63/89 ... thanks to Composer ... thanks to Composer

Slide 64

Slide 64 text

Bernhard Schussek @webmozart 64/89 Features Features Are Are Missing… Missing… http://www.flickr.com/photos/31246066@N04/6365239995/

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

Bernhard Schussek @webmozart 66/89 We Need We Need Your Your Help! Help! http://www.flickr.com/photos/59949757@N06/10822072804

Slide 67

Slide 67 text

Bernhard Schussek @webmozart 67/89 http://www.flickr.com/photos/99314200@N04/11339612014/ Claim 3 Claim 3 "No Defined Roadmap" "No Defined Roadmap"

Slide 68

Slide 68 text

Bernhard Schussek @webmozart 68/89

Slide 69

Slide 69 text

Bernhard Schussek @webmozart 69/89

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

Bernhard Schussek @webmozart 75/89 Claim 4 Claim 4 "No Community Support" "No Community Support" http://www.flickr.com/photos/jonathankosread/9283478903/

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

Bernhard Schussek @webmozart 77/89 How To Get How To Get Involved Involved? ? http://www.flickr.com/photos/pagedooley/3258088498/

Slide 78

Slide 78 text

Bernhard Schussek @webmozart 78/89 Easy: Create An Issue

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

Bernhard Schussek @webmozart 80/89 contribute experiment learn

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

Bernhard Schussek @webmozart 82/89 Reproduce Issue Fork Symfony Standard Reproduce Upload Create PR/Issue Comment 1 contribute

Slide 83

Slide 83 text

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/

Slide 84

Slide 84 text

Bernhard Schussek @webmozart 84/89 Understand Try to Understand the Problem Source 2 experiment

Slide 85

Slide 85 text

Bernhard Schussek @webmozart 85/89 Fix Attempt a Fix 3 learn

Slide 86

Slide 86 text

Bernhard Schussek @webmozart 86/89 Actual Core Development reproduce #1234 not reproducible reproduce #5678 not fixable attempt fix reproduce #9123 implement fix

Slide 87

Slide 87 text

Bernhard Schussek @webmozart 87/89 Ideal Core Development #5678 #7856 not fixable attempt fix #9123 implement fix implement feature attempt fix not fixable #4321

Slide 88

Slide 88 text

Bernhard Schussek @webmozart 88/89 http://www.flickr.com/photos/59949757@N06/10822072804 Join The Join The Hackday Hackday! !

Slide 89

Slide 89 text

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