Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfony Forms in Detail

Symfony Forms in Detail

Workshop at Web Summer Camp 2019

Forms are a important element on various websites and come in different variations. A simple form is easily set up with Symfony's Form Component, but what about complex scenarios? We will have a look at the architecture of the component, which extension points are helpful and which features might even be implemented without the component.

Christopher Hertel

August 30, 2019
Tweet

More Decks by Christopher Hertel

Other Decks in Programming

Transcript

  1. @el_stoffel
    Web Summer Camp 2019
    Symfony Forms in Detail

    View Slide

  2. @el_stoffel
    Web Summer Camp 2019
    Christopher Hertel
    Consultant & Trainer @ SensioLabs
    Symfony Certified Developer
    Symfony User Group Berlin
    Christian Flothmann
    Software Developer @ SensioLabs
    Symfony Core & Docs Member

    View Slide

  3. @el_stoffel
    Web Summer Camp 2019
    Workshop Agenda
    Form Component
    Basic Glue Code
    Building a Form
    Extension Points
    Recap

    View Slide

  4. @el_stoffel
    Web Summer Camp 2019
    Basics
    Times
    Workshop 9.30 – 12.30
    coffee break 10.50 – 11.10
    Repository: //github.com/chr-hertel/product-crud

    View Slide

  5. @el_stoffel
    Web Summer Camp 2019
    Getting Started
    $ cd /var/www/html/symfony/forms
    $ git pull
    $ composer install
    $ symfony serve -d
    Open in browser: //localhost:8000/

    View Slide

  6. @el_stoffel
    Web Summer Camp 2019
    $ bin/console --version
    Symfony 4.3.4 (env: dev, debug: true)

    View Slide

  7. @el_stoffel
    Web Summer Camp 2019
    Coding Challenges
    Defined goals
    Make tests green
    Rescue branches
    Merge branches to get new code and challenges

    View Slide

  8. @el_stoffel
    Web Summer Camp 2019
    $ bin/check
    Code Quality Helper
    Yaml, Twig and PHP linting
    Code style and static code analysis
    PHPUnit testsuite
    Composer and schema validation

    View Slide

  9. @el_stoffel
    Web Summer Camp 2019
    Form Component

    View Slide

  10. @el_stoffel
    Web Summer Camp 2019
    Form
    DependencyInjection
    Validator
    HttpKernel
    Console
    Security
    HttpFoundation
    Routing
    Intl
    Serializer
    Messenger
    Config
    Mime
    56325
    40958
    32511
    26474
    24935
    24466
    23711
    18558
    17970
    16729
    16267
    12665
    12416
    Largest Symfony Component
    Source: symfony/symfony:master on 08/20/19

    View Slide

  11. @el_stoffel
    Web Summer Camp 2019
    "Make simple cases simple,
    make complex cases possible"
    Bernhard Schussek

    View Slide

  12. @el_stoffel
    Web Summer Camp 2019
    [email protected]
    Hello World
    Lorem ipsum …

    View Slide

  13. @el_stoffel
    Web Summer Camp 2019
    Foundation
    OptionsResolver Component
    Form Component
    Core Validation DI CSRF Doctrine
    Twig PHP Templating
    Extensions
    View
    Source: http://webmozarts.com/2012/03/06/symfony2-form-architecture/
    EventDispatcher Component
    PropertyAccess Component

    View Slide

  14. @el_stoffel
    Web Summer Camp 2019
    Basic Glue Code

    View Slide

  15. @el_stoffel
    Web Summer Camp 2019
    Controller

    View Slide

  16. @el_stoffel
    Web Summer Camp 2019

    View Slide

  17. @el_stoffel
    Web Summer Camp 2019
    FormType

    View Slide

  18. @el_stoffel
    Web Summer Camp 2019

    View Slide

  19. @el_stoffel
    Web Summer Camp 2019
    Template

    View Slide

  20. @el_stoffel
    Web Summer Camp 2019

    View Slide

  21. @el_stoffel
    Web Summer Camp 2019
    Controller
    Handles Request
    Creates Form
    Triggers Processing
    Creates Response
    Template
    Renders Form
    Additional Markup
    FormType
    Describes Structure
    Configures Options
    ?

    View Slide

  22. @el_stoffel
    Web Summer Camp 2019
    Challenge 1 – Contact Form

    View Slide

  23. @el_stoffel
    Web Summer Camp 2019
    $ git merge contact/01-base
    Challenge 1 – Contact Form
    Implement App\Contact\Dto
    Implement App\Controller\ContactController::contact
    implement template templates/contact.html.twig
    Implement App\Form\ContactType
    See Challenges.md

    View Slide

  24. @el_stoffel
    Web Summer Camp 2019
    $ git checkout contact/solution
    Got stuck?
    commit or stash your changes

    View Slide

  25. @el_stoffel
    Web Summer Camp 2019
    Building a Form

    View Slide

  26. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    Config
    FormBuilder

    View Slide

  27. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    Config
    FormBuilder

    View Slide

  28. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    Config
    FormBuilder
    Form

    View Slide

  29. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    Config
    FormBuilder
    Form
    handleRequest(…)
    submit(…)
    Request
    Handler
    Data

    View Slide

  30. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    FormBuilder
    Form
    handleRequest(…)
    submit(…)
    Request
    Handler
    Data
    // …
    Config

    View Slide

  31. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    FormBuilder
    Form
    handleRequest(…)
    submit(…)
    Request
    Handler
    Data
    // … buildView(…)
    finishView(…)
    Config
    createView() FormView

    View Slide

  32. @el_stoffel
    Web Summer Camp 2019
    Extension Points

    View Slide

  33. @el_stoffel
    Web Summer Camp 2019
    FormType

    View Slide

  34. @el_stoffel
    Web Summer Camp 2019

    View Slide

  35. @el_stoffel
    Web Summer Camp 2019
    FormType
    describes structure
    has options

    View Slide

  36. @el_stoffel
    Web Summer Camp 2019
    FormType
    describes structure
    has options
    inheritance possible
    extensible
    changes behavior

    View Slide

  37. @el_stoffel
    Web Summer Camp 2019
    FormType
    describes structure
    has options
    inheritance possible
    extensible
    changes behavior

    View Slide

  38. @el_stoffel
    Web Summer Camp 2019
    FormTypeExtension

    View Slide

  39. @el_stoffel
    Web Summer Camp 2019

    View Slide

  40. @el_stoffel
    Web Summer Camp 2019
    FormTypeExtension
    manipulate existing form types
    implement extensions across multiple types

    View Slide

  41. @el_stoffel
    Web Summer Camp 2019

    View Slide

  42. @el_stoffel
    Web Summer Camp 2019

    View Slide

  43. @el_stoffel
    Web Summer Camp 2019
    Controller
    Handles Request
    Creates Form
    Triggers Processing
    Creates Response
    Template
    Renders Form
    Additional Markup
    FormType
    Describes Structure
    Configures Options
    ?

    View Slide

  44. @el_stoffel
    Web Summer Camp 2019
    Controller
    Handles Request
    Creates Form
    Triggers Processing
    Creates Response
    Template
    Renders Form
    Additional Markup
    FormType
    Describes Structure
    Configures Options
    Configures Behavior

    View Slide

  45. @el_stoffel
    Web Summer Camp 2019
    Using FormTypes to
    configure behavior of
    Form handling

    View Slide

  46. @el_stoffel
    Web Summer Camp 2019
    [email protected]
    Hello World
    Lorem ipsum …

    View Slide

  47. @el_stoffel
    Web Summer Camp 2019
    Controller
    Incoming HTTP Request FormFactory
    FormType
    buildForm(…)
    FormRegistry
    Core
    Extension
    Doctrine
    Extension
    DI
    Extension

    FormBuilder
    Form
    handleRequest(…)
    submit(…)
    Request
    Handler
    Data
    // … buildView(…)
    finishView(…)
    Config
    createView() FormView

    View Slide

  48. @el_stoffel
    Web Summer Camp 2019
    createForm
    handleRequest
    [email protected]
    Hello World
    Lorem ipsum …

    View Slide

  49. @el_stoffel
    Web Summer Camp 2019
    createForm
    handleRequest
    [email protected]
    'Hallo World'
    'This is a test'
    Hallo Welt
    This is a test

    View Slide

  50. @el_stoffel
    Web Summer Camp 2019
    createForm
    handleRequest
    [email protected]
    'Hallo World'
    'This is a test'
    setData
    submit
    Hallo Welt
    This is a test

    View Slide

  51. @el_stoffel
    Web Summer Camp 2019
    DataMapper

    View Slide

  52. @el_stoffel
    Web Summer Camp 2019
    Default Data Mapping

    View Slide

  53. @el_stoffel
    Web Summer Camp 2019
    Default Data Mapping

    View Slide

  54. @el_stoffel
    Web Summer Camp 2019
    PropertyPath Data Mapping

    View Slide

  55. @el_stoffel
    Web Summer Camp 2019
    PropertyPath Data Mapping

    View Slide

  56. @el_stoffel
    Web Summer Camp 2019
    And now?

    View Slide

  57. @el_stoffel
    Web Summer Camp 2019
    [email protected]
    Hello World
    Lorem ipsum …
    setData
    submit
    Data Mapper

    View Slide

  58. @el_stoffel
    Web Summer Camp 2019

    View Slide

  59. @el_stoffel
    Web Summer Camp 2019
    DataMapper
    maps data between model and form
    registered in FormType
    often combined with empty_data option

    View Slide

  60. @el_stoffel
    Web Summer Camp 2019

    View Slide

  61. @el_stoffel
    Web Summer Camp 2019

    View Slide

  62. @el_stoffel
    Web Summer Camp 2019

    View Slide

  63. @el_stoffel
    Web Summer Camp 2019
    Challenge 2 – Category Form

    View Slide

  64. @el_stoffel
    Web Summer Camp 2019
    $ git merge category/01-base
    $ bin/console doctrine:schema:update --force
    Challenge 2 – Category Form

    View Slide

  65. @el_stoffel
    Web Summer Camp 2019
    $ git merge category/01-base
    $ bin/console doctrine:schema:update --force
    Challenge 2 – Category Form
    Implement App\Form\CategoryType
    Catch CategoryException and convert to FormError
    See Challenges.md

    View Slide

  66. @el_stoffel
    Web Summer Camp 2019
    $ git checkout category/solution
    Got stuck?
    commit or stash your changes

    View Slide

  67. @el_stoffel
    Web Summer Camp 2019
    [email protected]
    Hello World
    Lorem ipsum …
    setData
    submit
    Data Mapper

    View Slide

  68. @el_stoffel
    Web Summer Camp 2019
    DataTransformer

    View Slide

  69. @el_stoffel
    Web Summer Camp 2019
    [email protected]
    Hello World
    Lorem ipsum …
    setData
    submit
    Data Transformer

    View Slide

  70. @el_stoffel
    Web Summer Camp 2019

    View Slide

  71. @el_stoffel
    Web Summer Camp 2019
    DataTransformer
    converts data between representations
    registered in FormType
    model data to normalized data
    normalized data to model data
    view data to normalized data
    normalized data to view data
    ModelTransformer
    ViewTransformer

    View Slide

  72. @el_stoffel
    Web Summer Camp 2019

    View Slide

  73. @el_stoffel
    Web Summer Camp 2019

    View Slide

  74. @el_stoffel
    Web Summer Camp 2019

    View Slide

  75. @el_stoffel
    Web Summer Camp 2019
    Challenge 3 – Product Form

    View Slide

  76. @el_stoffel
    Web Summer Camp 2019
    $ git merge product/01-base
    Challenge 3 – Product Form
    Implement App\Form\SkuType using DataTransformer
    Implement App\Form\ProductType using DataMapper
    See Challenges.md

    View Slide

  77. @el_stoffel
    Web Summer Camp 2019
    $ git checkout product/solution
    Got stuck?
    commit or stash your changes

    View Slide

  78. @el_stoffel
    Web Summer Camp 2019
    [email protected]
    Hello World
    Lorem ipsum …
    setData
    submit
    Data Transformer

    View Slide

  79. @el_stoffel
    Web Summer Camp 2019
    FormEvents

    View Slide

  80. @el_stoffel
    Web Summer Camp 2019
    Form::setData Form::submit
    FormEvents::PRE_SET_DATA
    FormEvents::POST_SET_DATA
    FormEvents::PRE_SUBMIT
    FormEvents::POST_SUBMIT
    Transformer
    Model -> Normalized
    Normalized -> View
    Mapper
    mapDataToForms
    Transformer
    View -> Normalized
    Normalized -> Model
    Mapper
    mapFormsToData
    FormEvents::SUBMIT

    View Slide

  81. @el_stoffel
    Web Summer Camp 2019
    FormEvents
    interact with Form or data dynamically
    registered in FormType
    PRE_SET_DATA
    POST_SET_DATA
    PRE_SUBMIT
    SUBMIT
    Form::setData
    Form::submit
    POST_SUBMIT

    View Slide

  82. @el_stoffel
    Web Summer Camp 2019

    View Slide

  83. @el_stoffel
    Web Summer Camp 2019
    More Advanced Extension Points
    FormTypeGuesserInterface
    FormExtensionInterface
    . . .

    View Slide

  84. @el_stoffel
    Web Summer Camp 2019
    Recap: Extending Forms

    View Slide

  85. @el_stoffel
    Web Summer Camp 2019
    Recap: Extending Forms
    FormType is starting point to configure Form and FormView
    FormTypeExtension to extend given or multiple FormTypes
    Transformer to transform data between Model and View
    Mapper to control where data is coming and going
    FormEvents to manipulate Form and data dynamically

    View Slide

  86. @el_stoffel
    Web Summer Camp 2019
    Thank you! Questions?

    View Slide