diff -u /dev/null b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php --- /dev/null +++ b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php @@ -0,0 +1,71 @@ +assertIdentical(drupal_get_filename('module', 'system'), 'core/modules/system/system.info.yml'); + + // Retrieving the location of a theme. + \Drupal::service('theme_handler')->install(array('stark')); + $this->assertIdentical(drupal_get_filename('theme', 'stark'), 'core/themes/stark/stark.info.yml'); + + // Retrieving the location of a theme engine. + $this->assertIdentical(drupal_get_filename('theme_engine', 'twig'), 'core/themes/engines/twig/twig.info.yml'); + + // Retrieving the location of a profile. Profiles are a special case with + // a fixed location and naming. + $this->assertIdentical(drupal_get_filename('profile', 'testing'), 'core/profiles/testing/testing.info.yml'); + + + // Generate a non-existing module name. + $non_existing_module = uniqid("", TRUE); + + // Set a custom error handler so we can ignore the file not found error. + set_error_handler(function($severity, $message, $file, $line) { + // Skip error handling if this is a "file not found" error. + if (strstr($message, 'is missing from the file system:')) { + \Drupal::state()->set('get_filename_test_triggered_error', TRUE); + return; + } + throw new \ErrorException($message, 0, $severity, $file, $line); + }); + $this->assertNull(drupal_get_filename('module', $non_existing_module), 'Searching for an item that does not exist returns NULL.'); + $this->assertTrue(\Drupal::state()->get('get_filename_test_triggered_error'), 'Searching for an item that does not exist triggers an error.'); + // Restore the original error handler. + restore_error_handler(); + } +} only in patch2: unchanged: --- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php @@ -125,8 +125,9 @@ public function __construct($root) { */ public function scan($type, $include_tests = NULL) { // Determine the installation profile directories to scan for extensions, - // unless explicit profile directories have been set. - if (!isset($this->profileDirectories)) { + // unless explicit profile directories have been set. Exclude profiles + // as we can't have profiles within profiles. + if (!isset($this->profileDirectories) && $type != 'profile') { $this->setProfileDirectoriesFromSettings(); } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Extension/ThemeHandler.php +++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php @@ -466,7 +466,8 @@ public function rebuildThemeData() { ); $sub_themes = array(); - $files = array(); + $files_theme = array(); + $files_theme_engine = array(); // Read info files for each theme. foreach ($themes as $key => $theme) { // @todo Remove all code that relies on the $status property. @@ -495,6 +496,7 @@ public function rebuildThemeData() { if (isset($engines[$engine])) { $theme->owner = $engines[$engine]->getExtensionPathname(); $theme->prefix = $engines[$engine]->getName(); + $files_theme_engine[$engine] = $engines[$engine]->getPathname(); } // Prefix screenshot with theme path. @@ -502,7 +504,7 @@ public function rebuildThemeData() { $theme->info['screenshot'] = $theme->getPath() . '/' . $theme->info['screenshot']; } - $files[$key] = $theme->getPathname(); + $files_theme[$key] = $theme->getPathname(); } // Build dependencies. // @todo Move into a generic ExtensionHandler base class. @@ -511,7 +513,8 @@ public function rebuildThemeData() { // Store filenames to allow system_list() and drupal_get_filename() to // retrieve them without having to scan the filesystem. - $this->state->set('system.theme.files', $files); + $this->state->set('system.theme.files', $files_theme); + $this->state->set('system.theme_engine.files', $files_theme_engine); // After establishing the full list of available themes, fill in data for // sub-themes. only in patch2: unchanged: --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -883,14 +883,19 @@ function system_get_info($type, $name = NULL) { */ function _system_rebuild_module_data() { $listing = new ExtensionDiscovery(\Drupal::root()); - // Find modules - $modules = $listing->scan('module'); // Find installation profiles. $profiles = $listing->scan('profile'); + $profile = drupal_get_profile(); + if ($profile && isset($profiles[$profile])) { + // Prime drupal_get_filename() with the profile info file location. + drupal_get_filename('profile', $profile, $profiles[$profile]->getPathname()); + } + // Find modules + $modules = $listing->scan('module'); // Include the installation profile in modules that are loaded. - if ($profile = drupal_get_profile()) { + if ($profile) { $modules[$profile] = $profiles[$profile]; // Installation profile hooks are always executed last. $modules[$profile]->weight = 1000;