/** * {@inheritdoc} */ function apiFindFile($api, $class) { // Fix the behavior of some PHP versions that prepend '\\' to the class name. if ('\\' === $class[0]) { $class = substr($class, 1); } // First check if the literal class name is registered. if (!empty($this->classes[$class])) { foreach ($this->classes[$class] as $filepath => $true) { if ($api->suggestFile($filepath)) { return TRUE; } } } // Check if the class has a namespace. if (FALSE !== ($pos = strrpos($class, '\\'))) { // Build the "logical path" based on PSR-4 replacement rules. $logical_path = str_replace('\\', '/', $class) . '.php'; return $this->namespaceMap->apiFindFile($api, $logical_path, $pos); } // Build the "logical path" based on PEAR replacement rules. $pear_logical_path = str_replace('_', '/', $class) . '.php'; // Clean up surplus '/' resulting from duplicate underscores, or an // underscore at the beginning of the class. while (FALSE !== ($pos = strrpos('/' . $pear_logical_path, '//'))) { $pear_logical_path[$pos] = '_'; } // Check if the class has any underscore. $pos = strrpos($pear_logical_path, '/'); return $this->prefixMap->apiFindFile($api, $pear_logical_path, $pos); }
/** * {@inheritdoc} */ function addPear($prefix, $paths) { $logical_base_path = Util::prefixLogicalPath($prefix); foreach ((array) $paths as $root_path) { $deep_path = strlen($root_path) ? rtrim($root_path, '/') . '/' . $logical_base_path : $logical_base_path; $this->prefixMap->registerDeepPath($logical_base_path, $deep_path, $this->defaultBehavior); } }
/** * Register PSR-4 directory for an extension. * Override previous settings for this extension. * * @param string $name * The extension name. * @param string $extension_dir * The directory of the extension. * @param string $subdir * The PSR-4 base directory, relative to the extension directory. * E.g. 'lib' or 'src'. */ function registerExtensionPsr4($name, $extension_dir, $subdir) { if (!empty($this->registered[$name])) { if ('psr-4' === $this->registered[$name]) { // It already happened. return; } // Unregister the lazy plugins. $this->namespaceMap->unregisterDeepPath('Drupal/' . $name . '/', $name); $this->prefixMap->unregisterDeepPath(str_replace('_', '/', $name) . '/', $name); } $dir = strlen($subdir) ? $extension_dir . '/' . trim($subdir, '/') . '/' : $extension_dir . '/'; $this->namespaceMap->registerDeepPath('Drupal/' . $name . '/', $dir, $this->defaultBehavior); // Re-add the PSR-0 test directory, for consistency's sake. if (is_dir($psr0_tests_dir = $extension_dir . '/lib/Drupal/' . $name . '/Tests')) { $this->namespaceMap->registerDeepPath('Drupal/' . $name . '/Tests/', $psr0_tests_dir, $this->defaultBehavior); } }
/** * Looks up a class starting with "Drupal\$extension_name\\". * * This plugin method will be called for every class beginning with * "Drupal\\$extension_name\\", as long as the plugin is registered for * $logical_base_path = 'Drupal/$extension_name/'. * * A similar plugin will is registered along with this one for the PEAR-FLAT * pattern, called for every class beginning with $modulename . '_'. * * The plugin will eventually unregister itself and its cousin, once it has * - determined the correct path for the module, and * - determined that the module is using either PSR-0 or PSR-4. * It does that by including the file candidate for PSR-0 and/or PSR-4 and * checking whether the class is now defined. * * The plugin will instead register a direct * * @param \Drupal\xautoload\ClassFinder\InjectedApi\InjectedApiInterface $api * An object with methods like suggestFile() and guessFile(). * @param string $logical_base_path * The logical base path determined from the registered namespace. * E.g. 'Drupal/menupoly/'. * @param string $relative_path * Remaining part of the logical path following $logical_base_path. * E.g. 'FooNamespace/BarClass.php'. * @param string|null $extension_name * Second key that the plugin was registered with. Usually this would be the * physical base directory where we prepend the relative path to get the * file path. But in this case it is simply the extensions name. * E.g. 'menupoly'. * * @return bool|null * TRUE, if the file was found. * FALSE or NULL, otherwise. */ function findFile($api, $logical_base_path, $relative_path, $extension_name = NULL) { $extension_file = $this->system->drupalGetFilename($this->type, $extension_name); if (empty($extension_file)) { // Extension does not exist, or is not installed. return FALSE; } $nspath = 'Drupal/' . $extension_name . '/'; $testpath = $nspath . 'Tests/'; $uspath = $extension_name . '/'; $extension_dir = dirname($extension_file); $src = $extension_dir . '/src/'; $lib_psr0 = $extension_dir . '/lib/Drupal/' . $extension_name . '/'; $is_test_class = 0 === strpos($relative_path, 'Tests/'); // Try PSR-4. if ($api->guessPath($src . $relative_path)) { if ($is_test_class) { // Register PSR-0 directory for "Drupal\\$modulename\\Tests\\" // This generally happens only once per module, because for subsequent // test classes the class will be found before this plugin is triggered. // However, for class_exists() with nonexistent test files, this line // will occur more than once. $this->namespaceMap->registerDeepPath($testpath, $src . 'Tests/', $this->defaultBehavior); // We found the class, but it is a test class, so it does not tell us // anything about whether non-test classes are in PSR-0 or PSR-4. return TRUE; } // Register PSR-4 directory for "Drupal\\$modulename\\". $this->namespaceMap->registerDeepPath($nspath, $src, $this->defaultBehavior); // Unregister the lazy plugins, including this one, for // "Drupal\\$modulename\\" and for $modulename . '_'. $this->namespaceMap->unregisterDeepPath($nspath, $extension_name); $this->prefixMap->unregisterDeepPath($uspath, $extension_name); // Test classes in PSR-4 are already covered by the PSR-4 plugin we just // registered. But test classes in PSR-0 would slip through. So we check // if a separate behavior needs to be registered for those. if (is_dir($lib_psr0 . 'Tests/')) { $this->namespaceMap->registerDeepPath($testpath, $lib_psr0 . 'Tests/', $this->psr0Behavior); } // The class was found, so return TRUE. return TRUE; } // Build PSR-0 relative path. if (FALSE === ($nspos = strrpos($relative_path, '/'))) { // No namespace separators in $relative_path, so all underscores must be // replaced. $relative_path = str_replace('_', '/', $relative_path); } else { // Replace only those underscores in $relative_path after the last // namespace separator, from right to left. On average there is no or very // few of them, so this loop rarely iterates even once. while ($nspos < ($uspos = strrpos($relative_path, '_'))) { $relative_path[$uspos] = '/'; } } // Try PSR-0 if ($api->guessPath($lib_psr0 . $relative_path)) { if ($is_test_class) { // We know now that there are test classes using PSR-0. $this->namespaceMap->registerDeepPath($testpath, $lib_psr0 . 'Tests/', $this->psr0Behavior); // We found the class, but it is a test class, so it does not tell us // anything about whether non-test classes are in PSR-0 or PSR-4. return TRUE; } // Unregister the lazy plugins, including this one. $this->namespaceMap->unregisterDeepPath($nspath, $extension_name); $this->prefixMap->unregisterDeepPath($uspath, $extension_name); // Register PSR-0 for regular namespaced classes. $this->namespaceMap->registerDeepPath($nspath, $lib_psr0, $this->psr0Behavior); // Test classes in PSR-0 are already covered by the PSR-0 plugin we just // registered. But test classes in PSR-4 would slip through. So we check // if a separate behavior needs to be registered for those. # if (is_dir($src . 'Tests/')) { # $this->namespaceMap->registerDeepPath($testpath, $src . 'Tests/', $this->psr0Behavior); # } // The class was found, so return TRUE. return TRUE; } return FALSE; }
/** * {@inheritdoc} */ function findFile($api, $logical_base_path, $relative_path, $extension_name = NULL) { $extension_file = $this->system->drupalGetFilename($this->type, $extension_name); if (empty($extension_file)) { // Extension does not exist, or is not installed. return FALSE; } $nspath = 'Drupal/' . $extension_name . '/'; $testpath = $nspath . 'Tests/'; $uspath = $extension_name . '/'; $lib = dirname($extension_file) . '/lib/'; $lib_psr0 = $lib . 'Drupal/' . $extension_name . '/'; $is_test_class = 0 === strpos($relative_path, 'Tests/'); // Try PSR-4. if (FALSE && $api->guessPath($lib . $relative_path)) { if ($is_test_class) { $this->namespaceMap->registerDeepPath($testpath, $lib . 'Tests/', $this->defaultBehavior); // We found the class, but it is a test class, so it does not tell us // anything about whether non-test classes are in PSR-0 or PSR-4. return TRUE; } // Register PSR-4. $this->namespaceMap->registerDeepPath($nspath, $lib, $this->defaultBehavior); // Unregister the lazy plugins. $this->namespaceMap->unregisterDeepPath($nspath, $extension_name); $this->prefixMap->unregisterDeepPath($uspath, $extension_name); // Test classes in PSR-4 are already covered by the PSR-4 plugin we just // registered. But test classes in PSR-0 would slip through. So we check // if a separate behavior needs to be registered for those. if (is_dir($lib_psr0 . 'Tests/')) { $this->namespaceMap->registerDeepPath($testpath, $lib_psr0 . 'Tests/', $this->psr0Behavior); } // The class was found, so return TRUE. return TRUE; } // Build PSR-0 relative path. if (FALSE === ($nspos = strrpos($relative_path, '/'))) { // No namespace separators in $relative_path, so all underscores must be // replaced. $relative_path = str_replace('_', '/', $relative_path); } else { // Replace only those underscores in $relative_path after the last // namespace separator, from right to left. On average there is no or very // few of them, so this loop rarely iterates even once. while ($nspos < ($uspos = strrpos($relative_path, '_'))) { $relative_path[$uspos] = '/'; } } // Try PSR-0 if ($api->guessPath($lib_psr0 . $relative_path)) { if ($is_test_class) { // We know now that there are test classes using PSR-0. $this->namespaceMap->registerDeepPath($testpath, $lib_psr0 . 'Tests/', $this->psr0Behavior); // We found the class, but it is a test class, so it does not tell us // anything about whether non-test classes are in PSR-0 or PSR-4. return TRUE; } // Unregister the lazy plugins. $this->namespaceMap->unregisterDeepPath($nspath, $extension_name); $this->prefixMap->unregisterDeepPath($uspath, $extension_name); // Register PSR-0 for regular namespaced classes. $this->namespaceMap->registerDeepPath($nspath, $lib_psr0, $this->psr0Behavior); // Test classes in PSR-0 are already covered by the PSR-0 plugin we just // registered. But test classes in PSR-4 would slip through. So we check // if a separate behavior needs to be registered for those. if (is_dir($lib . 'Tests/')) { # $this->namespaceMap->registerDeepPath($testpath, $lib . 'Tests/', $this->psr0Behavior); } // The class was found, so return TRUE. return TRUE; } }