vendor/sylius/resource-bundle/src/Bundle/EventListener/ORMMappedSuperClassSubscriber.php line 38

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Sylius package.
  4.  *
  5.  * (c) Paweł Jędrzejewski
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace Sylius\Bundle\ResourceBundle\EventListener;
  12. use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
  13. use Doctrine\ORM\Configuration;
  14. use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
  15. use Doctrine\ORM\Events;
  16. use Doctrine\ORM\Mapping\ClassMetadata;
  17. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  18. use Webmozart\Assert\Assert;
  19. final class ORMMappedSuperClassSubscriber extends AbstractDoctrineSubscriber
  20. {
  21.     public function getSubscribedEvents(): array
  22.     {
  23.         return [
  24.             Events::loadClassMetadata,
  25.         ];
  26.     }
  27.     public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
  28.     {
  29.         $metadata $eventArgs->getClassMetadata();
  30.         if (!$metadata->isMappedSuperclass) {
  31.             $this->setAssociationMappings($metadata$eventArgs->getEntityManager()->getConfiguration());
  32.         } else {
  33.             $this->unsetAssociationMappings($metadata);
  34.         }
  35.     }
  36.     private function setAssociationMappings(ClassMetadataInfo $metadataConfiguration $configuration): void
  37.     {
  38.         $class $metadata->getName();
  39.         if (!class_exists($class)) {
  40.             return;
  41.         }
  42.         $metadataDriver $configuration->getMetadataDriverImpl();
  43.         Assert::isInstanceOf($metadataDriverMappingDriver::class);
  44.         foreach (class_parents($class) as $parent) {
  45.             if (false === in_array($parent$metadataDriver->getAllClassNames(), true)) {
  46.                 continue;
  47.             }
  48.             $parentMetadata = new ClassMetadata(
  49.                 $parent,
  50.                 $configuration->getNamingStrategy()
  51.             );
  52.             // Wakeup Reflection
  53.             $parentMetadata->wakeupReflection($this->getReflectionService());
  54.             // Load Metadata
  55.             $metadataDriver->loadMetadataForClass($parent$parentMetadata);
  56.             /** @psalm-suppress InvalidArgument */
  57.             if (false === $this->isResource($parentMetadata)) {
  58.                 continue;
  59.             }
  60.             if ($parentMetadata->isMappedSuperclass) {
  61.                 foreach ($parentMetadata->getAssociationMappings() as $key => $value) {
  62.                     if ($this->isRelation($value['type']) && !isset($metadata->associationMappings[$key])) {
  63.                         $metadata->associationMappings[$key] = $value;
  64.                     }
  65.                 }
  66.             }
  67.         }
  68.     }
  69.     private function unsetAssociationMappings(ClassMetadataInfo $metadata): void
  70.     {
  71.         /** @psalm-suppress InvalidArgument */
  72.         if (false === $this->isResource($metadata)) {
  73.             return;
  74.         }
  75.         foreach ($metadata->getAssociationMappings() as $key => $value) {
  76.             if ($this->isRelation($value['type'])) {
  77.                 unset($metadata->associationMappings[$key]);
  78.             }
  79.         }
  80.     }
  81.     private function isRelation(int $type): bool
  82.     {
  83.         return in_array(
  84.             $type,
  85.             [
  86.                 ClassMetadataInfo::MANY_TO_MANY,
  87.                 ClassMetadataInfo::ONE_TO_MANY,
  88.                 ClassMetadataInfo::ONE_TO_ONE,
  89.             ],
  90.             true
  91.         );
  92.     }
  93. }