/** * Registers test namespaces of all available extensions. * * @return array * An associative array whose keys are PSR-4 namespace prefixes and whose * values are directory names. */ public function registerTestNamespaces() { if (isset($this->testNamespaces)) { return $this->testNamespaces; } $this->testNamespaces = array(); $existing = $this->classLoader->getPrefixesPsr4(); // Add PHPUnit test namespace of Drupal core. $this->testNamespaces['Drupal\\Tests\\'] = [DRUPAL_ROOT . '/core/tests/Drupal/Tests']; $this->availableExtensions = array(); foreach ($this->getExtensions() as $name => $extension) { $this->availableExtensions[$extension->getType()][$name] = $name; $base_namespace = "Drupal\\{$name}\\"; $base_path = DRUPAL_ROOT . '/' . $extension->getPath(); // Add namespace of disabled/uninstalled extensions. if (!isset($existing[$base_namespace])) { $this->classLoader->addPsr4($base_namespace, "{$base_path}/src"); } // Add Simpletest test namespace. $this->testNamespaces[$base_namespace . 'Tests\\'][] = "{$base_path}/src/Tests"; // Add PHPUnit test namespace. // @todo Move PHPUnit namespace of extensions into Drupal\Tests\$name. // @see https://www.drupal.org/node/2260121 $this->testNamespaces[$base_namespace . 'Tests\\'][] = "{$base_path}/tests/src"; } foreach ($this->testNamespaces as $prefix => $paths) { $this->classLoader->addPsr4($prefix, $paths); } return $this->testNamespaces; }
/** * Registers test namespaces of all available extensions. * * @return array * An associative array whose keys are PSR-4 namespace prefixes and whose * values are directory names. */ public function registerTestNamespaces() { if (isset($this->testNamespaces)) { return $this->testNamespaces; } $this->testNamespaces = array(); $existing = $this->classLoader->getPrefixesPsr4(); // Add PHPUnit test namespaces of Drupal core. $this->testNamespaces['Drupal\\Tests\\'] = [DRUPAL_ROOT . '/core/tests/Drupal/Tests']; $this->testNamespaces['Drupal\\FunctionalTests\\'] = [DRUPAL_ROOT . '/core/tests/Drupal/FunctionalTests']; $this->availableExtensions = array(); foreach ($this->getExtensions() as $name => $extension) { $this->availableExtensions[$extension->getType()][$name] = $name; $base_path = DRUPAL_ROOT . '/' . $extension->getPath(); // Add namespace of disabled/uninstalled extensions. if (!isset($existing["Drupal\\{$name}\\"])) { $this->classLoader->addPsr4("Drupal\\{$name}\\", "{$base_path}/src"); } // Add Simpletest test namespace. $this->testNamespaces["Drupal\\{$name}\\Tests\\"][] = "{$base_path}/src/Tests"; // Add PHPUnit test namespaces. $this->testNamespaces["Drupal\\Tests\\{$name}\\Unit\\"][] = "{$base_path}/tests/src/Unit"; $this->testNamespaces["Drupal\\Tests\\{$name}\\Functional\\"][] = "{$base_path}/tests/src/Functional"; } foreach ($this->testNamespaces as $prefix => $paths) { $this->classLoader->addPsr4($prefix, $paths); } return $this->testNamespaces; }
/** * @param ClassLoader $loader * @param string $apps * @param string $appDir */ public static function registerLoader(ClassLoader $loader, &$apps, $appDir) { foreach ($apps['apps'] as &$app) { $namespace = $app['namespace'] . '\\'; $prefixes = $loader->getPrefixesPsr4(); if (isset($prefixes[$namespace])) { $app['path'] = $prefixes[$namespace][0]; continue; } $app['path'] = $loader->getPrefixesPsr4()[$namespace]; } AnnotationRegistry::registerLoader([$loader, 'loadClass']); AnnotationReader::addGlobalIgnoredName('noinspection'); AnnotationReader::addGlobalIgnoredName('returns'); }
public function addPsr4($prefix, $paths, $prepend = false) { $this->mainLoader->addPsr4($prefix, $paths, $prepend); $this->prefixesPsr4 = array_merge($this->prefixesPsr4, $this->mainLoader->getPrefixesPsr4()); $this->fallbackDirsPsr4 = array_merge($this->fallbackDirsPsr4, $this->mainLoader->getFallbackDirsPsr4()); return $this; }
/** * Returns all matching files by namespace * * Example: find all route.php files in Routes folders, * $loader->find('App\Route\routes.php') * * Example: find all Cron directories * $loader->find('App\Controller\Cron') * * @return array */ public function find($glob) : array { @(list($prefix, $match) = explode('/', $this->utils->unixPath(trim($glob, '\\/')), 2)); foreach ($folders = $this->loader->getPrefixesPsr4()["{$prefix}\\"] ?? [] as $folder) { if (is_readable($path = sprintf('%s/%s', $folder, $match))) { $matches[] = realpath($path); } } return $matches ?? []; }
/** * Returns class loading information for a single package * * @param PackageInterface $package The package to generate the class loading info for * @param bool $useRelativePaths If set to TRUE, make the path relative to the current TYPO3 instance (PATH_site) * @return array */ public function buildClassLoadingInformationForPackage(PackageInterface $package, $useRelativePaths = false) { $classMap = []; $psr4 = []; $packagePath = $package->getPackagePath(); $manifest = $package->getValueFromComposerManifest(); if (empty($manifest->autoload)) { // Legacy mode: Scan the complete extension directory for class files $classMap = $this->createClassMap($packagePath, $useRelativePaths, !$this->isDevMode); } else { $autoloadPsr4 = $this->getAutoloadSectionFromManifest($manifest, 'psr-4'); if (!empty($autoloadPsr4)) { $classLoaderPrefixesPsr4 = $this->classLoader->getPrefixesPsr4(); foreach ($autoloadPsr4 as $namespacePrefix => $paths) { foreach ((array) $paths as $path) { $namespacePath = $packagePath . $path; if ($useRelativePaths) { $psr4[$namespacePrefix][] = $this->makePathRelative($namespacePath, realpath($namespacePath)); } else { $psr4[$namespacePrefix][] = $namespacePath; } if (!empty($classLoaderPrefixesPsr4[$namespacePrefix])) { // The namespace prefix has been registered already, which means there also might be // a class map which we need to override $classMap = array_merge($classMap, $this->createClassMap($namespacePath, $useRelativePaths, false, $namespacePrefix)); } } } } $autoloadClassmap = $this->getAutoloadSectionFromManifest($manifest, 'classmap'); if (!empty($autoloadClassmap)) { foreach ($autoloadClassmap as $path) { $classMap = array_merge($classMap, $this->createClassMap($packagePath . $path, $useRelativePaths)); } } } return ['classMap' => $classMap, 'psr-4' => $psr4]; }
public function __construct(ClassLoader $loader, Engine $engine = null) { if (!$engine) { $engine = new Engine(); } $this->engine = $engine; $this->add(null, $loader->getFallbackDirs()); $this->addPsr4(null, $loader->getFallbackDirsPsr4()); foreach ($loader->getPrefixes() as $prefix => $path) { $this->add($prefix, $path); } foreach ($loader->getPrefixesPsr4() as $prefix => $path) { $this->addPsr4($prefix, $path); } $this->setUseIncludePath($loader->getUseIncludePath()); }
/** * {@inheritdoc} */ public function getConfig() { // Initialize empty configuration. $config = ['psr-0' => [], 'psr-4' => [], 'class-location' => []]; // Find the tokenized paths. $psrs = array('psr-0' => $this->classLoader->getPrefixes(), 'psr-4' => $this->classLoader->getPrefixesPsr4()); // Get all the PSR-0 and PSR-0 and detect the ones that have Drupal tokens. foreach ($psrs as $psr_type => $namespaces) { $namespaces = $namespaces ?: []; foreach ($namespaces as $prefix => $paths) { $token_paths = array(); if (!is_array($paths)) { $paths = array($paths); } foreach ($paths as $path) { $token_resolver = $this->tokenFactory->factory($path); if (!$token_resolver->hasToken()) { continue; } $path = $token_resolver->trimPath(); $token_paths[] = $path; } // If there were paths, add them to the config. if (!empty($token_paths)) { $config[$psr_type][$prefix] = $token_paths; } } } // Get the drupal path configuration. $composer_config = json_decode(file_get_contents(static::COMPOSER_CONFIGURATION_NAME)); $config['class-location'] = array(); if (isset($composer_config->autoload->{'class-location'})) { $config['class-location'] = array_merge($config['class-location'], (array) $composer_config->autoload->{'class-location'}); } if (isset($composer_config->{'autoload-dev'}->{'class-location'})) { $config['class-location'] = array_merge($config['class-location'], (array) $composer_config->{'autoload-dev'}->{'class-location'}); } return $config; }
function registerRoutes() { // Auto-register routes. if (!isset($this->classLoader->getPrefixesPsr4()[$this->config->namespacePrefix . '\\'])) { throw new Exception(sprintf('Namespace prefix "%s" defined in the config was not found in the autoloader.', $this->config->namespacePrefix)); } $sourcePath = array_pop($this->classLoader->getPrefixesPsr4()[$this->config->namespacePrefix . '\\']); $routes = []; $app = $this->app; $formatNegotiator = $this->formatNegotiator; $serializer = $this->serializer; $config = $this->config; foreach ($this->getWebServiceClasses($this->config->namespacePrefix, $sourcePath) as $webServiceClass) { // Need to get methods and DTOs from class $classReflection = new ClassReflection($webServiceClass); $httpMethodNames = $this->config->httpMethodNames; $httpMethodReflections = array_filter($classReflection->getMethods(), function ($methodReflection) use($httpMethodNames) { return in_array($methodReflection->name, $httpMethodNames); }); // @todo add a check to make sure DTOs are unique. This might happen implicitly when registering routes. // Call for each http method/DTO in web service /** @var MethodReflection $httpMethodReflection */ foreach ($httpMethodReflections as $httpMethodReflection) { // This assumes that the first argument of the HTTP method is a DTO. $httpMethodReflectionPrototype = $httpMethodReflection->getPrototype(); $requestDtoClass = array_shift($httpMethodReflectionPrototype['arguments'])['type']; $requestDtoClassReflection = new ClassReflection($requestDtoClass); $requestDtoProperties = $requestDtoClassReflection->getProperties(); $returnDtoClass = $httpMethodReflection->getReturnType(); $returnDtoProperties = (new ClassReflection($returnDtoClass))->getProperties(); $requestMethod = $httpMethodReflectionPrototype['name']; $route = '/' . $this->config->baseUrl . '/' . $requestDtoClassReflection->getShortName(); $routes[] = new class($route, $requestDtoClass, $requestDtoProperties, $returnDtoClass, $returnDtoProperties) { public $path; public $requestDto; public $requestDtoParameters; public $returnDto; public $returnDtoProperties; public function __construct(string $path, string $requestDto, array $requestDtoParameters, string $returnDto, array $returnDtoProperties) { $this->path = $path; $this->requestDto = $requestDto; $this->requestDtoParameters = $requestDtoParameters; $this->returnDto = $returnDto; $this->returnDtoProperties = $returnDtoProperties; } }; $app->get($route, function () use($app, $formatNegotiator, $serializer, $config, $webServiceClass, $requestDtoClass, $requestMethod) { /** @var Request $httpRequest */ $httpRequest = $app['request']; // Convert request parameters to the request DTO. $params = $serializer->serialize($httpRequest->query->all(), 'json'); $requestDto = $serializer->deserialize($params, $requestDtoClass, 'json'); // Get the response DTO by calling the HTTP method of the web service class, with the request DTO. $responseDto = (new $webServiceClass())->{$requestMethod}($requestDto); // Content negotiation $format = $formatNegotiator->getBestFormat(implode(',', $httpRequest->getAcceptableContentTypes()), $config->contentNegotiation->priorities); return new Response($serializer->serialize($responseDto, $format), 200, array('Content-Type' => $app['request']->getMimeType($format))); }); } } /** * Register custom _routes meta route */ $app->get($config->baseUrl . '/_routes', function () use($app, $formatNegotiator, $serializer, $config, $routes) { $httpRequest = $app['request']; $format = $formatNegotiator->getBestFormat(implode(',', $httpRequest->getAcceptableContentTypes()), $config->contentNegotiation->priorities); $serializedData = $serializer->serialize($routes, $format); $responseCode = Response::HTTP_OK; if ($serializedData === false) { $serializedData = ''; $responseCode = Response::HTTP_INTERNAL_SERVER_ERROR; } return new Response($serializedData, $responseCode, array('Content-Type' => $app['request']->getMimeType($format))); }); }