Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
50.00% |
3 / 6 |
CRAP | |
80.00% |
40 / 50 |
| ComposerClassLocator | |
0.00% |
0 / 1 |
|
50.00% |
3 / 6 |
30.00 | |
80.00% |
40 / 50 |
| __construct | |
0.00% |
0 / 1 |
4.06 | |
84.62% |
11 / 13 |
|||
| setup | |
0.00% |
0 / 1 |
17.82 | |
73.08% |
19 / 26 |
|||
| loadComposerAutoloader | |
0.00% |
0 / 1 |
2.06 | |
75.00% |
3 / 4 |
|||
| getClasses | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| mapClassNameToFileName | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
| mapFileNameToClassName | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
| <?php declare(strict_types = 1); | |
| /* | |
| * Copyright (c) 2019, Josef Kufner <josef@kufner.cz> | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| * | |
| */ | |
| namespace Smalldb\ClassLocator; | |
| use Composer\Autoload\ClassLoader; | |
| class ComposerClassLocator extends CompositeClassLocator implements ClassLocator | |
| { | |
| private bool $setupComplete = false; | |
| private string $baseDir; | |
| private string $comopserAutoloaderPath; | |
| private string $vendorDir; | |
| private RealPathList $includePaths; | |
| private RealPathList $excludePaths; | |
| public function __construct(string $baseDir, $includePaths = [], $excludePaths = [], bool $excludeVendor = true, string $vendorDir = 'vendor') | |
| { | |
| parent::__construct(); | |
| $this->baseDir = realpath($baseDir); | |
| $this->vendorDir = "$baseDir/$vendorDir"; | |
| $this->comopserAutoloaderPath = $this->vendorDir . "/autoload.php"; | |
| if ($includePaths instanceof RealPathList) { | |
| $this->includePaths = $includePaths; | |
| } else { | |
| $this->includePaths = new RealPathList($baseDir, $includePaths ?? []); | |
| } | |
| if ($excludePaths instanceof RealPathList) { | |
| $this->excludePaths = $excludePaths; | |
| } else { | |
| $this->excludePaths = new RealPathList($baseDir, $excludePaths ?? []); | |
| } | |
| if ($excludeVendor) { | |
| $this->excludePaths->add($this->vendorDir); | |
| } | |
| } | |
| private function setup() | |
| { | |
| if ($this->setupComplete) { | |
| return; | |
| } | |
| $autoloader = $this->loadComposerAutoloader($this->comopserAutoloaderPath); | |
| // Class map | |
| $classMap = []; | |
| foreach ($autoloader->getClassMap() as $classname => $filename) { | |
| if (!$this->includePaths->isEmpty() && !$this->includePaths->contains($filename)) { | |
| continue; | |
| } | |
| if ($this->excludePaths->contains($filename)) { | |
| continue; | |
| } | |
| $classMap[$classname] = $filename; | |
| } | |
| if (!empty($classMap)) { | |
| $this->addClassLocator(new ClassMapClassLocator($classMap)); | |
| } | |
| if ($autoloader->isClassMapAuthoritative()) { | |
| // Class map is authoritative, i.e., it contains all existing classes. | |
| return; | |
| } | |
| // PSR-4 | |
| foreach ($autoloader->getPrefixesPsr4() as $prefix => $dirs) { | |
| foreach ($dirs as $dir) { | |
| if ($this->excludePaths->contains($dir)) { | |
| continue; | |
| } | |
| $this->addClassLocator(new Psr4ClassLocator($prefix, $dir, $this->includePaths, $this->excludePaths)); | |
| } | |
| } | |
| // PSR-0 | |
| foreach ($autoloader->getPrefixes() as $dirs) { | |
| foreach ($dirs as $dir) { | |
| if ($this->excludePaths->contains($dir)) { | |
| continue; | |
| } | |
| $this->addClassLocator(new Psr0ClassLocator($dir, $this->includePaths, $this->excludePaths)); | |
| } | |
| } | |
| $this->setupComplete = true; | |
| } | |
| private function loadComposerAutoloader(string $autoloaderFilename): ClassLoader | |
| { | |
| $composerAutoloader = require($autoloaderFilename); | |
| if (!($composerAutoloader instanceof ClassLoader)) { | |
| throw new \RuntimeException("Composer autoloader not found in $autoloaderFilename"); | |
| } | |
| return $composerAutoloader; | |
| } | |
| public function getClasses(): \Generator | |
| { | |
| $this->setup(); | |
| yield from parent::getClasses(); | |
| } | |
| public function mapClassNameToFileName(string $className): ?string | |
| { | |
| $this->setup(); | |
| return parent::mapClassNameToFileName($className); | |
| } | |
| public function mapFileNameToClassName(string $fileName): ?string | |
| { | |
| $this->setup(); | |
| return parent::mapFileNameToClassName($fileName); | |
| } | |
| } |