diff --git a/modules/filter/filter.admin.inc b/modules/filter/filter.admin.inc index c03d586452ee95c357cee9547f8da36e614a2904..e1f6d9c902841891dba6ef6a742fa9d9a2535af7 100644 --- a/modules/filter/filter.admin.inc +++ b/modules/filter/filter.admin.inc @@ -135,7 +135,8 @@ function filter_admin_format_form($form, &$form_state, $format) { } // Table with filters $filter_info = filter_get_filters(); - $filters = filter_list_format($format->format); + // Load all configured filters for existing text formats. + $filters = !empty($format->format) ? filter_list_format($format->format) : array(); $form['filters'] = array('#type' => 'fieldset', '#title' => t('Filters'), diff --git a/modules/filter/filter.install b/modules/filter/filter.install index 389100be8da9954a8b49e1d518e24d837903a45c..d07ee3082785e8da2b475e685676fae580fe4d7b 100644 --- a/modules/filter/filter.install +++ b/modules/filter/filter.install @@ -59,7 +59,7 @@ function filter_schema() { 'fmn' => array('format', 'module', 'name'), ), 'indexes' => array( - 'list' => array('format', 'weight', 'module', 'name'), + 'list' => array('weight', 'module', 'name'), ), ); $schema['filter_format'] = array( @@ -350,6 +350,14 @@ function filter_update_7005() { // @todo This variable can be deleted in Drupal 8. } +/** + * Remove the 'format' column from 'list' index on {filter}. + */ +function filter_update_7006() { + db_drop_index('filter', 'list'); + db_add_index('filter', 'list', array('weight', 'module', 'name')); +} + /** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. diff --git a/modules/filter/filter.module b/modules/filter/filter.module index 90a7f8f3370560677988341d775c3ef2cfa8f283..d696f8cfc6e1fbe14dc9ee39be8ebe46a66f15ad 100644 --- a/modules/filter/filter.module +++ b/modules/filter/filter.module @@ -193,22 +193,47 @@ function filter_format_save(&$format) { } // Get the current filters in the format, to add new filters to the bottom. - $current = filter_list_format($format->format); + $current = ($return != SAVED_NEW ? filter_list_format($format->format) : array()); $filter_info = filter_get_filters(); + // Programmatic saves may not contain any filters. if (!isset($format->filters)) { $format->filters = array(); } - foreach ($format->filters as $name => $filter) { - $fields = array(); - // Add new filters to the bottom. - $fields['weight'] = isset($current[$name]->weight) ? $current[$name]->weight : 10; - $fields['status'] = $filter['status']; - $fields['module'] = $filter_info[$name]['module']; - $format->filters[$name]['module'] = $filter_info[$name]['module']; - // Only update settings if there are any. - if (!empty($filter['settings'])) { - $fields['settings'] = serialize($filter['settings']); + foreach ($filter_info as $name => $filter) { + // As of now, only programmatic saves may contain weight (see below). If + // there is no weight, either fall back to the currently stored weight or + // add new filters to the bottom. + if (!isset($format->filters[$name]['weight'])) { + $format->filters[$name]['weight'] = isset($current[$name]->weight) ? $current[$name]->weight : 10; + } + $format->filters[$name]['status'] = isset($format->filters[$name]['status']) ? $format->filters[$name]['status'] : 0; + $format->filters[$name]['module'] = $filter['module']; + + // Since filter configuration/order lives on separate pages, there may be no + // filter settings contained. In that case, we either fall back to currently + // stored settings, default settings (if existent), or an empty array. + // @see http://drupal.org/node/558666 + // If settings were passed, only ensure default settings. + if (isset($format->filters[$name]['settings'])) { + if (isset($filter['default settings'])) { + $format->filters[$name]['settings'] = array_merge($filter['default settings'], $format->filters[$name]['settings']); + } } + // If we have existing settings, take them over directly. + elseif (isset($current[$name]->settings)) { + $format->filters[$name]['settings'] = $current[$name]->settings; + } + // Otherwise, use default settings or fall back to an empty array. + else { + $format->filters[$name]['settings'] = isset($filter['default settings']) ? $filter['default settings'] : array(); + } + + $fields = array(); + $fields['weight'] = $format->filters[$name]['weight']; + $fields['status'] = $format->filters[$name]['status']; + $fields['module'] = $format->filters[$name]['module']; + $fields['settings'] = serialize($format->filters[$name]['settings']); + db_merge('filter') ->key(array( 'format' => $format->format, @@ -530,7 +555,7 @@ function _filter_format_is_cacheable($format) { $filter_info = filter_get_filters(); foreach ($format->filters as $name => $filter) { // By default, 'cache' is TRUE for all filters unless specified otherwise. - if (isset($filter_info[$name]['cache']) && !$filter_info[$name]['cache']) { + if (!empty($filter['status']) && isset($filter_info[$name]['cache']) && !$filter_info[$name]['cache']) { return FALSE; } } @@ -556,24 +581,21 @@ function filter_list_format($format_id) { $filters = &drupal_static(__FUNCTION__, array()); $filter_info = filter_get_filters(); + if (!isset($filters['all'])) { + $result = db_query('SELECT * FROM {filter} ORDER BY weight, module, name'); + foreach ($result as $record) { + $filters['all'][$record->format][$record->name] = $record; + } + } + if (!isset($filters[$format_id])) { $format_filters = array(); - $query = db_select('filter', 'filter') - ->fields('filter') - ->condition('format', $format_id) - ->orderBy('weight') - ->orderBy('module') - ->orderBy('name'); - $result = $query->execute()->fetchAllAssoc('name'); - foreach ($result as $name => $filter) { + foreach ($filters['all'][$format_id] as $name => $filter) { if (isset($filter_info[$name])) { $filter->title = $filter_info[$name]['title']; // Unpack stored filter settings. $filter->settings = (isset($filter->settings) ? unserialize($filter->settings) : array()); - // Apply default filter settings. - if (isset($filter_info[$name]['default settings'])) { - $filter->settings = array_merge($filter_info[$name]['default settings'], $filter->settings); - } + $format_filters[$name] = $filter; } } diff --git a/modules/filter/filter.test b/modules/filter/filter.test index a7302c8daacfc37571a48b57a5c35542d892687b..09b069fa4c37800e25c49b5153b9b124e2e70433 100644 --- a/modules/filter/filter.test +++ b/modules/filter/filter.test @@ -97,8 +97,9 @@ class FilterCRUDTestCase extends DrupalWebTestCase { foreach ($filters as $name => $filter) { // If this filter is not cacheable, update $cacheable accordingly, so we // can verify $format->cache after iterating over all filters. - if (isset($filter_info[$name]['cache']) && !$filter_info[$name]['cache']) { + if ($filter->status && isset($filter_info[$name]['cache']) && !$filter_info[$name]['cache']) { $cacheable = FALSE; + break; } } $this->assertEqual($filter_format->cache, $cacheable, t('Text format contains proper cache property.')); @@ -114,18 +115,11 @@ class FilterCRUDTestCase extends DrupalWebTestCase { foreach ($filters as $name => $filter) { $t_args = array('%format' => $format->name, '%filter' => $name); - // Check whether the filter is contained in the saved $format. - if (isset($format_filters[$name])) { - // Verify that filter status is properly stored. - $this->assertEqual($filter->status, $format_filters[$name]['status'], t('Database: Proper status for %filter in text format %format.', $t_args)); + // Verify that filter status is properly stored. + $this->assertEqual($filter->status, $format_filters[$name]['status'], t('Database: Proper status for %filter in text format %format.', $t_args)); - // Verify that filter settings were properly stored. - $this->assertEqual(unserialize($filter->settings), isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), t('Database: Proper filter settings for %filter in text format %format.', $t_args)); - } - // Otherwise, the stored filter must be disabled. - else { - $this->assertTrue($filter->status == 0, t('Database: Proper status for disabled %filter in text format %format.', $t_args)); - } + // Verify that filter settings were properly stored. + $this->assertEqual(unserialize($filter->settings), isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), t('Database: Proper filter settings for %filter in text format %format.', $t_args)); // Verify that each filter has a module name assigned. $this->assertTrue(!empty($filter->module), t('Database: Proper module name for %filter in text format %format.', $t_args)); @@ -143,18 +137,11 @@ class FilterCRUDTestCase extends DrupalWebTestCase { foreach ($filters as $name => $filter) { $t_args = array('%format' => $format->name, '%filter' => $name); - // Check whether the filter is contained in the saved $format. - if (isset($format_filters[$name])) { - // Verify that filter status is properly stored. - $this->assertEqual($filter->status, $format_filters[$name]['status'], t('filter_list_format: Proper status for %filter in text format %format.', $t_args)); + // Verify that filter status is properly stored. + $this->assertEqual($filter->status, $format_filters[$name]['status'], t('filter_list_format: Proper status for %filter in text format %format.', $t_args)); - // Verify that filter settings were properly stored. - $this->assertEqual($filter->settings, isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), t('filter_list_format: Proper filter settings for %filter in text format %format.', $t_args)); - } - // Otherwise, the stored filter must be disabled. - else { - $this->assertTrue($filter->status == 0, t('filter_list_format: Proper status for disabled %filter in text format %format.', $t_args)); - } + // Verify that filter settings were properly stored. + $this->assertEqual($filter->settings, isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), t('filter_list_format: Proper filter settings for %filter in text format %format.', $t_args)); // Verify that each filter has a module name assigned. $this->assertTrue(!empty($filter->module), t('filter_list_format: Proper module name for %filter in text format %format.', $t_args)); diff --git a/modules/locale/locale.test b/modules/locale/locale.test index 2d2d14153db850076d3eb1487de6e29ce16698db..2e6cceade6ea1aa4f4e62c9375496433b5f3fc1e 100644 --- a/modules/locale/locale.test +++ b/modules/locale/locale.test @@ -1716,7 +1716,7 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase { // Check if node body is showed. $this->drupalGet("node/$node->nid"); $body_xpath = '//div[@id="node-' . $node->nid . '"]//div[@property="content:encoded"]/p'; - $this->assertEqual(current($this->xpath($body_xpath)), $node->body['en'][0]['value'], 'Node body is correctly showed.', 'Node'); + $this->assertEqual(current($this->xpath($body_xpath)), $node->body['en'][0]['value'], 'Node body is correctly showed.'); $settings['body[full][type]'] = 'hidden'; $this->drupalPost('admin/structure/types/manage/page/display', $settings, t('Save')); diff --git a/modules/php/php.install b/modules/php/php.install index c010fc738c7ee16503c786480bf932d19d99976a..a8ac75ce728d776eaec932eacee0beffa8e70d7a 100644 --- a/modules/php/php.install +++ b/modules/php/php.install @@ -7,34 +7,33 @@ */ /** - * Implement hook_install(). + * Implements hook_enable(). */ -function php_install() { +function php_enable() { $format_exists = (bool) db_query_range('SELECT 1 FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField(); // Add a PHP code text format, if it does not exist. Do this only for the // first install (or if the format has been manually deleted) as there is no // reliable method to identify the format in an uninstall hook or in // subsequent clean installs. if (!$format_exists) { - $format = db_insert('filter_format') - ->fields(array( - 'name' => 'PHP code', - 'cache' => 0, - )) - ->execute(); + $php_format = array( + 'name' => 'PHP code', + // 'Plain text' format is installed with a weight of 10 by default. Use a + // higher weight here to ensure that this format will not be the default + // format for anyone. + 'weight' => 11, + 'filters' => array( + // Enable the PHP evaluator filter. + 'php_code' => array( + 'weight' => 0, + 'status' => 1, + ), + ), + ); + $php_format = (object) $php_format; + filter_format_save($php_format); - // Enable the PHP evaluator filter. - db_insert('filter') - ->fields(array( - 'format' => $format, - 'module' => 'php', - 'name' => 'php_code', - 'weight' => 0, - 'status' => 1, - )) - ->execute(); - - drupal_set_message(t('A !php-code text format has been created.', array('!php-code' => l('PHP code', 'admin/config/content/formats/' . $format)))); + drupal_set_message(t('A !php-code text format has been created.', array('!php-code' => l('PHP code', 'admin/config/content/formats/' . $php_format->format)))); } } diff --git a/modules/php/php.test b/modules/php/php.test index a70fb0ac666ef6d02a49a2b29f1a0e9ee9b19736..778cb1052f136e2d90cd55e285f3865e068b8095 100644 --- a/modules/php/php.test +++ b/modules/php/php.test @@ -14,14 +14,26 @@ class PHPTestCase extends DrupalWebTestCase { $admin_user = $this->drupalCreateUser(array('administer filters')); $this->drupalLogin($admin_user); - // Confirm that the PHP code text format was inserted as the newest format - // on the site. - $newest_format_id = db_query("SELECT MAX(format) FROM {filter_format}")->fetchField(); - $newest_format = filter_format_load($newest_format_id); - $this->assertEqual($newest_format->name, 'PHP code', t('PHP code text format was created.')); + // Verify that the PHP code text format was inserted. + $php_format_id = db_query_range('SELECT format FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField(); + $php_format = filter_format_load($php_format_id); + $this->assertEqual($php_format->name, 'PHP code', t('PHP code text format was created.')); + + // Verify that the format has the PHP code filter enabled. + $filters = filter_list_format($php_format_id); + $this->assertTrue($filters['php_code']->status, t('PHP code filter is enabled.')); + + // Verify that the format exists on the administration page. + $this->drupalGet('admin/config/content/formats'); + $this->assertText('PHP code', t('PHP code text format was created.')); + + // Verify that anonymous and authenticated user roles do not have access. + $this->drupalGet('admin/config/content/formats/' . $php_format_id); + $this->assertFieldByName('roles[1]', FALSE, t('Anonymous users do not have access to PHP code format.')); + $this->assertFieldByName('roles[2]', FALSE, t('Authenticated users do not have access to PHP code format.')); // Store the format ID of the PHP code text format for later use. - $this->php_code_format = $newest_format_id; + $this->php_code_format = $php_format_id; } /** @@ -60,7 +72,7 @@ class PHPFilterTestCase extends PHPTestCase { // Make sure that the PHP code shows up as text. $this->drupalGet('node/' . $node->nid); - $this->assertText('print', t('PHP code is displayed.')); + $this->assertText('print', t('PHP code was not evaluated.')); // Change filter to PHP filter and see that PHP code is evaluated. $edit = array(); @@ -98,7 +110,7 @@ class PHPAccessTestCase extends PHPTestCase { // Make sure that the PHP code shows up as text. $this->drupalGet('node/' . $node->nid); - $this->assertText('print', t('PHP code is displayed.')); + $this->assertText('print', t('PHP code was not evaluated.')); // Make sure that user doesn't have access to filter. $this->drupalGet('node/' . $node->nid . '/edit'); diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index 274dceb4511cb7b648bed7b6484d140503bdec9d..8b2e24e2171fe5a4e15a58b456060d879cc07079 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -590,16 +590,14 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase { $expected = 'font-size:254px;'; // Create a node, using the PHP filter that tests drupal_add_css(). + $php_format_id = db_query_range('SELECT format FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField(); $settings = array( 'type' => 'page', 'body' => array( LANGUAGE_NONE => array( array( 'value' => t('This tests the inline CSS!') . "<?php drupal_add_css('$css', 'inline'); ?>", - // The "PHP code" format is always the most recent one added, since - // the PHP module was enabled in the setUp() method of the current - // test. - 'format' => db_query("SELECT MAX(format) FROM {filter_format}")->fetchField(), + 'format' => $php_format_id, ), ), ), diff --git a/modules/system/system.install b/modules/system/system.install index 8bd1dcce8507c65186179b0e4ef6a1c7ab9e2130..0558bd42682b15e85d256709c519003af327b414 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -417,113 +417,6 @@ function system_install() { )) ->execute(); - // Add text formats. - $filtered_html_format = db_insert('filter_format') - ->fields(array( - 'name' => 'Filtered HTML', - 'cache' => 1, - 'weight' => 0, - )) - ->execute(); - $full_html_format = db_insert('filter_format') - ->fields(array( - 'name' => 'Full HTML', - 'cache' => 1, - 'weight' => 0, - )) - ->execute(); - $plain_text_format = db_insert('filter_format') - ->fields(array( - 'name' => 'Plain text', - 'cache' => 1, - 'weight' => 1, - )) - ->execute(); - - // Enable filters for each text format. - - // Filtered HTML: - db_insert('filter') - ->fields(array('format', 'module', 'name', 'weight', 'status')) - // URL filter. - ->values(array( - 'format' => $filtered_html_format, - 'module' => 'filter', - 'name' => 'filter_url', - 'weight' => 0, - 'status' => 1, - )) - // HTML filter. - ->values(array( - 'format' => $filtered_html_format, - 'module' => 'filter', - 'name' => 'filter_html', - 'weight' => 1, - 'status' => 1, - )) - // Line break filter. - ->values(array( - 'format' => $filtered_html_format, - 'module' => 'filter', - 'name' => 'filter_autop', - 'weight' => 2, - 'status' => 1, - )) - // HTML corrector filter. - ->values(array( - 'format' => $filtered_html_format, - 'module' => 'filter', - 'name' => 'filter_htmlcorrector', - 'weight' => 10, - 'status' => 1, - )) - // Full HTML: - // URL filter. - ->values(array( - 'format' => $full_html_format, - 'module' => 'filter', - 'name' => 'filter_url', - 'weight' => 0, - 'status' => 1, - )) - // Line break filter. - ->values(array( - 'format' => $full_html_format, - 'module' => 'filter', - 'name' => 'filter_autop', - 'weight' => 1, - 'status' => 1, - )) - // HTML corrector filter. - ->values(array( - 'format' => $full_html_format, - 'module' => 'filter', - 'name' => 'filter_htmlcorrector', - 'weight' => 10, - 'status' => 1, - )) - // Plain text: - // Escape all HTML. - ->values(array( - 'format' => $plain_text_format, - 'module' => 'filter', - 'name' => 'filter_html_escape', - 'weight' => 0, - 'status' => 1, - )) - // Line break filter. - ->values(array( - 'format' => $plain_text_format, - 'module' => 'filter', - 'name' => 'filter_autop', - 'weight' => 1, - 'status' => 1, - )) - ->execute(); - - // Set the fallback format to plain text. - variable_set('filter_fallback_format', $plain_text_format); - $cron_key = md5(mt_rand()); variable_set('cron_key', $cron_key); diff --git a/profiles/default/default.install b/profiles/default/default.install index 05b54936b8903d02542876f894b5ffe5b67b0182..1b72498f86693b19a21e46941c361fa4404e228b 100644 --- a/profiles/default/default.install +++ b/profiles/default/default.install @@ -7,6 +7,81 @@ * Perform actions to set up the site for this profile. */ function default_install() { + // Add text formats. + $filtered_html_format = array( + 'name' => 'Filtered HTML', + 'weight' => 0, + 'filters' => array( + // URL filter. + 'filter_url' => array( + 'weight' => 0, + 'status' => 1, + ), + // HTML filter. + 'filter_html' => array( + 'weight' => 1, + 'status' => 1, + ), + // Line break filter. + 'filter_autop' => array( + 'weight' => 2, + 'status' => 1, + ), + // HTML corrector filter. + 'filter_htmlcorrector' => array( + 'weight' => 10, + 'status' => 1, + ), + ), + ); + $filtered_html_format = (object) $filtered_html_format; + filter_format_save($filtered_html_format); + + $full_html_format = array( + 'name' => 'Full HTML', + 'weight' => 1, + 'filters' => array( + // URL filter. + 'filter_url' => array( + 'weight' => 0, + 'status' => 1, + ), + // Line break filter. + 'filter_autop' => array( + 'weight' => 1, + 'status' => 1, + ), + // HTML corrector filter. + 'filter_htmlcorrector' => array( + 'weight' => 10, + 'status' => 1, + ), + ), + ); + $full_html_format = (object) $full_html_format; + filter_format_save($full_html_format); + + $plain_text_format = array( + 'name' => 'Plain text', + 'weight' => 10, + 'filters' => array( + // Escape all HTML. + 'filter_html_escape' => array( + 'weight' => 0, + 'status' => 1, + ), + // Line break filter. + 'filter_autop' => array( + 'weight' => 1, + 'status' => 1, + ), + ), + ); + $plain_text_format = (object) $plain_text_format; + filter_format_save($plain_text_format); + + // Set the fallback format to plain text. + variable_set('filter_fallback_format', $plain_text_format->format); // Enable some standard blocks. $values = array( @@ -313,8 +388,9 @@ function default_install() { field_create_instance($instance); // Enable default permissions for system roles. - user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access content', 'use text format 1')); - user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'post comments without approval', 'use text format 1')); + $filtered_html_permission = filter_permission_name($filtered_html_format); + user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access content', $filtered_html_permission)); + user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'post comments without approval', $filtered_html_permission)); // Create a default role for site administrators, with all available permissions assigned. $admin_role = new stdClass(); diff --git a/profiles/expert/expert.install b/profiles/expert/expert.install index 6682016dcabe8fcc2ccc0596fd890732bb84dbba..f6cb00ac8dbeb209868fe47486fe786baad11658 100644 --- a/profiles/expert/expert.install +++ b/profiles/expert/expert.install @@ -7,6 +7,28 @@ * Perform actions to set up the site for this profile. */ function expert_install() { + // Add text formats. + $plain_text_format = array( + 'name' => 'Plain text', + 'weight' => 10, + 'filters' => array( + // Escape all HTML. + 'filter_html_escape' => array( + 'weight' => 0, + 'status' => 1, + ), + // Line break filter. + 'filter_autop' => array( + 'weight' => 1, + 'status' => 1, + ), + ), + ); + $plain_text_format = (object) $plain_text_format; + filter_format_save($plain_text_format); + + // Set the fallback format to plain text. + variable_set('filter_fallback_format', $plain_text_format->format); // Enable some standard blocks. $values = array(