TheCelavi

Aop - support for doctrine entities

Jul 8th, 2017
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 2.62 KB | None | 0 0
  1. <?php
  2.  
  3. namespace AppBundle\Listener\Aop;
  4.  
  5. use AppBundle\Utils\ClassUtils;
  6. use Doctrine\Common\EventSubscriber;
  7. use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
  8. use Doctrine\ORM\Events;
  9. use Doctrine\ORM\Mapping\ClassMetadata;
  10. use Go\Core\AspectContainer;
  11.  
  12. class MetadataLoadInterceptor implements EventSubscriber
  13. {
  14.     /**
  15.      * {@inheritdoc}
  16.      */
  17.     public function getSubscribedEvents()
  18.     {
  19.         return [
  20.             Events::loadClassMetadata
  21.         ];
  22.     }
  23.    
  24.     public function loadClassMetadata(LoadClassMetadataEventArgs $args)
  25.     {
  26.         /**
  27.          * @var ClassMetadata $metadata
  28.          */
  29.         $metadata = $args->getClassMetadata();
  30.  
  31.         // First, I will check if entity class is AOP proxy class (instead of strpos, string->endsWith() should be used, TODO)
  32.         if (false !== strpos($metadata->name, AspectContainer::AOP_PROXIED_SUFFIX)) {
  33.  
  34.             // I will fix entity data first, it is a mapped superclass, it is not embedded, it does not have table, nor repo
  35.             $metadata->isMappedSuperclass = true;
  36.             $metadata->isEmbeddedClass = false;
  37.             $metadata->table = [];
  38.             $metadata->customRepositoryClassName = null;
  39.  
  40.             // Last thing I have to do is to remove all mappings got from traits,
  41.             // All of those will be mapped again in subclass (a concrete class)
  42.             // That is how I can support Gedmo extensions, like TimestampableEntity or BlameableEntity, etc...
  43.             // This class utils is taken from https://github.com/RunOpenCode/traitor-bundle/blob/master/src/RunOpenCode/Bundle/Traitor/Utils/ClassUtils.php
  44.             $traits = ClassUtils::getTraits($metadata->name);
  45.  
  46.             foreach ($traits as $trait) {
  47.  
  48.                 $trait = new \ReflectionClass($trait);
  49.  
  50.                 /**
  51.                  * @var \ReflectionProperty $property
  52.                  */
  53.                 foreach ($trait->getProperties() as $property) {
  54.  
  55.                     $name = $property->getName();
  56.  
  57.                     if (isset($metadata->fieldMappings[$name])) {
  58.                         $mapping = $metadata->fieldMappings[$name];
  59.                         // Each property from trait, found in mapping will be removed, it will be
  60.                         // remapped in concrete class again
  61.                         unset(
  62.                             $metadata->fieldMappings[$name],
  63.                             $metadata->fieldNames[$mapping['columnName']],
  64.                             $metadata->columnNames[$name]
  65.                         );
  66.                     }
  67.                 }
  68.             }
  69.         }
  70.     }
  71. }
Advertisement
Add Comment
Please, Sign In to add comment