Index: CHANGELOG.txt =================================================================== RCS file: /cvs/drupal/drupal/CHANGELOG.txt,v retrieving revision 1.300 diff -u -p -r1.300 CHANGELOG.txt --- CHANGELOG.txt 15 Mar 2009 01:53:16 -0000 1.300 +++ CHANGELOG.txt 7 Apr 2009 04:33:11 -0000 @@ -33,6 +33,7 @@ Drupal 7.0, xxxx-xx-xx (development vers * Redesigned the add content type screen. * Highlight duplicate URL aliases. * Renamed "input formats" to "text formats". + * Moved text format permissions to the main permissions page. * Added configurable ability for users to cancel their own accounts. * Added optional filter that can use [internal:node/123] to link to internal pages. @@ -41,6 +42,8 @@ Drupal 7.0, xxxx-xx-xx (development vers objects in a single database query. - Documentation: * Hook API documentation now included in Drupal core. +- Filter system: + * Added support for default text formats to be assigned on a per-role basis. - News aggregator: * Added OPML import functionality for RSS feeds. * Optionally, RSS feeds may be configured to not automatically generate feed blocks. Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.326 diff -u -p -r1.326 form.inc --- includes/form.inc 30 Mar 2009 03:15:40 -0000 1.326 +++ includes/form.inc 7 Apr 2009 04:33:12 -0000 @@ -1883,7 +1883,7 @@ function form_process_radios($element) { * $form['body'] = array( * '#type' => 'textarea', * '#title' => t('Body'), - * '#text_format' => isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT, + * '#text_format' => isset($node->format) ? $node->format : filter_default_format(), * ); * @endcode * Index: modules/block/block.module =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.module,v retrieving revision 1.325 diff -u -p -r1.325 block.module --- modules/block/block.module 5 Apr 2009 12:31:56 -0000 1.325 +++ modules/block/block.module 7 Apr 2009 04:33:12 -0000 @@ -198,7 +198,7 @@ function block_block_list() { * Implementation of hook_block_configure(). */ function block_block_configure($delta = 0, $edit = array()) { - $box = array('format' => FILTER_FORMAT_DEFAULT); + $box = array('format' => filter_default_format()); if ($delta) { $box = block_box_get($delta); } @@ -383,7 +383,7 @@ function block_box_form($edit = array()) '#type' => 'textarea', '#title' => t('Block body'), '#default_value' => $edit['body'], - '#text_format' => isset($edit['format']) ? $edit['format'] : FILTER_FORMAT_DEFAULT, + '#text_format' => isset($edit['format']) ? $edit['format'] : filter_default_format(), '#rows' => 15, '#description' => t('The content of the block as shown to the user.'), '#required' => TRUE, @@ -395,7 +395,7 @@ function block_box_form($edit = array()) function block_box_save($edit, $delta) { if (!filter_access($edit['body_format'])) { - $edit['body_format'] = FILTER_FORMAT_DEFAULT; + $edit['body_format'] = filter_default_format(); } db_query("UPDATE {box} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['body_format'], $delta); Index: modules/blogapi/blogapi.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.module,v retrieving revision 1.147 diff -u -p -r1.147 blogapi.module --- modules/blogapi/blogapi.module 1 Apr 2009 01:28:24 -0000 1.147 +++ modules/blogapi/blogapi.module 7 Apr 2009 04:33:12 -0000 @@ -202,7 +202,7 @@ function blogapi_blogger_new_post($appke $edit['promote'] = in_array('promote', $node_type_default); $edit['comment'] = variable_get('comment_' . $edit['type'], 2); $edit['revision'] = in_array('revision', $node_type_default); - $edit['format'] = FILTER_FORMAT_DEFAULT; + $edit['format'] = filter_default_format($user); $edit['status'] = $publish; // Check for bloggerAPI vs. metaWeblogAPI. @@ -231,6 +231,12 @@ function blogapi_blogger_new_post($appke return $valid; } + // Attach the node format to the body field, in the manner expected by the + // validation and submission handlers. + // @see form_process_text_format() + $edit['body_format'] = $edit['format']; + unset($edit['format']); + node_validate($edit); if ($errors = form_get_errors()) { return blogapi_error(implode("\n", $errors)); @@ -289,6 +295,12 @@ function blogapi_blogger_edit_post($appk return $valid; } + // Attach the node format to the body field, in the manner expected by the + // validation and submission handlers. + // @see form_process_text_format() + $node->body_format = $node->format; + unset($node->format); + node_validate($node); if ($errors = form_get_errors()) { return blogapi_error(implode("\n", $errors)); @@ -622,7 +634,7 @@ function blogapi_mt_validate_terms($node function blogapi_mt_supported_text_filters() { // NOTE: we're only using anonymous' formats because the MT spec // does not allow for per-user formats. - $formats = filter_formats(); + $formats = filter_formats(drupal_anonymous_user()); $filters = array(); foreach ($formats as $format) { Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.701 diff -u -p -r1.701 comment.module --- modules/comment/comment.module 4 Apr 2009 12:35:16 -0000 1.701 +++ modules/comment/comment.module 7 Apr 2009 04:33:12 -0000 @@ -1565,7 +1565,7 @@ function comment_form(&$form_state, $edi '#title' => t('Comment'), '#rows' => 15, '#default_value' => $default, - '#text_format' => isset($edit['format']) ? $edit['format'] : FILTER_FORMAT_DEFAULT, + '#text_format' => isset($edit['format']) ? $edit['format'] : filter_default_format(), '#required' => TRUE, ); Index: modules/field/modules/text/text.module =================================================================== RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v retrieving revision 1.5 diff -u -p -r1.5 text.module --- modules/field/modules/text/text.module 26 Mar 2009 13:31:25 -0000 1.5 +++ modules/field/modules/text/text.module 7 Apr 2009 04:33:12 -0000 @@ -240,7 +240,7 @@ function text_elements() { '#input' => TRUE, '#columns' => array('value', 'format'), '#delta' => 0, '#process' => array('text_textarea_process'), - '#filter_value' => FILTER_FORMAT_DEFAULT, + '#filter_value' => filter_default_format(), ), ); } @@ -332,7 +332,7 @@ function text_textfield_process($element if (!empty($instance['settings']['text_processing'])) { $filter_key = $element['#columns'][1]; - $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT; + $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_default_format(); $parents = array_merge($element['#parents'] , array($filter_key)); $element[$filter_key] = filter_form($format, 1, $parents); } @@ -371,7 +371,7 @@ function text_textarea_process($element, if (!empty($instance['settings']['text_processing'])) { $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format'; - $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT; + $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_default_format(); $parents = array_merge($element['#parents'] , array($filter_key)); $element[$filter_key] = filter_form($format, 1, $parents); } Index: modules/filter/filter.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.admin.inc,v retrieving revision 1.25 diff -u -p -r1.25 filter.admin.inc --- modules/filter/filter.admin.inc 8 Mar 2009 21:25:18 -0000 1.25 +++ modules/filter/filter.admin.inc 7 Apr 2009 04:33:12 -0000 @@ -7,52 +7,47 @@ */ /** - * Menu callback; Displays a list of all text formats and which - * one is the default. + * Menu callback; displays a list of all text formats and allows them to + * be rearranged. * * @ingroup forms * @see filter_admin_overview_submit() */ function filter_admin_overview() { - // Overview of all formats. $formats = filter_formats(); - $error = FALSE; $form = array('#tree' => TRUE); foreach ($formats as $id => $format) { - $roles = array(); - foreach (user_roles() as $rid => $name) { - // Prepare a roles array with roles that may access the filter. - if (strstr($format->roles, ",$rid,")) { - $roles[] = $name; - } - } - $default = ($id == variable_get('filter_default_format', 1)); - $options[$id] = ''; - $form[$id]['name'] = array('#markup' => $format->name); - $form[$id]['roles'] = array('#markup' => $default ? t('All roles may use the default format') : ($roles ? implode(', ', $roles) : t('No roles may use this format'))); - $form[$id]['configure'] = array('#markup' => l(t('configure'), 'admin/settings/filter/' . $id)); - $form[$id]['delete'] = array('#markup' => $default ? '' : l(t('delete'), 'admin/settings/filter/delete/' . $id)); + // Check whether this is the fallback text format. This format is + // available to all roles and cannot be configured via the admin + // interface. + $is_fallback_format = ($id == filter_fallback_format()); + $form[$id]['name'] = array('#markup' => $is_fallback_format ? theme('placeholder', $format->name) : check_plain($format->name)); + if ($is_fallback_format) { + $roles_markup = theme('placeholder', t('All roles may use this format')); + } + else { + $roles = filter_format_roles($format); + $roles_markup = $roles ? implode(', ', $roles) : t('No roles may use this format'); + } + $form[$id]['roles'] = array('#markup' => $roles_markup); + $form[$id]['configure'] = array('#markup' => $is_fallback_format ? '' : l(t('configure'), 'admin/settings/filter/' . $id)); + $form[$id]['delete'] = array('#markup' => $is_fallback_format ? '' : l(t('delete'), 'admin/settings/filter/delete/' . $id)); $form[$id]['weight'] = array('#type' => 'weight', '#default_value' => $format->weight); } - $form['default'] = array('#type' => 'radios', '#options' => $options, '#default_value' => variable_get('filter_default_format', 1)); $form['submit'] = array('#type' => 'submit', '#value' => t('Save changes')); return $form; } function filter_admin_overview_submit($form, &$form_state) { - // Process form submission to set the default format. - if (is_numeric($form_state['values']['default'])) { - drupal_set_message(t('Default format updated.')); - variable_set('filter_default_format', $form_state['values']['default']); - } foreach ($form_state['values'] as $id => $data) { if (is_array($data) && isset($data['weight'])) { // Only update if this is a form element with weight. db_query("UPDATE {filter_format} SET weight = %d WHERE format = %d", $data['weight'], $id); } } + filter_format_reset_cache(); drupal_set_message(t('The text format ordering has been saved.')); } @@ -68,9 +63,8 @@ function theme_filter_admin_overview($fo $element['weight']['#attributes']['class'] = 'text-format-order-weight'; $rows[] = array( 'data' => array( - check_plain($element['name']['#markup']), + drupal_render($element['name']), drupal_render($element['roles']), - drupal_render($form['default'][$id]), drupal_render($element['weight']), drupal_render($element['configure']), drupal_render($element['delete']), @@ -80,7 +74,7 @@ function theme_filter_admin_overview($fo unset($form[$id]); } } - $header = array(t('Name'), t('Roles'), t('Default'), t('Weight'), array('data' => t('Operations'), 'colspan' => 2)); + $header = array(t('Name'), t('Roles'), t('Weight'), array('data' => t('Operations'), 'colspan' => 2)); $output = theme('table', $header, $rows, array('id' => 'text-format-order')); $output .= drupal_render_children($form); @@ -95,8 +89,9 @@ function theme_filter_admin_overview($fo function filter_admin_format_page($format = NULL) { if (!isset($format->name)) { drupal_set_title(t('Add text format'), PASS_THROUGH); - $format = (object)array('name' => '', 'roles' => '', 'format' => ''); + $format = (object)array('name' => '', 'format' => ''); } + filter_admin_display_warning($format); return drupal_get_form('filter_admin_format_form', $format); } @@ -108,12 +103,6 @@ function filter_admin_format_page($forma * @see filter_admin_format_form_submit() */ function filter_admin_format_form(&$form_state, $format) { - $default = ($format->format == variable_get('filter_default_format', 1)); - if ($default) { - $help = t('All roles for the default format must be enabled and cannot be changed.'); - $form['default_format'] = array('#type' => 'hidden', '#value' => 1); - } - $form['name'] = array('#type' => 'textfield', '#title' => t('Name'), '#default_value' => $format->name, @@ -121,23 +110,6 @@ function filter_admin_format_form(&$form '#required' => TRUE, ); - // Add a row of checkboxes for form group. - $form['roles'] = array('#type' => 'fieldset', - '#title' => t('Roles'), - '#description' => $default ? $help : t('Choose which roles may use this text format. Note that roles with the "administer filters" permission can always use all text formats.'), - '#tree' => TRUE, - ); - - foreach (user_roles() as $rid => $name) { - $checked = strstr($format->roles, ",$rid,"); - $form['roles'][$rid] = array('#type' => 'checkbox', - '#title' => $name, - '#default_value' => ($default || $checked), - ); - if ($default) { - $form['roles'][$rid]['#disabled'] = TRUE; - } - } // Table with filters $all = filter_list_all(); $enabled = filter_list_format($format->format); @@ -221,26 +193,15 @@ function filter_admin_format_form_submit } } - // We store the roles as a string for ease of use. - // We should always set all roles to TRUE when saving a default role. - // We use leading and trailing comma's to allow easy substring matching. - $roles = array(); - if (isset($form_state['values']['roles'])) { - foreach ($form_state['values']['roles'] as $id => $checked) { - if ($checked) { - $roles[] = $id; - } - } - } - if (!empty($form_state['values']['default_format'])) { - $roles = ',' . implode(',', array_keys(user_roles())) . ','; - } - else { - $roles = ',' . implode(',', $roles) . ','; - } - - db_query("UPDATE {filter_format} SET cache = %d, name='%s', roles = '%s' WHERE format = %d", $cache, $name, $roles, $format); + db_update('filter_format') + ->fields(array( + 'cache' => $cache, + 'name' => $name, + )) + ->condition('format', $format) + ->execute(); + filter_format_reset_cache(); cache_clear_all($format . ':', 'cache_filter', TRUE); // If a new filter was added, return to the main list of filters. Otherwise, stay on edit filter page to show new changes. @@ -253,30 +214,29 @@ function filter_admin_format_form_submit } /** + * Display a warning when the administrator is editing a format that + * potentially-untrusted users have permission to use. + * + * @param $format + * An object representing the text format. + */ +function filter_admin_display_warning($format) { + $roles = filter_format_roles($format); + if (!empty($roles)) { + drupal_set_message(t('This text format is available to the following roles: %roles. Since text formats can have security implications depending on how they are configured, you should be careful making changes here if any of these roles are untrusted.', array('%roles' => implode(', ', $roles))), 'warning'); + } +} + +/** * Menu callback; confirm deletion of a format. * * @ingroup forms * @see filter_admin_delete_submit() */ -function filter_admin_delete() { - $format = arg(4); - $format = db_fetch_object(db_query('SELECT * FROM {filter_format} WHERE format = %d', $format)); - - if ($format) { - if ($format->format != variable_get('filter_default_format', 1)) { - $form['format'] = array('#type' => 'hidden', '#value' => $format->format); - $form['name'] = array('#type' => 'hidden', '#value' => $format->name); - - return confirm_form($form, t('Are you sure you want to delete the text format %format?', array('%format' => $format->name)), 'admin/settings/filter', t('If you have any content left in this text format, it will be switched to the default text format. This action cannot be undone.'), t('Delete'), t('Cancel')); - } - else { - drupal_set_message(t('The default format cannot be deleted.')); - drupal_goto('admin/settings/filter'); - } - } - else { - drupal_not_found(); - } +function filter_admin_delete(&$form_state, $format) { + $form['format'] = array('#type' => 'value', '#value' => $format->format); + $form['name'] = array('#type' => 'value', '#value' => $format->name); + return confirm_form($form, t('Are you sure you want to delete the text format %format?', array('%format' => $format->name)), 'admin/settings/filter', t('If you have any content left in this text format, it will be displayed as %plain_text until you manually assign it a new format. This action cannot be undone.', array('%plain_text' => filter_fallback_format_title())), t('Delete'), t('Cancel')); } /** @@ -286,12 +246,19 @@ function filter_admin_delete_submit($for db_query("DELETE FROM {filter_format} WHERE format = %d", $form_state['values']['format']); db_query("DELETE FROM {filter} WHERE format = %d", $form_state['values']['format']); - $default = variable_get('filter_default_format', 1); - // Replace existing instances of the deleted format with the default format. - db_query("UPDATE {node_revision} SET format = %d WHERE format = %d", $default, $form_state['values']['format']); - db_query("UPDATE {comment} SET format = %d WHERE format = %d", $default, $form_state['values']['format']); - db_query("UPDATE {box} SET format = %d WHERE format = %d", $default, $form_state['values']['format']); + // Replace existing instances of the deleted format with the fallback format. + $fallback_format = filter_fallback_format(); + $database_tables = array('node_revision', 'comment', 'box'); + foreach ($database_tables as $table) { + if (db_table_exists($table)) { + db_update($table) + ->fields(array('format' => $fallback_format)) + ->condition('format', $form_state['values']['format']) + ->execute(); + } + } + filter_format_reset_cache(); cache_clear_all($form_state['values']['format'] . ':', 'cache_filter', TRUE); drupal_set_message(t('Deleted text format %format.', array('%format' => $form_state['values']['name']))); @@ -299,12 +266,12 @@ function filter_admin_delete_submit($for return; } - /** * Menu callback; display settings defined by a format's filters. */ function filter_admin_configure_page($format) { drupal_set_title(t("Configure %format", array('%format' => $format->name)), PASS_THROUGH); + filter_admin_display_warning($format); return drupal_get_form('filter_admin_configure', $format); } @@ -346,6 +313,7 @@ function filter_admin_configure_submit($ */ function filter_admin_order_page($format) { drupal_set_title(t("Rearrange %format", array('%format' => $format->name)), PASS_THROUGH); + filter_admin_display_warning($format); return drupal_get_form('filter_admin_order', $format); } Index: modules/filter/filter.install =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.install,v retrieving revision 1.12 diff -u -p -r1.12 filter.install --- modules/filter/filter.install 21 Jan 2009 16:58:42 -0000 1.12 +++ modules/filter/filter.install 7 Apr 2009 04:33:12 -0000 @@ -64,13 +64,6 @@ function filter_schema() { 'default' => '', 'description' => 'Name of the text format (Filtered HTML).', ), - 'roles' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'A comma-separated string of roles; references {role}.rid.', // This is bad since you can't use joins, nor index. - ), 'cache' => array( 'type' => 'int', 'not null' => TRUE, @@ -99,6 +92,11 @@ function filter_schema() { } /** + * @defgroup updates-6.x-to-7.x Filter updates from 6.x to 7.x + * @{ + */ + +/** * Add a weight column to the filter formats table. */ function filter_update_7000() { @@ -132,3 +130,73 @@ function filter_update_7002() { db_rename_table($ret, 'filter_formats', 'filter_format'); return $ret; } + +/** + * Move text format access to the user permissions handler, create a fallback + * (plain text) text format, and explicitly set the text format in cases that + * used to rely on a single site-wide default. + */ +function filter_update_7003() { + $ret = array(); + + // Move role data from the filter system to the user permission system. + $all_roles = array_keys(user_roles()); + $default_format = variable_get('filter_default_format', 1); + $result = db_query("SELECT * FROM {filter_format}"); + while ($format = db_fetch_object($result)) { + // We need to assign the default format to all roles (regardless of what + // was stored in the database) to preserve the behavior of the site at + // the moment of the upgrade. + $format_roles = ($format->format == $default_format ? $all_roles : explode(',', $format->roles)); + foreach ($format_roles as $format_role) { + if (in_array($format_role, $all_roles)) { + $ret[] = update_sql("INSERT INTO {role_permission} (rid, permission) VALUES (" . $format_role . ", '" . filter_permission_name($format) . "')"); + } + } + } + + // Drop the roles field from the {filter_format} table. + db_drop_field($ret, 'filter_format', 'roles'); + + // Add a fallback text format which appears last on the last for all users. + $ret[] = update_sql("INSERT INTO {filter_format} (name, cache, weight) VALUES ('Plain text', 1, 1)"); + $fallback_format = db_last_insert_id('filter_format', 'format'); + if ($fallback_format != filter_fallback_format()) { + variable_set('filter_fallback_format', $fallback_format); + } + // The fallback text format should output plain text, so we escape all HTML + // and apply the line break filter only. + $ret[] = update_sql("INSERT INTO {filter} (format, module, delta, weight) VALUES (" . $fallback_format . ", 'filter', 4, 0)"); + $ret[] = update_sql("INSERT INTO {filter} (format, module, delta, weight) VALUES (" . $fallback_format . ", 'filter', 1, 1)"); + + // Move the former site-wide default text format to the top of the list, + // so that it continues to be the default text format for all users. + $ret[] = update_sql("UPDATE {filter_format} SET weight = -1 WHERE format = " . $default_format); + + // It was previously possible for a value of "0" to be stored in database + // tables to indicate that a particular piece of text should be filtered + // using the default text format. Therefore, we have to convert all such + // instances (in Drupal core) to explicitly use the appropriate format. + $ret[] = update_sql("UPDATE {box} SET format = " . $default_format . " WHERE format = 0"); + $ret[] = update_sql("UPDATE {comment} SET format = " . $default_format . " WHERE format = 0"); + // The {node_revisions} table is a special case, since there, a value of + // "0" could also mean that the revision was saved without the node body + // enabled, so that it does not have any text format at all. We can't + // distinguish these cases exactly, so we assume that a revision with + // text in the body field is intended to be displayed in the default + // format, while a revision with no text in the body field was saved with + // an undefined format. In the latter case, we leave the format at "0", + // which is the value of the new defined constant FILTER_FORMAT_UNASSIGNED + // that is used for this purpose. + $ret[] = update_sql("UPDATE {node_revisions} SET format = " . $default_format . " WHERE format = 0 AND body != '' AND body IS NOT NULL"); + + // Note: We do not delete the 'filter_default_format' variable since + // other modules may need it in their update functions. + // @TODO: This variable can probably be deleted in Drupal 8. + return $ret; +} + +/** + * @} End of "defgroup updates-6.x-to-7.x" + * The next series of updates should start at 8000. + */ Index: modules/filter/filter.module =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v retrieving revision 1.246 diff -u -p -r1.246 filter.module --- modules/filter/filter.module 30 Mar 2009 03:15:40 -0000 1.246 +++ modules/filter/filter.module 7 Apr 2009 04:33:12 -0000 @@ -7,12 +7,15 @@ */ /** - * Special format ID which means "use the default format". + * Special format ID which is used to indicate that a piece of text does + * not have a text format assigned. * - * This value can be passed to the filter APIs as a format ID: this is - * equivalent to not passing an explicit format at all. + * This value can be passed to the filter APIs as a format ID; this is + * equivalent to not passing an explicit format at all. In particular, if + * text with this format is ever displayed, it will be filtered using the + * fallback format available to all users. */ -define('FILTER_FORMAT_DEFAULT', 0); +define('FILTER_FORMAT_UNASSIGNED', 0); /** * Implementation of hook_help(). @@ -22,12 +25,13 @@ function filter_help($path, $arg) { case 'admin/help#filter': $output = '
' . t("The filter module allows administrators to configure text formats for use on your site. A text format defines the HTML tags, codes, and other input allowed in both content and comments, and is a key feature in guarding against potentially damaging input from malicious users. Two formats included by default are Filtered HTML (which allows only an administrator-approved subset of HTML tags) and Full HTML (which allows the full set of HTML tags). Additional formats may be created by an administrator.") . '
'; $output .= '' . t('Each text format uses filters to manipulate text, and most formats apply several different filters to text in a specific order. Each filter is designed for a specific purpose, and generally either adds, removes or transforms elements within user-entered text before it is displayed. A filter does not change the actual content of a post, but instead, modifies it temporarily before it is displayed. A filter may remove unapproved HTML tags, for instance, while another automatically adds HTML to make links referenced in text clickable.') . '
'; - $output .= '' . t('Users with access to more than one text format can use the Text format fieldset to choose between available text formats when creating or editing multi-line content. Administrators determine the text formats available to each user role, select a default text format, and control the order of formats listed in the Text format fieldset.') . '
'; + $output .= '' . t('Users with access to more than one text format can use the Text format fieldset to choose between available text formats when creating or editing multi-line content. Administrators determine the text formats available to each user role and control the order of formats listed in the Text format fieldset.') . '
'; + $output .= '' . t('The special %plain_text text format is available to all users. Content with this format will be displayed with line and paragraph breaks preserved but otherwise without any visible formatting.', array('%plain_text' => filter_fallback_format_title())) . '
'; $output .= '' . t('For more information, see the online handbook entry for Filter module.', array('@filter' => 'http://drupal.org/handbook/modules/filter/')) . '
'; return $output; case 'admin/settings/filter': - $output = '' . t('Use the list below to review the text formats available to each user role, to select a default text format, and to control the order of formats listed in the Text format fieldset. (The Text format fieldset is displayed below textareas when users with access to more than one text format create multi-line content.) The text format selected as Default is available to all users and, unless another format is selected, is applied to all content. All text formats are available to users in roles with the "administer filters" permission.') . '
'; - $output .= '' . t('Since text formats, if available, are presented in the same order as the list below, it may be helpful to arrange the formats in descending order of your preference for their use. To change the order of an text format, grab a drag-and-drop handle under the Name column and drag to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save changes button at the bottom of the page.') . '
'; + $output = '' . t('Use the list below to review the text formats available to each user role and to control the order of formats listed in the Text format fieldset. (The Text format fieldset is displayed below textareas when users with access to more than one text format create multi-line content.) All text formats are available to users in roles with the "Administer filters" permission, and the special %plain_text format is available to all users. You can configure access to other text formats on the permissions page.', array('%plain_text' => filter_fallback_format_title(), '@url' => url('admin/user/permissions', array('fragment' => 'module-filter')))) . '
'; + $output .= '' . t('It may be helpful to arrange the text formats in order of your preference for their use, since the default text format for each user is the first one on the list for which that user has access. To change the order of a text format, grab a drag-and-drop handle under the Name column and drag to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save changes button at the bottom of the page.') . '
'; return $output; case 'admin/settings/filter/%': return '' . t('Every filter performs one particular change on the user input, for example stripping out malicious HTML or making URLs clickable. Choose which filters you want to apply to text in this format. If you notice some filters are causing conflicts in the output, you can rearrange them.', array('@rearrange' => url('admin/settings/filter/' . $arg[3] . '/order'))) . '
'; @@ -88,11 +92,12 @@ function filter_menu() { 'type' => MENU_LOCAL_TASK, 'weight' => 1, ); - $items['admin/settings/filter/delete'] = array( + $items['admin/settings/filter/delete/%filter_format'] = array( 'title' => 'Delete text format', 'page callback' => 'drupal_get_form', - 'page arguments' => array('filter_admin_delete'), - 'access arguments' => array('administer filters'), + 'page arguments' => array('filter_admin_delete', 4), + 'access callback' => 'filter_edit_format_access', + 'access arguments' => array(4), 'type' => MENU_CALLBACK, ); $items['filter/tips'] = array( @@ -107,7 +112,8 @@ function filter_menu() { 'title arguments' => array(3), 'page callback' => 'filter_admin_format_page', 'page arguments' => array(3), - 'access arguments' => array('administer filters'), + 'access callback' => 'filter_edit_format_access', + 'access arguments' => array(3), ); $items['admin/settings/filter/%filter_format/edit'] = array( 'title' => 'Edit', @@ -118,7 +124,8 @@ function filter_menu() { 'title' => 'Configure', 'page callback' => 'filter_admin_configure_page', 'page arguments' => array(3), - 'access arguments' => array('administer filters'), + 'access callback' => 'filter_edit_format_access', + 'access arguments' => array(3), 'type' => MENU_LOCAL_TASK, 'weight' => 1, ); @@ -126,15 +133,31 @@ function filter_menu() { 'title' => 'Rearrange', 'page callback' => 'filter_admin_order_page', 'page arguments' => array(3), - 'access arguments' => array('administer filters'), + 'access callback' => 'filter_edit_format_access', + 'access arguments' => array(3), 'type' => MENU_LOCAL_TASK, 'weight' => 2, ); return $items; } -function filter_format_load($arg) { - return filter_formats($arg); +/** + * Return the text format object corresponding to the provided format ID. + */ +function filter_format_load($id) { + $formats = filter_formats(); + if (isset($formats[$id])) { + return $formats[$id]; + } + return FALSE; +} + +/** + * Determine access for editing text formats. + */ +function filter_edit_format_access($format) { + // The fallback format can never be edited. + return user_access('administer filters') && ($format->format != filter_fallback_format()); } /** @@ -148,12 +171,45 @@ function filter_admin_format_title($form * Implementation of hook_perm(). */ function filter_perm() { - return array( - 'administer filters' => array( - 'title' => t('Administer filters'), - 'description' => t('Manage text formats and filters, and select which roles may use them. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))), - ), - ); + $perms = array(); + $perms['administer filters'] = array( + 'title' => t('Administer filters'), + 'description' => t('Manage text formats and filters, and use any of them, without restriction, when entering or editing content. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))), + ); + + // Generate permissions for each text format. Warn the administrator + // that any of them are potentially unsafe. + foreach (filter_formats() as $format) { + $permission = filter_permission_name($format); + if (!empty($permission)) { + // Only link to the text format configuration page if the user who + // is viewing this will have access to that page. + $format_name_replacement = user_access('administer filters') ? l($format->name, 'admin/settings/filter/' . $format->format) : theme('placeholder', $format->name); + $perms[$permission] = array( + 'title' => t("Use the '@text_format' text format", array('@text_format' => $format->name)), + 'description' => t('Use !text_format in forms when entering or editing content. %warning', array('!text_format' => $format_name_replacement, '%warning' => t('Warning: This permission may have security implications depending on how the text format is configured.'))), + ); + } + } + return $perms; +} + +/** + * Returns the machine-readable permission name for the provided text + * format. + * + * @param $format + * An object representing the text format. + * @return + * The machine-readable permission name, or FALSE if the provided text + * format is either (a) malformed, or (b) the fallback format available + * to all users (and therefore not controlled by the permission system). + */ +function filter_permission_name($format) { + if (isset($format->format) && $format->format != filter_fallback_format()) { + return 'use text format ' . $format->format; + } + return FALSE; } /** @@ -286,41 +342,83 @@ function filter_filter_tips($delta, $for } /** - * Retrieve a list of text formats. - */ -function filter_formats($index = NULL) { - global $user; - static $formats; - - // Administrators can always use all text formats. - $all = user_access('administer filters'); - - if (!isset($formats)) { + * Retrieve a list of text formats, ordered by weight. + * + * @param $account + * Optional. If provided, only those formats that are allowed for this + * user account will be returned. All formats will be returned otherwise. + * @param $reset + * Whether to reset the internal cache of all text formats. Defaults to + * FALSE. + */ +function filter_formats($account = NULL, $reset = FALSE) { + $formats = &drupal_static(__FUNCTION__, array()); + if ($reset) { $formats = array(); + } - $query = db_select('filter_format', 'f'); - $query->addField('f', 'format', 'format'); - $query->addField('f', 'name', 'name'); - $query->addField('f', 'roles', 'roles'); - $query->addField('f', 'cache', 'cache'); - $query->addField('f', 'weight', 'weight'); - $query->orderBy('weight'); - - // Build query for selecting the format(s) based on the user's roles. - if (!$all) { - $or = db_or()->condition('format', variable_get('filter_default_format', 1)); - foreach ($user->roles as $rid => $role) { - $or->condition('roles', '%'. (int)$rid .'%', 'LIKE'); + // Check if we've already loaded format data before doing a query. + if (!isset($formats['all'])) { + $formats['all'] = db_query('SELECT * FROM {filter_format} ORDER BY weight')->fetchAllAssoc('format'); + } + + // Build a list of user-specific formats if not already set. + if (isset($account) && !isset($formats['user'][$account->uid])) { + $formats['user'][$account->uid] = array(); + foreach ($formats['all'] as $format) { + if (filter_access($format, $account)) { + $formats['user'][$account->uid][$format->format] = $format; } - $query->condition($or); } + } - $formats = $query->execute()->fetchAllAssoc('format'); + return isset($account) ? $formats['user'][$account->uid] : $formats['all']; +} + +/** + * Helper function to reset the static cache of all text formats. + */ +function filter_format_reset_cache() { + filter_formats(NULL, TRUE); +} + +/** + * Return the ID of the default text format for a particular user. + * + * @param $account + * Optional. The user account to check. Defaults to the current logged-in + * user. + */ +function filter_default_format($account = NULL) { + global $user; + if (!isset($account)) { + $account = $user; } - if (isset($index)) { - return isset($formats[$index]) ? $formats[$index] : FALSE; + // Get a list of formats for this user, ordered by weight. The first one + // available is that user's default format. + $formats = filter_formats($account); + $first_format = array_shift($formats); + if (isset($first_format) && isset($first_format->format)) { + return $first_format->format; } - return $formats; + // All users have access to the fallback format, so we use that here if + // no formats were available above (however, under normal circumstances + // this code should never be reached). + return filter_fallback_format(); +} + +/** + * Return the ID of the fallback text format that all users have access to. + */ +function filter_fallback_format() { + return variable_get('filter_fallback_format', 3); +} + +/** + * Display the title of the fallback text format. + */ +function filter_fallback_format_title() { + return filter_admin_format_title(filter_format_load(filter_fallback_format())); } /** @@ -352,11 +450,13 @@ function _filter_list_cmp($a, $b) { } /** - * Resolve a format id, including the default format. + * Resolve a format id, including an unassigned format (which defaults to + * using the fallback format available to all users). */ function filter_resolve_format($format) { - return $format == FILTER_FORMAT_DEFAULT ? variable_get('filter_default_format', 1) : $format; + return $format == FILTER_FORMAT_UNASSIGNED ? filter_fallback_format() : $format; } + /** * Check if text in a certain text format is allowed to be cached. */ @@ -411,8 +511,8 @@ function filter_list_format($format) { * @param $text * The text to be filtered. * @param $format - * The format of the text to be filtered. Specify FILTER_FORMAT_DEFAULT for - * the default format. + * The format of the text to be filtered. If no format is assigned, the + * fallback format will be used. * @param $langcode * Optional: the language code of the text to be filtered, e.g. 'en' for * English. This allows filters to be language aware so language specific @@ -424,9 +524,10 @@ function filter_list_format($format) { * showing content that is not (yet) stored in the database (eg. upon preview), * set to TRUE so the user's permissions are checked. */ -function check_markup($text, $format = FILTER_FORMAT_DEFAULT, $langcode = '', $check = TRUE) { +function check_markup($text, $format = FILTER_FORMAT_UNASSIGNED, $langcode = '', $check = TRUE) { // When $check = TRUE, do an access check on $format. if (isset($text) && (!$check || filter_access($format))) { + // Make sure to use the fallback format if none was provided. $format = filter_resolve_format($format); // Check for a cached version of this piece of text. @@ -435,9 +536,6 @@ function check_markup($text, $format = F return $cached->data; } - // See if caching is allowed for this format. - $cache = filter_format_allowcache($format); - // Convert all Windows and Mac newlines to a single newline, // so filters only need to deal with one possibility. $text = str_replace(array("\r\n", "\r"), "\n", $text); @@ -456,7 +554,7 @@ function check_markup($text, $format = F } // Store in cache with a minimum expiration time of 1 day. - if ($cache) { + if (filter_format_allowcache($format)) { cache_set($cache_id, $text, 'cache_filter', REQUEST_TIME + (60 * 60 * 24)); } } @@ -481,9 +579,24 @@ function check_markup($text, $format = F * @return * HTML for the form element. */ -function filter_form($value = FILTER_FORMAT_DEFAULT, $weight = NULL, $parents = array('format')) { - $value = filter_resolve_format($value); - $formats = filter_formats(); +function filter_form($value = FILTER_FORMAT_UNASSIGNED, $weight = NULL, $parents = array('format')) { + global $user; + + // Use the default format for this user if none was selected. + if ($value == FILTER_FORMAT_UNASSIGNED) { + $value = filter_default_format($user); + } + + // Get a list of formats that the current user has access to. + $formats = filter_formats($user); + + // If the user doesn't have access to the currently-selected format, it + // could be because the format doesn't exist any more. The fallback text + // format is designed for this situation, so we pre-select that format + // on the form. + if (!isset($formats[$value])) { + $value = filter_fallback_format(); + } drupal_add_js('misc/form.js'); drupal_add_css(drupal_get_path('module', 'filter') . '/filter.css'); @@ -526,17 +639,74 @@ function filter_form($value = FILTER_FOR } /** - * Returns TRUE if the user is allowed to access this format. + * Check if a user has access to a particular text format. + * + * @param $format + * Either the format ID or format object that will be checked for access. + * @param $account + * The user object that access will be checked against. Defaults to the + * current logged-in user. + * @return + * Boolean TRUE if the user has access to the requested format. */ -function filter_access($format) { - $format = filter_resolve_format($format); - if (user_access('administer filters') || ($format == variable_get('filter_default_format', 1))) { +function filter_access($format, $account = NULL) { + global $user; + if (!isset($account)) { + $account = $user; + } + // Handle special cases up front. All users have access to the fallback + // format, and administrators have access to all formats. + $format_id = isset($format->format) ? $format->format : $format; + $format_id = filter_resolve_format($format_id); + if (user_access('administer filters', $account) || $format_id == filter_fallback_format()) { return TRUE; } - else { - $formats = filter_formats(); - return isset($formats[$format]); + // Otherwise, retrieve the full format object if one was not provided. + if (!isset($format->format)) { + $format = filter_format_load($format); } + // Check the permission if one exists; otherwise, we have a nonexistent + // format so we return FALSE. + $permission = filter_permission_name($format); + return !empty($permission) && user_access($permission, $account); +} + +/** + * Retrieve a list of roles that are allowed to use a particular text format. + * + * @param $format + * Either the format ID or format object that will be checked for access. + * @return + * An array of roles structured $rid => $role_name. + */ +function filter_format_roles($format) { + // Handle the fallback format up front (all roles have access to this + // format). + $format_id = isset($format->format) ? $format->format : $format; + if ($format_id == filter_fallback_format()) { + return user_roles(); + } + // Otherwise, retrieve the full format object if one was not provided. + if (!isset($format->format)) { + $format = filter_format_load($format); + } + // Don't list any roles if the permission doesn't exist. + $permission = filter_permission_name($format); + return !empty($permission) ? user_roles(FALSE, $permission) : array(); +} + +/** + * Retrieve a list of text formats that are allowed for a particular role. + */ +function filter_role_formats($rid) { + $formats = array(); + foreach (filter_formats() as $format) { + $roles = filter_format_roles($format); + if (isset($roles[$rid])) { + $formats[$format->format] = $format->name; + } + } + return $formats; } /** @@ -548,11 +718,13 @@ function filter_access($format) { * Helper function for fetching filter tips. */ function _filter_tips($format, $long = FALSE) { + global $user; + if ($format == -1) { - $formats = filter_formats(); + $formats = filter_formats($user); } else { - $formats = array(db_fetch_object(db_query("SELECT * FROM {filter_format} WHERE format = %d", $format))); + $formats = array(filter_format_load($format)); } $tips = array(); Index: modules/filter/filter.test =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.test,v retrieving revision 1.18 diff -u -p -r1.18 filter.test --- modules/filter/filter.test 31 Mar 2009 01:49:52 -0000 1.18 +++ modules/filter/filter.test 7 Apr 2009 04:33:12 -0000 @@ -1,7 +1,79 @@ admin_user = $this->drupalCreateUser(array('administer filters', 'create page content', 'edit own page content')); + } + + /** + * Create a new text format. + * + * @param $filters + * An array containing the combined 'module/delta' value for each filter + * to be added to this text format. + * @param $name + * The name of the text format. (If not set, a random name is used.) + * @return + * An object representing the new text format. + */ + protected function drupalCreateTextFormat($filters = array(), $name = NULL) { + $edit = array(); + + // Add the parameters that were provided. + foreach ($filters as $filter) { + $edit['filters[' . $filter . ']'] = TRUE; + } + $edit['name'] = !isset($name) ? $this->randomName() : $name; + + // Submit the form. + $this->drupalPost('admin/settings/filter/add', $edit, t('Save configuration')); + + // Verify that the text format exists in the database. + $format = db_query("SELECT * FROM {filter_format} WHERE name = :name", array(':name' => $edit['name']))->fetchObject(); + $this->assertTrue($format, t('New text format successfully loaded.')); + + // Clear the static permission cache, since a new permission has been + // added as a result of the new text format that was just created. + filter_format_reset_cache(); + $this->checkPermissions(array(), TRUE); + + return $format; + } + + /** + * Delete a text format. + * + * @param $format + * The ID of the text format to delete. + */ + protected function drupalDeleteTextFormat($format) { + // Submit the form. + $this->drupalPost('admin/settings/filter/delete/' . $format, array(), t('Delete')); + + // Verify that the deleted text format does not exist in the database. + $format = db_query("SELECT * FROM {filter_format} WHERE format = :format", array(':format' => $format))->fetchObject(); + $this->assertFalse($format, t('Text format deleted successfully.')); + } + + /** + * Load a text format by name. + * + * @param $name + * The name of the text format to load. + * @return + * The fully-loaded text format object. + */ + protected function getTextFormatByName($name) { + return db_query("SELECT * FROM {filter_format} WHERE name = :name", array(':name' => $name))->fetchObject(); + } + +} + +class FilterAdminTestCase extends FilterHelperTestCase { public static function getInfo() { return array( 'name' => t('Filter administration functionality'), @@ -17,41 +89,28 @@ class FilterAdminTestCase extends Drupal $first_filter = 2; // URL filter. $second_filter = 1; // Line filter. - // Create users. - $admin_user = $this->drupalCreateUser(array('administer filters')); - $web_user = $this->drupalCreateUser(array('create page content')); - - $this->drupalLogin($admin_user); + $this->drupalLogin($this->admin_user); - list($filtered, $full) = $this->checkFilterFormats(); - - // Change default filter. - $edit = array(); - $edit['default'] = $full; - $this->drupalPost('admin/settings/filter', $edit, t('Save changes')); - $this->assertText(t('Default format updated.'), t('Default filter updated successfully.')); - - $this->assertNoRaw('admin/settings/filter/delete/' . $full, t('Delete link not found.')); - - // Add an additional tag. + // Add an additional tag to the Filtered HTML format. + $filtered_html = $this->getTextFormatByName('Filtered HTML'); + $filtered_html_id = $filtered_html->format; $edit = array(); $edit['allowed_html_1'] = ' -
-
- ' . '
'; // Adding tag.
- $this->drupalPost('admin/settings/filter/' . $filtered . '/configure', $edit, t('Save configuration'));
+ $this->drupalPost('admin/settings/filter/' . $filtered_html_id . '/configure', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Allowed HTML tag added.'));
-
$this->assertRaw(htmlentities($edit['allowed_html_1']), t('Tag displayed.'));
+ // Test that the cache was cleared after the above operation.
$result = db_fetch_object(db_query('SELECT * FROM {cache_filter}'));
$this->assertFalse($result, t('Cache cleared.'));
- // Reorder filters.
+ // Reorder the filters in the Filtered HTML format.
$edit = array();
$edit['weights[filter/' . $second_filter . ']'] = 1;
$edit['weights[filter/' . $first_filter . ']'] = 2;
- $this->drupalPost('admin/settings/filter/' . $filtered . '/order', $edit, t('Save configuration'));
+ $this->drupalPost('admin/settings/filter/' . $filtered_html_id . '/order', $edit, t('Save configuration'));
$this->assertText(t('The filter ordering has been saved.'), t('Order saved successfully.'));
-
- $result = db_query('SELECT * FROM {filter} WHERE format = %d ORDER BY weight ASC', $filtered);
+ $result = db_query('SELECT * FROM {filter} WHERE format = %d ORDER BY weight ASC', $filtered_html_id);
$filters = array();
while ($filter = db_fetch_object($result)) {
if ($filter->delta == $second_filter || $filter->delta == $first_filter) {
@@ -60,125 +119,249 @@ class FilterAdminTestCase extends Drupal
}
$this->assertTrue(($filters[0]->delta == $second_filter && $filters[1]->delta == $first_filter), t('Order confirmed.'));
- // Add filter.
- $edit = array();
- $edit['name'] = $this->randomName();
- $edit['roles[2]'] = TRUE;
- $edit['filters[filter/' . $second_filter . ']'] = TRUE;
- $edit['filters[filter/' . $first_filter . ']'] = TRUE;
- $this->drupalPost('admin/settings/filter/add', $edit, t('Save configuration'));
- $this->assertRaw(t('Added text format %format.', array('%format' => $edit['name'])), t('New filter created.'));
-
- $format = $this->getFilter($edit['name']);
- $this->assertNotNull($format, t('Format found in database.'));
+ // Add a text format and check for the expected information on the page.
+ $format = $this->drupalCreateTextFormat(array('filter/' . $second_filter, 'filter/' . $first_filter));
+ $this->assertRaw(t('Added text format %format.', array('%format' => $format->name)), t('Message about the new text format appears on the page.'));
+ $this->assertFieldByName('filters[filter/' . $second_filter . ']', '', t('Line break filter found.'));
+ $this->assertFieldByName('filters[filter/' . $first_filter . ']', '', t('Url filter found.'));
+
+ // Delete the text format and check for the expected information on the
+ // page.
+ $this->drupalDeleteTextFormat($format->format);
+ $this->assertRaw(t('Deleted text format %format.', array('%format' => $format->name)), t('Message about the deleted text format appears on the page.'));
+
+ // Check that the fallback format cannot be edited or deleted.
+ $this->drupalGet('admin/settings/filter/' . filter_fallback_format());
+ $this->assertResponse(403, t('The fallback format cannot be edited.'));
+ $this->drupalGet('admin/settings/filter/' . filter_fallback_format() . '/configure');
+ $this->assertResponse(403, t('The fallback format cannot be configured.'));
+ $this->drupalGet('admin/settings/filter/' . filter_fallback_format() . '/order');
+ $this->assertResponse(403, t('The fallback format cannot have its filters reordered.'));
+ $this->drupalGet('admin/settings/filter/delete/' . filter_fallback_format());
+ $this->assertResponse(403, t('The fallback format cannot be deleted.'));
+ $this->drupalGet('admin/settings/filter');
+ $this->assertNoRaw('admin/settings/filter/' . filter_fallback_format(), t('Configure link for fallback format not found.'));
+ $this->assertNoRaw('admin/settings/filter/delete/' . filter_fallback_format(), t('Delete link for fallback format not found.'));
+
+ // Check that a regular user does not have access to the filter
+ // administration pages.
+ $web_user = $this->drupalCreateUser();
+ $this->drupalLogin($web_user);
+ $this->drupalGet('admin/settings/filter');
+ $this->assertResponse(403, t('A regular user does not have access to the filter administration pages.'));
+ }
+}
- if ($format !== NULL) {
- $this->assertFieldByName('roles[2]', '', t('Role found.'));
- $this->assertFieldByName('filters[filter/' . $second_filter . ']', '', t('Line break filter found.'));
- $this->assertFieldByName('filters[filter/' . $first_filter . ']', '', t('Url filter found.'));
-
- // Delete new filter.
- $this->drupalPost('admin/settings/filter/delete/' . $format->format, array(), t('Delete'));
- $this->assertRaw(t('Deleted text format %format.', array('%format' => $edit['name'])), t('Format successfully deleted.'));
- }
+class FilterAccessTestCase extends FilterHelperTestCase {
+ protected $web_user;
+ protected $allowed_format;
+ protected $disallowed_format;
- // Change default filter back.
- $edit = array();
- $edit['default'] = $filtered;
- $this->drupalPost('admin/settings/filter', $edit, t('Save changes'));
- $this->assertText(t('Default format updated.'), t('Default filter updated successfully.'));
-
- $this->assertNoRaw('admin/settings/filter/delete/' . $filtered, t('Delete link not found.'));
+ public static function getInfo() {
+ return array(
+ 'name' => t('Filter access functionality'),
+ 'description' => t('Test the filter access system.'),
+ 'group' => t('Filter'),
+ );
+ }
- // Allow authenticated users on full HTML.
- $edit = array();
- $edit['roles[2]'] = TRUE;
- $this->drupalPost('admin/settings/filter/' . $full, $edit, t('Save configuration'));
- $this->assertText(t('The text format settings have been updated.'), t('Full HTML format successfully updated.'));
+ function setUp() {
+ parent::setUp();
- // Switch user.
- $this->drupalLogout();
- $this->drupalLogin($web_user);
+ // Create two text formats and grant a regular user access to one of
+ // them.
+ $this->drupalLogin($this->admin_user);
+ $this->allowed_format = $this->drupalCreateTextFormat();
+ $this->disallowed_format = $this->drupalCreateTextFormat();
+ $this->web_user = $this->drupalCreateUser(array('create page content', filter_permission_name($this->allowed_format)));
+ }
+ function testFormatPermissions() {
+ // Make sure that a regular user only has access to the text format they
+ // were granted access to, as well to the fallback format.
+ $this->assertTrue(filter_access($this->allowed_format, $this->web_user), t('A regular user has access to a text format they were granted access to.'));
+ $this->assertFalse(filter_access($this->disallowed_format, $this->web_user), t('A regular user does not have access to a text format they were not granted access to.'));
+ $this->assertTrue(filter_access(filter_fallback_format(), $this->web_user), t('A regular user has access to the fallback format.'));
+
+ // Perform similar checks as above, but now against the entire list of
+ // available formats for this user.
+ $this->assertTrue(in_array($this->allowed_format->format, array_keys(filter_formats($this->web_user))), t('The allowed format appears in the list of available formats for a regular user.'));
+ $this->assertFalse(in_array($this->disallowed_format->format, array_keys(filter_formats($this->web_user))), t('The disallowed format does not appear in the list of available formats for a regular user.'));
+ $this->assertTrue(in_array(filter_fallback_format(), array_keys(filter_formats($this->web_user))), t('The fallback format appears in the list of available formats for a regular user.'));
+
+ // Make sure that a regular user only has permission to use the format
+ // they were granted access to.
+ $this->assertTrue(user_access(filter_permission_name($this->allowed_format), $this->web_user), t('A regular user has permission to use the allowed text format.'));
+ $this->assertFalse(user_access(filter_permission_name($this->disallowed_format), $this->web_user), t('A regular user does not have permission to use the disallowed text format.'));
+
+ // Make sure that the allowed format appears on the node form and that
+ // the disallowed format does not.
+ $this->drupalLogin($this->web_user);
$this->drupalGet('node/add/page');
- $this->assertRaw('', t('Full HTML filter accessible.'));
+ $this->assertFieldByXPath('//select[@name="body_format"]/option[@value="' . $this->allowed_format->format . '"]', NULL, t('The allowed text format appears as an option when adding a new node.'));
+ $this->assertNoFieldByXPath('//select[@name="body_format"]/option[@value="' . $this->disallowed_format->format . '"]', NULL, t('The disallowed text format does not appear as an option when adding a new node.'));
+ // The fallback format should appear as an option on the form, even
+ // though it does not have a permission associated with it.
+ $this->assertFieldByXPath('//select[@name="body_format"]/option[@value="' . filter_fallback_format() . '"]', NULL, t('The fallback format appears as an option when adding a new node.'));
+ }
- // Use filtered HTML and see if it removes tags that arn't allowed.
- $body = $this->randomName();
- $extra_text = 'text';
+ function testFilterFormatRoles() {
+ // Check that a regular user's role appears in the list of roles that
+ // have access to an allowed text format, but does not appear in the
+ // list of roles that have access to a disallowed format.
+ $rid = $this->drupalGetNewestRole($this->web_user);
+ $this->assertTrue(in_array($rid, array_keys(filter_format_roles($this->allowed_format))), t('A role which has access to a text format appears in the list of roles that have access to that format.'));
+ $this->assertFalse(in_array($rid, array_keys(filter_format_roles($this->disallowed_format))), t('A role which does not have access to a text format does not appear in the list of roles that have access to that format.'));
+
+ // Check that the correct text format appears in the list of formats
+ // available to that role.
+ $this->assertTrue(in_array($this->allowed_format->format, array_keys(filter_role_formats($rid))), t('A text format which a role has access to appears in the list of formats available to that role.'));
+ $this->assertFalse(in_array($this->disallowed_format->format, array_keys(filter_role_formats($rid))), t('A text format which a role does not have access to does not appear in the list of formats available to that role.'));
+
+ // Check that the fallback format is always allowed.
+ $this->assertEqual(filter_format_roles(filter_fallback_format()), user_roles(), t('All roles have access to the fallback format.'));
+ $this->assertTrue(in_array(filter_fallback_format(), array_keys(filter_role_formats($rid))), t('The fallback format appears in the list of allowed formats for any role.'));
+ }
+}
+
+class FilterDefaultFormatTestCase extends FilterHelperTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => t('Default text format functionality'),
+ 'description' => t('Test the default text formats for different users.'),
+ 'group' => t('Filter'),
+ );
+ }
+ function testDefaultTextFormats() {
+ // Create two text formats, and two users. The first user has access
+ // to both formats, but the second user only has access to the second
+ // one.
+ $this->drupalLogin($this->admin_user);
+ $first_format = $this->drupalCreateTextFormat();
+ $second_format = $this->drupalCreateTextFormat();
+ $first_user = $this->drupalCreateUser(array(filter_permission_name($first_format), filter_permission_name($second_format)));
+ $second_user = $this->drupalCreateUser(array(filter_permission_name($second_format)));
+
+ // Adjust the weights so that the first and second formats (in that
+ // order) are the two lowest weighted formats available to any user.
+ $minimum_weight = db_query("SELECT MIN(weight) FROM {filter_format}")->fetchField();
$edit = array();
- $edit['title'] = $this->randomName();
- $edit['body'] = $body . '' . $extra_text . ' ';
- $edit['body_format'] = $filtered;
- $this->drupalPost('node/add/page', $edit, t('Save'));
- $this->assertRaw(t('Page %title has been created.', array('%title' => $edit['title'])), t('Filtered node created.'));
+ $edit[$first_format->format . '[weight]'] = $minimum_weight - 2;
+ $edit[$second_format->format . '[weight]'] = $minimum_weight - 1;
+ $this->drupalPost('admin/settings/filter', $edit, t('Save changes'));
+ filter_format_reset_cache();
- $node = $this->drupalGetNodeByTitle($edit['title']);
- $this->assertTrue($node, t('Node found in database.'));
+ // Check that each user's default format is the lowest weighted format
+ // that the user has access to.
+ $this->assertEqual(filter_default_format($first_user), $first_format->format, t("The first user's default format is the lowest weighted format that the user has access to."));
+ $this->assertEqual(filter_default_format($second_user), $second_format->format, t("The second user's default format is the lowest weighted format that the user has access to, and is different than the first user's."));
- $this->drupalGet('node/' . $node->nid);
- $this->assertText($body . $extra_text, t('Filter removed invalid tag.'));
+ // Reorder the two formats, and check that both users now have the same
+ // default.
+ $edit = array();
+ $edit[$second_format->format . '[weight]'] = $minimum_weight - 3;
+ $this->drupalPost('admin/settings/filter', $edit, t('Save changes'));
+ filter_format_reset_cache();
+ $this->assertEqual(filter_default_format($first_user), filter_default_format($second_user), t('After the formats are reordered, both users have the same default format.'));
+ }
+}
+
+class FilterUnassignedFormatTestCase extends FilterHelperTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => t('Unassigned text format functionality'),
+ 'description' => t('Test the behavior of text that has an unassigned text format.'),
+ 'group' => t('Filter'),
+ );
+ }
- // Switch user.
+ function testUnassignedTextFormat() {
+ // Perform these tests as an anonymous user.
$this->drupalLogout();
- $this->drupalLogin($admin_user);
- // Clean up.
- // Allowed tags.
- $edit = array();
- $edit['allowed_html_1'] = ' -
-
- ';
- $this->drupalPost('admin/settings/filter/' . $filtered . '/configure', $edit, t('Save configuration'));
- $this->assertText(t('The configuration options have been saved.'), t('Changes reverted.'));
+ // Create some text. Include some HTML and line breaks, so we get a good
+ // test of the filtering that is applied to it.
+ $text = "" . $this->randomName(32) . "\n\n" . $this->randomName(32) . "";
+
+ // Make sure that when this text is run through check_markup() with an
+ // unassigned text format, it is filtered as though it is in the fallback
+ // format. Note that we are letting check_markup() check access here.
+ // This is on purpose, since we want to be sure that check_markup() never
+ // refuses to filter text with an unassigned format.
+ $this->assertEqual(check_markup($text, FILTER_FORMAT_UNASSIGNED), check_markup($text, filter_fallback_format()), t('Text with an unassigned format is filtered the same as text in the fallback format.'));
- // Full HTML.
- $edit = array();
- $edit['roles[2]'] = FALSE;
- $this->drupalPost('admin/settings/filter/' . $full, $edit, t('Save configuration'));
- $this->assertText(t('The text format settings have been updated.'), t('Full HTML format successfully reverted.'));
+ // Explicitly check that access is granted to an unassigned text format.
+ $this->assertTrue(filter_access(FILTER_FORMAT_UNASSIGNED), t('Access is granted to an unassigned text format.'));
+ }
+}
- // Filter order.
- $edit = array();
- $edit['weights[filter/' . $second_filter . ']'] = 2;
- $edit['weights[filter/' . $first_filter . ']'] = 1;
- $this->drupalPost('admin/settings/filter/' . $filtered . '/order', $edit, t('Save configuration'));
- $this->assertText(t('The filter ordering has been saved.'), t('Order successfully reverted.'));
+class FilterInitialFormatsTestCase extends FilterHelperTestCase {
+ protected $web_user;
+ protected $text_before_tags;
+ protected $text_in_tags;
+ protected $complete_text;
+
+ public static function getInfo() {
+ return array(
+ 'name' => t('Initial text format functionality'),
+ 'description' => t('Test the behavior of the text formats that are provided in the initial installation of Drupal.'),
+ 'group' => t('Filter'),
+ );
}
- /**
- * Query the database to get the two basic formats.
- *
- * @return Array Array containing filtered and full filter ids.
- */
- function checkFilterFormats() {
- $result = db_query('SELECT format, name FROM {filter_format}');
+ function setUp() {
+ parent::setUp();
- $filtered = -1;
- $full = -1;
- while ($format = db_fetch_object($result)) {
- if ($format->name == 'Filtered HTML') {
- $filtered = $format->format;
- }
- elseif ($format->name == 'Full HTML') {
- $full = $format->format;
- }
- }
+ // Log in as a regular user.
+ $this->web_user = $this->drupalCreateUser();
+ $this->drupalLogin($this->web_user);
+
+ // Create some sample text that has an invalid HTML tag in it.
+ $this->text_before_tags = $this->randomName();
+ $this->text_in_tags = $this->randomName();
+ $this->complete_text = $this->text_before_tags . '
' . $this->text_in_tags . ' ';
+ }
- return array($filtered, $full);
+ function testFilteredHtml() {
+ // Create a node with filtered HTML and make sure the tags which weren't
+ // allowed were removed.
+ $node = $this->createNodeWithFormat('Filtered HTML');
+ $this->drupalGet('node/' . $node->nid);
+ $this->assertText($this->text_before_tags . $this->text_in_tags, t('The "Filtered HTML" text format removes an invalid pair of HTML tags.'));
+ }
+
+ function testFullHtml() {
+ // Create a node with full HTML and make sure the tags appear.
+ $node = $this->createNodeWithFormat('Full HTML');
+ $this->drupalGet('node/' . $node->nid);
+ $this->assertRaw($this->complete_text, t('The "Full HTML" text format does not remove or alter HTML tags.'));
+ }
+
+ function testPlainText() {
+ $node = $this->createNodeWithFormat('Plain text');
+ $this->drupalGet('node/' . $node->nid);
+ $this->assertText(check_plain($this->complete_text), t('The "Plain text" text format escapes an invalid pair of HTML tags.'));
}
/**
- * Get filter by name.
+ * Populates a node body with the sample text defined in the setUp() method,
+ * and saves the node in the provided text format.
*
- * @param string $name Name of filter to find.
- * @return object Filter object.
+ * @param $name
+ * The name of the text format to use for the node body.
+ * @return
+ * The saved node.
*/
- function getFilter($name) {
- return db_fetch_object(db_query("SELECT * FROM {filter_format} WHERE name = '%s'", $name));
+ function createNodeWithFormat($name) {
+ $edit = array();
+ $edit['body'] = $this->complete_text;
+ $edit['format'] = $this->getTextFormatByName($name)->format;
+ return $this->drupalCreateNode($edit);
}
}
-class FilterTestCase extends DrupalWebTestCase {
+class FilterTestCase extends FilterHelperTestCase {
protected $format;
public static function getInfo() {
@@ -189,13 +372,6 @@ class FilterTestCase extends DrupalWebTe
);
}
- function setUp() {
- parent::setUp();
-
- $admin_user = $this->drupalCreateUser(array('administer filters', 'create page content'));
- $this->drupalLogin($admin_user);
- }
-
/**
* Test the line break filter
*/
@@ -216,21 +392,4 @@ class FilterTestCase extends DrupalWebTe
function testHtmlFilter() {
}
-
- function createFormat($filter) {
- $edit = array(
- 'name' => $this->randomName(),
- 'roles[2]' => TRUE,
- 'filters[filter/' . $filter . ']' => TRUE,
- );
- $this->drupalPost('admin/settings/filter/add', $edit, t('Save configuration'));
- return db_fetch_object(db_query("SELECT * FROM {filter_format} WHERE name = '%s'", $edit['name']));
- }
-
- function deleteFormat($format) {
- if ($format !== NULL) {
- // Delete new filter.
- $this->drupalPost('admin/settings/filter/delete/' . $format->format, array(), t('Delete'));
- }
- }
}
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1033
diff -u -p -r1.1033 node.module
--- modules/node/node.module 26 Mar 2009 13:31:25 -0000 1.1033
+++ modules/node/node.module 7 Apr 2009 04:33:12 -0000
@@ -1011,12 +1011,14 @@ function node_submit($node) {
// Convert the node to an object, if necessary.
$node = (object)$node;
+ // Generate the text format.
+ $node->format = (!empty($node->body_format) ? $node->body_format : FILTER_FORMAT_UNASSIGNED);
+
// Generate the teaser, but only if it hasn't been set (e.g. by a
// module-provided 'teaser' form item).
if (!isset($node->teaser)) {
if (isset($node->body)) {
- $node->format = (!empty($node->body_format) ? $node->body_format : FILTER_FORMAT_DEFAULT);
- $node->teaser = node_teaser($node->body, isset($node->format) ? $node->format : NULL);
+ $node->teaser = node_teaser($node->body, $node->format);
// Chop off the teaser from the body if needed. The teaser_include
// property might not be set (eg. in Blog API postings), so only act on
// it, if it was set with a given value.
@@ -1026,7 +1028,6 @@ function node_submit($node) {
}
else {
$node->teaser = '';
- $node->format = 0;
}
}
Index: modules/node/node.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.pages.inc,v
retrieving revision 1.58
diff -u -p -r1.58 node.pages.inc
--- modules/node/node.pages.inc 26 Mar 2009 13:31:25 -0000 1.58
+++ modules/node/node.pages.inc 7 Apr 2009 04:33:12 -0000
@@ -308,7 +308,7 @@ function node_body_field(&$node, $label,
'#default_value' => $include ? $node->body : ($node->teaser . $node->body),
'#rows' => 20,
'#required' => ($word_count > 0),
- '#text_format' => isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT,
+ '#text_format' => isset($node->format) ? $node->format : filter_default_format(),
);
return $form;
Index: modules/php/php.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/php/php.install,v
retrieving revision 1.5
diff -u -p -r1.5 php.install
--- modules/php/php.install 13 Mar 2009 21:35:02 -0000 1.5
+++ modules/php/php.install 7 Apr 2009 04:33:12 -0000
@@ -14,7 +14,6 @@ function php_install() {
$format = db_insert('filter_format')
->fields(array(
'name' => 'PHP code',
- 'roles' => '',
'cache' => 0,
))
->execute();
Index: modules/php/php.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/php/php.test,v
retrieving revision 1.8
diff -u -p -r1.8 php.test
--- modules/php/php.test 31 Mar 2009 01:49:53 -0000 1.8
+++ modules/php/php.test 7 Apr 2009 04:33:12 -0000
@@ -5,6 +5,8 @@
* Base PHP test case class.
*/
class PHPTestCase extends DrupalWebTestCase {
+ protected $php_code_format;
+
function setUp() {
parent::setUp('php');
@@ -12,9 +14,14 @@ class PHPTestCase extends DrupalWebTestC
$admin_user = $this->drupalCreateUser(array('administer filters'));
$this->drupalLogin($admin_user);
- // Confirm that the PHP filter is #3.
- $this->drupalGet('admin/settings/filter/3');
- $this->assertText('PHP code', t('On PHP code filter page.'));
+ // 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.'));
+
+ // Store the format ID of the PHP code text format for later use.
+ $this->php_code_format = $newest_format_id;
}
/**
@@ -26,7 +33,10 @@ class PHPTestCase extends DrupalWebTestC
function createNodeWithCode($user) {
$node = $this->drupalCreateNode(array('uid' => $user->uid));
$edit = array();
- $edit['body'] = '';
+ // If the code executes, "PHP code was evaluated" should appear on the
+ // page. If the code does not execute, "PHP code was not evaluated"
+ // should appear instead.
+ $edit['body'] = "";
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Page %title has been updated.', array('%title' => $node->title)), t('PHP code inserted into node.'));
return $node;
@@ -49,30 +59,28 @@ class PHPFilterTestCase extends PHPTestC
* Make sure that the PHP filter evaluates PHP code when used.
*/
function testPHPFilter() {
- // Setup PHP filter.
- $edit = array();
- $edit['roles[2]'] = TRUE; // Set authenticated users to have permission to use filter.
- $this->drupalPost(NULL, $edit, 'Save configuration');
- $this->assertText(t('The text format settings have been updated.'), t('PHP format available to authenticated users.'));
-
- // Create node with PHP filter enabled.
- $web_user = $this->drupalCreateUser(array('access content', 'create page content', 'edit own page content'));
+ // Log in as a user with permission to use the PHP code text format.
+ $php_code_permission = filter_permission_name(filter_format_load($this->php_code_format));
+ $web_user = $this->drupalCreateUser(array('access content', 'create page content', 'edit own page content', $php_code_permission));
$this->drupalLogin($web_user);
+ // Create a node with PHP code in it.
$node = $this->createNodeWithCode($web_user);
- // Make sure that the PHP code shows up as text.
- $this->assertText('print', t('PHP code is displayed.'));
+ // Make sure that the PHP code shows up as text and is not evaluated.
+ $this->assertText('PHP code was not evaluated', t('Raw PHP code is displayed.'));
+ $this->assertNoText('PHP code was evaluated', t('PHP code is not evaluated.'));
// Change filter to PHP filter and see that PHP code is evaluated.
$edit = array();
- $edit['body_format'] = 3;
+ $edit['body_format'] = $this->php_code_format;
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Page %title has been updated.', array('%title' => $node->title)), t('PHP code filter turned on.'));
- // Make sure that the PHP code shows up as text.
- $this->assertNoText('print', t('PHP code isn\'t displayed.'));
- $this->assertText('SimpleTest PHP was executed!', t('PHP code has been evaluated.'));
+ // Make sure that the PHP code is evaluated and that the raw code is
+ // not displayed.
+ $this->assertNoText('PHP code was not evaluated', t('Raw PHP code isn\'t displayed.'));
+ $this->assertText('PHP code was evaluated', t('PHP code has been evaluated.'));
}
}
@@ -95,14 +103,14 @@ class PHPAccessTestCase extends PHPTestC
// Create node with PHP filter enabled.
$web_user = $this->drupalCreateUser(array('access content', 'create page content', 'edit own page content'));
$this->drupalLogin($web_user);
-
$node = $this->createNodeWithCode($web_user);
- // Make sure that the PHP code shows up as text.
- $this->assertText('print', t('PHP code is displayed.'));
+ // Make sure that the PHP code shows up as text and is not evaluated.
+ $this->assertText('PHP code was not evaluated', t('Raw PHP code is displayed.'));
+ $this->assertNoText('PHP code was evaluated', t('PHP code is not evaluated.'));
// Make sure that user doesn't have access to filter.
$this->drupalGet('node/' . $node->nid . '/edit');
- $this->assertNoFieldByName('body_format', '3', t('Format not available.'));
+ $this->assertNoFieldByXPath('//select[@name="body_format"]/option[@value="' . $this->php_code_format . '"]', NULL, t('PHP code format not available.'));
}
}
Index: modules/profile/profile.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.module,v
retrieving revision 1.252
diff -u -p -r1.252 profile.module
--- modules/profile/profile.module 14 Mar 2009 23:01:37 -0000 1.252
+++ modules/profile/profile.module 7 Apr 2009 04:33:12 -0000
@@ -299,7 +299,7 @@ function profile_view_field($user, $fiel
if (isset($user->{$field->name}) && $value = $user->{$field->name}) {
switch ($field->type) {
case 'textarea':
- return check_markup($value);
+ return check_markup($value, filter_default_format($user), '', FALSE);
case 'textfield':
case 'selection':
return $browse ? l($value, 'profile/' . $field->name . '/' . $value) : check_plain($value);
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.92
diff -u -p -r1.92 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php 30 Mar 2009 05:35:35 -0000 1.92
+++ modules/simpletest/drupal_web_test_case.php 7 Apr 2009 04:33:12 -0000
@@ -491,7 +491,7 @@ class DrupalWebTestCase {
'title' => $this->randomName(8),
'comment' => 2,
'changed' => REQUEST_TIME,
- 'format' => FILTER_FORMAT_DEFAULT,
+ 'format' => filter_default_format(),
'moderate' => 0,
'promote' => 0,
'revision' => 1,
@@ -714,6 +714,27 @@ class DrupalWebTestCase {
}
/**
+ * Returns the ID of the newest role assigned to a given user account.
+ *
+ * This can be used to find the new role that was created when a user is
+ * added via drupalCreateUser().
+ *
+ * @param $account
+ * A user object representing the account in which the newest role will
+ * be searched for.
+ * @return
+ * The ID of the newest role that is assigned to this user.
+ *
+ * @see drupalCreateUser()
+ */
+ protected function drupalGetNewestRole(stdClass $account) {
+ // Find the new role ID; it must be the maximum.
+ $all_rids = array_keys($account->roles);
+ sort($all_rids);
+ return array_pop($all_rids);
+ }
+
+ /**
* Check to make sure that the array of permissions are valid.
*
* @param $permissions
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.32
diff -u -p -r1.32 common.test
--- modules/simpletest/tests/common.test 31 Mar 2009 01:49:53 -0000 1.32
+++ modules/simpletest/tests/common.test 7 Apr 2009 04:33:12 -0000
@@ -261,8 +261,9 @@ class CascadingStylesheetsTestCase exten
// Create a node, using the PHP filter that tests drupal_add_css().
$settings = array(
'type' => 'page',
- 'format' => 3, // PHP filter.
- 'body_format' => 3,
+ // 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(),
'body' => t('This tests the inline CSS!') . "",
'promote' => 1,
);
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.314
diff -u -p -r1.314 system.install
--- modules/system/system.install 3 Apr 2009 17:50:21 -0000 1.314
+++ modules/system/system.install 7 Apr 2009 04:33:12 -0000
@@ -360,12 +360,14 @@ function system_install() {
// Anonymous role permissions.
db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 1, 'access content');
+ db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 1, 'use text format 1'); // Filtered HTML
// Authenticated role permissions.
db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 2, 'access comments');
db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 2, 'access content');
db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 2, 'post comments');
db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 2, 'post comments without approval');
+ db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 2, 'use text format 1'); // Filtered HTML
db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", 'theme_default', 's:7:"garland";');
db_query("UPDATE {system} SET status = %d WHERE type = '%s' AND name = '%s'", 1, 'theme', 'garland');
@@ -373,8 +375,9 @@ function system_install() {
db_query("INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, '%s', %d, %d, %d)", 0, 0, 'all', 1, 0, 0);
// Add text formats.
- db_query("INSERT INTO {filter_format} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Filtered HTML', ',1,2,', 1);
- db_query("INSERT INTO {filter_format} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Full HTML', '', 1);
+ db_query("INSERT INTO {filter_format} (name, cache, weight) VALUES ('%s', %d, %d)", 'Filtered HTML', 1, 0);
+ db_query("INSERT INTO {filter_format} (name, cache, weight) VALUES ('%s', %d, %d)", 'Full HTML', 1, 0);
+ db_query("INSERT INTO {filter_format} (name, cache, weight) VALUES ('%s', %d, %d)", 'Plain text', 1, 1);
// Enable filters for each text format.
@@ -396,6 +399,12 @@ function system_install() {
// HTML corrector filter.
db_query("INSERT INTO {filter} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", 2, 'filter', 3, 10);
+ // Plain text:
+ // Escape HTML.
+ db_query("INSERT INTO {filter} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", 3, 'filter', 4, 0);
+ // Line break filter.
+ db_query("INSERT INTO {filter} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", 3, 'filter', 1, 1);
+
db_query("INSERT INTO {variable} (name, value) VALUES ('%s','%s')", 'filter_html_1', 'i:1;');
db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", 'node_options_forum', 'a:1:{i:0;s:6:"status";}');
Index: modules/upload/upload.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.test,v
retrieving revision 1.14
diff -u -p -r1.14 upload.test
--- modules/upload/upload.test 31 Mar 2009 01:49:55 -0000 1.14
+++ modules/upload/upload.test 7 Apr 2009 04:33:12 -0000
@@ -98,7 +98,7 @@ class UploadTestCase extends DrupalWebTe
$settings['upload_extensions'] = 'html';
$settings['upload_uploadsize'] = '1';
$settings['upload_usersize'] = '1';
- $this->setUploadSettings($settings, $this->getSimpletestRoleId($web_user));
+ $this->setUploadSettings($settings, $this->drupalGetNewestRole($web_user));
$this->drupalLogin($web_user);
@@ -141,7 +141,7 @@ class UploadTestCase extends DrupalWebTe
$settings['upload_extensions'] = 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp';
$settings['upload_uploadsize'] = '0.5';
$settings['upload_usersize'] = '1.5';
- $this->setUploadSettings($settings, $this->getSimpletestRoleId($web_user));
+ $this->setUploadSettings($settings, $this->drupalGetNewestRole($web_user));
$this->drupalLogin($web_user);
@@ -200,19 +200,4 @@ class UploadTestCase extends DrupalWebTe
$this->assertResponse(array(200), 'Uploaded ' . $filename . ' is accessible.');
$this->assertEqual(file_get_contents($file), $this->drupalGetContent(), 'Uploaded contents of ' . $filename . ' verified.');
}
-
- /**
- * Get the role id of the 'simpletest' role associated with a SimpleTest test user.
- *
- * @param object $user User object.
- * @return integer SimpleTest role id.
- */
- function getSimpletestRoleId($user) {
- foreach ($user->roles as $rid => $role) {
- if (strpos($role, 'simpletest') !== FALSE) {
- return $rid;
- }
- }
- return NULL;
- }
}
Index: modules/user/user.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.test,v
retrieving revision 1.33
diff -u -p -r1.33 user.test
--- modules/user/user.test 31 Mar 2009 01:49:55 -0000 1.33
+++ modules/user/user.test 7 Apr 2009 04:33:12 -0000
@@ -724,13 +724,8 @@ class UserPermissionsTestCase extends Dr
function setUp() {
parent::setUp();
-
$this->admin_user = $this->drupalCreateUser(array('administer permissions', 'access user profiles'));
-
- // Find the new role ID - it must be the maximum.
- $all_rids = array_keys($this->admin_user->roles);
- sort($all_rids);
- $this->rid = array_pop($all_rids);
+ $this->rid = $this->drupalGetNewestRole($this->admin_user);
}
/**