Commit 6481f6db authored by Dries's avatar Dries

- Patch #456088 by dww, JohnAlbin | Dave Reid, Gábor Hojtsy, pwolanin,...

- Patch #456088 by dww, JohnAlbin | Dave Reid, Gábor Hojtsy, pwolanin, tic2000, meba: sub-themes not notified of security updates for base themes.
parent 332c4ab5
<?xml version="1.0" encoding="utf-8"?>
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Update test base theme</title>
<short_name>update_test_basetheme</short_name>
<dc:creator>Drupal</dc:creator>
<api_version>7.x</api_version>
<recommended_major>1</recommended_major>
<supported_majors>1</supported_majors>
<default_major>1</default_major>
<project_status>published</project_status>
<link>http://example.com/project/update_test_basetheme</link>
<terms>
<term><name>Projects</name><value>Themes</value></term>
</terms>
<releases>
<release>
<name>update_test_basetheme 7.x-1.1</name>
<version>7.x-1.1</version>
<tag>DRUPAL-7--1-1</tag>
<version_major>1</version_major>
<version_patch>1</version_patch>
<status>published</status>
<release_link>http://example.com/update_test_basetheme-7-x-1-1-release</release_link>
<download_link>http://example.com/update_test_basetheme-7.x-1.1.tar.gz</download_link>
<date>1250624521</date>
<mdhash>b966255555d9c9b86d480ca08cfaa98e</mdhash>
<filesize>1073763241</filesize>
<terms>
<term><name>Release type</name><value>Security update</value></term>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>update_test_basetheme 7.x-1.0</name>
<version>7.x-1.0</version>
<tag>DRUPAL-7--1-0</tag>
<version_major>1</version_major>
<version_patch>0</version_patch>
<status>published</status>
<release_link>http://example.com/update_test_basetheme-7-x-1-0-release</release_link>
<download_link>http://example.com/update_test_basetheme-7.x-1.0.tar.gz</download_link>
<date>1250524521</date>
<mdhash>b966255555d9c9b86d480ca08cfaa98e</mdhash>
<filesize>1073741824</filesize>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
</releases>
</project>
<?xml version="1.0" encoding="utf-8"?>
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Update test subtheme</title>
<short_name>update_test_subtheme</short_name>
<dc:creator>Drupal</dc:creator>
<api_version>7.x</api_version>
<recommended_major>1</recommended_major>
<supported_majors>1</supported_majors>
<default_major>1</default_major>
<project_status>published</project_status>
<link>http://example.com/project/update_test_subtheme</link>
<terms>
<term><name>Projects</name><value>Themes</value></term>
</terms>
<releases>
<release>
<name>update_test_subtheme 7.x-1.0</name>
<version>7.x-1.0</version>
<tag>DRUPAL-7--1-0</tag>
<version_major>1</version_major>
<version_patch>0</version_patch>
<status>published</status>
<release_link>http://example.com/update_test_subtheme-7-x-1-0-release</release_link>
<download_link>http://example.com/update_test_subtheme-7.x-1.0.tar.gz</download_link>
<date>1250524521</date>
<mdhash>b966255555d9c9b86d480ca08cfaa98e</mdhash>
<filesize>1073741824</filesize>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
</releases>
</project>
......@@ -81,7 +81,24 @@ function update_get_projects() {
*/
function _update_process_info_list(&$projects, $list, $project_type, $status) {
foreach ($list as $file) {
if ($file->status != $status) {
// A disabled base theme of an enabled sub-theme still has all of its code
// run by the sub-theme, so we include it in our "enabled" projects list.
if ($status && !$file->status && !empty($file->sub_themes)) {
foreach ($file->sub_themes as $key => $name) {
// Build a list of enabled sub-themes.
if ($list[$key]->status) {
$file->enabled_sub_themes[$key] = $name;
}
}
// If there are no enabled subthemes, we should ignore this base theme
// for the enabled case. If the site is trying to display disabled
// themes, we'll catch it then.
if (empty($file->enabled_sub_themes)) {
continue;
}
}
// Otherwise, just add projects of the proper status to our list.
elseif ($file->status != $status) {
continue;
}
......@@ -133,10 +150,25 @@ function _update_process_info_list(&$projects, $list, $project_type, $status) {
else {
$project_display_type = $project_type;
}
if (empty($status)) {
if (empty($status) && empty($file->enabled_sub_themes)) {
// If we're processing disabled modules or themes, append a suffix.
// However, we don't do this to a a base theme with enabled
// subthemes, since we treat that case as if it is enabled.
$project_display_type .= '-disabled';
}
// Add a list of sub-themes that "depend on" the project and a list of base
// themes that are "required by" the project.
if ($project_name == 'drupal') {
// Drupal core is always required, so this extra info would be noise.
$sub_themes = array();
$base_themes = array();
}
else {
// Add list of enabled sub-themes.
$sub_themes = !empty($file->enabled_sub_themes) ? $file->enabled_sub_themes : array();
// Add list of base themes.
$base_themes = !empty($file->base_themes) ? $file->base_themes : array();
}
if (!isset($projects[$project_name])) {
// Only process this if we haven't done this project, since a single
// project can have multiple modules or themes.
......@@ -147,6 +179,8 @@ function _update_process_info_list(&$projects, $list, $project_type, $status) {
'includes' => array($file->name => $file->info['name']),
'project_type' => $project_display_type,
'project_status' => $status,
'sub_themes' => $sub_themes,
'base_themes' => $base_themes,
);
}
elseif ($projects[$project_name]['project_type'] == $project_display_type) {
......@@ -158,6 +192,12 @@ function _update_process_info_list(&$projects, $list, $project_type, $status) {
$projects[$project_name]['includes'][$file->name] = $file->info['name'];
$projects[$project_name]['info']['_info_file_ctime'] = max($projects[$project_name]['info']['_info_file_ctime'], $file->info['_info_file_ctime']);
$projects[$project_name]['datestamp'] = max($projects[$project_name]['datestamp'], $file->info['datestamp']);
if (!empty($sub_themes)) {
$projects[$project_name]['sub_themes'] += $sub_themes;
}
if (!empty($base_themes)) {
$projects[$project_name]['base_themes'] += $base_themes;
}
}
elseif (empty($status)) {
// If we have a project_name that matches, but the project_display_type
......
......@@ -172,6 +172,9 @@ function update_theme() {
'update_version' => array(
'arguments' => array('version' => NULL, 'tag' => NULL, 'class' => array()),
),
'update_status_label' => array(
'arguments' => array('status' => NULL),
),
);
}
......
......@@ -41,6 +41,15 @@ function theme_update_report($data) {
$notification_level = variable_get('update_notification_threshold', 'all');
// Create an array of status values keyed by module or theme name, since
// we'll need this while generating the report if we have to cross reference
// anything (e.g. subthemes which have base themes missing an update).
foreach ($data as $project) {
foreach ($project['includes'] as $key => $name) {
$status[$key] = $project['status'];
}
}
foreach ($data as $project) {
switch ($project['status']) {
case UPDATE_CURRENT:
......@@ -67,26 +76,8 @@ function theme_update_report($data) {
}
$row = '<div class="version-status">';
switch ($project['status']) {
case UPDATE_NOT_SECURE:
$row .= '<span class="security-error">' . t('Security update required!') . '</span>';
break;
case UPDATE_REVOKED:
$row .= '<span class="revoked">' . t('Revoked!') . '</span>';
break;
case UPDATE_NOT_SUPPORTED:
$row .= '<span class="not-supported">' . t('Not supported!') . '</span>';
break;
case UPDATE_NOT_CURRENT:
$row .= '<span class="not-current">' . t('Update available') . '</span>';
break;
case UPDATE_CURRENT:
$row .= '<span class="current">' . t('Up to date') . '</span>';
break;
default:
$row .= check_plain($project['reason']);
break;
}
$status_label = theme('update_status_label', $project['status']);
$row .= !empty($status_label) ? $status_label : check_plain($project['reason']);
$row .= '<span class="icon">' . $icon . '</span>';
$row .= "</div>\n";
......@@ -194,6 +185,33 @@ function theme_update_report($data) {
}
$row .= "</div>\n";
if (!empty($project['base_themes'])) {
$row .= '<div class="basethemes">';
asort($project['base_themes']);
$base_themes = array();
foreach ($project['base_themes'] as $base_key => $base_theme) {
switch ($status[$base_key]) {
case UPDATE_NOT_SECURE:
case UPDATE_REVOKED:
case UPDATE_NOT_SUPPORTED:
$base_themes[] = t('%base_theme (!base_label)', array('%base_theme' => $base_theme, '!base_label' => theme('update_status_label', $status[$base_key])));
break;
default:
$base_themes[] = theme('placeholder', $base_theme);
}
}
$row .= t('Depends on: !basethemes', array('!basethemes' => implode(', ', $base_themes)));
$row .= "</div>\n";
}
if (!empty($project['sub_themes'])) {
$row .= '<div class="subthemes">';
sort($project['sub_themes']);
$row .= t('Required by: %subthemes', array('%subthemes' => implode(', ', $project['sub_themes'])));
$row .= "</div>\n";
}
$row .= "</div>\n"; // info div.
if (!isset($rows[$project['project_type']])) {
......@@ -224,6 +242,34 @@ function theme_update_report($data) {
return $output;
}
/**
* Generate the HTML for the label to display for a project's update status.
*
* @param $status
* The integer code for a project's current update status.
*
* @see update_calculate_project_data()
*/
function theme_update_status_label($status) {
switch ($status) {
case UPDATE_NOT_SECURE:
return '<span class="security-error">' . t('Security update required!') . '</span>';
case UPDATE_REVOKED:
return '<span class="revoked">' . t('Revoked!') . '</span>';
case UPDATE_NOT_SUPPORTED:
return '<span class="not-supported">' . t('Not supported!') . '</span>';
case UPDATE_NOT_CURRENT:
return '<span class="not-current">' . t('Update available') . '</span>';
case UPDATE_CURRENT:
return '<span class="current">' . t('Up to date') . '</span>';
}
}
/**
* Theme the version display of a project.
*
......
......@@ -266,5 +266,104 @@ class UpdateTestContribCase extends UpdateTestHelper {
$this->assertTrue(strpos($this->drupalGetContent(), $bbb_project_link) < strpos($this->drupalGetContent(), $ccc_project_link), "'BBB Update test' project is listed before the 'CCC Update test' project");
}
/**
* Test that subthemes are notified about security updates for base themes.
*/
function testUpdateBaseThemeSecurityUpdate() {
// Only enable the subtheme, not the base theme.
db_update('system')
->fields(array('status' => 1))
->condition('type', 'theme')
->condition('name', 'update_test_subtheme')
->execute();
// Define the initial state for core and the subtheme.
$system_info = array(
// We want core to be version 7.0.
'#all' => array(
'version' => '7.0',
),
// Show the update_test_basetheme
'update_test_basetheme' => array(
'project' => 'update_test_basetheme',
'version' => '7.x-1.0',
'hidden' => FALSE,
),
// Show the update_test_subtheme
'update_test_subtheme' => array(
'project' => 'update_test_subtheme',
'version' => '7.x-1.0',
'hidden' => FALSE,
),
);
variable_set('update_test_system_info', $system_info);
$xml_mapping = array(
'drupal' => '0',
'update_test_subtheme' => '1_0',
'update_test_basetheme' => '1_1-sec',
);
$this->refreshUpdateStatus($xml_mapping);
$this->drupalGet('admin/reports/updates');
$this->assertText(t('Security update required!'));
$this->assertRaw(l(t('Update test base theme'), 'http://example.com/project/update_test_basetheme'), t('Link to the Update test base theme project appears.'));
}
/**
* Test that disabled themes are only shown when desired.
*/
function testUpdateShowDisabledThemes() {
// Make sure all the update_test_* themes are disabled.
db_update('system')
->fields(array('status' => 0))
->condition('type', 'theme')
->condition('name', 'update_test_%', 'LIKE')
->execute();
// Define the initial state for core and the test contrib themes.
$system_info = array(
// We want core to be version 7.0.
'#all' => array(
'version' => '7.0',
),
// The update_test_basetheme should be visible and up to date.
'update_test_basetheme' => array(
'project' => 'update_test_basetheme',
'version' => '7.x-1.1',
'hidden' => FALSE,
),
// The update_test_subtheme should be visible and up to date.
'update_test_subtheme' => array(
'project' => 'update_test_subtheme',
'version' => '7.x-1.0',
'hidden' => FALSE,
),
);
variable_set('update_test_system_info', $system_info);
$xml_mapping = array(
'drupal' => '0',
'update_test_subtheme' => '1_0',
'update_test_basetheme' => '1_1-sec',
);
$base_theme_project_link = l(t('Update test base theme'), 'http://example.com/project/update_test_basetheme');
$sub_theme_project_link = l(t('Update test subtheme'), 'http://example.com/project/update_test_subtheme');
foreach (array(TRUE, FALSE) as $check_disabled) {
variable_set('update_check_disabled', $check_disabled);
$this->refreshUpdateStatus($xml_mapping);
$this->drupalGet('admin/reports/updates');
// In neither case should we see the "Themes" heading for enabled themes.
$this->assertNoText(t('Themes'));
if ($check_disabled) {
$this->assertText(t('Disabled themes'));
$this->assertRaw($base_theme_project_link, t('Link to the Update test base theme project appears.'));
$this->assertRaw($sub_theme_project_link, t('Link to the Update test subtheme project appears.'));
}
else {
$this->assertNoText(t('Disabled themes'));
$this->assertNoRaw($base_theme_project_link, t('Link to the Update test base theme project does not appear.'));
$this->assertNoRaw($sub_theme_project_link, t('Link to the Update test subtheme project does not appear.'));
}
}
}
}
; $Id$
name = Update test base theme
description = Test theme which acts as a base theme for other test subthemes.
core = 7.x
engine = phptemplate
hidden = TRUE
; $Id$
name = Update test subtheme
description = Test theme which uses update_test_basetheme as the base theme.
core = 7.x
engine = phptemplate
base theme = update_test_basetheme
hidden = TRUE
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