Neos\Flow\Core\ClassLoader::loadClass PHP Method

loadClass() public method

Loads php files containing classes or interfaces found in the classes directory of a package and specifically registered classes.
public loadClass ( string $className ) : boolean
$className string Name of the class/interface to load
return boolean
    public function loadClass($className)
    {
        if ($className[0] === '\\') {
            $className = ltrim($className, '\\');
        }
        $namespaceParts = explode('\\', $className);
        // Workaround for Doctrine's annotation parser which does a class_exists() for annotations like "@param" and so on:
        if (isset($this->ignoredClassNames[$className]) || isset($this->ignoredClassNames[end($namespaceParts)]) || isset($this->nonExistentClasses[$className])) {
            return false;
        }
        // Loads any known proxied class:
        if ($this->classesCache !== null && ($this->availableProxyClasses === null || isset($this->availableProxyClasses[implode('_', $namespaceParts)])) && $this->classesCache->requireOnce(implode('_', $namespaceParts)) !== false) {
            return true;
        }
        $classNamePart = array_pop($namespaceParts);
        $classNameParts = explode('_', $classNamePart);
        $namespaceParts = array_merge($namespaceParts, $classNameParts);
        $namespacePartCount = count($namespaceParts);
        $currentPackageArray = $this->packageNamespaces;
        $packagenamespacePartCount = 0;
        // This will contain all possible class mappings for the given class name. We start with the fallback paths and prepend mappings with growing specificy.
        $collectedPossibleNamespaceMappings = [['p' => $this->fallbackClassPaths, 'c' => 0]];
        if ($namespacePartCount > 1) {
            while ($packagenamespacePartCount + 1 < $namespacePartCount) {
                $possiblePackageNamespacePart = $namespaceParts[$packagenamespacePartCount];
                if (!isset($currentPackageArray[$possiblePackageNamespacePart])) {
                    break;
                }
                $packagenamespacePartCount++;
                $currentPackageArray = $currentPackageArray[$possiblePackageNamespacePart];
                if (isset($currentPackageArray['_pathData'])) {
                    array_unshift($collectedPossibleNamespaceMappings, ['p' => $currentPackageArray['_pathData'], 'c' => $packagenamespacePartCount]);
                }
            }
        }
        foreach ($collectedPossibleNamespaceMappings as $nameSpaceMapping) {
            if ($this->loadClassFromPossiblePaths($nameSpaceMapping['p'], $namespaceParts, $nameSpaceMapping['c'])) {
                return true;
            }
        }
        $this->nonExistentClasses[$className] = true;
        return false;
    }

Usage Example

 /**
  * @test
  */
 public function classesFromOverlayedPsr4PackagesAreOverwritten()
 {
     $this->classLoader = new ClassLoader();
     $mockPackage1 = $this->getMockBuilder(Package::class)->disableOriginalConstructor()->getMock();
     $mockPackage1->expects($this->any())->method('getNamespaces')->will($this->returnValue(['TestPackage\\Foo']));
     $mockPackage1->expects($this->any())->method('getFlattenedAutoloadConfiguration')->will($this->returnValue([['namespace' => 'TestPackage\\Foo', 'classPath' => 'vfs://Test/Packages/Libraries/test/subPackage/src/', 'mappingType' => ClassLoader::MAPPING_TYPE_PSR4]]));
     $mockPackage2 = $this->getMockBuilder(Package::class)->disableOriginalConstructor()->getMock();
     $mockPackage2->expects($this->any())->method('getNamespaces')->will($this->returnValue(['TestPackage']));
     $mockPackage2->expects($this->any())->method('getFlattenedAutoloadConfiguration')->will($this->returnValue([['namespace' => 'TestPackage', 'classPath' => 'vfs://Test/Packages/Libraries/test/mainPackage/src/', 'mappingType' => ClassLoader::MAPPING_TYPE_PSR4]]));
     $packages = [$mockPackage2, $mockPackage1];
     mkdir('vfs://Test/Packages/Libraries/test/subPackage/src/', 0770, true);
     mkdir('vfs://Test/Packages/Libraries/test/mainPackage/src/Foo', 0770, true);
     file_put_contents('vfs://Test/Packages/Libraries/test/subPackage/src/Bar3.php', '<?php ' . __CLASS__ . '::$testClassWasOverwritten = TRUE; ?>');
     file_put_contents('vfs://Test/Packages/Libraries/test/mainPackage/src/Foo/Bar3.php', '<?php ' . __CLASS__ . '::$testClassWasOverwritten = FALSE; ?>');
     $this->classLoader->setPackages($packages);
     $this->classLoader->loadClass('TestPackage\\Foo\\Bar3');
     $this->assertTrue(self::$testClassWasOverwritten);
 }