vendor/doctrine/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 /*
       
     3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
     4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
     5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
     6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
     7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
     8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
     9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    14  *
       
    15  * This software consists of voluntary contributions made by many individuals
       
    16  * and is licensed under the LGPL. For more information, see
       
    17  * <http://www.doctrine-project.org>.
       
    18  */
       
    19 
       
    20 namespace Doctrine\ORM\Mapping\Driver;
       
    21 
       
    22 use Doctrine\Common\Cache\ArrayCache,
       
    23     Doctrine\Common\Annotations\AnnotationReader,
       
    24     Doctrine\Common\Annotations\AnnotationRegistry,
       
    25     Doctrine\ORM\Mapping\ClassMetadataInfo,
       
    26     Doctrine\ORM\Mapping\MappingException;
       
    27 
       
    28 /**
       
    29  * The AnnotationDriver reads the mapping metadata from docblock annotations.
       
    30  *
       
    31  * @since 2.0
       
    32  * @author Benjamin Eberlei <kontakt@beberlei.de>
       
    33  * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
       
    34  * @author Jonathan H. Wage <jonwage@gmail.com>
       
    35  * @author Roman Borschel <roman@code-factory.org>
       
    36  */
       
    37 class AnnotationDriver implements Driver
       
    38 {
       
    39     /**
       
    40      * The AnnotationReader.
       
    41      *
       
    42      * @var AnnotationReader
       
    43      */
       
    44     protected $_reader;
       
    45 
       
    46     /**
       
    47      * The paths where to look for mapping files.
       
    48      *
       
    49      * @var array
       
    50      */
       
    51     protected $_paths = array();
       
    52 
       
    53     /**
       
    54      * The file extension of mapping documents.
       
    55      *
       
    56      * @var string
       
    57      */
       
    58     protected $_fileExtension = '.php';
       
    59 
       
    60     /**
       
    61      * @param array
       
    62      */
       
    63     protected $_classNames;
       
    64 
       
    65     /**
       
    66      * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
       
    67      * docblock annotations.
       
    68      *
       
    69      * @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
       
    70      * @param string|array $paths One or multiple paths where mapping classes can be found.
       
    71      */
       
    72     public function __construct($reader, $paths = null)
       
    73     {
       
    74         $this->_reader = $reader;
       
    75         if ($paths) {
       
    76             $this->addPaths((array) $paths);
       
    77         }
       
    78     }
       
    79 
       
    80     /**
       
    81      * Append lookup paths to metadata driver.
       
    82      *
       
    83      * @param array $paths
       
    84      */
       
    85     public function addPaths(array $paths)
       
    86     {
       
    87         $this->_paths = array_unique(array_merge($this->_paths, $paths));
       
    88     }
       
    89 
       
    90     /**
       
    91      * Retrieve the defined metadata lookup paths.
       
    92      *
       
    93      * @return array
       
    94      */
       
    95     public function getPaths()
       
    96     {
       
    97         return $this->_paths;
       
    98     }
       
    99 
       
   100     /**
       
   101      * Get the file extension used to look for mapping files under
       
   102      *
       
   103      * @return void
       
   104      */
       
   105     public function getFileExtension()
       
   106     {
       
   107         return $this->_fileExtension;
       
   108     }
       
   109 
       
   110     /**
       
   111      * Set the file extension used to look for mapping files under
       
   112      *
       
   113      * @param string $fileExtension The file extension to set
       
   114      * @return void
       
   115      */
       
   116     public function setFileExtension($fileExtension)
       
   117     {
       
   118         $this->_fileExtension = $fileExtension;
       
   119     }
       
   120 
       
   121     /**
       
   122      * {@inheritdoc}
       
   123      */
       
   124     public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
       
   125     {
       
   126         $class = $metadata->getReflectionClass();
       
   127 
       
   128         $classAnnotations = $this->_reader->getClassAnnotations($class);
       
   129 
       
   130         // Compatibility with Doctrine Common 3.x
       
   131         if ($classAnnotations && is_int(key($classAnnotations))) {
       
   132             foreach ($classAnnotations as $annot) {
       
   133                 $classAnnotations[get_class($annot)] = $annot;
       
   134             }
       
   135         }
       
   136 
       
   137         // Evaluate Entity annotation
       
   138         if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) {
       
   139             $entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity'];
       
   140             $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
       
   141 
       
   142             if ($entityAnnot->readOnly) {
       
   143                 $metadata->markReadOnly();
       
   144             }
       
   145         } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
       
   146             $metadata->isMappedSuperclass = true;
       
   147         } else {
       
   148             throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
       
   149         }
       
   150 
       
   151         // Evaluate Table annotation
       
   152         if (isset($classAnnotations['Doctrine\ORM\Mapping\Table'])) {
       
   153             $tableAnnot = $classAnnotations['Doctrine\ORM\Mapping\Table'];
       
   154             $primaryTable = array(
       
   155                 'name' => $tableAnnot->name,
       
   156                 'schema' => $tableAnnot->schema
       
   157             );
       
   158 
       
   159             if ($tableAnnot->indexes !== null) {
       
   160                 foreach ($tableAnnot->indexes as $indexAnnot) {
       
   161                     $primaryTable['indexes'][$indexAnnot->name] = array(
       
   162                         'columns' => $indexAnnot->columns
       
   163                     );
       
   164                 }
       
   165             }
       
   166 
       
   167             if ($tableAnnot->uniqueConstraints !== null) {
       
   168                 foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) {
       
   169                     $primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array(
       
   170                         'columns' => $uniqueConstraint->columns
       
   171                     );
       
   172                 }
       
   173             }
       
   174 
       
   175             $metadata->setPrimaryTable($primaryTable);
       
   176         }
       
   177 
       
   178         // Evaluate NamedQueries annotation
       
   179         if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
       
   180             $namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
       
   181 
       
   182             foreach ($namedQueriesAnnot->value as $namedQuery) {
       
   183                 $metadata->addNamedQuery(array(
       
   184                     'name'  => $namedQuery->name,
       
   185                     'query' => $namedQuery->query
       
   186                 ));
       
   187             }
       
   188         }
       
   189 
       
   190         // Evaluate InheritanceType annotation
       
   191         if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
       
   192             $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
       
   193             $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value));
       
   194 
       
   195             if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
       
   196                 // Evaluate DiscriminatorColumn annotation
       
   197                 if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) {
       
   198                     $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'];
       
   199                     $metadata->setDiscriminatorColumn(array(
       
   200                         'name' => $discrColumnAnnot->name,
       
   201                         'type' => $discrColumnAnnot->type,
       
   202                         'length' => $discrColumnAnnot->length
       
   203                     ));
       
   204                 } else {
       
   205                     $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
       
   206                 }
       
   207 
       
   208                 // Evaluate DiscriminatorMap annotation
       
   209                 if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) {
       
   210                     $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'];
       
   211                     $metadata->setDiscriminatorMap($discrMapAnnot->value);
       
   212                 }
       
   213             }
       
   214         }
       
   215 
       
   216 
       
   217         // Evaluate DoctrineChangeTrackingPolicy annotation
       
   218         if (isset($classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'])) {
       
   219             $changeTrackingAnnot = $classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'];
       
   220             $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' . $changeTrackingAnnot->value));
       
   221         }
       
   222 
       
   223         // Evaluate annotations on properties/fields
       
   224         foreach ($class->getProperties() as $property) {
       
   225             if ($metadata->isMappedSuperclass && ! $property->isPrivate()
       
   226                 ||
       
   227                 $metadata->isInheritedField($property->name)
       
   228                 ||
       
   229                 $metadata->isInheritedAssociation($property->name)) {
       
   230                 continue;
       
   231             }
       
   232 
       
   233             $mapping = array();
       
   234             $mapping['fieldName'] = $property->getName();
       
   235 
       
   236             // Check for JoinColummn/JoinColumns annotations
       
   237             $joinColumns = array();
       
   238 
       
   239             if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
       
   240                 $joinColumns[] = array(
       
   241                     'name' => $joinColumnAnnot->name,
       
   242                     'referencedColumnName' => $joinColumnAnnot->referencedColumnName,
       
   243                     'unique' => $joinColumnAnnot->unique,
       
   244                     'nullable' => $joinColumnAnnot->nullable,
       
   245                     'onDelete' => $joinColumnAnnot->onDelete,
       
   246                     'onUpdate' => $joinColumnAnnot->onUpdate,
       
   247                     'columnDefinition' => $joinColumnAnnot->columnDefinition,
       
   248                 );
       
   249             } else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
       
   250                 foreach ($joinColumnsAnnot->value as $joinColumn) {
       
   251                     $joinColumns[] = array(
       
   252                         'name' => $joinColumn->name,
       
   253                         'referencedColumnName' => $joinColumn->referencedColumnName,
       
   254                         'unique' => $joinColumn->unique,
       
   255                         'nullable' => $joinColumn->nullable,
       
   256                         'onDelete' => $joinColumn->onDelete,
       
   257                         'onUpdate' => $joinColumn->onUpdate,
       
   258                         'columnDefinition' => $joinColumn->columnDefinition,
       
   259                     );
       
   260                 }
       
   261             }
       
   262 
       
   263             // Field can only be annotated with one of:
       
   264             // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
       
   265             if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) {
       
   266                 if ($columnAnnot->type == null) {
       
   267                     throw MappingException::propertyTypeIsRequired($className, $property->getName());
       
   268                 }
       
   269 
       
   270                 $mapping['type'] = $columnAnnot->type;
       
   271                 $mapping['length'] = $columnAnnot->length;
       
   272                 $mapping['precision'] = $columnAnnot->precision;
       
   273                 $mapping['scale'] = $columnAnnot->scale;
       
   274                 $mapping['nullable'] = $columnAnnot->nullable;
       
   275                 $mapping['unique'] = $columnAnnot->unique;
       
   276                 if ($columnAnnot->options) {
       
   277                     $mapping['options'] = $columnAnnot->options;
       
   278                 }
       
   279 
       
   280                 if (isset($columnAnnot->name)) {
       
   281                     $mapping['columnName'] = $columnAnnot->name;
       
   282                 }
       
   283 
       
   284                 if (isset($columnAnnot->columnDefinition)) {
       
   285                     $mapping['columnDefinition'] = $columnAnnot->columnDefinition;
       
   286                 }
       
   287 
       
   288                 if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
       
   289                     $mapping['id'] = true;
       
   290                 }
       
   291 
       
   292                 if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) {
       
   293                     $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
       
   294                 }
       
   295 
       
   296                 if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
       
   297                     $metadata->setVersionMapping($mapping);
       
   298                 }
       
   299 
       
   300                 $metadata->mapField($mapping);
       
   301 
       
   302                 // Check for SequenceGenerator/TableGenerator definition
       
   303                 if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) {
       
   304                     $metadata->setSequenceGeneratorDefinition(array(
       
   305                         'sequenceName' => $seqGeneratorAnnot->sequenceName,
       
   306                         'allocationSize' => $seqGeneratorAnnot->allocationSize,
       
   307                         'initialValue' => $seqGeneratorAnnot->initialValue
       
   308                     ));
       
   309                 } else if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
       
   310                     throw MappingException::tableIdGeneratorNotImplemented($className);
       
   311                 }
       
   312             } else if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
       
   313                 if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
       
   314                     $mapping['id'] = true;
       
   315                 }
       
   316 
       
   317                 $mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
       
   318                 $mapping['joinColumns'] = $joinColumns;
       
   319                 $mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
       
   320                 $mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
       
   321                 $mapping['cascade'] = $oneToOneAnnot->cascade;
       
   322                 $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
       
   323                 $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneAnnot->fetch);
       
   324                 $metadata->mapOneToOne($mapping);
       
   325             } else if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) {
       
   326                 $mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
       
   327                 $mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
       
   328                 $mapping['cascade'] = $oneToManyAnnot->cascade;
       
   329                 $mapping['indexBy'] = $oneToManyAnnot->indexBy;
       
   330                 $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
       
   331                 $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyAnnot->fetch);
       
   332 
       
   333                 if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
       
   334                     $mapping['orderBy'] = $orderByAnnot->value;
       
   335                 }
       
   336 
       
   337                 $metadata->mapOneToMany($mapping);
       
   338             } else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
       
   339                 if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
       
   340                     $mapping['id'] = true;
       
   341                 }
       
   342 
       
   343                 $mapping['joinColumns'] = $joinColumns;
       
   344                 $mapping['cascade'] = $manyToOneAnnot->cascade;
       
   345                 $mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
       
   346                 $mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
       
   347                 $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneAnnot->fetch);
       
   348                 $metadata->mapManyToOne($mapping);
       
   349             } else if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) {
       
   350                 $joinTable = array();
       
   351 
       
   352                 if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) {
       
   353                     $joinTable = array(
       
   354                         'name' => $joinTableAnnot->name,
       
   355                         'schema' => $joinTableAnnot->schema
       
   356                     );
       
   357 
       
   358                     foreach ($joinTableAnnot->joinColumns as $joinColumn) {
       
   359                         $joinTable['joinColumns'][] = array(
       
   360                             'name' => $joinColumn->name,
       
   361                             'referencedColumnName' => $joinColumn->referencedColumnName,
       
   362                             'unique' => $joinColumn->unique,
       
   363                             'nullable' => $joinColumn->nullable,
       
   364                             'onDelete' => $joinColumn->onDelete,
       
   365                             'onUpdate' => $joinColumn->onUpdate,
       
   366                             'columnDefinition' => $joinColumn->columnDefinition,
       
   367                         );
       
   368                     }
       
   369 
       
   370                     foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
       
   371                         $joinTable['inverseJoinColumns'][] = array(
       
   372                             'name' => $joinColumn->name,
       
   373                             'referencedColumnName' => $joinColumn->referencedColumnName,
       
   374                             'unique' => $joinColumn->unique,
       
   375                             'nullable' => $joinColumn->nullable,
       
   376                             'onDelete' => $joinColumn->onDelete,
       
   377                             'onUpdate' => $joinColumn->onUpdate,
       
   378                             'columnDefinition' => $joinColumn->columnDefinition,
       
   379                         );
       
   380                     }
       
   381                 }
       
   382 
       
   383                 $mapping['joinTable'] = $joinTable;
       
   384                 $mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
       
   385                 $mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
       
   386                 $mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
       
   387                 $mapping['cascade'] = $manyToManyAnnot->cascade;
       
   388                 $mapping['indexBy'] = $manyToManyAnnot->indexBy;
       
   389                 $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyAnnot->fetch);
       
   390 
       
   391                 if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
       
   392                     $mapping['orderBy'] = $orderByAnnot->value;
       
   393                 }
       
   394 
       
   395                 $metadata->mapManyToMany($mapping);
       
   396             }
       
   397         }
       
   398 
       
   399         // Evaluate @HasLifecycleCallbacks annotation
       
   400         if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
       
   401             foreach ($class->getMethods() as $method) {
       
   402                 // filter for the declaring class only, callbacks from parents will already be registered.
       
   403                 if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) {
       
   404                     $annotations = $this->_reader->getMethodAnnotations($method);
       
   405 
       
   406                     // Compatibility with Doctrine Common 3.x
       
   407                     if ($annotations && is_int(key($annotations))) {
       
   408                         foreach ($annotations as $annot) {
       
   409                             $annotations[get_class($annot)] = $annot;
       
   410                         }
       
   411                     }
       
   412 
       
   413                     if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) {
       
   414                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
       
   415                     }
       
   416 
       
   417                     if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) {
       
   418                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist);
       
   419                     }
       
   420 
       
   421                     if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) {
       
   422                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate);
       
   423                     }
       
   424 
       
   425                     if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) {
       
   426                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate);
       
   427                     }
       
   428 
       
   429                     if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) {
       
   430                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove);
       
   431                     }
       
   432 
       
   433                     if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) {
       
   434                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove);
       
   435                     }
       
   436 
       
   437                     if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) {
       
   438                         $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
       
   439                     }
       
   440                 }
       
   441             }
       
   442         }
       
   443     }
       
   444 
       
   445     /**
       
   446      * Whether the class with the specified name is transient. Only non-transient
       
   447      * classes, that is entities and mapped superclasses, should have their metadata loaded.
       
   448      * A class is non-transient if it is annotated with either @Entity or
       
   449      * @MappedSuperclass in the class doc block.
       
   450      *
       
   451      * @param string $className
       
   452      * @return boolean
       
   453      */
       
   454     public function isTransient($className)
       
   455     {
       
   456         $classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className));
       
   457 
       
   458         // Compatibility with Doctrine Common 3.x
       
   459         if ($classAnnotations && is_int(key($classAnnotations))) {
       
   460             foreach ($classAnnotations as $annot) {
       
   461                 if ($annot instanceof \Doctrine\ORM\Mapping\Entity) {
       
   462                     return false;
       
   463                 }
       
   464                 if ($annot instanceof \Doctrine\ORM\Mapping\MappedSuperclass) {
       
   465                     return false;
       
   466                 }
       
   467             }
       
   468 
       
   469             return true;
       
   470         }
       
   471 
       
   472         return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) &&
       
   473                ! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']);
       
   474     }
       
   475 
       
   476     /**
       
   477      * {@inheritDoc}
       
   478      */
       
   479     public function getAllClassNames()
       
   480     {
       
   481         if ($this->_classNames !== null) {
       
   482             return $this->_classNames;
       
   483         }
       
   484 
       
   485         if (!$this->_paths) {
       
   486             throw MappingException::pathRequired();
       
   487         }
       
   488 
       
   489         $classes = array();
       
   490         $includedFiles = array();
       
   491 
       
   492         foreach ($this->_paths as $path) {
       
   493             if ( ! is_dir($path)) {
       
   494                 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
       
   495             }
       
   496 
       
   497             $iterator = new \RegexIterator(
       
   498                 new \RecursiveIteratorIterator(
       
   499                     new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
       
   500                     \RecursiveIteratorIterator::LEAVES_ONLY
       
   501                 ),
       
   502                 '/^.+\\' . $this->_fileExtension . '$/i', 
       
   503                 \RecursiveRegexIterator::GET_MATCH
       
   504             );
       
   505             
       
   506             foreach ($iterator as $file) {
       
   507                 $sourceFile = realpath($file[0]);
       
   508                 
       
   509                 require_once $sourceFile;
       
   510                 
       
   511                 $includedFiles[] = $sourceFile;
       
   512             }
       
   513         }
       
   514 
       
   515         $declared = get_declared_classes();
       
   516 
       
   517         foreach ($declared as $className) {
       
   518             $rc = new \ReflectionClass($className);
       
   519             $sourceFile = $rc->getFileName();
       
   520             if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
       
   521                 $classes[] = $className;
       
   522             }
       
   523         }
       
   524 
       
   525         $this->_classNames = $classes;
       
   526 
       
   527         return $classes;
       
   528     }
       
   529 
       
   530     /**
       
   531      * Factory method for the Annotation Driver
       
   532      *
       
   533      * @param array|string $paths
       
   534      * @param AnnotationReader $reader
       
   535      * @return AnnotationDriver
       
   536      */
       
   537     static public function create($paths = array(), AnnotationReader $reader = null)
       
   538     {
       
   539         if ($reader == null) {
       
   540             $reader = new AnnotationReader();
       
   541             $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
       
   542         }
       
   543         return new self($reader, $paths);
       
   544     }
       
   545 }