Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. ClassMapGenerator.php

function ClassMapGenerator::scanPaths

Iterate over all files in the given directory searching for classes

Parameters

string|\Traversable<\SplFileInfo>|array<\SplFileInfo> $path The path to search in or an array/traversable of SplFileInfo (e.g. symfony/finder instance):

non-empty-string|null $excluded Regex that matches file paths to be excluded from the classmap:

'classmap'|'psr-0'|'psr-4' $autoloadType Optional autoload standard to use mapping rules with the namespace instead of purely doing a classmap:

string|null $namespace Optional namespace prefix to filter by, only for psr-0/psr-4 autoloading:

array<string> $excludedDirs Optional dirs to exclude from search relative to $path:

Throws

\RuntimeException When the path is neither an existing file nor directory

File

vendor/composer/class-map-generator/src/ClassMapGenerator.php, line 104

Class

ClassMapGenerator
ClassMapGenerator

Namespace

Composer\ClassMapGenerator

Code

public function scanPaths($path, ?string $excluded = null, string $autoloadType = 'classmap', ?string $namespace = null, array $excludedDirs = []) : void {
    if (!in_array($autoloadType, [
        'psr-0',
        'psr-4',
        'classmap',
    ], true)) {
        throw new \InvalidArgumentException('$autoloadType must be one of: "psr-0", "psr-4" or "classmap"');
    }
    if ('classmap' !== $autoloadType) {
        if (!is_string($path)) {
            throw new \InvalidArgumentException('$path must be a string when specifying a psr-0 or psr-4 autoload type');
        }
        if (!is_string($namespace)) {
            throw new \InvalidArgumentException('$namespace must be given (even if it is an empty string if you do not want to filter) when specifying a psr-0 or psr-4 autoload type');
        }
        $basePath = $path;
    }
    if (is_string($path)) {
        if (is_file($path)) {
            $path = [
                new \SplFileInfo($path),
            ];
        }
        elseif (is_dir($path) || strpos($path, '*') !== false) {
            $path = Finder::create()->files()
                ->followLinks()
                ->name('/\\.(?:' . implode('|', array_map('preg_quote', $this->extensions)) . ')$/')
                ->in($path)
                ->exclude($excludedDirs);
        }
        else {
            throw new \RuntimeException('Could not scan for classes inside "' . $path . '" which does not appear to be a file nor a folder');
        }
    }
    $cwd = realpath(self::getCwd());
    foreach ($path as $file) {
        $filePath = $file->getPathname();
        if (!in_array(pathinfo($filePath, PATHINFO_EXTENSION), $this->extensions, true)) {
            continue;
        }
        if (!self::isAbsolutePath($filePath)) {
            $filePath = $cwd . '/' . $filePath;
            $filePath = self::normalizePath($filePath);
        }
        else {
            $filePath = Preg::replace('{[\\\\/]{2,}}', '/', $filePath);
        }
        if ('' === $filePath) {
            throw new \LogicException('Got an empty $filePath for ' . $file->getPathname());
        }
        $realPath = realpath($filePath);
        // fallback just in case but this really should not happen
        if (false === $realPath) {
            throw new \RuntimeException('realpath of ' . $filePath . ' failed to resolve, got false');
        }
        // if a list of scanned files is given, avoid scanning twice the same file to save cycles and avoid generating warnings
        // in case a PSR-0/4 declaration follows another more specific one, or a classmap declaration, which covered this file already
        if ($this->scannedFiles !== null && $this->scannedFiles
            ->contains($realPath)) {
            continue;
        }
        // check the realpath of the file against the excluded paths as the path might be a symlink and the excluded path is realpath'd so symlink are resolved
        if (null !== $excluded && Preg::isMatch($excluded, strtr($realPath, '\\', '/'))) {
            continue;
        }
        // check non-realpath of file for directories symlink in project dir
        if (null !== $excluded && Preg::isMatch($excluded, strtr($filePath, '\\', '/'))) {
            continue;
        }
        $classes = PhpFileParser::findClasses($filePath);
        if ('classmap' !== $autoloadType && isset($namespace)) {
            $classes = $this->filterByNamespace($classes, $filePath, $namespace, $autoloadType, $basePath);
            // if no valid class was found in the file then we do not mark it as scanned as it might still be matched by another rule later
            if (\count($classes) > 0 && $this->scannedFiles !== null) {
                $this->scannedFiles
                    ->add($realPath);
            }
        }
        elseif ($this->scannedFiles !== null) {
            // classmap autoload rules always collect all classes so for these we definitely do not want to scan again
            $this->scannedFiles
                ->add($realPath);
        }
        foreach ($classes as $class) {
            if (!$this->classMap
                ->hasClass($class)) {
                $this->classMap
                    ->addClass($class, $filePath);
            }
            elseif ($filePath !== $this->classMap
                ->getClassPath($class)) {
                $this->classMap
                    ->addAmbiguousClass($class, $filePath);
            }
        }
    }
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal