symfony form basics - oromeetup #3 cherkassy

Post on 16-Apr-2017

813 Views

Category:

Engineering

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Presentation title here

Symfony Form

“Make simple cases simple, make complex cases possible”

- Bernhard Schussek

presented by Andreii Yatsenko

Presentation title here

About me

● Я Андрюха● PHP Developer at Oro Inc.● Live in Kyiv● Studied at GeekHub ~3 years ago● 6 years with PHP

Presentation title here

Agenda

● Form Flow● Form EventListeners● Form Extensions● Data Transformers● Form Tests

● Bad and Good Practices● Almost W/O code samples

Presentation title here

Form flow

● create form● set data to form● handle request● Profit! do something with updated data

○ E.g. persist data to DB

Presentation title here

How to create form?At first ● you need to create formFactory● or if you are using Symfony just get it from

ServiceContainer

$formFactory = $container->get(“form.factory”);

Presentation title here

How to create form?

● 1) using FormBuilder in Controller :($formFactory->createFormBuilder()

->add(‘firstName”)->add(“lastName”)->add(“email”);

Presentation title here

How to create form?

● 2) using FormType

Presentation title here

How to create form?

● If you in Controller$this->createForm($formType)// or$this->createFormBuilder()

->add(“name”, “text”)->getForm();

Presentation title here

How to set form data?

Presentation title here

Always set form data at form creation!

$data = new User();$formFactory

->createForm($formType, $data, $options);// or$formFactory->createFormBuilder($data);

Presentation title here

Try to not setData after form creation

Because● All form events will be triggered twice :(

$form = $formFactory->createForm($formType);

$form->setData($data);

Presentation title here

Always use objects instead of arrays!

Presentation title here

If you don’t have object - you just not created it yet!

● Create DTO

Presentation title here

Why objects, I like kittens arrays?

Presentation title here

Because of ValidationValidation

Presentation title here

How to Validate Form

● Do not validate form!● Validate data

○ yaml, xml, annotation drivers for constrants

● But what if my form doesn’t submit the data? ○ like “Apply terms checkbox”

● Make field mapped = false and validate form

Presentation title here

$formFactory->createForm($formType, $data, $options);

Form options (configuration)

Presentation title here

Form options (configuration)

● Form options is a form configuration. And it’s a data too, data that needed for building and submitting the form, but it’s not the Form Data (Usually don’t need to be updated from user input)

Presentation title here

Form options (configuration)

● Buy the way Form Data is an option too. You can just set $options[‘data’], and form factory internally use it too. It’s have higher priority than $data (second param) in

$formFactory->createForm($type, $data, $options)

Presentation title here

Next

Some form internals

Presentation title here

How form saves your memory

In Symfony2 all form fields are forms too, and can be reused.

E.x. ● TextFormType● CategoryFormType● ProductFormType● etc.

Presentation title here

How form saves your memory

Form composed from ● Form (form builder template etc.) and● FormConfig (options with data)

● Form and FormConfig are different objects.

Presentation title here

How form saves your memory

When you reuse Form, e.x. if you create form with 20 text fields, only ONE TextForm will be created.

Presentation title here

How form saves your memory

● But for different fields you have different data, and usually different options, they are so called FormConfig and will be created for each fields, so in our example you will have 20 FormConfig objects

Presentation title here

How to create form, that depends on data?● Use dependency injections:inject data to FormType container

E.x. new FormType($someData);

Presentation title here

• How to create form, that depends on data?● Use dependency injections:inject data to FormType container

E.x. new FormType($someData);

Presentation title here

Never inject dinamic objects to FormType!

Presentation title here

Never inject dinamic objects to FormType!

Because you will change FormType, not the FormConfig, so all forms on page will be configured the same.

Presentation title here

The right way :)

● Inject to container static objects E.x. Doctine, not concrete Entities

Presentation title here

If I don’t have static object? :(

● Use custom form options

$formFactory->createFrom($type, $data, $options);

At first you need to configure them in FormType::configureOptions()

Presentation title here

But wait, Where to place dinamic business logic, if I can’t place it in FormType?

:(

Presentation title here

But wait, Where to place dinamic business logic, if I can’t place it in FormType?

In EventListeners! :)

Presentation title here

Form Events

● PRE_SET_DATA● POST_SET_DATA

● PRE_SUBMIT● SUBMIT● POST_SUBMIT

Presentation title here

How to subscribe to form events?

1) Create:● EventListener - any callable● EventSubscriber - separate class

implementedSymfony\Component\EventDispatcher\EventSubscriberInterface

2) Add them to FormBuilder

$builder->addEventListener(“PRE_SUBMIT”, $listener);

$builder->addEventSubscriber($subscriber)

Presentation title here

You can even change the form in EventListeners● add or remove form fields

http://symfony.com/doc/current/components/form/form_events.html

Presentation title here

But you can’t register event listener like in symfony or doctrine EventDispatcher, from another bundle

Presentation title here

How to solve this?

Presentation title here

How to solve this?

FormTypeExtensions

Presentation title here

FormTypeExtensions● Like form types but have getExtendedType()

method● extends Symfony\Component\Form\AbstractTypeExtension

● Registered in DI with tag form.type_extension

Presentation title here

How form works with data internally?

Presentation title here

How form works with data internally?

E.x. DateTimeFormType● You set to form timestamp

● User will see human formatted string

Presentation title here

How form works with data internally?

E.x. DateTimeFormType● You set to form timestamp● In EventListeners you work with DateTime ● User will see human formatted string

Presentation title here

How form works with data internally?

E.x.● Controller - timestamp● Form - DateTime ● User - formatted string

Presentation title here

How form works with data internally?

E.x.● Model Data - timestamp● Normalized Data - DateTime ● View Data - formatted string

Presentation title here

Data Transformers● Model Transformer● View Transformer

implement Symfony\Component\Form\DataTransformerInterface

2 methods:● transform($data)● reverseTransform($data)

Presentation title here

Data Transformers

Register at $builder

$builder->get('date') ->addModelTransformer($transformer);

Presentation title here

Data Transformers

● Should only transform data from one format to another, but never change the data.

● If you want to change data use EventListeners

Presentation title here

Debugging Forms

Presentation title here

How to test forms

Unit Test$builder = $this->createMock(“FormBuilder”);$builder->expects($this->at(1))->method(“add”)->withArguments(“username”, “text”)//...

Presentation title here

How to test forms

Unit Test$builder = $this->createMock(“FormBuilder”);$builder->expects($this->at(1))->method(“add”)->withArguments(“username”, “text”)//...

Presentation title here

Presentation title here

Agenda

● Form Flow● Form EventListeners● Form Extensions● Data Transformers● Form Tests

Presentation title here

?

top related