src/Service/JsonFormManager.php line 28

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\Contracts\FormInterface;
  4. use App\Entity\Form;
  5. use App\Entity\MasterForm;
  6. use App\Form\CollectionJsonType;
  7. use App\Validator\UniqueLeadDataBy;
  8. use DateTime;
  9. use Exception;
  10. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  11. use Symfony\Component\Filesystem\Exception\FileNotFoundException;
  12. use Symfony\Component\Filesystem\Filesystem;
  13. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  14. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  15. use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
  16. use Symfony\Component\Form\Extension\Core\Type\DateType;
  17. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  18. use Symfony\Component\Form\Extension\Core\Type\FormType;
  19. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  20. use Symfony\Component\Form\Extension\Core\Type\NumberType;
  21. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  22. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  23. use Symfony\Component\Form\Extension\Core\Type\TextType;
  24. use Symfony\Component\Validator\Validator\ValidatorInterface;
  25. class JsonFormManager
  26. {
  27.     /** @var Filesystem $filesystem */
  28.     private $filesystem;
  29.     /** @var array $formDefinition */
  30.     private $formDefinition;
  31.     /** @var ParameterBagInterface $params */
  32.     private $params;
  33.     /** @var ValidatorInterface $validator */
  34.     private $validator;
  35.     /** @var Form $form */
  36.     private $form;
  37.     /** @var array $queryParams */
  38.     private $queryParams = [];
  39.     public const FOLDER_NAME 'forms';
  40.     public const GROUP_TYPE 'group';
  41.     public const TEXT_TYPE 'text';
  42.     public const TEXTAREA_TYPE 'textarea';
  43.     public const EMAIL_TYPE 'email';
  44.     public const NUMBER_TYPE 'number';
  45.     public const SELECT_TYPE 'select';
  46.     public const CHECKBOX_TYPE 'checkbox';
  47.     public const RADIO_TYPE 'radio';
  48.     public const DATE_TYPE 'date';
  49.     public const DATETIME_TYPE 'datetime';
  50.     public const HIDDEN_TYPE 'hidden';
  51.     public const COLLECTION_TYPE 'collection';
  52.     public const SUBMIT_TYPE 'submit';
  53.     public const SUPPORTED_TYPES = [
  54.         self::GROUP_TYPE,
  55.         self::TEXT_TYPE,
  56.         self::TEXTAREA_TYPE,
  57.         self::EMAIL_TYPE,
  58.         self::NUMBER_TYPE,
  59.         self::SELECT_TYPE,
  60.         self::CHECKBOX_TYPE,
  61.         self::RADIO_TYPE,
  62.         self::DATE_TYPE,
  63.         self::DATETIME_TYPE,
  64.         self::HIDDEN_TYPE,
  65.         self::COLLECTION_TYPE,
  66.         self::SUBMIT_TYPE
  67.     ];
  68.     public const SELECTABLE_TYPES = [
  69.         self::SELECT_TYPE,
  70.         self::CHECKBOX_TYPE,
  71.         self::RADIO_TYPE
  72.     ];
  73.     public const ADDABLE_TYPES = [
  74.         self::TEXT_TYPE => self::TEXT_TYPE,
  75.         self::TEXTAREA_TYPE => self::TEXTAREA_TYPE,
  76.         self::EMAIL_TYPE => self::EMAIL_TYPE,
  77.         self::NUMBER_TYPE => self::NUMBER_TYPE,
  78.         // TODO
  79.         // self::SELECT_TYPE => self::SELECT_TYPE,
  80.         // self::CHECKBOX_TYPE => self::CHECKBOX_TYPE,
  81.         // self::RADIO_TYPE => self::RADIO_TYPE,
  82.         self::DATE_TYPE => self::DATE_TYPE,
  83.         self::DATETIME_TYPE => self::DATETIME_TYPE,
  84.         self::HIDDEN_TYPE => self::HIDDEN_TYPE
  85.     ];
  86.     public const VALUABLE_TYPES = [
  87.         self::TEXT_TYPE => self::TEXT_TYPE,
  88.         self::TEXTAREA_TYPE => self::TEXTAREA_TYPE,
  89.         self::EMAIL_TYPE => self::EMAIL_TYPE,
  90.         self::NUMBER_TYPE => self::NUMBER_TYPE,
  91.         self::SELECT_TYPE => self::SELECT_TYPE,
  92.         self::CHECKBOX_TYPE => self::CHECKBOX_TYPE,
  93.         self::RADIO_TYPE => self::RADIO_TYPE,
  94.         self::DATE_TYPE => self::DATE_TYPE,
  95.         self::DATETIME_TYPE => self::DATETIME_TYPE,
  96.         self::HIDDEN_TYPE => self::HIDDEN_TYPE
  97.     ];
  98.     // Delimiters
  99.     public const FIELDNAME_DELIMITER '_';
  100.     public const CHECKBOX_VIEW_DELIMITER ' | ';
  101.     public const INCOMPATIBLE_FIELD_DELIMITER '__';
  102.     /**
  103.      * @param Filesystem $filesystem
  104.      * @param ParameterBagInterface $params
  105.      * @param ValidatorInterface $validator
  106.      */
  107.     public function __construct(Filesystem $filesystemParameterBagInterface $paramsValidatorInterface $validator)
  108.     {
  109.         $this->filesystem $filesystem;
  110.         $this->params $params;
  111.         $this->validator $validator;
  112.     }
  113.     /**
  114.      * @return FormInterface|null
  115.      */
  116.     public function getForm(): ?FormInterface
  117.     {
  118.         return $this->form;
  119.     }
  120.     /**
  121.      * @param FormInterface $form
  122.      * @return self
  123.      */
  124.     public function setForm(FormInterface $form): self
  125.     {
  126.         $this->form $form;
  127.         return $this;
  128.     }
  129.     /**
  130.      * @param array $queryParams
  131.      * @return $this
  132.      */
  133.     public function setQueryParams(array $queryParams): self
  134.     {
  135.         $this->queryParams $queryParams;
  136.         return $this;
  137.     }
  138.     /**
  139.      * @param string $filePath
  140.      * @return $this
  141.      */
  142.     public function loadFromFilePath(string $filePath): JsonFormManager
  143.     {
  144.         $filePath $this->getBasePath() . "/" $filePath;
  145.         if (!$this->filesystem->exists($filePath)) {
  146.             throw new FileNotFoundException();
  147.         }
  148.         $this->formDefinition json_decode(file_get_contents($filePath), true);
  149.         if ($this->form instanceof MasterForm) {
  150.             return $this;
  151.         }
  152.         if ($formFieldAddings $this->form->getFormFieldAddings()) {
  153.             foreach ($formFieldAddings as $adding) {
  154.                 // TODO group 0 only
  155.                 $this->formDefinition[0]['fields'][] = [
  156.                     'type' => $adding->getType(),
  157.                     'common' => [
  158.                         'name' => $adding->getName(),
  159.                         'label' => $adding->getLabel()
  160.                     ],
  161.                     'attr' => [],
  162.                     'constraints' => []
  163.                 ];
  164.             }
  165.         }
  166.         $this->addFieldToDefinition();
  167.         return $this;
  168.     }
  169.     public function getFromFormLead(Type $var null)
  170.     {
  171.         # code...
  172.     }
  173.     /**
  174.      * @return array|array[]
  175.      * @throws Exception
  176.      */
  177.     public function getFormDefinition(): array
  178.     {
  179.         if (!$this->formDefinition) {
  180.             throw new Exception('No se puede obtener la definición del formulario sin cargar antes el archvo de definición');
  181.         }
  182.         return array_map(function($value) {
  183.             return $this->buildFormItem($value);
  184.         }, $this->formDefinition);
  185.     }
  186.     /**
  187.      * @param array $formItem
  188.      * @return array
  189.      * @throws Exception
  190.      */
  191.     private function buildFormItem(array $formItem): array
  192.     {
  193.         if (!$this->formTypeIsSupported($formItem['type'])) {
  194.             throw new Exception(sprintf('El tipo %s no está soportado'$formItem['type']));
  195.         }
  196.         if ($formItem['type'] == self::GROUP_TYPE) {
  197.             $nativeFields = [];
  198.             foreach ($formItem['fields'] as $formSubItem) {
  199.                 $nativeFields[] = $this->buildFormItem($formSubItem);
  200.             }
  201.             return [
  202.                 'name' =>  $formItem['name'],
  203.                 'class' => FormType::class,
  204.                 'options' => [
  205.                     'label' => $formItem['title'],
  206.                     'inherit_data' => true
  207.                 ],
  208.                 'fields' => $nativeFields,
  209.                 'attr' => isset($formItem['attr']) ? $formItem['attr'] : []
  210.             ];
  211.         }
  212.         return $this->configureNativeFormItemByType($this->buildNativeFormItem($formItem), $formItem);
  213.     }
  214.     /**
  215.      * @param array $formItem
  216.      * @return array
  217.      * @throws Exception
  218.      */
  219.     private function buildNativeFormItem(array $formItem): array
  220.     {
  221.         $nativeFormItem = [
  222.             'name' =>  self::buildFieldName($formItem['common']['name'], $formItem['type']),
  223.             'options' => [
  224.                 'label' => $formItem['common']['label'],
  225.                 'attr' => $formItem['attr'],
  226.                 'label_html' => true
  227.             ]
  228.         ];
  229.         if (isset($formItem['common']['help'])) {
  230.             $nativeFormItem['options']['help'] = $formItem['common']['help'];
  231.         }
  232.         if (isset($formItem['attr']['disabled'])) {
  233.             $nativeFormItem['options']['disabled'] = $formItem['attr']['disabled'];
  234.         }
  235.         if (isset($formItem['constraints']['required'])) {
  236.             $nativeFormItem['options']['required'] = $formItem['constraints']['required'];
  237.         }
  238.         // Check if persist field
  239.         if (isset($formItem['bind'])) {
  240.             $nativeFormItem['options']['attr']['bind'] = $formItem['bind'];
  241.         }
  242.         // Check if unique
  243.         if (isset($formItem['constraints']['unique'])) {
  244.             $nativeFormItem['options']['attr']['unique'] = $formItem['constraints']['unique'];
  245.         }
  246.         if (self::COLLECTION_TYPE === $formItem['type']) {
  247.             $nativeFormItem $this->buildNativeCollection($nativeFormItem$formItem);
  248.         }
  249.         // Constraints
  250.         $nativeFormItem $this->buildConstraints($nativeFormItem$formItem);
  251.         // Conditioned fields
  252.         return $this->getConditionedFields($nativeFormItem$formItem);
  253.     }
  254.     /**
  255.      * @param array $nativeFormItem
  256.      * @param array $formItem
  257.      * @return array
  258.      * @throws Exception
  259.      */
  260.     private function buildNativeCollection(array $nativeFormItem, array $formItem): array
  261.     {
  262.         // Min number of elements (for type collections)
  263.         if (isset($formItem['constraints']['min_items'])) {
  264.             if (!is_numeric($formItem['constraints']['min_items'])) {
  265.                 throw new Exception($formItem['constraints']['min_items'] . ' debe ser un número entero');
  266.             }
  267.             $nativeFormItem['options']['attr']['min_items'] = $formItem['constraints']['min_items'];
  268.         }
  269.         // Max number of elements (for type collections)
  270.         if (isset($formItem['constraints']['max_items'])) {
  271.             if (!is_numeric($formItem['constraints']['max_items'])) {
  272.                 throw new Exception($formItem['constraints']['max_items'] . ' debe ser un número entero');
  273.             }
  274.             $nativeFormItem['options']['attr']['max_items'] = $formItem['constraints']['max_items'];
  275.         }
  276.         // Add label text (for type collections)
  277.         if (isset($formItem['constraints']['add_label'])) {
  278.             if (!is_string($formItem['constraints']['add_label'])) {
  279.                 throw new Exception($formItem['constraints']['add_label'] . ' debe ser texto');
  280.             }
  281.             $nativeFormItem['options']['attr']['add_label'] = $formItem['constraints']['add_label'];
  282.         }
  283.         // Remove label text (for type collections)
  284.         if (isset($formItem['constraints']['remove_label'])) {
  285.             if (!is_string($formItem['constraints']['remove_label'])) {
  286.                 throw new Exception($formItem['constraints']['remove_label'] . ' debe ser texto');
  287.             }
  288.             $nativeFormItem['options']['attr']['remove_label'] = $formItem['constraints']['remove_label'];
  289.         }
  290.         return $nativeFormItem;
  291.     }
  292.     /**
  293.      * @param array $nativeFormItem
  294.      * @param array $formItem
  295.      * @return array
  296.      * @throws Exception
  297.      */
  298.     private function configureNativeFormItemByType(array $nativeFormItem, array $formItem): array
  299.     {
  300.         switch ($formItem['type']) {
  301.             case self::TEXT_TYPE:
  302.                 $nativeFormItem['class'] = TextType::class;
  303.                 break;
  304.             case self::TEXTAREA_TYPE:
  305.                 $nativeFormItem['class'] = TextareaType::class;
  306.                 break;
  307.             case self::EMAIL_TYPE:
  308.                 $nativeFormItem['class'] = EmailType::class;
  309.                 break;
  310.             case self::NUMBER_TYPE:
  311.                 $nativeFormItem['options']['html5'] = true;
  312.                 $nativeFormItem['class'] = NumberType::class;
  313.                 break;
  314.             case self::SELECT_TYPE:
  315.                 $nativeFormItem['options']['choices'] = $this->buildFieldOptions($formItem['choices']);
  316.                 if (isset($formItem['attr']['value'])) {
  317.                     $nativeFormItem['options']['data'] = $formItem['attr']['value'];
  318.                 }
  319.                 $nativeFormItem['class'] = ChoiceType::class;
  320.                 break;
  321.             case self::CHECKBOX_TYPE:
  322.                 $nativeFormItem['options']['expanded'] = true;
  323.                 $nativeFormItem['options']['multiple'] = true;
  324.                 $nativeFormItem['options']['choices'] = $this->buildFieldOptions($formItem['choices']);
  325.                 $data = [];
  326.                 foreach ($formItem['choices'] as $choice) {
  327.                     if (isset($choice['checked']) && $choice['checked']) {
  328.                         $data[$choice['label']] = $choice['value'];
  329.                     }
  330.                 }
  331.                 if (!empty($data)) {
  332.                     $nativeFormItem['options']['data'] = $data;
  333.                 }
  334.                 $nativeFormItem['class'] = ChoiceType::class;
  335.                 break;
  336.             case self::RADIO_TYPE:
  337.                 $nativeFormItem['options']['expanded'] = true;
  338.                 $nativeFormItem['options']['multiple'] = false;
  339.                 $nativeFormItem['options']['choices'] = $this->buildFieldOptions($formItem['choices']);
  340.                 if (isset($formItem['attr']['value'])) {
  341.                     $nativeFormItem['options']['data'] = $formItem['attr']['value'];
  342.                 }
  343.                 $nativeFormItem['class'] = ChoiceType::class;
  344.                 break;
  345.             case self::DATE_TYPE:
  346.                 $nativeFormItem['options']['widget'] = 'single_text';
  347.                 $nativeFormItem['options']['html5'] = true;
  348.                 $nativeFormItem['class'] = DateType::class;
  349.                 break;
  350.             case self::DATETIME_TYPE:
  351.                 $nativeFormItem['options']['widget'] = 'single_text';
  352.                 $nativeFormItem['options']['html5'] = true;
  353.                 $nativeFormItem['class'] = DateTimeType::class;
  354.                 break;
  355.             case self::HIDDEN_TYPE:
  356.                 $nativeFormItem['class'] = HiddenType::class;
  357.                 if (isset($formItem['attr']['value'])) {
  358.                     $nativeFormItem['options']['data'] = $formItem['attr']['value'];
  359.                 }
  360.                 break;
  361.             case self::COLLECTION_TYPE:
  362.                 $items = [];
  363.                 foreach ($formItem['items'] as $item) {
  364.                     $items[] = $this->buildFormItem($item);
  365.                 }
  366.                 $nativeFormItem['class'] = CollectionType::class;
  367.                 $nativeFormItem['options']['entry_type'] = CollectionJsonType::class;
  368.                 $nativeFormItem['options']['entry_options'] = ['collection' => $items];
  369.                 $nativeFormItem['options']['allow_add'] = true;
  370.                 $nativeFormItem['options']['allow_delete'] = true;
  371.                 break;
  372.             case self::SUBMIT_TYPE:
  373.                 $nativeFormItem['class'] = SubmitType::class;
  374.                 break;
  375.             default:
  376.                 break;
  377.         }
  378.         return $nativeFormItem;
  379.     }
  380.     /**
  381.      * @param string $type
  382.      * @return bool
  383.      */
  384.     public static function formTypeIsSupported(string $type): bool
  385.     {
  386.         return in_array($typeself::SUPPORTED_TYPES);
  387.     }
  388.     /**
  389.      * @param array $choices
  390.      * @param bool $fieldIsRequired
  391.      * @return array
  392.      */
  393.     private function buildFieldOptions(array $choicesbool $fieldIsRequired false): array
  394.     {
  395.         $nativeChoices = [];
  396.         foreach ($choices as $choice) {
  397.             $nativeChoices[$choice['label']] = $choice['value'];
  398.         }
  399.         return $nativeChoices;
  400.     }
  401.     /**
  402.      * @param string $fieldName
  403.      * @param $fieldValue
  404.      * @return string
  405.      * @throws Exception
  406.      */
  407.     public static function formFieldResponseToDb(string $fieldName$fieldValue): string
  408.     {
  409.         $type self::getTypeFromFieldName($fieldName);
  410.         if (!self::formTypeIsSupported($type)) {
  411.             throw new Exception(sprintf('El tipo %s no está soportado'$type));
  412.         }
  413.         switch ($type) {
  414.             case self::TEXT_TYPE:
  415.             case self::TEXTAREA_TYPE:
  416.             case self::EMAIL_TYPE:
  417.             case self::SELECT_TYPE:
  418.             case self::RADIO_TYPE:
  419.                 return $fieldValue;
  420.             case self::NUMBER_TYPE:
  421.                 return (str_replace(',''.'$fieldValue));
  422.             case self::CHECKBOX_TYPE:
  423.                 return serialize($fieldValue);
  424.             case self::DATE_TYPE:
  425.                 return $fieldValue->format('Y-m-d');
  426.             case self::DATETIME_TYPE:
  427.                 return $fieldValue->format('Y-m-d H:i:s');
  428.             default:
  429.                 break;
  430.         }
  431.         return $fieldValue;
  432.     }
  433.     /**
  434.      * @param $field
  435.      * @param $type
  436.      * @return string
  437.      * @throws Exception
  438.      */
  439.     public static function formFieldDbItemToPrint($field$type): string
  440.     {
  441.         if (!self::formTypeIsSupported($type)) {
  442.             throw new Exception(sprintf('El tipo %s no está soportado'$type));
  443.         }
  444.         switch ($type) {
  445.             case self::TEXT_TYPE:
  446.             case self::TEXTAREA_TYPE:
  447.             case self::EMAIL_TYPE:
  448.             case self::SELECT_TYPE:
  449.             case self::RADIO_TYPE:
  450.                 return $field;
  451.             case self::NUMBER_TYPE:
  452.                 return str_replace("."","$field);
  453.             case self::CHECKBOX_TYPE:
  454.                 $unserialize unserialize($field);
  455.                 if (is_string($unserialize) || $field === "") {
  456.                     return $unserialize;
  457.                 }
  458.                 return implode(self::CHECKBOX_VIEW_DELIMITER$unserialize);
  459.             case self::DATE_TYPE:
  460.                 return (new DateTime($field))->format('d-m-Y');
  461.             case self::DATETIME_TYPE:
  462.                 return (new DateTime($field))->format('d-m-Y H:i');
  463.             default:
  464.                 break;
  465.         }
  466.         return $field;
  467.     }
  468.     /**
  469.      * @param string $fieldName
  470.      * @return string
  471.      */
  472.     public static function getNameFromFieldName(string $fieldName): string
  473.     {
  474.         return self::explodeFieldName($fieldName0);
  475.     }
  476.     /**
  477.      * @param string $fieldName
  478.      * @return string
  479.      */
  480.     public static function getTypeFromFieldName(string $fieldName): string
  481.     {
  482.         return self::explodeFieldName($fieldName1);
  483.     }
  484.     /**
  485.      * @return array
  486.      * @throws Exception
  487.      */
  488.     public function getFormDefinitionFields(): array
  489.     {
  490.         $result = [];
  491.         foreach ($this->getFormDefinition() as $item) {
  492.             if (!$this->formItemIsGroup($item)) {
  493.                 // Is field
  494.                 $result[] = $item;
  495.                 continue;
  496.             }
  497.             foreach ($item['fields'] as $field) {
  498.                 $result[] = $field;
  499.             }
  500.         }
  501.         return $result;
  502.     }
  503.     /**
  504.      * @param array $formData
  505.      * @param array $formDefinitionFields
  506.      * @return array
  507.      */
  508.     public function getFormDataInFormDefinitionFields(array $formData, array $formDefinitionFields): array
  509.     {
  510.         foreach ($formData as $key => $value) {
  511.             foreach ($formDefinitionFields as $field) {
  512.                 if ($field['name'] !== $key) {
  513.                     continue;
  514.                 }
  515.                 // TODO: hardcoded
  516.                 $formData $this->processPayment($formData$field$key$value);
  517.                 // Check not binding fields
  518.                 if (isset($field['options']['attr']['bind']) && !$field['options']['attr']['bind']) {
  519.                     unset($formData[$key]);
  520.                 }
  521.             }
  522.         }
  523.         return $formData;
  524.     }
  525.     /**
  526.      * @param string $incompatibleValueString
  527.      * @return mixed|string
  528.      */
  529.     public function getIncompatibleGroup(string $incompatibleValueString)
  530.     {
  531.         return $this->getExplodedIncompatibleField($incompatibleValueString)[0];
  532.     }
  533.     /**
  534.      * @param string $incompatibleValueString
  535.      * @return false|string[]
  536.      */
  537.     public function getExplodedIncompatibleField(string $incompatibleValueString)
  538.     {
  539.         return explode(self::INCOMPATIBLE_FIELD_DELIMITER$incompatibleValueString);
  540.     }
  541.     /**
  542.      * @param string $value
  543.      * @return string
  544.      */
  545.     public static function unFormattedHtml(string $value): string
  546.     {
  547.         return $value != strip_tags($value) ? strip_tags($value) : $value;
  548.     }
  549.     /**
  550.      * @param array $formItem
  551.      * @return bool
  552.      */
  553.     private function formItemIsGroup(array $formItem): bool
  554.     {
  555.         return isset($formItem['fields']);
  556.     }
  557.     /**
  558.      * @param array $nativeFormItem
  559.      * @param array $formItem
  560.      * @return array
  561.      * @throws Exception
  562.      */
  563.     private function buildConstraints(array $nativeFormItem, array $formItem): array
  564.     {
  565.         if (
  566.             !isset($formItem['constraints']['validators']) &&
  567.             !isset($formItem['constraints']['unique_by']) &&
  568.             !isset($formItem['constraints']['incompatible_with'])
  569.         ) {
  570.             return $nativeFormItem;
  571.         }
  572.         if (isset($formItem['constraints']['unique_by'])) {
  573.             $nativeFormItem $this->buildConstraintUniqueBy($nativeFormItem$formItem);
  574.         }
  575.         if (isset($formItem['constraints']['incompatible_with'])) {
  576.             $nativeFormItem $this->buildIncompatibleField($nativeFormItem$formItem);
  577.         }
  578.         if (isset($formItem['constraints']['validators'])) {
  579.             $nativeFormItem $this->buildConstraintValidators($nativeFormItem$formItem);
  580.         }
  581.         return $nativeFormItem;
  582.     }
  583.     /**
  584.      * @param array $nativeFormItem
  585.      * @param array $formItem
  586.      * @return array
  587.      */
  588.     private function buildConstraintUniqueBy(array $nativeFormItem, array $formItem): array
  589.     {
  590.         $entity null;
  591.         $campaign $this->getForm()->getCampaign();
  592.         $company $campaign->getCompany();
  593.         switch ($formItem['constraints']['unique_by']) {
  594.             case $this->getForm()->getCampaign()->getClass():
  595.                 $entity $campaign;
  596.                 break;
  597.             case $this->getForm()->getCampaign()->getCompany()->getClass():
  598.                 $entity $company;
  599.         }
  600.         $nativeFormItem['options']['constraints'][] = new UniqueLeadDataBy(['entity' => $entity]);
  601.         return $nativeFormItem;
  602.     }
  603.     /**
  604.      * @param array $nativeFormItem
  605.      * @param array $formItem
  606.      * @return array
  607.      */
  608.     private function buildIncompatibleField(array $nativeFormItem, array $formItem): array
  609.     {
  610.         $indexes = ['group''name''type'];
  611.         foreach ($formItem['constraints']['incompatible_with'] as $key => $value) {
  612.             $value '';
  613.             foreach ($indexes as $index) {
  614.                 $value .= $formItem['constraints']['incompatible_with'][$key][$index] . self::INCOMPATIBLE_FIELD_DELIMITER;
  615.             }
  616.             $nativeFormItem['options']['attr']["incompatible-with-$key"] = substr(
  617.                 $value,
  618.                 0,
  619.                 -strlen(self::INCOMPATIBLE_FIELD_DELIMITER)
  620.             );
  621.         }
  622.         return $nativeFormItem;
  623.     }
  624.     /**
  625.      * @param array $nativeFormItem
  626.      * @param array $formItem
  627.      * @return array
  628.      * @throws Exception
  629.      */
  630.     private function buildConstraintValidators(array $nativeFormItem, array $formItem): array
  631.     {
  632.         foreach ($formItem['constraints']['validators'] as $validator => $params) {
  633.             $validatorNamespaces = [
  634.                 'App\Validator',
  635.                 '\Symfony\Component\Validator\Constraints'
  636.             ];
  637.             $className null;
  638.             foreach ($validatorNamespaces as $validatorNamespace) {
  639.                 $className $validatorNamespace '\\' $validator;
  640.                 if ($this->validator->hasMetadataFor($className)) {
  641.                     break;
  642.                 }
  643.             }
  644.             if (!$className) {
  645.                 throw new Exception();
  646.             }
  647.             if (!empty($params)) {
  648.                 $nativeFormItem['options']['constraints'][] = new $className($params);
  649.             } else {
  650.                 $nativeFormItem['options']['constraints'][] = new $className();
  651.             }
  652.         }
  653.         return $nativeFormItem;
  654.     }
  655.     /**
  656.      * @param string $fieldName
  657.      * @param int $index
  658.      * @return string
  659.      */
  660.     private static function explodeFieldName(string $fieldNameint $index): string
  661.     {
  662.         return explode(self::FIELDNAME_DELIMITER$fieldName)[$index];
  663.     }
  664.     /**
  665.      * @param string $name
  666.      * @param string $type
  667.      * @return string
  668.      */
  669.     public static function buildFieldName(string $namestring $type): string
  670.     {
  671.         return $name self::FIELDNAME_DELIMITER $type;
  672.     }
  673.     /**
  674.      * @param string $name
  675.      * @param string $type
  676.      * @param string $label
  677.      * @param string $groupLabel
  678.      * @return string
  679.      */
  680.     public static function buildFieldIndexLabel(string $namestring $typestring $labelstring $groupLabel): string
  681.     {
  682.         return
  683.             $name self::FIELDNAME_DELIMITER .
  684.             $type self::FIELDNAME_DELIMITER .
  685.             self::unFormattedHtml($label) . self::FIELDNAME_DELIMITER .
  686.             self::unFormattedHtml($groupLabel);
  687.     }
  688.     /**
  689.      * @return array
  690.      * @throws Exception
  691.      */
  692.     public function buildCsvHeader(): array
  693.     {
  694.         $result = [];
  695.         foreach ($this->getFormDefinition() as $item) {
  696.             if (!$this->formItemIsGroup($item)) {
  697.                 // Is field
  698.                 continue;
  699.             }
  700.             $groupLabel $item['options']['label'] ?? '';
  701.             foreach ($item['fields'] as $field) {
  702.                 $index $field['name'];
  703.                 $result[$index]['label'] = $field['options']['label'];
  704.                 $result[$index]['group_label'] = $groupLabel;
  705.             }
  706.         }
  707.         return $result;
  708.     }
  709.     /**
  710.      * @return string
  711.      */
  712.     public function getBasePath(): string
  713.     {
  714.         return $this->params->get('kernel.project_dir') . "/" self::FOLDER_NAME;
  715.     }
  716.     public function getOrderedJsonFields() 
  717.     {
  718.         $path $this->getBasePath() . '/order.json';
  719.         $jsonContent file_get_contents($path);
  720.         $data json_decode($jsonContenttrue);
  721.         return $data;
  722.     }
  723.     /**
  724.      * @param array $nativeFormItem
  725.      * @param array $formItem
  726.      * @return array
  727.      */
  728.     private function getConditionedFields(array $nativeFormItem, array $formItem): array
  729.     {
  730.         if (!in_array($formItem['type'], self::SELECTABLE_TYPES)) {
  731.             return $nativeFormItem;
  732.         }
  733.         if (!isset($formItem['choices'])) {
  734.             return $nativeFormItem;
  735.         }
  736.         $conditionedFields = [];
  737.         foreach ($formItem['choices'] as $keyChoice => $choice) {
  738.             if (!isset($choice['conditional_on']) || !$choice['conditional_on']) {
  739.                 continue;
  740.             }
  741.             $conditionedFields[$keyChoice]['parent_value'] = $choice['value'];
  742.             foreach ($choice['conditional_on'] as $key => $item) {
  743.                 $conditionedFields[$keyChoice]['conditioned_fields'][$key] = $item;
  744.                 $conditionedFields[$keyChoice]['conditioned_fields'][$key]['field_name'] = self::buildNativeFieldName(
  745.                     isset($this->findFieldGroup($formItem)['name']) ? $this->findFieldGroup($formItem)['name'] : '',
  746.                     $item['field']['name'],
  747.                     $item['field']['type']
  748.                 );
  749.                 unset($conditionedFields[$keyChoice]['conditioned_fields'][$key]['field']);
  750.             }
  751.         }
  752.         if (!empty($conditionedFields)) {
  753.             $nativeFormItem['options']['attr']['data-conditioned-fields'] = json_encode($conditionedFieldstrue);
  754.         }
  755.         return $nativeFormItem;
  756.     }
  757.     /**
  758.      * @param array $formItem
  759.      * @return array|mixed|void
  760.      */
  761.     private function findFieldGroup(array $formItem)
  762.     {
  763.         foreach ($this->formDefinition as $group) {
  764.             if (!$this->formItemIsGroup($group)) {
  765.                 continue;
  766.             }
  767.             foreach ($group['fields'] as $field) {
  768.                 if ($field['type'] === $formItem['type'] && $field['common']['name'] === $formItem['common']['name']) {
  769.                     return $group;
  770.                 }
  771.             }
  772.         }
  773.         return [];
  774.     }
  775.     /**
  776.      * @param string $groupName
  777.      * @param string $name
  778.      * @param string $type
  779.      * @return string
  780.      */
  781.     private function buildNativeFieldName(string $groupNamestring $namestring $type): string
  782.     {
  783.         return 'json_' $groupName self::FIELDNAME_DELIMITER self::buildFieldName($name$type);
  784.     }
  785.     /**
  786.      * @return void
  787.      */
  788.     private function addFieldToDefinition()
  789.     {
  790.         if (!$this->queryParams) {
  791.             return;
  792.         }
  793.         foreach ($this->queryParams as $key => $param) {
  794.             foreach ($this->formDefinition as $keyGroup => $group) {
  795.                 if (!$this->formItemIsGroup($group)) {
  796.                     continue;
  797.                 }
  798.                 foreach ($group['fields'] as $keyField => $field) {
  799.                     if ($key !== $field['common']['name']) {
  800.                         continue;
  801.                     }
  802.                     $value null;
  803.                     $readOnly false;
  804.                     switch ($field['type']) {
  805.                         case self::EMAIL_TYPE:
  806.                         case self::TEXT_TYPE:
  807.                         case self::NUMBER_TYPE:
  808.                             $value $param;
  809.                             $readOnly true;
  810.                         break;
  811.                         case self::HIDDEN_TYPE:
  812.                             $value $param;
  813.                             break;
  814.                         case self::DATE_TYPE:
  815.                             if (DateTimeService::isDate($param)) {
  816.                                 $value $param;
  817.                                 $readOnly true;
  818.                             }
  819.                             break;
  820.                         case self::DATETIME_TYPE:
  821.                             if (DateTimeService::isDateTime($param)) {
  822.                                 $value $param;
  823.                                 $readOnly true;
  824.                             }
  825.                             break;
  826.                         case self::RADIO_TYPE:
  827.                         case self::SELECT_TYPE:
  828.                             if (!isset($field['choices'])) {
  829.                                 break;
  830.                             }
  831.                             foreach ($field['choices'] as $choice) {
  832.                                 if ($choice['value'] !== $param) {
  833.                                     continue;
  834.                                 }
  835.                                 $value $param;
  836.                                 $readOnly true;
  837.                                 break;
  838.                             }
  839.                             break;
  840.                         case self::CHECKBOX_TYPE:
  841.                             $value $param;
  842.                             $readOnly true;
  843.                             $this->formDefinition[$keyGroup]['fields'][$keyField]['choices'][0]['label'] = $param;
  844.                             break;
  845.                     }
  846.                     if (!$value) {
  847.                         continue;
  848.                     }
  849.                     $this->formDefinition[$keyGroup]['fields'][$keyField]['attr']['value'] = $value;
  850.                     if ($readOnly) {
  851.                         $this->formDefinition[$keyGroup]['fields'][$keyField]['attr']['readonly'] = true;
  852.                     }
  853.                 }
  854.             }
  855.         }
  856.     }
  857.     /**
  858.      * @TODO: hardcoded
  859.      * @param array $formData
  860.      * @param array $field
  861.      * @param string $key
  862.      * @param $value
  863.      * @return array
  864.      */
  865.     private function processPayment(array $formData, array $fieldstring $key$value): array
  866.     {
  867.         $paymentExentionKey 'aportacion-economica-exenciones_checkbox';
  868.         if ($paymentExentionKey === $field['name'] && !$value) {
  869.             $formData[$key] = ['Ninguno'];
  870.             return $formData;
  871.         }
  872.         if ($paymentExentionKey === $field['name'] && $value) {
  873.             $formData['preferencia-pago-aportacion-economica_radio'] = '-';
  874.             $formData['preferencia-domiciliar-pago-aportacion-economica_radio'] = '-';
  875.         }
  876.         return $formData;
  877.     }
  878. }