Simplifying form handling

PHP Göteborg, second meetup, 2015-09-30

Rickard Bennison

Sorry!

No speakers found :(

Form handling

With three simple objects

  • FormType - contains form fields
  • FormData - stores form data
  • FormHandler - handles form submission

Inspired from November Camp talk

"Decoupling the Model from the Framework"
joind.in/12537

Key separations of concerns

Only FormHandler knows about the model

FormType and FormData reflects the user interface, not the model

Case: Booking Laserdome

FormType

class LaserdomeType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('persons', 'number', ['required' => true]);
        $builder->add('complete', 'checkbox', ['required' => false]);
        $builder->add('date', 'date', ['required'    => true]);
        $builder->add('name', 'text', ['required' => true]);
        $builder->add('email', 'email', ['required' => true]);
        $builder->add('phone', 'text', ['required' => true]);
        $builder->add('comment', 'text', ['required' => false]);
        $builder->add('termsAccepted', 'checkbox', ['required' => true]);
    }
}

FormData

class LaserdomeData
{
    protected $persons;
    protected $complete;
    protected $date;
    protected $name;
    protected $email;
    protected $phone;
    protected $comment;
    protected $termsAccepted;

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    // ...
}

FormHandler

class LaserdomeHandler
{
    public function handle(FormInterface $form)
    {
        $data  = $form->getData();
        $order = new OrderData();
        $count = $data->getPersons();
        $meta  = ['type' => 'standard', 'persons' => $count, 'complete' => $data->isComplete()];
        $order->setMeta($meta);

        foreach ($data->getTimes() as $time) {
            // Create one booking per time and person
        }

        return $order;
    }
}

Controller

class BookingController extends Controller
{
    public function indexAction($resourceType, $type)
    {
        $form    = $this->getForm($resourceType, $type);
        $request = $this->get('request');
        $form->handleRequest($request);

        if ($form->isValid()) {
            $handler = $this->getHandler($resourceType, $type);
            $order   = $handler->handle($form);

            // Success
        }
    }
}

@rickard2

https://about.me/rickard2
www.montania.se