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

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.             if (false === $this->isResource($parentMetadata)) {
  57.                 continue;
  58.             }
  59.             if ($parentMetadata->isMappedSuperclass) {
  60.                 foreach ($parentMetadata->getAssociationMappings() as $key => $value) {
  61.                     if ($this->isRelation($value['type']) && !isset($metadata->associationMappings[$key])) {
  62.                         $metadata->associationMappings[$key] = $value;
  63.                     }
  64.                 }
  65.             }
  66.         }
  67.     }
  68.     private function unsetAssociationMappings(ClassMetadataInfo $metadata): void
  69.     {
  70.         if (false === $this->isResource($metadata)) {
  71.             return;
  72.         }
  73.         foreach ($metadata->getAssociationMappings() as $key => $value) {
  74.             if ($this->isRelation($value['type'])) {
  75.                 unset($metadata->associationMappings[$key]);
  76.             }
  77.         }
  78.     }
  79.     private function isRelation(int $type): bool
  80.     {
  81.         return in_array(
  82.             $type,
  83.             [
  84.                 ClassMetadataInfo::MANY_TO_MANY,
  85.                 ClassMetadataInfo::ONE_TO_MANY,
  86.                 ClassMetadataInfo::ONE_TO_ONE,
  87.             ],
  88.             true
  89.         );
  90.     }
  91. }