src/V4/EventSubscriber/SynchronizeChildrenFieldsEventSubscriber.php line 133

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