src/EventSubscriber/Import/EntityMapper/Censorship/CensorshipSubscriber.php line 34

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber\Import\EntityMapper\Censorship;
  3. use App\Application\EntityImportBundle\Event\EntityPreInitEvent;
  4. use App\Entity\Product;
  5. use App\Entity\ProductCensorship;
  6. use App\Enum\AgeRatingSymbol;
  7. use App\EventSubscriber\Import\EntityMapper\BasePreInitSubscriber;
  8. /**
  9.  * Class CensorshipSubscriber.
  10.  */
  11. class CensorshipSubscriber extends BasePreInitSubscriber
  12. {
  13.     /**
  14.      * {@inheritdoc}
  15.      *
  16.      * @uses \App\EventSubscriber\Import\EntityMapper\Censorship\CensorshipSubscriber::onEntityPreInit()
  17.      */
  18.     public static function getSubscribedEvents()
  19.     {
  20.         return [
  21.             EntityPreInitEvent::class => 'onEntityPreInit',
  22.         ];
  23.     }
  24.     /**
  25.      * Public callback responsible for initializing the censorship entity.
  26.      *
  27.      * @param \App\Application\EntityImportBundle\Event\EntityPreInitEvent $event
  28.      *   The instance of the dispatched event
  29.      */
  30.     public function onEntityPreInit(EntityPreInitEvent $event): void
  31.     {
  32.         if (ProductCensorship::class !== $event->getTargetClassName()) {
  33.             return;
  34.         }
  35.         $configuredProperties $event->getConfigurationProperties();
  36.         // Look-up the "product" property. We need to find the product
  37.         // entity reference first, because it's mandatory in order to
  38.         // create or update the censorship entities.
  39.         // Since censorship collection can be managed only through
  40.         // a product, then this means - "no product = no censorship".
  41.         $productProperty $this->filterConfiguredProperty('product'$configuredPropertiestrue);
  42.         if (null === $productProperty) {
  43.             $event->setSkipRowProcessing(true);
  44.             return;
  45.         }
  46.         // The product id cannot be obtained from the data array.
  47.         if (!$productId = (int) $this->getValue($productProperty$event->getData())) {
  48.             $event->setSkipRowProcessing(true);
  49.             return;
  50.         }
  51.         // The product reference cannot be found in the database.
  52.         if ((!$product $this->findRelatedProduct($productId)) || !$product instanceof Product) {
  53.             $event->setSkipRowProcessing(true);
  54.             return;
  55.         }
  56.         // Unable to process the data.
  57.         if (!$this->handleRow($product$configuredProperties$event->getData())) {
  58.             $event->setSkipRowProcessing(true);
  59.             return;
  60.         }
  61.         // All good, set the entity reference so it's accessible
  62.         // in the DataMapper service.
  63.         $event->setEntity($product);
  64.     }
  65.     /**
  66.      * Returns the product entity.
  67.      *
  68.      * @param int $id
  69.      *   The entity ie
  70.      *
  71.      * @return Product|object|null
  72.      *   Either null for invalid ID or the instance of the entity
  73.      */
  74.     protected function findRelatedProduct(int $id): ?object
  75.     {
  76.         return $this->getEntityManager()
  77.             ->getRepository(Product::class)
  78.             ->find($id)
  79.         ;
  80.     }
  81.     /**
  82.      * Responsible for processing the data.
  83.      *
  84.      * @param \App\Entity\Product $entity
  85.      *   The product entity containing the censorship collection
  86.      * @param \App\Application\EntityImportBundle\ValueObject\ConfigItemPropertiesValue[] $configuredProperties
  87.      *   The collection with configured properties
  88.      * @param array $data
  89.      *   The parsed data array for the current row
  90.      *
  91.      * @return \App\Entity\Product|null
  92.      *   Either the product entity to persist or null if error occurred
  93.      */
  94.     protected function handleRow(
  95.         Product $entity,
  96.         array $configuredProperties,
  97.         array $data
  98.     ): ?Product {
  99.         $countryProperty $this->filterConfiguredProperty('country'$configuredProperties);
  100.         $contentProperty $this->filterConfiguredProperty('content'$configuredProperties);
  101.         $ratingProperty $this->filterConfiguredProperty('rating'$configuredProperties);
  102.         $ratingSymbolProperty $this->filterConfiguredProperty('ratingSymbol'$configuredProperties);
  103.         // We need these properties in order to find specific collection element
  104.         // or create new one and attach it.
  105.         if (!$countryProperty || !$contentProperty || !$ratingProperty) {
  106.             return null;
  107.         }
  108.         $countryValue $this->getValue($countryProperty$data);
  109.         $contentValue $this->getValue($contentProperty$data);
  110.         $ratingValue $this->getValue($ratingProperty$data);
  111.         $ratingSymbolValue $this->getValue($ratingSymbolProperty$data);
  112.         if (!$countryValue || !$contentValue || !$ratingValue) {
  113.             return null;
  114.         }
  115.         if (!$censorship $this->filterCensorshipElement($entity$countryValue$contentValue)) {
  116.             $censorship = new ProductCensorship();
  117.             $censorship->setProduct($entity);
  118.             $censorship->setContent($contentValue);
  119.             $censorship->setCountry($countryValue);
  120.             $entity->addCensorship($censorship);
  121.         }
  122.         $censorship->setRating($ratingValue);
  123.         if (!empty($ratingSymbolValue) && ProductCensorship::COUNTRY_FI === $countryValue) {
  124.             $symbols = [];
  125.             foreach (explode(','$ratingSymbolValue) as $symbolChoice) {
  126.                 if (AgeRatingSymbol::accepts($symbolChoice)) {
  127.                     $symbols[] = $symbolChoice;
  128.                 }
  129.             }
  130.             $censorship->setRatingSymbol($symbols);
  131.         }
  132.         $this->getEntityManager()->persist($censorship);
  133.         return $entity;
  134.     }
  135.     /**
  136.      * Responsible for filtering the collection with given values.
  137.      *
  138.      * @param \App\Entity\Product $entity
  139.      *   The instance of the product entity
  140.      * @param string $countryValue
  141.      *   The selected country
  142.      * @param string $contentValue
  143.      *   The selected content type
  144.      *
  145.      * @return \App\Entity\ProductCensorship|null
  146.      *   Either null of no element match the criteria or the censorship item
  147.      */
  148.     protected function filterCensorshipElement(
  149.         Product $entity,
  150.         string $countryValue,
  151.         string $contentValue
  152.     ): ?ProductCensorship {
  153.         // Important - the management form allows for a user to create
  154.         // multiple elements with the same options. While, this should
  155.         // never be a case, you would never know what a user might do.
  156.         // And this is why here, we don't care if such case exists or not.
  157.         // THe moment we find an element matching the criteria, we ignore the rest.
  158.         if ($entity->getCensorship()->isEmpty()) {
  159.             return null;
  160.         }
  161.         $censorshipElement null;
  162.         /** @var \App\Entity\ProductCensorship $element */
  163.         foreach ($entity->getCensorship() as $element) {
  164.             if ($countryValue === $element->getCountry() && $contentValue === $element->getContent()) {
  165.                 $censorshipElement $element;
  166.                 break;
  167.             }
  168.         }
  169.         return $censorshipElement;
  170.     }
  171. }