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\ClassMapGeneratorCode
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);
}
}
}
}