src/V4/EventSubscriber/SynchronizeChildrenFieldsEventSubscriber.php line 132

Open in your IDE?
  1. <?php
  2. namespace App\V4\EventSubscriber;
  3. use ApiPlatform\Core\DataPersister\DataPersisterInterface;
  4. use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
  5. use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
  6. use App\Model\SpecificFieldsAwareInterface;
  7. use App\Model\ViewOrderInfo\ViewOrderInfo;
  8. use App\Service\ApiWebServiceFilterBuilder\PaginationFilterBuilder;
  9. use App\Service\Form\FormUtils;
  10. use App\Service\PreSendSerializer;
  11. use App\Service\ViewOrders\ViewOrdersManager;
  12. use App\Transformer\EntityToFormTypeTransformer;
  13. use App\V4\DataPersister\AbstractWithoutRequestDataPersister;
  14. use App\V4\Event\PostPersistEvent;
  15. use App\V4\Logger\SentryLogger;
  16. use App\V4\Model\ChildrenAwareInterface;
  17. use App\V4\Model\Quote\Quote;
  18. use App\V4\Model\QuoteState\QuoteState;
  19. use App\V4\Model\SpecificField\SpecificField;
  20. use DateTime;
  21. use Doctrine\Common\Annotations\AnnotationException;
  22. use Exception;
  23. use Psr\Log\LogLevel;
  24. use ReflectionClass;
  25. use ReflectionException;
  26. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  27. use Symfony\Component\Form\FormFactoryInterface;
  28. use Symfony\Component\Serializer\Exception\ExceptionInterface;
  29. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  30. use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
  31. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  32. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  33. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  34. class SynchronizeChildrenFieldsEventSubscriber extends AbstractSubscriber implements EventSubscriberInterface
  35. {
  36.     use FormUtils;
  37.     /**
  38.      * @var CollectionDataProviderInterface
  39.      */
  40.     private $collectionDataProvider;
  41.     /**
  42.      * @var DataPersisterInterface
  43.      */
  44.     private $dataPersister;
  45.     /**
  46.      * @var ViewOrdersManager
  47.      */
  48.     private $viewOrdersManager;
  49.     /**
  50.      * @var FormFactoryInterface
  51.      */
  52.     private $formFactory;
  53.     /**
  54.      * @var PreSendSerializer
  55.      */
  56.     private $serializer;
  57.     /**
  58.      * @var SentryLogger
  59.      */
  60.     private $sentryLogger;
  61.     /**
  62.      * @param CollectionDataProviderInterface $collectionDataProvider
  63.      * @param DataPersisterInterface          $dataPersister
  64.      * @param ViewOrdersManager               $viewOrdersManager
  65.      * @param FormFactoryInterface            $formFactory
  66.      * @param PreSendSerializer               $serializer
  67.      * @param SentryLogger                    $sentryLogger
  68.      */
  69.     public function __construct(
  70.         CollectionDataProviderInterface $collectionDataProvider,
  71.         DataPersisterInterface $dataPersister,
  72.         ViewOrdersManager $viewOrdersManager,
  73.         FormFactoryInterface $formFactory,
  74.         PreSendSerializer $serializer,
  75.         SentryLogger $sentryLogger
  76.     ) {
  77.         $this->collectionDataProvider $collectionDataProvider;
  78.         $this->dataPersister $dataPersister;
  79.         $this->viewOrdersManager $viewOrdersManager;
  80.         $this->formFactory $formFactory;
  81.         $this->serializer $serializer;
  82.         $this->sentryLogger $sentryLogger;
  83.     }
  84.     /**
  85.      * @param $entity
  86.      *
  87.      * @return bool
  88.      */
  89.     public function supports($entity): bool
  90.     {
  91.         return $entity instanceof ChildrenAwareInterface
  92.             && $entity->isParent()
  93.             && method_exists($entity'getId')
  94.             && null !== $entity->getId()
  95.         ;
  96.     }
  97.     /**
  98.      * @return string[]
  99.      */
  100.     public static function getSubscribedEvents(): array
  101.     {
  102.         return [
  103.             PostPersistEvent::NAME => 'onPostPersist',
  104.         ];
  105.     }
  106.     /**
  107.      * @param PostPersistEvent $event
  108.      *
  109.      * @throws AnnotationException
  110.      * @throws ClientExceptionInterface
  111.      * @throws DecodingExceptionInterface
  112.      * @throws ExceptionInterface
  113.      * @throws RedirectionExceptionInterface
  114.      * @throws ServerExceptionInterface
  115.      * @throws TransportExceptionInterface
  116.      * @throws ResourceClassNotSupportedException
  117.      * @throws ReflectionException
  118.      * @throws Exception
  119.      */
  120.     public function onPostPersist(PostPersistEvent $event): void
  121.     {
  122.         $objPersisted $event->getAfter();
  123.         if (!$this->supports($objPersisted) || $this->isIdAlreadyManaged($objPersisted->getId(), get_class($this))) {
  124.             return;
  125.         }
  126.         $rc = new ReflectionClass($objPersisted);
  127.         $voiParentFields $this->viewOrdersManager->getParentFieldNames($rc->getShortName());
  128.         if (empty($voiParentFields)) {
  129.             return;
  130.         }
  131.         $children $this->collectionDataProvider->getCollection($rc->getName(), null, [
  132.             'filters' => [
  133.                 PaginationFilterBuilder::ACTIVATE_PAGNIATION_KEY => false,
  134.                 'parent' => $objPersisted->getId(),
  135.             ],
  136.         ]);
  137.         /** @var SpecificFieldsAwareInterface $child */
  138.         foreach ($children as $child) {
  139.             $updateData = [];
  140.             /* @var ViewOrderInfo $voParentField */
  141.             foreach ($voiParentFields as $voiParentField) {
  142.                 $getter 'get'.ucfirst($voiParentField->getFieldKey());
  143.                 if (method_exists($event->getAfter(), $getter)) {
  144.                     $value $objPersisted->$getter();
  145.                     if ($value instanceof DateTime) {
  146.                         $value $value->format('Y-m-d H:i');
  147.                     }
  148.                     $updateData[$voiParentField->getFieldKey()] = $value;
  149.                     continue;
  150.                 }
  151.                 $sf $objPersisted->getSpecificFieldByFieldId($voiParentField->getFieldKey());
  152.                 if ($sf instanceof SpecificField) {
  153.                     $updateData['sf_'.$voiParentField->getFieldKey()] = $sf->getValue();
  154.                 }
  155.             }
  156.             try {
  157.                 $formType = (new EntityToFormTypeTransformer())->transform(get_class($child));
  158.                 $form $this->formFactory->create($formType$child, ['allow_extra_fields' => true]);
  159.                 $form->submit($updateDatafalse);
  160.                 if ($form->isSubmitted()) {
  161.                     if (!$form->isValid()) {
  162.                         $this->sentryLogger->captureMessage(
  163.                             SentryLogger::CHANNEL_SUBSCRIBER,
  164.                             sprintf('Invalid submission form for child with id %s'$child->getId()),
  165.                             [
  166.                                 'catchOnClass' => self::class,
  167.                                 'form' => $this->getFormErrorsForLog($form$this->serializer->serialize($form->getData(), 'quote:update')),
  168.                             ],
  169.                             LogLevel::ERROR
  170.                         );
  171.                         throw new Exception('Invalid submission form');
  172.                     }
  173.                     $data $form->getData();
  174.                     if ($data instanceof Quote) {
  175.                         if ($data->getStatus() instanceof QuoteState) {
  176.                             $data->getStatus()->setNormalizeAsIRI(true);
  177.                         }
  178.                         foreach ($data->getQuoteLines() as $quoteLine) {
  179.                             $quoteLine->setNormalizeAsIRI(true);
  180.                         }
  181.                     }
  182.                     $this->dataPersister->persist($form->getData(), [
  183.                         AbstractWithoutRequestDataPersister::CONTEXT_IS_V4 => true,
  184.                     ]);
  185.                 }
  186.             } catch (Exception $exception) {
  187.                 $this->sentryLogger->captureException(
  188.                     SentryLogger::CHANNEL_SUBSCRIBER,
  189.                     $exception,
  190.                     [
  191.                         'catchOnClass' => self::class,
  192.                     ]
  193.                 );
  194.             }
  195.         }
  196.     }
  197. }