vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php line 143

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\Persistence\Mapping\Driver;
  4. use Doctrine\Persistence\Mapping\MappingException;
  5. use FilesystemIterator;
  6. use RecursiveDirectoryIterator;
  7. use RecursiveIteratorIterator;
  8. use RecursiveRegexIterator;
  9. use ReflectionClass;
  10. use RegexIterator;
  11. use function array_merge;
  12. use function array_unique;
  13. use function assert;
  14. use function get_declared_classes;
  15. use function in_array;
  16. use function is_dir;
  17. use function preg_match;
  18. use function preg_quote;
  19. use function realpath;
  20. use function str_replace;
  21. use function strpos;
  22. /**
  23.  * The ColocatedMappingDriver reads the mapping metadata located near the code.
  24.  */
  25. trait ColocatedMappingDriver
  26. {
  27.     /**
  28.      * The paths where to look for mapping files.
  29.      *
  30.      * @var array<int, string>
  31.      */
  32.     protected $paths = [];
  33.     /**
  34.      * The paths excluded from path where to look for mapping files.
  35.      *
  36.      * @var array<int, string>
  37.      */
  38.     protected $excludePaths = [];
  39.     /**
  40.      * The file extension of mapping documents.
  41.      *
  42.      * @var string
  43.      */
  44.     protected $fileExtension '.php';
  45.     /**
  46.      * Cache for getAllClassNames().
  47.      *
  48.      * @var array<int, string>|null
  49.      * @psalm-var list<class-string>|null
  50.      */
  51.     protected $classNames;
  52.     /**
  53.      * Appends lookup paths to metadata driver.
  54.      *
  55.      * @param array<int, string> $paths
  56.      *
  57.      * @return void
  58.      */
  59.     public function addPaths(array $paths)
  60.     {
  61.         $this->paths array_unique(array_merge($this->paths$paths));
  62.     }
  63.     /**
  64.      * Retrieves the defined metadata lookup paths.
  65.      *
  66.      * @return array<int, string>
  67.      */
  68.     public function getPaths()
  69.     {
  70.         return $this->paths;
  71.     }
  72.     /**
  73.      * Append exclude lookup paths to metadata driver.
  74.      *
  75.      * @param string[] $paths
  76.      *
  77.      * @return void
  78.      */
  79.     public function addExcludePaths(array $paths)
  80.     {
  81.         $this->excludePaths array_unique(array_merge($this->excludePaths$paths));
  82.     }
  83.     /**
  84.      * Retrieve the defined metadata lookup exclude paths.
  85.      *
  86.      * @return array<int, string>
  87.      */
  88.     public function getExcludePaths()
  89.     {
  90.         return $this->excludePaths;
  91.     }
  92.     /**
  93.      * Gets the file extension used to look for mapping files under.
  94.      *
  95.      * @return string
  96.      */
  97.     public function getFileExtension()
  98.     {
  99.         return $this->fileExtension;
  100.     }
  101.     /**
  102.      * Sets the file extension used to look for mapping files under.
  103.      *
  104.      * @return void
  105.      */
  106.     public function setFileExtension(string $fileExtension)
  107.     {
  108.         $this->fileExtension $fileExtension;
  109.     }
  110.     /**
  111.      * {@inheritDoc}
  112.      *
  113.      * Returns whether the class with the specified name is transient. Only non-transient
  114.      * classes, that is entities and mapped superclasses, should have their metadata loaded.
  115.      *
  116.      * @psalm-param class-string $className
  117.      *
  118.      * @return bool
  119.      */
  120.     abstract public function isTransient(string $className);
  121.     /**
  122.      * Gets the names of all mapped classes known to this driver.
  123.      *
  124.      * @return string[] The names of all mapped classes known to this driver.
  125.      * @psalm-return list<class-string>
  126.      */
  127.     public function getAllClassNames()
  128.     {
  129.         if ($this->classNames !== null) {
  130.             return $this->classNames;
  131.         }
  132.         if ($this->paths === []) {
  133.             throw MappingException::pathRequiredForDriver(static::class);
  134.         }
  135.         $classes       = [];
  136.         $includedFiles = [];
  137.         foreach ($this->paths as $path) {
  138.             if (! is_dir($path)) {
  139.                 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
  140.             }
  141.             $iterator = new RegexIterator(
  142.                 new RecursiveIteratorIterator(
  143.                     new RecursiveDirectoryIterator($pathFilesystemIterator::SKIP_DOTS),
  144.                     RecursiveIteratorIterator::LEAVES_ONLY
  145.                 ),
  146.                 '/^.+' preg_quote($this->fileExtension) . '$/i',
  147.                 RecursiveRegexIterator::GET_MATCH
  148.             );
  149.             foreach ($iterator as $file) {
  150.                 $sourceFile $file[0];
  151.                 if (preg_match('(^phar:)i'$sourceFile) === 0) {
  152.                     $sourceFile realpath($sourceFile);
  153.                 }
  154.                 foreach ($this->excludePaths as $excludePath) {
  155.                     $realExcludePath realpath($excludePath);
  156.                     assert($realExcludePath !== false);
  157.                     $exclude str_replace('\\''/'$realExcludePath);
  158.                     $current str_replace('\\''/'$sourceFile);
  159.                     if (strpos($current$exclude) !== false) {
  160.                         continue 2;
  161.                     }
  162.                 }
  163.                 require_once $sourceFile;
  164.                 $includedFiles[] = $sourceFile;
  165.             }
  166.         }
  167.         $declared get_declared_classes();
  168.         foreach ($declared as $className) {
  169.             $rc = new ReflectionClass($className);
  170.             $sourceFile $rc->getFileName();
  171.             if (! in_array($sourceFile$includedFilestrue) || $this->isTransient($className)) {
  172.                 continue;
  173.             }
  174.             $classes[] = $className;
  175.         }
  176.         $this->classNames $classes;
  177.         return $classes;
  178.     }
  179. }