diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index a5fb606..8168257 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -3138,8 +3138,21 @@ class DrupalWebTestCase extends DrupalTestCase {
* @return
* TRUE on pass, FALSE on fail.
*/
- protected function assertFieldByName($name, $value = '', $message = '') {
- return $this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value, $message ? $message : t('Found field by name @name', array('@name' => $name)), t('Browser'));
+ protected function assertFieldByName($name, $value = NULL, $message = NULL) {
+ if (!isset($message)) {
+ if (!isset($value)) {
+ $message = t('Found field with name @name', array(
+ '@name' => var_export($name, TRUE),
+ ));
+ }
+ else {
+ $message = t('Found field with name @name and value @value', array(
+ '@name' => var_export($name, TRUE),
+ '@value' => var_export($value, TRUE),
+ ));
+ }
+ }
+ return $this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value, $message, t('Browser'));
}
/**
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 6dca80b..de069f6 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -451,15 +451,13 @@ function system_theme_settings($form, &$form_state, $key = '') {
$form['logo'] = array(
'#type' => 'fieldset',
'#title' => t('Logo image settings'),
- '#description' => t('If toggled on, the following logo will be displayed.'),
'#attributes' => array('class' => array('theme-settings-bottom')),
);
$form['logo']['default_logo'] = array(
'#type' => 'checkbox',
- '#title' => t('Use the default logo'),
+ '#title' => t('Use the default logo supplied by the theme'),
'#default_value' => theme_get_setting('default_logo', $key),
'#tree' => FALSE,
- '#description' => t('Check here if you want the theme to use the logo supplied with it.')
);
$form['logo']['settings'] = array(
'#type' => 'container',
@@ -470,17 +468,10 @@ function system_theme_settings($form, &$form_state, $key = '') {
),
),
);
- $logo_path = theme_get_setting('logo_path', $key);
- // If $logo_path is a public:// URI, display the path relative to the files
- // directory; stream wrappers are not end-user friendly.
- if (file_uri_scheme($logo_path) == 'public') {
- $logo_path = file_uri_target($logo_path);
- }
$form['logo']['settings']['logo_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to custom logo'),
- '#default_value' => $logo_path,
- '#description' => t('The path to the file you would like to use as your logo file instead of the default logo.'),
+ '#default_value' => theme_get_setting('logo_path', $key),
);
$form['logo']['settings']['logo_upload'] = array(
'#type' => 'file',
@@ -498,9 +489,8 @@ function system_theme_settings($form, &$form_state, $key = '') {
);
$form['favicon']['default_favicon'] = array(
'#type' => 'checkbox',
- '#title' => t('Use the default shortcut icon.'),
+ '#title' => t('Use the default shortcut icon supplied by the theme'),
'#default_value' => theme_get_setting('default_favicon', $key),
- '#description' => t('Check here if you want the theme to use the default shortcut icon.')
);
$form['favicon']['settings'] = array(
'#type' => 'container',
@@ -511,17 +501,10 @@ function system_theme_settings($form, &$form_state, $key = '') {
),
),
);
- $favicon_path = theme_get_setting('favicon_path', $key);
- // If $favicon_path is a public:// URI, display the path relative to the
- // files directory; stream wrappers are not end-user friendly.
- if (file_uri_scheme($favicon_path) == 'public') {
- $favicon_path = file_uri_target($favicon_path);
- }
$form['favicon']['settings']['favicon_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to custom icon'),
- '#default_value' => $favicon_path,
- '#description' => t('The path to the image file you would like to use as your custom shortcut icon.')
+ '#default_value' => theme_get_setting('favicon_path', $key),
);
$form['favicon']['settings']['favicon_upload'] = array(
'#type' => 'file',
@@ -530,6 +513,40 @@ function system_theme_settings($form, &$form_state, $key = '') {
);
}
+ // Inject human-friendly values and form element descriptions for logo and
+ // favicon.
+ foreach (array('logo' => 'logo.png', 'favicon' => 'favicon.ico') as $type => $default) {
+ if (isset($form[$type]['settings'][$type . '_path'])) {
+ $element = &$form[$type]['settings'][$type . '_path'];
+
+ // If path is a public:// URI, display the path relative to the files
+ // directory; stream wrappers are not end-user friendly.
+ $original_path = $element['#default_value'];
+ $friendly_path = NULL;
+ if (file_uri_scheme($original_path) == 'public') {
+ $friendly_path = file_uri_target($original_path);
+ $element['#default_value'] = $friendly_path;
+ }
+
+ // Prepare local file path for description.
+ if ($original_path && isset($friendly_path)) {
+ $local_file = strtr($original_path, array('public:/' => variable_get('file_public_path', conf_path() . '/files')));
+ }
+ elseif ($key) {
+ $local_file = drupal_get_path('theme', $key) . '/' . $default;
+ }
+ else {
+ $local_file = path_to_theme() . '/' . $default;
+ }
+
+ $element['#description'] = t('Use @implicit-public-file
to reference a file in the public filesystem, @explicit-file
for a specific filesystem, or @local-file
for an arbitrary local file within this site.', array(
+ '@implicit-public-file' => isset($friendly_path) ? $friendly_path : $default,
+ '@explicit-file' => file_uri_scheme($original_path) !== FALSE ? $original_path : 'public://' . $default,
+ '@local-file' => $local_file,
+ ));
+ }
+ }
+
if ($key) {
// Call engine-specific settings.
$function = $themes[$key]->prefix . '_engine_settings';
@@ -657,13 +674,20 @@ function system_theme_settings_validate($form, &$form_state) {
* the path could not be validated.
*/
function _system_theme_settings_validate_path($path) {
- if (drupal_realpath($path)) {
- // The path is relative to the Drupal root, or is a valid URI.
+ // Absolute local file paths are invalid.
+ if (drupal_realpath($path) == $path) {
+ return FALSE;
+ }
+ // A path relative to the Drupal root or a fully qualified URI is valid.
+ if (is_file($path)) {
return $path;
}
- $uri = 'public://' . $path;
- if (file_exists($uri)) {
- return $uri;
+ // Prepend 'public://' for relative file paths within public filesystem.
+ if (file_uri_scheme($path) === FALSE) {
+ $path = 'public://' . $path;
+ }
+ if (is_file($path)) {
+ return $path;
}
return FALSE;
}
@@ -672,6 +696,11 @@ function _system_theme_settings_validate_path($path) {
* Process system_theme_settings form submissions.
*/
function system_theme_settings_submit($form, &$form_state) {
+ // Exclude unnecessary elements before saving.
+ form_state_values_clean($form_state);
+ $key = $form_state['values']['var'];
+ unset($form_state['values']['var']);
+
$values = $form_state['values'];
// If the user uploaded a new logo or favicon, save it to a permanent location
@@ -703,10 +732,7 @@ function system_theme_settings_submit($form, &$form_state) {
if (empty($values['default_favicon']) && !empty($values['favicon_path'])) {
$values['favicon_mimetype'] = file_get_mimetype($values['favicon_path']);
}
- $key = $values['var'];
- // Exclude unnecessary elements before saving.
- unset($values['var'], $values['submit'], $values['reset'], $values['form_id'], $values['op'], $values['form_build_id'], $values['form_token']);
variable_set($key, $values);
drupal_set_message(t('The configuration options have been saved.'));
diff --git a/core/modules/system/system.test b/core/modules/system/system.test
index 12797ed..f83a7fa 100644
--- a/core/modules/system/system.test
+++ b/core/modules/system/system.test
@@ -1600,6 +1600,8 @@ class SystemMainContentFallback extends DrupalWebTestCase {
* Tests for the theme interface functionality.
*/
class SystemThemeFunctionalTest extends DrupalWebTestCase {
+ protected $profile = 'testing';
+
public static function getInfo() {
return array(
'name' => 'Theme interface functionality',
@@ -1609,7 +1611,9 @@ class SystemThemeFunctionalTest extends DrupalWebTestCase {
}
function setUp() {
- parent::setUp();
+ parent::setUp(array('block'));
+
+ $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
$this->admin_user = $this->drupalCreateUser(array('access administration pages', 'view the administration theme', 'administer themes', 'bypass node access', 'administer blocks'));
$this->drupalLogin($this->admin_user);
@@ -1622,26 +1626,127 @@ class SystemThemeFunctionalTest extends DrupalWebTestCase {
function testThemeSettings() {
// Specify a filesystem path to be used for the logo.
$file = current($this->drupalGetTestFiles('image'));
- $fullpath = drupal_realpath($file->uri);
- $edit = array(
- 'default_logo' => FALSE,
- 'logo_path' => $fullpath,
+ $file_relative = strtr($file->uri, array('public:/' => variable_get('file_public_path', conf_path() . '/files')));
+ $default_theme_path = 'core/themes/stark';
+
+ $supported_paths = array(
+ // Raw stream wrapper URI.
+ $file->uri => array(
+ 'form' => file_uri_target($file->uri),
+ 'src' => file_create_url($file->uri),
+ ),
+ // Relative path within the public filesystem.
+ file_uri_target($file->uri) => array(
+ 'form' => file_uri_target($file->uri),
+ 'src' => file_create_url($file->uri),
+ ),
+ // Relative path to a public file.
+ $file_relative => array(
+ 'form' => $file_relative,
+ 'src' => file_create_url($file->uri),
+ ),
+ // Relative path to an arbitrary file.
+ 'core/misc/druplicon.png' => array(
+ 'form' => 'core/misc/druplicon.png',
+ 'src' => $GLOBALS['base_url'] . '/' . 'core/misc/druplicon.png',
+ ),
+ // Relative path to a file in a theme.
+ $default_theme_path . '/logo.png' => array(
+ 'form' => $default_theme_path . '/logo.png',
+ 'src' => $GLOBALS['base_url'] . '/' . $default_theme_path . '/logo.png',
+ ),
);
- $this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'));
- $this->drupalGet('node');
- $this->assertRaw($fullpath, t('Logo path successfully changed.'));
+ foreach ($supported_paths as $input => $expected) {
+ $edit = array(
+ 'default_logo' => FALSE,
+ 'logo_path' => $input,
+ );
+ $this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'));
+ $this->assertNoText('The custom logo path is invalid.');
+ $this->assertFieldByName('logo_path', $expected['form']);
+
+ // Verify logo path examples.
+ $elements = $this->xpath('//div[contains(@class, :item)]/div[@class=:description]/code', array(
+ ':item' => 'form-item-logo-path',
+ ':description' => 'description',
+ ));
+ // Expected default values (if all else fails).
+ $implicit_public_file = 'logo.png';
+ $explicit_file = 'public://logo.png';
+ $local_file = $default_theme_path . '/logo.png';
+ // Adjust for fully qualified stream wrapper URI in public filesystem.
+ if (file_uri_scheme($input) == 'public') {
+ $implicit_public_file = file_uri_target($input);
+ $explicit_file = $input;
+ $local_file = strtr($input, array('public:/' => variable_get('file_public_path', conf_path() . '/files')));
+ }
+ // Adjust for fully qualified stream wrapper URI elsewhere.
+ elseif (file_uri_scheme($input) !== FALSE) {
+ $explicit_file = $input;
+ }
+ // Adjust for relative path within public filesystem.
+ elseif ($input == file_uri_target($file->uri)) {
+ $implicit_public_file = $input;
+ $explicit_file = 'public://' . $input;
+ $local_file = variable_get('file_public_path', conf_path() . '/files') . '/' . $input;
+ }
+ $this->assertEqual((string) $elements[0], $implicit_public_file);
+ $this->assertEqual((string) $elements[1], $explicit_file);
+ $this->assertEqual((string) $elements[2], $local_file);
+
+ // Verify the actual 'src' attribute of the logo being output.
+ $this->drupalGet('');
+ $elements = $this->xpath('//*[@id=:id]/img', array(':id' => 'logo'));
+ $this->assertEqual((string) $elements[0]['src'], $expected['src']);
+ }
+
+ $unsupported_paths = array(
+ // Stream wrapper URI to non-existing file.
+ 'public://whatever.png',
+ 'private://whatever.png',
+ 'temporary://whatever.png',
+ // Bogus stream wrapper URIs.
+ 'public:/whatever.png',
+ '://whatever.png',
+ ':whatever.png',
+ 'public://',
+ // Relative path within the public filesystem to non-existing file.
+ 'whatever.png',
+ // Relative path to non-existing file in public filesystem.
+ variable_get('file_public_path', conf_path() . '/files') . '/whatever.png',
+ // Semi-absolute path to non-existing file in public filesystem.
+ '/' . variable_get('file_public_path', conf_path() . '/files') . '/whatever.png',
+ // Relative path to arbitrary non-existing file.
+ 'core/misc/whatever.png',
+ // Semi-absolute path to arbitrary non-existing file.
+ '/core/misc/whatever.png',
+ // Absolute paths to any local file (even if it exists).
+ drupal_realpath($file->uri),
+ );
+ $this->drupalGet('admin/appearance/settings');
+ foreach ($unsupported_paths as $path) {
+ $edit = array(
+ 'default_logo' => FALSE,
+ 'logo_path' => $path,
+ );
+ $this->drupalPost(NULL, $edit, t('Save configuration'));
+ $this->assertText('The custom logo path is invalid.');
+ }
// Upload a file to use for the logo.
- $file = current($this->drupalGetTestFiles('image'));
$edit = array(
'default_logo' => FALSE,
'logo_path' => '',
'files[logo_upload]' => drupal_realpath($file->uri),
);
- $options = array();
- $this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'), $options);
- $this->drupalGet('node');
- $this->assertRaw($file->name, t('Logo file successfully uploaded.'));
+ $this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'));
+
+ $fields = $this->xpath($this->constructFieldXpath('name', 'logo_path'));
+ $uploaded_filename = 'public://' . $fields[0]['value'];
+
+ $this->drupalGet('');
+ $elements = $this->xpath('//*[@id=:id]/img', array(':id' => 'logo'));
+ $this->assertEqual($elements[0]['src'], file_create_url($uploaded_filename));
}
/**
@@ -1700,20 +1805,20 @@ class SystemThemeFunctionalTest extends DrupalWebTestCase {
* Test switching the default theme.
*/
function testSwitchDefaultTheme() {
- // Enable "stark" and set it as the default theme.
- theme_enable(array('stark'));
+ // Enable Bartik and set it as the default theme.
+ theme_enable(array('bartik'));
$this->drupalGet('admin/appearance');
- $this->clickLink(t('Set default'), 1);
- $this->assertTrue(variable_get('theme_default', '') == 'stark', t('Site default theme switched successfully.'));
+ $this->clickLink(t('Set default'));
+ $this->assertEqual(variable_get('theme_default', ''), 'bartik');
// Test the default theme on the secondary links (blocks admin page).
$this->drupalGet('admin/structure/block');
- $this->assertText('Stark(' . t('active tab') . ')', t('Default local task on blocks admin page is the default theme.'));
- // Switch back to Bartik and test again to test that the menu cache is cleared.
+ $this->assertText('Bartik(' . t('active tab') . ')', t('Default local task on blocks admin page is the default theme.'));
+ // Switch back to Stark and test again to test that the menu cache is cleared.
$this->drupalGet('admin/appearance');
$this->clickLink(t('Set default'), 0);
$this->drupalGet('admin/structure/block');
- $this->assertText('Bartik(' . t('active tab') . ')', t('Default local task on blocks admin page has changed.'));
+ $this->assertText('Stark(' . t('active tab') . ')', t('Default local task on blocks admin page has changed.'));
}
}