<?php
namespace App\V4\Form\Type\CustomEventTrigger;
use App\V4\Entity\CustomEventTrigger;
use App\V4\Form\FormFieldExtractor;
use App\V4\Model\Prospect\Prospect;
use App\V4\Model\Quote\Quote;
use App\V4\Transformer\FQCNToShortNameTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CustomEventTriggerType extends AbstractType
{
/**
* @var FormFieldExtractor
*/
private $formFieldExtractor;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @param FormFieldExtractor $formFieldExtractor
* @param TranslatorInterface $translator
*/
public function __construct(
FormFieldExtractor $formFieldExtractor,
TranslatorInterface $translator
) {
$this->formFieldExtractor = $formFieldExtractor;
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
/** @var CustomEventTrigger $customEventTrigger */
$customEventTrigger = $builder->getData();
$customerId = $customEventTrigger instanceof CustomEventTrigger
? $customEventTrigger->getCustomerId()
: $options['customerId'];
$builder
->add('entity', ChoiceType::class, [
'choices' => [
FQCNToShortNameTransformer::ENTITY_QUOTE,
FQCNToShortNameTransformer::ENTITY_PROSPECT,
],
'required' => true,
'data' => $customEventTrigger instanceof CustomEventTrigger ? $customEventTrigger->getEntity() : FQCNToShortNameTransformer::ENTITY_QUOTE,
])
->add('field', ChoiceType::class, [
'choices' => $this->getAllFormFieldNames(),
'data' => $customEventTrigger instanceof CustomEventTrigger ? $customEventTrigger->getField() : CustomEventTrigger::FIELD_QUOTE_NAME,
'constraints' => [
new Callback(function (string $value, ExecutionContextInterface $context) {
/** @var FormInterface $formField */
$formField = $context->getObject();
$availableFields = array_flip($formField->getConfig()->getOption('choices'));
$chosenEntity = $context->getRoot()->get('entity')->getData();
if (str_contains($availableFields[$value], '['.$chosenEntity.']')) {
return true;
}
if (str_contains($availableFields[$value], '[Multiple]')) {
return true;
}
$context->addViolation("Le champ ne fait pas partie de l'entité choisie");
return false;
}),
],
])
->add('type', ChoiceType::class, [
'choices' => CustomEventTrigger::TYPES,
'data' => $customEventTrigger instanceof CustomEventTrigger ? $customEventTrigger->getType() : CustomEventTrigger::TYPE_STRING,
])
->add('value', TextareaType::class, [
'required' => true,
])
->add('aCondition', ChoiceType::class, [
'choices' => CustomEventTrigger::CONDITIONS,
'data' => $customEventTrigger instanceof CustomEventTrigger ? $customEventTrigger->getACondition() : CustomEventTrigger::CONDITION_IS_EMPTY,
])
->add('description', TextType::class, [
'required' => false,
])
->add('specificFieldId', TextType::class, [
'required' => false,
])
->add('whenApply', ChoiceType::class, [
'choices' => CustomEventTrigger::WHEN_CHOICES,
'data' => $customEventTrigger instanceof CustomEventTrigger ? $customEventTrigger->getWhenApply() : CustomEventTrigger::WHEN_PRE_SUBMIT,
])
->add('containValues', TextType::class, [
'required' => false,
])
->add('customerId', TextType::class, [
// @todo refacto : changer en HiddenType à terme, cause liform ne gère pas le HiddenType
'data' => $customerId,
'required' => true,
'attr' => [
'type' => 'hidden',
],
])
->add('mode', ChoiceType::class, [
'choices' => [CustomEventTrigger::MODE_SIMPLE, CustomEventTrigger::MODE_TWIG],
'data' => $customEventTrigger instanceof CustomEventTrigger ? $customEventTrigger->getMode() : CustomEventTrigger::MODE_SIMPLE,
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'data_class' => CustomEventTrigger::class,
'customerId' => null,
'csrf_protection' => false,
]);
}
private function getAllFormFieldNames(): array
{
$entities = [
Quote::class,
Prospect::class,
];
$fieldChoices = [];
foreach ($entities as $entity) {
$fields = $this->formFieldExtractor->getAllFormFieldNamesFromEntity($entity);
$entityShortName = (new FQCNToShortNameTransformer())->transform($entity);
/** @var Form $field * */
foreach ($fields as $key => $field) {
$label = "{$this->translator->trans($field->getConfig()->getOption('label') ?? $key)} ({$key})";
if (isset($fieldChoices[$key])) {
$fieldChoices[$key] = '[Multiple] '.$label;
continue;
}
$fieldChoices[$key] = '['.$entityShortName.'] '.$label;
}
asort($fieldChoices);
}
$fieldChoices[CustomEventTrigger::FIELD_TASKS] = CustomEventTrigger::FIELD_TASKS;
return array_flip($fieldChoices);
}
}