/** * Renew the cache prefix, save it, and notify all observers. */ function renewCachePrefix() { $this->prefix = Util::randomString(); $this->system->variableSet('xautoload_cache_prefix', $this->prefix); foreach ($this->observers as $observer) { $observer->setCachePrefix($this->prefix); } }
/** * Renew the cache prefix, save it, and notify all observers. */ function renewCachePrefix() { $this->prefix = Util::randomString(); $this->system->variableSet(XAUTOLOAD_VARNAME_CACHE_PREFIX, $this->prefix); foreach ($this->observers as $observer) { $observer->setCachePrefix($this->prefix); } }
/** * @param string[] $paths * * @return string[] */ function wildcardPathsToClassmap($paths) { // Attempt to load from cache. $cid = 'xautoload:wildcardPathsToClassmap:' . md5(serialize($paths)); $cache = $this->system->cacheGet($cid); if ($cache && isset($cache->data)) { return $cache->data; } // Resolve cache miss and save. $map = $this->decorated->wildcardPathsToClassmap($paths); $this->system->cacheSet($cid, $map); return $map; }
/** * Checks if new extensions have been enabled, and registers them. * * This is called from xautoload_module_implements_alter(), which is called * whenever a new module is enabled, but also some calls we need to ignore. */ public function checkNewExtensions() { if (!$this->awake) { // The entire thing is not initialized yet. // Postpone until operateOnFinder() return; } $activeExtensions = $this->system->getActiveExtensions(); if ($activeExtensions === $this->extensions) { // Nothing actually changed. False alarm. return; } // Now check all extensions to find out if any of them is new. foreach ($activeExtensions as $name => $type) { if (!isset($this->extensions[$name])) { // This extension was freshly enabled. if ('xautoload' === $name) { // If xautoload is enabled in this request, then boot phase and main // phase are not properly initialized yet. $this->enterMainPhase(); } // Notify observers about the new extension. foreach ($this->observers as $observer) { $observer->welcomeNewExtension($name, $type); } } } }
/** * React to new extensions that were just enabled. * * @param string $name * @param string $type */ public function welcomeNewExtension($name, $type) { if (isset($this->registered[$name])) { // Already registered. return; } $dir = $this->system->drupalGetPath($type, $name); $this->_registerExtension($name, $dir); }
/** * Runs hook_xautoload() on all enabled modules. * * This may occur multiple times in a request, if new modules are enabled. * * @param array $modules */ private function runHookXautoload(array $modules) { // Let other modules register stuff to the finder via hook_xautoload(). $adapter = \xautoload_InjectedAPI_hookXautoload::create($this->finder, ''); foreach ($modules as $module) { $adapter->setExtensionDir($dir = $this->system->drupalGetPath('module', $module)); $function = $module . '_xautoload'; $function($adapter, $dir); } }
/** * @return array[] */ private function buildLibrariesXautoloadInfo() { // @todo Reset drupal_static('libraries') ? $all = array(); foreach ($this->system->getLibrariesInfo() as $name => $info) { serialize($info); if (!isset($info['xautoload'])) { continue; } $callback = $info['xautoload']; if (!is_callable($callback)) { continue; } $path = $this->system->librariesGetPath($name); if (FALSE === $path) { continue; } $all[$name] = array($path, $callback); } return $all; }
/** * @return array[] */ private function buildLibrariesXautoloadInfo() { // @todo Reset drupal_static('libraries') ? $all = array(); foreach ($this->system->getLibrariesInfo() as $name => $info) { if (!isset($info['xautoload'])) { continue; } $callback = $info['xautoload']; if (!is_callable($callback)) { continue; } /** See https://www.drupal.org/node/2473901 */ $path = isset($info['library path']) ? $info['library path'] : $this->system->librariesGetPath($name); if (FALSE === $path) { continue; } $all[$name] = array($path, $callback); } return $all; }
/** * 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; }
/** * React to xautoload_modules_enabled() * * @param string[] $modules * New module names. */ public function modulesEnabled($modules) { $this->system->drupalStaticReset('libraries_info'); $this->system->cacheClearAll(XAUTOLOAD_CACHENAME_LIBRARIES_INFO, 'cache'); $this->registerLibrariesFinderPlugin(); }
/** * {@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; } }
/** * React to xautoload_modules_enabled() * * @param string[] $modules * New module names. */ public function modulesEnabled($modules) { $this->system->drupalStaticReset('libraries_info'); $this->system->cacheClearAll('xautoload_libraries_info', 'cache'); $this->registerLibrariesFinderPlugin(); }
function registerActiveExtensions() { $this->registerExtensions($this->system->getActiveExtensions()); }