src/Listing/Transformer/ListingResponseTransformer.php line 123

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