vendor/symfony/src/Symfony/Bundle/DoctrineBundle/Mapping/MetadataFactory.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Bundle\DoctrineBundle\Mapping;
       
    13 
       
    14 use Symfony\Bridge\Doctrine\RegistryInterface;
       
    15 use Symfony\Component\HttpKernel\Bundle\BundleInterface;
       
    16 use Doctrine\ORM\Tools\EntityRepositoryGenerator;
       
    17 use Doctrine\ORM\Mapping\ClassMetadata;
       
    18 use Doctrine\ORM\Mapping\ClassMetadataInfo;
       
    19 use Doctrine\ORM\Mapping\MappingException;
       
    20 use Doctrine\ORM\ORMException;
       
    21 
       
    22 /**
       
    23  * This class provides methods to access Doctrine entity class metadata for a
       
    24  * given bundle, namespace or entity class.
       
    25  *
       
    26  * @author Fabien Potencier <fabien@symfony.com>
       
    27  */
       
    28 class MetadataFactory
       
    29 {
       
    30     private $registry;
       
    31 
       
    32     /**
       
    33      * Constructor.
       
    34      *
       
    35      * @param RegistryInterface $registry A RegistryInterface instance
       
    36      */
       
    37     public function __construct(RegistryInterface $registry)
       
    38     {
       
    39         $this->registry = $registry;
       
    40     }
       
    41 
       
    42     /**
       
    43      * Gets the metadata of all classes of a bundle.
       
    44      *
       
    45      * @param BundleInterface $bundle A BundleInterface instance
       
    46      *
       
    47      * @return ClassMetadataCollection A ClassMetadataCollection instance
       
    48      */
       
    49     public function getBundleMetadata(BundleInterface $bundle)
       
    50     {
       
    51         $namespace = $bundle->getNamespace();
       
    52         $metadata = $this->getMetadataForNamespace($namespace);
       
    53         if (!$metadata->getMetadata()) {
       
    54             throw new \RuntimeException(sprintf('Bundle "%s" does not contain any mapped entities.', $bundle->getName()));
       
    55         }
       
    56 
       
    57         $path = $this->getBasePathForClass($bundle->getName(), $bundle->getNamespace(), $bundle->getPath());
       
    58 
       
    59         $metadata->setPath($path);
       
    60         $metadata->setNamespace($bundle->getNamespace());
       
    61 
       
    62         return $metadata;
       
    63     }
       
    64 
       
    65     /**
       
    66      * Gets the metadata of a class.
       
    67      *
       
    68      * @param string $class A class name
       
    69      * @param string $path  The path where the class is stored (if known)
       
    70      *
       
    71      * @return ClassMetadataCollection A ClassMetadataCollection instance
       
    72      */
       
    73     public function getClassMetadata($class, $path = null)
       
    74     {
       
    75         $metadata = $this->getMetadataForClass($class);
       
    76         if (!$metadata->getMetadata()) {
       
    77             throw MappingException::classIsNotAValidEntityOrMappedSuperClass($class);
       
    78         }
       
    79 
       
    80         $all = $metadata->getMetadata();
       
    81         if (class_exists($class)) {
       
    82             $r = $all[0]->getReflectionClass();
       
    83             $path = $this->getBasePathForClass($class, $r->getNamespacename(), dirname($r->getFilename()));
       
    84         } elseif (!$path) {
       
    85             throw new \RuntimeException(sprintf('Unable to determine where to save the "%s" class (use the --path option).', $class));
       
    86         }
       
    87 
       
    88         $metadata->setPath($path);
       
    89         $metadata->setNamespace($r->getNamespacename());
       
    90 
       
    91         return $metadata;
       
    92     }
       
    93 
       
    94     /**
       
    95      * Gets the metadata of all classes of a namespace.
       
    96      *
       
    97      * @param string $namespace A namespace name
       
    98      * @param string $path      The path where the class is stored (if known)
       
    99      *
       
   100      * @return ClassMetadataCollection A ClassMetadataCollection instance
       
   101      */
       
   102     public function getNamespaceMetadata($namespace, $path = null)
       
   103     {
       
   104         $metadata = $this->getMetadataForNamespace($namespace);
       
   105         if (!$metadata->getMetadata()) {
       
   106             throw new \RuntimeException(sprintf('Namespace "%s" does not contain any mapped entities.', $namespace));
       
   107         }
       
   108 
       
   109         $all = $metadata->getMetadata();
       
   110         if (class_exists($all[0]->name)) {
       
   111             $r = $all[0]->getReflectionClass();
       
   112             $path = $this->getBasePathForClass($namespace, $r->getNamespacename(), dirname($r->getFilename()));
       
   113         } elseif (!$path) {
       
   114             throw new \RuntimeException(sprintf('Unable to determine where to save the "%s" class (use the --path option).', $all[0]->name));
       
   115         }
       
   116 
       
   117         $metadata->setPath($path);
       
   118         $metadata->setNamespace($namespace);
       
   119 
       
   120         return $metadata;
       
   121     }
       
   122 
       
   123     private function getBasePathForClass($name, $namespace, $path)
       
   124     {
       
   125         $namespace = str_replace('\\', '/', $namespace);
       
   126         $search = str_replace('\\', '/', $path);
       
   127         $destination = str_replace('/'.$namespace, '', $search, $c);
       
   128 
       
   129         if ($c != 1) {
       
   130             throw new \RuntimeException(sprintf('Can\'t find base path for "%s" (path: "%s", destination: "%s").', $name, $path, $destination));
       
   131         }
       
   132 
       
   133         return $destination;
       
   134     }
       
   135 
       
   136     private function getMetadataForNamespace($namespace)
       
   137     {
       
   138         $metadata = array();
       
   139         foreach ($this->getAllMetadata() as $m) {
       
   140             if (strpos($m->name, $namespace) === 0) {
       
   141                 $metadata[] = $m;
       
   142             }
       
   143         }
       
   144 
       
   145         return new ClassMetadataCollection($metadata);
       
   146     }
       
   147 
       
   148     private function getMetadataForClass($entity)
       
   149     {
       
   150         foreach ($this->getAllMetadata() as $metadata) {
       
   151             if ($metadata->name === $entity) {
       
   152                 return new ClassMetadataCollection(array($metadata));
       
   153             }
       
   154         }
       
   155 
       
   156         return new ClassMetadataCollection(array());
       
   157     }
       
   158 
       
   159     private function getAllMetadata()
       
   160     {
       
   161         $metadata = array();
       
   162         foreach ($this->registry->getEntityManagers() as $em) {
       
   163             $class = $this->getClassMetadataFactoryClass();
       
   164             $cmf = new $class();
       
   165             $cmf->setEntityManager($em);
       
   166             foreach ($cmf->getAllMetadata() as $m) {
       
   167                 $metadata[] = $m;
       
   168             }
       
   169         }
       
   170 
       
   171         return $metadata;
       
   172     }
       
   173 
       
   174     protected function getClassMetadataFactoryClass()
       
   175     {
       
   176         return 'Doctrine\\ORM\\Mapping\\ClassMetadataFactory';
       
   177     }
       
   178 }