src/CoreBundle/Form/JsFormValidatorFactory.php line 68

Open in your IDE?
  1. <?php
  2. namespace App\CoreBundle\Form;
  3. use Fp\JsFormValidatorBundle\Factory\JsFormValidatorFactory as BaseJsFormValidatorFactory;
  4. use Fp\JsFormValidatorBundle\Model\JsFormElement;
  5. use JsonSerializable;
  6. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  7. use Symfony\Component\Form\Form;
  8. use Symfony\Component\Form\FormInterface;
  9. use Symfony\Component\Routing\Exception\RouteNotFoundException;
  10. use Symfony\Component\Validator\Constraint;
  11. use Symfony\Component\Validator\Constraints;
  12. class JsFormValidatorFactory extends BaseJsFormValidatorFactory
  13. {
  14.     /**
  15.      * @param array $constraints
  16.      * @return array
  17.      */
  18.     protected function parseConstraints(array $constraints)
  19.     {
  20.         $result parent::parseConstraints($constraints);
  21.         foreach ($result as $items) {
  22.             foreach ($items as $item) {
  23.                 if ($item instanceof Constraints\All) {
  24.                     $item->constraints $this->parseConstraints($item->constraints);
  25.                 }
  26.             }
  27.         }
  28.         return $result;
  29.     }
  30.     /**
  31.      * @param \Symfony\Component\Form\FormInterface $form
  32.      * @param array $viewTransformers
  33.      *
  34.      * @return array
  35.      */
  36.     protected function normalizeViewTransformers(FormInterface $form, array $viewTransformers)
  37.     {
  38.         $config $form->getConfig();
  39.         // Choice(s)ToBooleanArrayTransformer was deprecated in SF2.7 in favor of CheckboxListMapper and RadioListMapper
  40.         if ($config->getType()->getInnerType() instanceof ChoiceType && $config->getOption('expanded')) {
  41.             $namespace 'Symfony\Component\Form\Extension\Core\DataTransformer\\';
  42.             $transformer $config->getOption('multiple')
  43.                 ? ['name' => $namespace 'ChoicesToBooleanArrayTransformer']
  44.                 : ['name' => $namespace 'ChoiceToBooleanArrayTransformer'];
  45.             $transformer['choiceList'] = [];
  46.             foreach ($config->getOption('choices') as $formOptionChoiceItem) {
  47.                 $transformer['choiceList'][] = $formOptionChoiceItem;
  48.             }
  49.             array_unshift($viewTransformers$transformer);
  50.         }
  51.         return $viewTransformers;
  52.     }
  53.     /**
  54.      * @param \Symfony\Component\Form\Form $form
  55.      * @return \Fp\JsFormValidatorBundle\Model\JsFormElement|null
  56.      */
  57.     public function createJsModel(Form $form)
  58.     {
  59.         /** @var \Symfony\Component\Form\Form|null $prototype */
  60.         $prototype $form->getConfig()->getAttribute('prototype');
  61.         if ($prototype !== null && $prototype->getParent() === null) {
  62.             $prototype->setParent($form);
  63.         }
  64.         $model parent::createJsModel($form);
  65.         if ($model !== null) {
  66.             $this->jsonSerializeValuesInAllConstraints($model);
  67.         }
  68.         return $model;
  69.     }
  70.     /**
  71.      * @param string $route
  72.      * @return string
  73.      */
  74.     protected function generateUrl($route)
  75.     {
  76.         if ($route === 'fp_js_form_validator.check_unique_entity') {
  77.             $message 'Unable to generate a URL for the named route "' $route '" as such route was removed as unsafe.';
  78.             throw new RouteNotFoundException($message);
  79.         }
  80.         return parent::generateUrl($route);
  81.     }
  82.     /**
  83.      * Method searches for all Constraints and serializes all their values implementing JsonSerializable
  84.      * (eg. $min and $max in {@see \App\ScraperBundle\Form\Constraints\MoneyRange}) because
  85.      * {@see \Fp\JsFormValidatorBundle\Model\JsModelAbstract::phpValueToJs()} does not support JsonSerializable objects
  86.      *
  87.      * Method does not modify the original Constraint objects (it clones all the Constraints)
  88.      *
  89.      * @param \Fp\JsFormValidatorBundle\Model\JsFormElement $model
  90.      */
  91.     protected function jsonSerializeValuesInAllConstraints(JsFormElement $model): void
  92.     {
  93.         if (isset($model->data['form']['constraints'])) {
  94.             foreach ($model->data['form']['constraints'] as $constraintName => $constraintSet) {
  95.                 foreach ($constraintSet as $key => $constraint) {
  96.                     $model->data['form']['constraints'][$constraintName][$key] = $this->jsonSerializeConstraintValues($constraint);
  97.                 }
  98.             }
  99.         }
  100.     }
  101.     /**
  102.      * @param \Symfony\Component\Validator\Constraint $constraint
  103.      * @return \Symfony\Component\Validator\Constraint
  104.      */
  105.     protected function jsonSerializeConstraintValues(Constraint $constraint): Constraint
  106.     {
  107.         $constraint = clone $constraint;
  108.         foreach ($constraint as $name => $value) {
  109.             if ($value instanceof JsonSerializable) {
  110.                 $constraint->$name $value->jsonSerialize();
  111.             }
  112.         }
  113.         return $constraint;
  114.     }
  115. }