<?php declare(strict_types=1); namespace App\Controller; use App\Exception\InvalidColorException; use App\Form\ColorType; use App\Model\ColorVo; use App\Model\ParentModel; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\DataMapperInterface; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Type; class TestHeahdudeController extends AbstractController { /** * @Route("/test-heahdude", name="test_heah_form") */ public function index(FormFactoryInterface $formFactory) { $form = $formFactory->createNamedBuilder('', FormType::class, null, [ 'data_class' => ParentModel::class, 'empty_data' => null, //function () { return new ParentModel('', new ColorVo('foo')); } ]) ->setDataMapper(new class implements DataMapperInterface { public function mapDataToForms($viewData, iterable $forms) { if ($viewData === null) { return; } $forms = iterator_to_array($forms); $forms['color']->setData($viewData->getColor()); $forms['content']->setData($viewData->getContent()); } public function mapFormsToData(iterable $forms, &$viewData) { $forms = iterator_to_array($forms); try { $viewData = new ParentModel($forms['content']->getData(), new ColorVo($forms['color']->getData())); // Catching all potential exception will result in null data in the form, which is ok. } catch (InvalidColorException $error) {} catch (\TypeError $error) {} } }) ->add('color', ColorType::class, [ // Those constraints will act on form data, not view data. The form data remains not altered if there // is an exception while processing the datamapper. 'constraints' => [ new Type(['type' => 'string']), new Callback(['callback' => ColorVo::class . '::validateColor']) ] ]) ->add('content', TextType::class) ->getForm(); $form->submit(['color' => 10, 'content' => 'foobar']); return $this->json([ 'message' => 'Welcome to your new controller!', 'path' => 'src/Controller/TestVoFormController.php', ]); } }