Commit 13ada2ac authored by webchick's avatar webchick

Issue #2187717 by sun, dawehner: Remove code duplication in system_list() and...

Issue #2187717 by sun, dawehner: Remove code duplication in system_list() and ThemeHandler::rebuildThemeData().
parent 029a18d7
......@@ -67,33 +67,6 @@ function system_list($type) {
);
}
}
// @todo Move into list_themes(). Read info for a particular requested
// theme from state instead.
foreach ($lists['theme'] as $key => $theme) {
if (!empty($theme->info['base theme'])) {
// Make a list of the theme's base themes.
require_once __DIR__ . '/theme.inc';
$lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key);
// Don't proceed if there was a problem with the root base theme.
if (!current($lists['theme'][$key]->base_themes)) {
continue;
}
// Determine the root base theme.
$base_key = key($lists['theme'][$key]->base_themes);
// Add to the list of sub-themes for each of the theme's base themes.
foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) {
$lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name'];
}
// Add the base theme's theme engine info.
$lists['theme'][$key]->info['engine'] = $lists['theme'][$base_key]->info['engine'];
}
else {
// A plain theme is its own base theme.
$base_key = $key;
}
// Set the theme engine prefix.
$lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine'];
}
\Drupal::cache('bootstrap')->set('system_list', $lists);
}
// To avoid a separate database lookup for the filepath, prime the
......
......@@ -319,41 +319,8 @@ function drupal_theme_rebuild() {
* @param $refresh
* Whether to reload the list of themes from the database. Defaults to FALSE.
*
* @return
* An associative array of the currently available themes. The keys are the
* themes' machine names and the values are objects having the following
* properties:
* - filename: The filepath and name of the .info.yml file.
* - name: The machine name of the theme.
* - status: 1 for enabled, 0 for disabled themes.
* - info: The contents of the .info.yml file.
* - stylesheets: A two dimensional array, using the first key for the
* media attribute (e.g. 'all'), the second for the name of the file
* (e.g. style.css). The value is a complete filepath (e.g.
* themes/bartik/style.css). Not set if no stylesheets are defined in the
* .info.yml file.
* - scripts: An associative array of JavaScripts, using the filename as key
* and the complete filepath as value. Not set if no scripts are defined in
* the .info.yml file.
* - prefix: The base theme engine prefix.
* - engine: The machine name of the theme engine.
* - base_theme: If this is a sub-theme, the machine name of the base theme
* defined in the .info.yml file. Otherwise, the element is not set.
* - base_themes: If this is a sub-theme, an associative array of the
* base-theme ancestors of this theme, starting with this theme's base
* theme, then the base theme's own base theme, etc. Each entry has an
* array key equal to the theme's machine name, and a value equal to the
* human-readable theme name; if a theme with matching machine name does
* not exist in the system, the value will instead be NULL (and since the
* system would not know whether that theme itself has a base theme, that
* will end the array of base themes). This is not set if the theme is not
* a sub-theme.
* - sub_themes: An associative array of themes on the system that are
* either direct sub-themes (that is, they declare this theme to be
* their base theme), direct sub-themes of sub-themes, etc. The keys are
* the themes' machine names, and the values are the themes' human-readable
* names. This element is not set if there are no themes on the system that
* declare this theme as their base theme.
* @return array
* An associative array of the currently available themes.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Use \Drupal::service('theme_handler')->listInfo().
......@@ -372,30 +339,6 @@ function list_themes($refresh = FALSE) {
return $theme_handler->listInfo();
}
/**
* Finds all the base themes for the specified theme.
*
* Themes can inherit templates and function implementations from earlier
* themes.
*
* @param $themes
* An array of available themes.
* @param $key
* The name of the theme whose base we are looking for.
*
* @return
* Returns an array of all of the theme's ancestors; the first element's value
* will be NULL if an error occurred.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Use \Drupal::service('theme_handler')->getBaseThemes().
*
* @see \Drupal\Core\Extension\ThemeHandler::getBaseThemes().
*/
function drupal_find_base_themes($themes, $key) {
return \Drupal::service('theme_handler')->getBaseThemes($themes, $key);
}
/**
* Generates themed output.
*
......
......@@ -271,62 +271,63 @@ public function rebuildThemeData() {
$sub_themes = array();
// Read info files for each theme.
foreach ($themes as $key => $theme) {
$themes[$key]->filename = $theme->uri;
$themes[$key]->info = $this->infoParser->parse($theme->getPathname()) + $defaults;
$theme->filename = $theme->uri;
$theme->info = $this->infoParser->parse($theme->getPathname()) + $defaults;
// Add the info file modification time, so it becomes available for
// contributed modules to use for ordering theme lists.
$themes[$key]->info['mtime'] = $theme->getMTime();
$theme->info['mtime'] = $theme->getMTime();
// Invoke hook_system_info_alter() to give installed modules a chance to
// modify the data in the .info.yml files if necessary.
// @todo Remove $type argument, obsolete with $theme->getType().
$type = 'theme';
$this->moduleHandler->alter('system_info', $themes[$key]->info, $themes[$key], $type);
$this->moduleHandler->alter('system_info', $theme->info, $theme, $type);
if (!empty($themes[$key]->info['base theme'])) {
if (!empty($theme->info['base theme'])) {
$sub_themes[] = $key;
}
$engine = $themes[$key]->info['engine'];
// Defaults to 'twig' (see $defaults above).
$engine = $theme->info['engine'];
if (isset($engines[$engine])) {
$themes[$key]->owner = $engines[$engine]->uri;
$themes[$key]->prefix = $engines[$engine]->name;
$themes[$key]->template = TRUE;
$theme->owner = $engines[$engine]->uri;
$theme->prefix = $engines[$engine]->name;
}
// Prefix stylesheets, scripts, and screenshot with theme path.
$path = $theme->getPath();
$theme->info['stylesheets'] = $this->themeInfoPrefixPath($theme->info['stylesheets'], $path);
$theme->info['scripts'] = $this->themeInfoPrefixPath($theme->info['scripts'], $path);
if (!empty($themes[$key]->info['screenshot'])) {
$themes[$key]->info['screenshot'] = $path . '/' . $themes[$key]->info['screenshot'];
if (!empty($theme->info['screenshot'])) {
$theme->info['screenshot'] = $path . '/' . $theme->info['screenshot'];
}
}
// Now that we've established all our master themes, go back and fill in
// data for sub-themes.
// After establishing the full list of available themes, fill in data for
// sub-themes.
foreach ($sub_themes as $key) {
$themes[$key]->base_themes = $this->getBaseThemes($themes, $key);
// Don't proceed if there was a problem with the root base theme.
if (!current($themes[$key]->base_themes)) {
$sub_theme = $themes[$key];
// The $base_themes property is optional; only set for sub themes.
// @see ThemeHandlerInterface::listInfo()
$sub_theme->base_themes = $this->getBaseThemes($themes, $key);
// empty() cannot be used here, since ThemeHandler::doGetBaseThemes() adds
// the key of a base theme with a value of NULL in case it is not found,
// in order to prevent needless iterations.
if (!current($sub_theme->base_themes)) {
continue;
}
$base_key = key($themes[$key]->base_themes);
foreach (array_keys($themes[$key]->base_themes) as $base_theme) {
$themes[$base_theme]->sub_themes[$key] = $themes[$key]->info['name'];
// Determine the root base theme.
$root_key = key($sub_theme->base_themes);
// Build the list of sub-themes for each of the theme's base themes.
foreach (array_keys($sub_theme->base_themes) as $base_theme) {
$themes[$base_theme]->sub_themes[$key] = $sub_theme->info['name'];
}
// Copy the 'owner' and 'engine' over if the top level theme uses a theme
// engine.
if (isset($themes[$base_key]->owner)) {
if (isset($themes[$base_key]->info['engine'])) {
$themes[$key]->info['engine'] = $themes[$base_key]->info['engine'];
$themes[$key]->owner = $themes[$base_key]->owner;
$themes[$key]->prefix = $themes[$base_key]->prefix;
}
else {
$themes[$key]->prefix = $key;
}
// Add the theme engine info from the root base theme.
if (isset($themes[$root_key]->owner)) {
$sub_theme->info['engine'] = $themes[$root_key]->info['engine'];
$sub_theme->owner = $themes[$root_key]->owner;
$sub_theme->prefix = $themes[$root_key]->prefix;
}
}
......
......@@ -244,6 +244,12 @@ public function testRebuildThemeData() {
->will($this->returnValue(array(
'seven' => new Extension('theme', DRUPAL_ROOT . '/core/themes/seven/seven.info.yml', 'seven.info.yml'),
)));
$this->extensionDiscovery->expects($this->at(1))
->method('scan')
->with('theme_engine')
->will($this->returnValue(array(
'twig' => new Extension('theme_engine', DRUPAL_ROOT . '/core/themes/engines/twig.info.yml', 'twig.info.yml'),
)));
$this->infoParser->expects($this->once())
->method('parse')
->with(DRUPAL_ROOT . '/core/themes/seven/seven.info.yml')
......@@ -264,6 +270,8 @@ public function testRebuildThemeData() {
$this->assertEquals('seven', $info->name);
$this->assertEquals(DRUPAL_ROOT . '/core/themes/seven/seven.info.yml', $info->uri);
$this->assertEquals(DRUPAL_ROOT . '/core/themes/seven/seven.info.yml', $info->filename);
$this->assertEquals(DRUPAL_ROOT . '/core/themes/engines/twig.info.yml', $info->owner);
$this->assertEquals('twig', $info->prefix);
$this->assertEquals('twig', $info->info['engine']);
$this->assertEquals(array(), $info->info['scripts']);
......@@ -280,6 +288,60 @@ public function testRebuildThemeData() {
$this->assertEquals(DRUPAL_ROOT . '/core/themes/seven/screenshot.png', $info->info['screenshot']);
}
/**
* Tests rebuild the theme data with theme parents.
*/
public function testRebuildThemeDataWithThemeParents() {
$this->extensionDiscovery->expects($this->at(0))
->method('scan')
->with('theme')
->will($this->returnValue(array(
'test_subtheme' => new Extension('theme', DRUPAL_ROOT . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml', 'test_subtheme.info.yml'),
'test_basetheme' => new Extension('theme', DRUPAL_ROOT . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml', 'test_basetheme.info.yml'),
)));
$this->extensionDiscovery->expects($this->at(1))
->method('scan')
->with('theme_engine')
->will($this->returnValue(array(
'twig' => new Extension('theme_engine', DRUPAL_ROOT . '/core/themes/engines/twig.info.yml', 'twig.info.yml'),
)));
$this->infoParser->expects($this->at(0))
->method('parse')
->with(DRUPAL_ROOT . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml')
->will($this->returnCallback(function ($file) {
$info_parser = new InfoParser();
return $info_parser->parse($file);
}));
$this->infoParser->expects($this->at(1))
->method('parse')
->with(DRUPAL_ROOT . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml')
->will($this->returnCallback(function ($file) {
$info_parser = new InfoParser();
return $info_parser->parse($file);
}));
$theme_data = $this->themeHandler->rebuildThemeData();
$this->assertCount(2, $theme_data);
$info_basetheme = $theme_data['test_basetheme'];
$info_subtheme = $theme_data['test_subtheme'];
// Ensure some basic properties.
$this->assertInstanceOf('Drupal\Core\Extension\Extension', $info_basetheme);
$this->assertEquals('test_basetheme', $info_basetheme->name);
$this->assertInstanceOf('Drupal\Core\Extension\Extension', $info_subtheme);
$this->assertEquals('test_subtheme', $info_subtheme->name);
// Test the parent/child-theme properties.
$info_subtheme->info['base theme'] = 'test_basetheme';
$info_basetheme->sub_themes = array('test_subtheme');
$this->assertEquals(DRUPAL_ROOT . '/core/themes/engines/twig.info.yml', $info_basetheme->owner);
$this->assertEquals('twig', $info_basetheme->prefix);
$this->assertEquals(DRUPAL_ROOT . '/core/themes/engines/twig.info.yml', $info_subtheme->owner);
$this->assertEquals('twig', $info_subtheme->prefix);
}
/**
* Tests getting the base themes for a set a defines themes.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment