Leveraging Symfony2 Forms

download Leveraging Symfony2 Forms

of 74

Embed Size (px)

description

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.

Transcript of Leveraging Symfony2 Forms

  • 1.BernhardSchussek LeveragingSymfony2FormsSymfonyLiveConference,March03rd2011

2. Aboutmyself SoftwareArchitectinVienna StudentofSoftware Engineering Symfonysince2006 Outdoorandmusicjunkie 3. Agenda Introductoryexample TheFormConfigclass Formprocessing Fields Usefulfeatures 4. TheSymfony2Formcomponent 5. TheSymfony2Formcomponent Evolutionofsymfony1sfForm 2.5yearsdevelopment Fixesmostofitsproblems Reusablewidgets Embeddedforms 6. Why2.5years? 7. "Ittakesalongtimetomakesomthingcomplicatedsimple,butifyoudo,itwillworkwithoutproblemsforalongtime."F.AndySeidl,http://faseidl.com 8. ServiceOrientedArchitecture Applicationsprovideservices Servicesareexchangable Theseservicescanbeconsumedbydifferentactors Humans Machines 9. Formsdontcontain businesslogic 10. Servicesdo 11. Example:Onlinesausageshop 12. Example:OnlinesausageshopYouRequestResponse 13. Example:OnlinesausageshopConsumer Service You Request Response 14. Example:OnlinesausageshopConsumer ServiceRequest Response 15. Example:OnlinesausageshopConsumer ServiceRequest Response 16. Serviceimplementationclass Order{function setName($name);function setAddress($address);function setSausage($sausage);function setAmount($amount);} 17. FlowofinformationI am Max! 18. FlowofinformationI am Max! $order->setName(Max) 19. Flowofinformation OrderformName:MaxAddress: SensioLabs, ParisSausage: BratwurstAmount: 5 20. Flowofinformation Orderform$orderName:Max->setName(Max)Address: SensioLabs, ->setAddress( Sensio Labs, ParisParis)Sausage: Bratwurst->setSausage(Bratwurst)Amount: 5 ->setAmount(5); 21. FlowofinformationExistingorder $order ->getName()Name: Bob ->getAddress() Address: LiipOffice Zurich ->getSausage() Sausage: Cervelat ->getAmount(); Amount: 10 22. TheFormConfigclass 23. Formdefinition PHPclassclass OrderFormConfig extends AbstractConfig{public function configure( FieldInterface $form, array $options){}} 24. Formdefinition PHPclassclass OrderFormConfig extends AbstractConfig{public function configure( FieldInterface $form, array $options){$form->add(text, name) ->add(text, address) ->add(text, sausage) ->add(integer, amount);}} 25. Formdefinition PHPclassclass OrderFormConfig extends AbstractConfig{...public function getIdentifier(){return form.order;}} 26. WhynotasimpleOrderFormclass? 27. WhyweneedConfigclasses OrderFormcannotbeputintotheDependency InjectionContainer... ...butOrderFormConfigcan! 28. DependencyInjectionContainer Tag alias == form identifierpublic function getIdentifier(){return form.order;} 29. Formprocessing 30. FormprocessingForm 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. Formprocessing$factory = $this->get(form.factory);$form = $factory->getInstance(form.order);$form->setData($order);Service objectif ($request->getMethod() === POST) {$form->bindRequest($request);if ($form->isValid()) {$order->send();return new RedirectResponse(...);}} 32. Formprocessing$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. Formprocessing$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. Formrendering Intheactionreturn $this->render(HelloBundle:Hello:index.twig.html,array(form => $form->getRenderer())); Contains view variables and methods 35. Formrendering Inthetemplate{{ form.widget }} "widget" is a view method 36. Formrendering "fields" is a view variable{{ form.errors }}{% for field in form.vars.fields %}{{ field.errors }}{{ field.label }}{{ field.widget }}{% endfor %}{{ form.rest }} 37. Formrendering{{ form.errors }}{{ form.name.errors }}{{ form.name.label }}{{ form.name.widget }}{{ form.rest }} 38. Formrendering{{ form.rest }} Rendersallfieldsthatwerentrenderedbefore ...fieldsthatyouforgottorendermanually ...hiddenfields 39. Whataboutvalidation? 40. Formvalidation usestheSymfony2Validator "Constraints"areputontoyourPHPclasses (services,entitiesetc.) 41. Validationconstraintsclass Order{/** * @check:NotNull * @check:AssertType("string") * @check:MaxLength(50, message= *"Long name, dude...") */private $name;} 42. Fields 43. TextinputTitle:$form->add(text, title); 44. Textarea Content:$form->add(textarea, content); 45. Dateselector Mmmh localized! Publishat: $form->add(date, publishAt); 46. Countryselector Localized too! Yummy!Nationality:$form->add(country, nationality); 47. Fileupload Profilepicture:$form->add(file, profilePicture);Remembers uploaded files on errors! 48. Repeatedinput Email:Email(again): $form->add(repeated, email); 49. Corefields entitybirthdaypassword filecheckboxpercent hiddenchoicerepeated integercollectiontextarea languagecountry text localedatetimezone moneydatetimeurl number 50. FieldarchitectureFiltersValuetransformers 51. FiltersmodifyavalueunidirectionalExample:FixUrlProtocolFiltersymfony-project.comhttp://symfony-project.com 52. ValueTransformers convertvaluesbetweentworepresentations bidirectional Example:DateTimeToArrayTransformerarray(year => 2011,object(DateTime)month => 5,day => 1,) 53. Example:EntityfieldTheusersees:Symfonysees:Entityfield CheckboxCheckbox Checkbox Checkbox"0" "1""2""3" Tag IDs 54. Tag IDsarray("0" => "0", "1" => "1", "2" => "1", ...)"0""1""0""0"CheckboxCheckboxCheckbox Checkbox "0" "1" "2""3" 55. Tag IDsarray("0" => "0", "1" => "1", "2" => "1", ...)"0""1""0""0"CheckboxCheckboxCheckbox Checkbox "0" "1" "2""3" 56. CheckboxCheckbox Checkbox Checkbox "0" "1""2""3"false true true falsearray("0" => false, "1" => true, "2" => true, ...) ArrayCollection($securityTag, $validatorTag) 57. CheckboxCheckbox Checkbox Checkbox "0" "1""2""3"false true true falseChoicesToArrayTransformerarray("0" => false, "1" => true, "2" => true, ...) ArrayCollection($securityTag, $validatorTag) 58. CheckboxCheckbox Checkbox Checkbox "0" "1""2""3"false true true falsearray("0" => false, "1" => true, "2" => true, ...)ArrayToEntitiesTransformer ArrayCollection($securityTag, $validatorTag) 59. CSRFprotection CrossSiteRequestForgery Aformissubmittedusingthesessionofanother person Allkindsofmisuse BuiltinprotectioninSymfony2 60. CSRFprotectionapp/config/config.ymlframework:csrf_protection:enabled: truesecret: 30665e19ef0010d5620553 61. FieldcreationManualAutomaticSymfony2looksatmetadataofthedomainclassto"guess"thecorrectfieldtypeandsettingsE.g.Validatormetadata,Doctrine2metadata 62. Manualfieldcreationpublic function configure( FieldInterface $form, array $options){$form->add(entity, sausage, array(class => Sausage,));} butDoctrinealreadyknows,that"sausage"isa ToOnerelationshiptotheSausageclass! 63. Automaticfieldcreationpublic function configure( FieldInterface $form, array $options){$form->setDataClass(Order);$form->add(sausage);} 64. Automaticwithoptionsoverridingpublic function configure( FieldInterface $form, array $options){$form->setDataClass(Order) ->add(sausage, array( required => false, ));} 65. Embeddedforms Symfony2allowstoembedformsintoanothervery easily FieldsandformsimplementFieldInterface "Aformisafield" 66. Embeddedtooneformspublic function configure( FieldInterface $form, array $options){$form->add(form.sausage, sausage);}Identifier of SausageFormConfig 67. Embeddedtomanyformspublic function configure(FieldInterface $form, array $options){$form->add(collection, sausages, array(identifier => form.sausage));} Identifier of SausageFormConfig 68. Configoptions Optionsforinfluencingthefields/formscreationclass ConcealedFieldConfig extends Abstract..{public function getDefaultOptions($options){return array(concealed => true,);}} 69. Configinheritance Dynamicinheritancefromotherforms/fieldsclass ConcealedFieldConfig extends Abstract..{public function getParent(array $options){return $options[concealed]? password : text;}} 70. Formthemes ArenormalTwigtemplates Blocksforeachfieldtype{% block textarea__widget %}{{ value }}{% endblock textarea__widget %} 71. Formthemes Canspecifywidget,errors,labelandrow templatesforspecificfieldtypes{% block textarea__row %}{{ this.errors }}{{ this.widget }}{% endblock textarea__row %} 72. Formthemes Corethemes: TwigBundle::div_layout.html.twig TwigBundle::table_layout.html.twig ConfigurationintheDIparameter "form.theme.template" Moreflexibleconfigurationoptionscomingsoon 73. Questions? Thanksforlistening!Codecancurrentlybefoundonhttps://github.com/bschussek/symfony/tree/experimentalBernhardSchussek Twitter:@webmozart 74. TheEndCopyright"dogwindow"byLarryWentzelhttp://www.flickr.com/photos/wentzelepsy"SymfonyLive2011Logo"bySensioLabshttp://www.sensiolabs.com