formable icon indicating copy to clipboard operation
formable copied to clipboard

Describe and validate DTOs with ease

This package is abandoned and no longer maintained. The author suggests using the https://github.com/PUGX/formable package instead.

Formable Symfony Bundle

Latest Stable Version Total Downloads Latest Unstable Version License

Why?

Because the cleanest way to transfer data from a web request to the domain is by using DTOs. For simple DTOs Symfony forces you to create 2 classes, the FormType class and the SomethingDTO class.

How?

This Bundle allows you to describe DTOs by the annotation @Formable(). Let's see an example.

Example

The Data Transfer Object


use Formable\Definition\Formable;
use Symfony\Component\Validator\Constraints as Assert;

class PublishPostCommand
{
    /**
     * @Formable(name="title", dataType="text")
     *
     * @Assert\Length(max=250)
     */
    public $title;

    /**
     * @Formable(name="content", dataType="text")
     */
    public $content;

    /**
     * @Formable(name="tags", dataType="collection", options={
     *   "type"="text",
     *   "allow_add"=true
     * })
     *
     * @Assert\Count(
     *   min = "2"
     * )
     *
     */
    public $tags;

    /**
     * @Formable(name="date", dataType="date", options={
     *   "widget"="single_text",
     *   "format"="yyyy-M-d"
     * })
     */
    public $date;
}

Embedded DTOs

    /**
     * @var
     *
     * @Formable(name="moneyDTO", class="Formable\Tests\Integration\DTOs\TestMoneyDTO")
     */
    public $moneyDTO;

The Controller


public function publishAction(Request $request)
{
    $publishCommand = new PublishPostCommand();
    $publishCommand->date = new \DateTime('now');
    
    $form = $this->get('trt.formable')->generate($publishCommand);
    $form->submit($request->request->all(), false /* Do not clear missing data */);
    
    if ($form->isValid()) {
        ...
    }
}

The annotation in depth

The @Formable() annotation follows the Symfony\Component\Form\FormBuilderInterface interface.

ARGUMENTS:

  • name: [string] the field name
  • dataType: [string] the FormType
  • options: [array] the FormType options
    /**
     * @Formable(name="date", dataType="date", options={
     *   "format"= IntlDateFormatter::MEDIUM,
     *   "days" = {1,2,3,4}
     * })
     */
    public $date;

Installation

composer require trt/formable

// Register the Bundle

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            ...
            new \Formable\Bundle\FormableBundle(),
        );

        return $bundles;
    }

}

Run tests

bin/test