src/V4/Form/Type/Task/TaskType.php line 52

Open in your IDE?
  1. <?php
  2. namespace App\V4\Form\Type\Task;
  3. use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
  4. use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
  5. use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
  6. use App\Form\CustomerConstraints\ConditionShowCustomerConstraintBuilder;
  7. use App\Form\Type\AbstractViewOrderAwareType;
  8. use App\Form\Type\CustomerResource\CustomerFileType;
  9. use App\Form\Type\SubresourceChoicesTrait;
  10. use App\Listing\Transformer\ListingResponseTransformer;
  11. use App\Model\Traits\TimeStampableFormType;
  12. use App\Model\ViewOrder\ViewOrder;
  13. use App\Normalizer\Form\TextAreaTypeNormalizer;
  14. use App\Service\Cache\CacheManager;
  15. use App\Service\Cache\Exception\UnableToSaveKeyException;
  16. use App\V4\Form\Type\ContactConcernedFilterTrait;
  17. use App\V4\Form\Type\ManagedByFilterTrait;
  18. use App\V4\Form\Type\SectionNameFilterTrait;
  19. use App\V4\Form\Type\TaskTypeFilterTrait;
  20. use App\V4\Logger\SentryLogger;
  21. use App\V4\Model\Contact\Contact;
  22. use App\V4\Model\Prospect\Prospect;
  23. use App\V4\Model\Quote\Quote;
  24. use App\V4\Model\Task\Task;
  25. use App\V4\Model\TaskName\TaskName;
  26. use App\V4\Model\TaskType\TaskType as TaskTypeModel;
  27. use App\V4\Model\TaskType\TaskType as TaskTypeV4;
  28. use DateTime;
  29. use Psr\Cache\CacheException;
  30. use Psr\Cache\InvalidArgumentException;
  31. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  32. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  33. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  34. use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
  35. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  36. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  37. use Symfony\Component\Form\Extension\Core\Type\TextType;
  38. use Symfony\Component\Form\FormBuilderInterface;
  39. use Symfony\Component\Form\FormInterface;
  40. use Symfony\Component\OptionsResolver\OptionsResolver;
  41. use Symfony\Component\Routing\RouterInterface;
  42. use Symfony\Component\Security\Core\Security;
  43. use Symfony\Component\Serializer\Exception\ExceptionInterface;
  44. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  45. use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
  46. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  47. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  48. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  49. class TaskType extends AbstractViewOrderAwareType
  50. {
  51.     use TaskTypeFilterTrait;
  52.     use ContactConcernedFilterTrait;
  53.     use ManagedByFilterTrait;
  54.     use SectionNameFilterTrait;
  55.     use TimeStampableFormType;
  56.     use SubresourceChoicesTrait {
  57.         getEntityChoices as private getEntityChoicesTrait;
  58.     }
  59.     /**
  60.      * @var CollectionDataProviderInterface
  61.      */
  62.     private $collectionDataProvider;
  63.     /**
  64.      * @var ItemDataProviderInterface
  65.      */
  66.     private $itemDataProvider;
  67.     /**
  68.      * @var CacheManager
  69.      */
  70.     private $cacheManager;
  71.     /**
  72.      * @var RouterInterface
  73.      */
  74.     private $router;
  75.     /**
  76.      * @var Security
  77.      */
  78.     private $security;
  79.     /**
  80.      * @var SentryLogger
  81.      */
  82.     private $sentryLogger;
  83.     /**
  84.      * @param CollectionDataProviderInterface $collectionDataProvider
  85.      * @param CacheManager                    $cacheManager
  86.      * @param RouterInterface                 $router
  87.      * @param ItemDataProviderInterface       $itemDataProvider
  88.      * @param Security                        $security
  89.      * @param SentryLogger                    $sentryLogger
  90.      */
  91.     public function __construct(
  92.         CollectionDataProviderInterface $collectionDataProvider,
  93.         CacheManager $cacheManager,
  94.         RouterInterface $router,
  95.         ItemDataProviderInterface $itemDataProvider,
  96.         Security $security,
  97.         SentryLogger $sentryLogger
  98.     ) {
  99.         $this->collectionDataProvider $collectionDataProvider;
  100.         $this->cacheManager $cacheManager;
  101.         $this->router $router;
  102.         $this->itemDataProvider $itemDataProvider;
  103.         $this->security $security;
  104.         $this->sentryLogger $sentryLogger;
  105.     }
  106.     /**
  107.      * @param FormBuilderInterface $builder
  108.      * @param array                $options
  109.      *
  110.      * @return void
  111.      *
  112.      * @throws CacheException
  113.      * @throws ClientExceptionInterface
  114.      * @throws DecodingExceptionInterface
  115.      * @throws ExceptionInterface
  116.      * @throws InvalidArgumentException
  117.      * @throws RedirectionExceptionInterface
  118.      * @throws ServerExceptionInterface
  119.      * @throws TransportExceptionInterface
  120.      * @throws UnableToSaveKeyException
  121.      * @throws ResourceClassNotSupportedException
  122.      */
  123.     public function buildForm(FormBuilderInterface $builder, array $options): void
  124.     {
  125.         parent::buildForm($builder$options);
  126.         $task $builder->getData();
  127.         $quote $options['quoteId'] ? $this->itemDataProvider->getItem(Quote::class, $options['quoteId']) : null;
  128.         $user $this->security->getUser();
  129.         $userId $user->getUserId();
  130.         $managedBy $task instanceof Task && $task->getManagedBy() ? $task->getManagedBy() : $userId;
  131.         $name $task instanceof Task $task->getName() : null;
  132.         if ($quote instanceof Quote) {
  133.             $managedBy $managedBy ?? $quote->getManagedBy();
  134.             $taskNames $this->getEntityChoices(TaskName::class);
  135.             /** @var TaskName $taskName */
  136.             foreach ($taskNames as $taskName) {
  137.                 if ($taskName->isQuoteReminder()) {
  138.                     $name $name ?? $taskName->getName().' '.$quote->getQuoteNumber();
  139.                     break;
  140.                 }
  141.             }
  142.         }
  143.         $prospect null;
  144.         if ($task instanceof Task) {
  145.             if ($task->getProspect() instanceof Prospect) {
  146.                 $prospect $task->getProspect();
  147.             }
  148.             if ($task->getTaskType() instanceof TaskTypeV4) {
  149.                 $task->getTaskType()->setNormalizeAsIRI(true);
  150.             }
  151.             foreach ($task->getContacts() as $contact) {
  152.                 $contact->setNormalizeAsIRI(true);
  153.             }
  154.         }
  155.         if (null === $prospect && $options['prospectId']) {
  156.             $prospect $this->itemDataProvider->getItem(Prospect::class, $options['prospectId']);
  157.         }
  158.         if (null !== $prospect) {
  159.             $prospect->setNormalizeAsIRI(true);
  160.         }
  161.         $taskTypes $this->getEntityChoices(TaskTypeModel::class);
  162.         $choicesTaskTypes = [];
  163.         $taskTypeTimestamped = [];
  164.         /** @var TaskTypeModel $taskType */
  165.         foreach ($taskTypes as $taskType) {
  166.             $choicesTaskTypes[$taskType->getName()] = $taskType;
  167.             if ($taskType->isTimestamped()) {
  168.                 $taskTypeTimestamped[] = $taskType->getId();
  169.             }
  170.         }
  171.         $builder
  172.             ->add('contacts'ChoiceType::class, [
  173.                 'label' => 'task_contacts',
  174.                 'choices' => $prospect instanceof Prospect
  175.                     $this->getEntityChoices(Contact::class, ['prospect' => $prospect->getId()])
  176.                     : [],
  177.                 'choice_label' => 'name',
  178.                 'choice_value' => 'id',
  179.                 'data' => $task array_map(function (Contact $contact) {
  180.                     return $contact->getId();
  181.                 }, $task->getContacts()->toArray()) : null,
  182.                 'attr' => [
  183.                     ListingResponseTransformer::FORM_SORT_KEY => 'contacts.fullname',
  184.                 ],
  185.                 'multiple' => true,
  186.                 'required' => false,
  187.             ])
  188.             ->add('prospect'ChoiceType::class, [
  189.                 'choices' => [
  190.                     $prospect,
  191.                 ],
  192.                 'choice_value' => 'id',
  193.                 'required' => false,
  194.                 'attr' => [
  195.                     'type' => 'hidden',
  196.                     'data-hide-from-vieworders' => true,
  197.                 ],
  198.             ])
  199.             ->add('name'TextType::class, [
  200.                 'label' => 'task_object',
  201.                 'attr' => [
  202.                     'data-autocomplete' => $this->router->generate('get_task_names'),
  203.                     'data-field' => 'name',
  204.                 ],
  205.                 'required' => true,
  206.                 'data' => $name,
  207.             ])
  208.             ->add('beginAt'DateTimeType::class, [
  209.                 'label' => 'beginAt_task',
  210.                 'input' => 'datetime',
  211.                 'widget' => 'single_text',
  212.                 'html5' => false,
  213.                 'data' => $task instanceof Task && $task->getBeginAt() instanceof DateTime $task->getBeginAt() : new DateTime(),
  214.                 'format' => "yyyy-MM-dd'T'HH:mm",
  215.             ])
  216.             ->add('endAt'DateTimeType::class, [
  217.                 'input' => 'datetime',
  218.                 'widget' => 'single_text',
  219.                 'html5' => false,
  220.                 'format' => "yyyy-MM-dd'T'HH:mm",
  221.                 'required' => false,
  222.                 'attr' => [
  223.                     ConditionShowCustomerConstraintBuilder::DATA_CONDITION_FIELD => 'taskType',
  224.                     ConditionShowCustomerConstraintBuilder::DATA_CONDITION_VALUE => $taskTypeTimestamped,
  225.                     ConditionShowCustomerConstraintBuilder::DATA_CONDITION_IS_VISIBLE => false,
  226.                 ],
  227.             ])
  228.             ->add('taskType'ChoiceType::class, [
  229.                 'choices' => $taskTypes,
  230.                 'choice_label' => 'name',
  231.                 'choice_value' => 'id',
  232.                 'attr' => [
  233.                     'data-hide-fields' => true,
  234.                     'data-targets' => 'endAt',
  235.                     'data-choices-attr' => implode(';'array_map(function (TaskTypeModel $taskType) {
  236.                         return $taskType->isTimestamped() ? '1' '0';
  237.                     }, $choicesTaskTypes)),
  238.                     ListingResponseTransformer::FORM_SORT_KEY => 'taskType.name',
  239.                 ],
  240.             ])
  241.             ->add('managedBy'ChoiceType::class, [
  242.                 'choices' => $this->getManagedByChoices(),
  243.                 'required' => true,
  244.                 'data' => $managedBy,
  245.             ])
  246.             ->add('isClosed'CheckboxType::class, [
  247.                 'false_values' => [null'0'0false'''false'],
  248.                 'required' => false,
  249.             ])
  250.             ->add('memo'TextareaType::class, [
  251.                 'required' => false,
  252.                 'attr' => [
  253.                     TextAreaTypeNormalizer::DATA_ATTR_WYSIWYG_MODE => TextAreaTypeNormalizer::WYSIWYG_MODE_FULL,
  254.                 ],
  255.             ])
  256.             ->add('sectionName'ChoiceType::class, [
  257.                 'choices' => $this->getSectionNameChoices(),
  258.                 'required' => false,
  259.                 'attr' => [
  260.                     'data-hide-from-vieworders' => true,
  261.                 ],
  262.             ])
  263.             ->add('report'TextareaType::class, [
  264.                 'required' => false,
  265.                 'attr' => [
  266.                     TextAreaTypeNormalizer::DATA_ATTR_WYSIWYG_MODE => TextAreaTypeNormalizer::WYSIWYG_MODE_FULL,
  267.                 ],
  268.             ])
  269.             ->add('customerFiles'CollectionType::class, [
  270.                 'entry_type' => CustomerFileType::class,
  271.                 'required' => false,
  272.                 'allow_add' => true,
  273.                 'delete_empty' => true,
  274.             ])
  275.             ->add('quotes'CollectionType::class, [
  276.                 'entry_type' => TaskQuoteExternalRefType::class,
  277.                 'entry_options' => [
  278.                     'allow_extra_fields' => $options['allow_extra_fields'] ?? false,
  279.                 ],
  280.                 'required' => false,
  281.                 'allow_add' => true,
  282.                 'delete_empty' => true,
  283.                 'attr' => [
  284.                     'data-hide-from-vieworders' => true,
  285.                     'type' => 'hidden',
  286.                 ],
  287.             ])
  288.             ->add('nbClic'HiddenType::class, [
  289.                 'label' => 'nb_clic',
  290.                 'required' => false,
  291.                 'mapped' => false,
  292.                 'attr' => [
  293.                     ListingResponseTransformer::FORM_SORT_KEY => 'taskMailingStats.nbClic',
  294.                 ],
  295.             ])
  296.             ->add('nbRead'HiddenType::class, [
  297.                 'label' => 'nb_readings',
  298.                 'required' => false,
  299.                 'mapped' => false,
  300.                 'attr' => [
  301.                     ListingResponseTransformer::FORM_SORT_KEY => 'taskMailingStats.nbReading',
  302.                 ],
  303.             ])
  304.             ->add('isDraft'CheckboxType::class, [
  305.                 'label' => 'task_isDraft',
  306.                 'false_values' => [null'0'0false'''false'],
  307.                 'required' => false,
  308.             ])
  309.         ;
  310.         $builder->get('contacts')->resetViewTransformers();
  311.     }
  312.     /**
  313.      * @param OptionsResolver $resolver
  314.      *
  315.      * @return void
  316.      */
  317.     public function configureOptions(OptionsResolver $resolver): void
  318.     {
  319.         parent::configureOptions($resolver);
  320.         $resolver->setDefaults([
  321.             'data_class' => Task::class,
  322.             'csrf_protection' => false,
  323.             'prospectId' => null,
  324.             'quoteId' => null,
  325.             self::FORM_CONFIG_VIEW_ORDER_ENTITY => Task::class,
  326.             self::FORM_CONFIG_VIEW_ORDER_TYPE => ViewOrder::VIEWORDER_TYPE_FORM,
  327.             self::FORM_CONFIG_SPECIFIC_FIELD_ENTITY => Task::class,
  328.             self::FORM_CONFIG_VIEW_ORDER_ENTITY_TYPE => null,
  329.             'validation_groups' => function (FormInterface $form) {
  330.                 $data $form->getData();
  331.                 if ($data instanceof Task && $data->getTaskType() instanceof TaskType) {
  332.                     $taskType $this->itemDataProvider->getItem(
  333.                         TaskType::class,
  334.                         $data->getTaskType()
  335.                     );
  336.                     if ($taskType->isTimestamped()) {
  337.                         return ['Default''tasktype_is_timestamped'];
  338.                     }
  339.                 }
  340.                 return ['Default'];
  341.             },
  342.         ]);
  343.     }
  344.     /**
  345.      * @param string $entityFQCN
  346.      * @param array  $filters
  347.      *
  348.      * @return array<string, object>
  349.      *
  350.      * @throws CacheException
  351.      * @throws InvalidArgumentException
  352.      */
  353.     private function getEntityChoices(string $entityFQCN, array $filters = []): array
  354.     {
  355.         return $this->getEntityChoicesTrait(
  356.             $this->collectionDataProvider,
  357.             $this->cacheManager,
  358.             $this->sentryLogger,
  359.             $entityFQCN,
  360.             $filters
  361.         );
  362.     }
  363. }