src/Listing/Transformer/ListingResponseTransformer.php line 262

Open in your IDE?
  1. <?php
  2. namespace App\Listing\Transformer;
  3. use App\Export\Builder\ExportBuilderInterface;
  4. use App\Export\Builder\ExporterInterface;
  5. use App\Export\ContactConcernedExporter;
  6. use App\Form\Type\CustomerResource\CustomerFileType;
  7. use App\Listing\Builder\HeaderEntryBuilder;
  8. use App\Listing\Builder\ResultEntryBuilder;
  9. use App\Transformer\EntityToFormTypeTransformer;
  10. use App\V4\Controller\AbstractGetSubListAction;
  11. use App\V4\DataProvider\CustomAction\ActionBuilder;
  12. use App\V4\Exporter\LongtextExporter;
  13. use App\V4\Form\FormFieldExtractor;
  14. use App\V4\Model\Contact\Contact;
  15. use App\V4\Model\Prospect\Prospect;
  16. use App\V4\Model\Quote\Quote;
  17. use App\V4\Model\Response\Listing\FieldEntry;
  18. use App\V4\Model\Response\Listing\HeaderEntry;
  19. use App\V4\Model\Response\Listing\ListingResponse;
  20. use App\V4\Model\Task\Task;
  21. use App\ViewOrders\Builder\ViewOrdersBuilder;
  22. use App\ViewOrders\Builder\ViewOrdersBuilderInterface;
  23. use App\ViewOrders\Model\Item;
  24. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  25. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  26. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  27. use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
  28. use Symfony\Component\Form\Extension\Core\Type\DateType;
  29. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  30. use Symfony\Component\Form\Extension\Core\Type\NumberType;
  31. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  32. use Symfony\Component\Form\Extension\Core\Type\TextType;
  33. use Symfony\Component\Form\FormFactoryInterface;
  34. use Symfony\Component\Form\FormInterface;
  35. use Symfony\Component\Serializer\Exception\ExceptionInterface;
  36. use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  37. class ListingResponseTransformer implements ListingResponseTransformerInterface
  38. {
  39.     public const FORM_SORT_KEY 'sortKey';
  40.     public const FORM_FILTER_KEY 'filterKey';
  41.     public const KEY_NOT_FOUND 'KEY_NOT_FOUND';
  42.     public const TYPE_TEL 'TelType';
  43.     public const TYPE_MONEY 'money';
  44.     public const TYPE_PERCENT 'percent';
  45.     public const TYPE_EMAIL 'email';
  46.     public const TYPE_LONGTEXT 'longtext';
  47.     public const TYPE_FILES 'files';
  48.     public const TYPE_HTML 'html';
  49.     const LONGTEXT_LENGTH_MAX 100;
  50.     /**
  51.      * @var NormalizerInterface
  52.      */
  53.     private $normalizer;
  54.     /**
  55.      * @var ViewOrdersBuilder
  56.      */
  57.     private $viewOrdersBuilder;
  58.     /**
  59.      * @var ExportBuilderInterface
  60.      */
  61.     private $exportBuilder;
  62.     /**
  63.      * @var FormFactoryInterface
  64.      */
  65.     private $formFactory;
  66.     /**
  67.      * @var HeaderEntryBuilder
  68.      */
  69.     private $headerEntryBuilder;
  70.     /**
  71.      * @var ResultEntryBuilder
  72.      */
  73.     private $resultEntryBuilder;
  74.     /**
  75.      * @var ActionBuilder
  76.      */
  77.     private $actionBuilder;
  78.     /**
  79.      * @var FormFieldExtractor
  80.      */
  81.     private $formFieldExtractor;
  82.     public function __construct(
  83.         NormalizerInterface $normalizer,
  84.         ViewOrdersBuilder $viewOrdersBuilder,
  85.         ExportBuilderInterface $exportBuilder,
  86.         FormFactoryInterface $formFactory,
  87.         HeaderEntryBuilder $headerEntryBuilder,
  88.         ResultEntryBuilder $resultEntryBuilder,
  89.         ActionBuilder $actionBuilder,
  90.         FormFieldExtractor $formFieldExtractor
  91.     ) {
  92.         $this->normalizer $normalizer;
  93.         $this->viewOrdersBuilder $viewOrdersBuilder;
  94.         $this->exportBuilder $exportBuilder;
  95.         $this->formFactory $formFactory;
  96.         $this->headerEntryBuilder $headerEntryBuilder;
  97.         $this->resultEntryBuilder $resultEntryBuilder;
  98.         $this->actionBuilder $actionBuilder;
  99.         $this->formFieldExtractor $formFieldExtractor;
  100.     }
  101.     /**
  102.      * @param string $entityFQCN
  103.      * @param array  $entities
  104.      * @param array  $context
  105.      *
  106.      * @return array
  107.      *
  108.      * @throws ExceptionInterface
  109.      */
  110.     public function transform(string $entityFQCN, array $entities, array $context = []): array
  111.     {
  112.         $replacementResponse = new ListingResponse();
  113.         $isSubResource $context[AbstractGetSubListAction::CONTEXT_IS_SUB_RESOURCE_KEY] ?? false;
  114.         $needToAddProspectFullname in_array($entityFQCN, [Prospect::class, Quote::class, Task::class, Contact::class], true)
  115.             && !$isSubResource
  116.         ;
  117.         if ($needToAddProspectFullname) {
  118.             switch ($entityFQCN) {
  119.                 case Contact::class:
  120.                     $entityFieldFullname 'prospect.fullname';
  121.                     break;
  122.                 case Task::class:
  123.                     $entityFieldFullname 'customerName';
  124.                     break;
  125.                 case Quote::class:
  126.                     $entityFieldFullname 'prospectFullName';
  127.                     break;
  128.                 default:
  129.                     $entityFieldFullname 'fullname';
  130.                     break;
  131.             }
  132.             $replacementResponse->addHeader(
  133.                 (new HeaderEntry())
  134.                     ->setKey($entityFieldFullname)
  135.                     ->setLabel('prospect_list_fullname')
  136.                     ->setSortKey($entityFieldFullname)
  137.                     ->addMetadata('type''string')
  138.                     ->addMetadata(HeaderEntry::KEY_SORT_TYPEHeaderEntry::VALUE_SORT_TYPE_ALPHABETICAL)
  139.             );
  140.         }
  141.         $form $this->formFactory->create((new EntityToFormTypeTransformer())->transform($entityFQCN));
  142.         $viewOrders $this->viewOrdersBuilder->getViewOrder($entityFQCNViewOrdersBuilderInterface::VIEW_ORDER_TYPE_LIST$context['tab'] ?? null);
  143.         foreach ($viewOrders->getGroups()[0]->getItems() as $viewOrderItem) {
  144.             $class $viewOrderItem->getValueType() ?? $this->getItemClass($form$viewOrderItem);
  145.             if (self::KEY_NOT_FOUND === $class) {
  146.                 continue;
  147.             }
  148.             switch ($class) {
  149.                 case CheckboxType::class:
  150.                     $type 'boolean';
  151.                     break;
  152.                 case NumberType::class:
  153.                 case IntegerType::class:
  154.                     $type 'number';
  155.                     break;
  156.                 case TextareaType::class:
  157.                     $type self::TYPE_LONGTEXT;
  158.                     break;
  159.                 case TextType::class:
  160.                 case ChoiceType::class:
  161.                     $type 'string';
  162.                     break;
  163.                 case CustomerFileType::class:
  164.                     $type 'file';
  165.                     if (str_contains($viewOrderItem->getKey(), 'image')) {
  166.                         $type 'image';
  167.                     }
  168.                     break;
  169.                 case self::TYPE_FILES:
  170.                 case CollectionType::class:
  171.                     if ('customerFiles' === $viewOrderItem->getKey()) {
  172.                         $type 'files';
  173.                     }
  174.                     break;
  175.                 case DateType::class:
  176.                     $type 'date';
  177.                     break;
  178.                 case DateTimeType::class:
  179.                     $type 'datetime';
  180.                     break;
  181.                 case self::TYPE_TEL:
  182.                 case self::TYPE_MONEY:
  183.                 case self::TYPE_PERCENT:
  184.                 case self::TYPE_EMAIL:
  185.                 case self::TYPE_HTML:
  186.                     $type $class;
  187.                     break;
  188.                 default:
  189.                     $type 'unknown';
  190.             }
  191.             switch ($viewOrderItem->getKey()) {
  192.                 case 'socialCapital':
  193.                 case 'turnover':
  194.                 case 'weightedTotal':
  195.                 case 'totalExcludingVat':
  196.                     $type self::TYPE_MONEY;
  197.                     break;
  198.                 case 'phone':
  199.                 case 'assistantPhone':
  200.                 case 'fax':
  201.                 case 'mobile':
  202.                     $type self::TYPE_TEL;
  203.                     break;
  204.                 case 'potential':
  205.                     $type self::TYPE_PERCENT;
  206.                     break;
  207.             }
  208.             $label $viewOrderItem->getLabel() ?? $viewOrderItem->getKey();
  209.             $sortKey $viewOrderItem->getKey();
  210.             $fieldOfForm $this->formFieldExtractor->getAllFormFieldNamesFromEntity($entityFQCN)[$viewOrderItem->getKey()] ?? null;
  211.             if ($fieldOfForm instanceof FormInterface) {
  212.                 $label $fieldOfForm->getConfig()->getOption('label'$label) ?? $label;
  213.                 $attr $fieldOfForm->getConfig()->getOption('attr', []) ?? [];
  214.                 if (!empty($attr[self::FORM_SORT_KEY])) {
  215.                     $sortKey $attr[self::FORM_SORT_KEY];
  216.                 }
  217.             }
  218.             $headerEntry $this->headerEntryBuilder
  219.                 ->getFormatter($viewOrderItem$entityFQCN$type ?? 'unknown'$class)
  220.                 ->build($viewOrderItem$entityFQCN$type ?? 'unknown'$class$label$sortKey)
  221.             ;
  222.             $replacementResponse->addHeader($headerEntry);
  223.         }
  224.         $replacementResponse->addHeader(
  225.             (new HeaderEntry())
  226.                 ->setKey('actions')
  227.                 ->setLabel('')
  228.                 ->addMetadata('type''rowActions')
  229.                 ->addMetadata(HeaderEntry::KEY_SORT_TYPEHeaderEntry::VALUE_SORT_TYPE_DISABLED)
  230.         );
  231.         foreach ($entities as $entity) {
  232.             $resultEntry $this->resultEntryBuilder
  233.                 ->getFormatter($entity$entityFQCN)
  234.                 ->build($entity$entityFQCN)
  235.             ;
  236.             if ($needToAddProspectFullname) {
  237.                 $fieldEntry = new FieldEntry();
  238.                 $value $this->exportBuilder
  239.                     ->getExporter($entity$entityFieldFullnameExporterInterface::EXPORT_TYPE_LISTING)
  240.                     ->convert($entity$entityFieldFullname);
  241.                 $fieldEntry
  242.                     ->setKey($entityFieldFullname)
  243.                     ->setValue($value);
  244.                 $resultEntry->addField($fieldEntry);
  245.             }
  246.             foreach ($viewOrders->getGroups()[0]->getItems() as $viewOrderItem) {
  247.                 $property $viewOrderItem->getKey();
  248.                 $fieldEntry = new FieldEntry();
  249.                 $value $this->exportBuilder
  250.                     ->getExporter($entity$propertyExporterInterface::EXPORT_TYPE_LISTING)
  251.                     ->convert($entity$property);
  252.                 if (in_array($viewOrderItem->getKey(), ContactConcernedExporter::FIELDS_SUPPORTEDtrue)
  253.                     && $entity instanceof Task) {
  254.                     $isUnknown false;
  255.                     foreach ($entity->getContacts() as $contact) {
  256.                         $isUnknown $contact->isUnknown();
  257.                         if ($isUnknown) {
  258.                             break;
  259.                         }
  260.                     }
  261.                     $fieldEntry->addMetadata('isUnknown'$isUnknown);
  262.                 }
  263.                 if (in_array($viewOrderItem->getKey(), LongtextExporter::FIELDS_SUPPORTEDtrue)) {
  264.                     $fieldEntry->addMetadata('tooltip'$value);
  265.                     $value strlen($value) > self::LONGTEXT_LENGTH_MAX
  266.                         mb_substr($value0self::LONGTEXT_LENGTH_MAX'UTF-8').'...'
  267.                         $value
  268.                     ;
  269.                     $fieldEntry
  270.                         ->setKey($property)
  271.                         ->setValue($value)
  272.                     ;
  273.                     $resultEntry->addField($fieldEntry);
  274.                     continue;
  275.                 }
  276.                 $fieldEntry
  277.                     ->setKey($property)
  278.                     ->setValue($this->exportBuilder
  279.                         ->getExporter($entity$propertyExporterInterface::EXPORT_TYPE_LISTING)
  280.                         ->convert($entity$property))
  281.                 ;
  282.                 $resultEntry->addField($fieldEntry);
  283.             }
  284.             $resultEntry->setRowActions($this->actionBuilder->getActions($entity));
  285.             $replacementResponse->addResult($resultEntry);
  286.         }
  287.         return $this->normalizer->normalize($replacementResponse);
  288.     }
  289.     /**
  290.      * @param FormInterface $form
  291.      * @param Item          $viewOrderItem
  292.      *
  293.      * @return string
  294.      */
  295.     private function getItemClass(FormInterface $formItem $viewOrderItem): string
  296.     {
  297.         $fieldName $viewOrderItem->getKey();
  298.         $formItem null;
  299.         if ($form->has($fieldName)) {
  300.             $formItem $form->get($fieldName);
  301.         }
  302.         if (null === $formItem) {
  303.             $explodedFieldName explode('_'$fieldName);
  304.             foreach ($explodedFieldName as $key => $part) {
  305.                 if ('sf' === $part) {
  306.                     // From here, this is the specificField fieldName
  307.                     $specificFieldFieldName implode('_'array_slice($explodedFieldName$key));
  308.                     if ($form->has($specificFieldFieldName)) {
  309.                         $formItem $form->get($specificFieldFieldName);
  310.                         break;
  311.                     }
  312.                     continue;
  313.                 }
  314.                 if ($form->has($part)) {
  315.                     $form $form->get($part);
  316.                 }
  317.                 if ($part === end($explodedFieldName)) {
  318.                     $formItem $form;
  319.                     break;
  320.                 }
  321.             }
  322.         }
  323.         return null === $formItem
  324.             self::KEY_NOT_FOUND
  325.             get_class($formItem->getConfig()->getType()->getInnerType())
  326.         ;
  327.     }
  328. }