### Eclipse Workspace Patch 1.0 #P drupal7-cvs Index: modules/filter/filter.install =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.install,v retrieving revision 1.16 diff -u -r1.16 filter.install --- modules/filter/filter.install 27 May 2009 18:33:57 -0000 1.16 +++ modules/filter/filter.install 22 Jul 2009 13:17:32 -0000 @@ -10,91 +10,81 @@ * Implement hook_schema(). */ function filter_schema() { - $schema['filter'] = array( - 'description' => 'Table that maps filters (HTML corrector) to text formats (Filtered HTML).', + $schema['format'] = array( + 'description' => 'Stores text formats: custom groupings of filters, such as Filtered HTML.', 'fields' => array( 'fid' => array( 'type' => 'serial', 'not null' => TRUE, - 'description' => 'Primary Key: Auto-incrementing filter ID.', + 'description' => 'Primary Key: Unique ID for format.', ), - 'format' => array( - 'type' => 'int', + 'name' => array( + 'type' => 'varchar', + 'length' => 255, 'not null' => TRUE, - 'default' => 0, - 'description' => 'Foreign key: The {filter_format}.format to which this filter is assigned.', + 'default' => '', + 'description' => 'Name of the text format (Filtered HTML).', ), - 'module' => array( + 'roles' => array( 'type' => 'varchar', - 'length' => 64, + 'length' => 255, 'not null' => TRUE, 'default' => '', - 'description' => 'The origin module of the filter.', + 'description' => 'A comma-separated string of roles; references {role}.rid.', // This is bad since you can't use joins, nor index. ), - 'delta' => array( + 'cache' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', - 'description' => 'ID to identify which filter within module is being referenced.', + 'description' => 'Flag to indicate whether format is cacheable. (1 = cacheable, 0 = not cacheable)', ), 'weight' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', - 'description' => 'Weight of filter within format.', + 'description' => 'Weight of text format to use when listing.', ) ), 'primary key' => array('fid'), 'unique keys' => array( - 'fmd' => array('format', 'module', 'delta'), - ), - 'indexes' => array( - 'list' => array('format', 'weight', 'module', 'delta'), + 'name' => array('name'), ), ); - $schema['filter_format'] = array( - 'description' => 'Stores text formats: custom groupings of filters, such as Filtered HTML.', + + $schema['format_filter'] = array( + 'description' => 'Table that maps text formats (Filtered HTML) to text formats (HTML corrector).', 'fields' => array( - 'format' => array( - 'type' => 'serial', + 'fid' => array( + 'type' => 'int', 'not null' => TRUE, - 'description' => 'Primary Key: Unique ID for format.', + 'default' => 0, + 'description' => 'Foreign key: The {format}.fid', ), - 'name' => array( + 'module' => array( 'type' => 'varchar', - 'length' => 255, + 'length' => 64, 'not null' => TRUE, 'default' => '', - 'description' => 'Name of the text format (Filtered HTML).', + 'description' => 'The origin module of the filter.', ), - 'roles' => array( + 'filter_id' => array( 'type' => 'varchar', - 'length' => 255, + 'length' => 64, '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, - 'default' => 0, - 'size' => 'tiny', - 'description' => 'Flag to indicate whether format is cacheable. (1 = cacheable, 0 = not cacheable)', - ), + 'description' => 'The filter referenced unique ID within the module.', + ), 'weight' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', - 'description' => 'Weight of text format to use when listing.', + 'description' => 'Weight of filter within format.', ) ), - 'primary key' => array('format'), - 'unique keys' => array( - 'name' => array('name'), - ), + 'primary key' => array('fid', 'module', 'filter_id'), ); $schema['cache_filter'] = drupal_get_schema_unprocessed('system', 'cache'); Index: modules/filter/filter.module =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v retrieving revision 1.263 diff -u -r1.263 filter.module --- modules/filter/filter.module 19 Jul 2009 05:34:52 -0000 1.263 +++ modules/filter/filter.module 22 Jul 2009 13:17:38 -0000 @@ -298,8 +298,8 @@ if (!isset($formats)) { $formats = array(); - $query = db_select('filter_format', 'f'); - $query->addField('f', 'format', 'format'); + $query = db_select('format', 'f'); + $query->addField('f', 'fid', 'fid'); $query->addField('f', 'name', 'name'); $query->addField('f', 'roles', 'roles'); $query->addField('f', 'cache', 'cache'); @@ -308,15 +308,16 @@ // 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)); + $or = db_or()->condition('fid', variable_get('filter_default_format', 1)); foreach ($user->roles as $rid => $role) { $or->condition('roles', '%' . (int)$rid . '%', 'LIKE'); } $query->condition($or); } - $formats = $query->execute()->fetchAllAssoc('format'); + $formats = $query->execute()->fetchAllAssoc('fid'); } + if (isset($index)) { return isset($formats[$index]) ? $formats[$index] : FALSE; } @@ -324,24 +325,36 @@ } /** + * Collect the filter definitions from modules that implement hook_filter_info(). + */ +function filter_build() { + static $filters; + + if (!isset($filters)) { + // We need to manually call each module so that we can know which module + // a given item came from. + + $filters = array(); + foreach (module_implements('filter_info') as $module) { + $filter_items = call_user_func($module . '_filter_info'); + if (isset($filter_items) && is_array($filter_items)) { + foreach ($filter_items as $filter_id => $filter) { + $filter_items[$filter_id] = (object)$filter; + $filter_items[$filter_id]->module = $module; + } + $filters = array_merge($filters, $filter_items); + } + } + uasort($filters, '_filter_list_cmp'); + } + return $filters; +} + +/** * Build a list of all filters. */ function filter_list_all() { - $filters = array(); - - foreach (module_implements('filter') as $module) { - $function = $module . '_filter'; - $list = $function('list'); - if (isset($list) && is_array($list)) { - foreach ($list as $delta => $name) { - $filters[$module . '/' . $delta] = (object)array('module' => $module, 'delta' => $delta, 'name' => $name); - } - } - } - - uasort($filters, '_filter_list_cmp'); - - return $filters; + return filter_build(); } /** @@ -360,11 +373,11 @@ /** * Check if text in a certain text format is allowed to be cached. */ -function filter_format_allowcache($format) { +function filter_format_allowcache($fid) { static $cache = array(); - $format = filter_resolve_format($format); + $format = filter_resolve_format($fid); if (!isset($cache[$format])) { - $cache[$format] = db_query('SELECT cache FROM {filter_format} WHERE format = :format', array(':format' => $format))->fetchField(); + $cache[$format] = db_query('SELECT cache FROM {format} WHERE fid = :fid', array(':fid' => $fid))->fetchField(); } return $cache[$format]; } @@ -372,22 +385,21 @@ /** * Retrieve a list of filters for a certain format. */ -function filter_list_format($format) { +function filter_list_format($fid) { static $filters = array(); - if (!isset($filters[$format])) { - $filters[$format] = array(); - $result = db_query("SELECT * FROM {filter} WHERE format = :format ORDER BY weight, module, delta", array(':format' => (int) $format)); + //@TODO: load from cache. + $all_filters = filter_list_all(); + + if (!isset($filters[$fid])) { + $filters[$fid] = array(); + $result = db_query("SELECT ff.module, ff.filter_id FROM {format} f INNER JOIN {format_filter} ff ON f.fid = ff.fid WHERE f.fid = :fid ORDER BY ff.weight", array(':fid' => (int) $fid)); foreach ($result as $filter) { - $list = module_invoke($filter->module, 'filter', 'list'); - if (isset($list) && is_array($list) && isset($list[$filter->delta])) { - $filter->name = $list[$filter->delta]; - $filters[$format][$filter->module . '/' . $filter->delta] = $filter; - } + $filters[$fid][$filter->filter_id] = $all_filters[$filter->filter_id]; } } - return $filters[$format]; + return $filters[$fid]; } /** @@ -448,12 +460,16 @@ // Give filters the chance to escape HTML-like data such as code or formulas. foreach ($filters as $filter) { - $text = module_invoke($filter->module, 'filter', 'prepare', $filter->delta, $format, $text, $langcode, $cache_id); + if (isset($filter->prepare) && drupal_function_exists($filter->prepare)) { + $text = call_user_func($filter->prepare, $text, $format, $langcode, $cache_id); + } } // Perform filtering. foreach ($filters as $filter) { - $text = module_invoke($filter->module, 'filter', 'process', $filter->delta, $format, $text, $langcode, $cache_id); + if (isset($filter->process) && drupal_function_exists($filter->process)) { + $text = call_user_func($filter->process, $text, $format, $langcode, $cache_id); + } } // Store in cache with a minimum expiration time of 1 day. @@ -500,8 +516,8 @@ '#weight' => 2, ); foreach ($formats as $format) { - $options[$format->format] = $format->name; - $form['format_guidelines'][$format->format] = array( + $options[$format->fid] = $format->name; + $form['format_guidelines'][$format->fid] = array( '#markup' => theme('filter_guidelines', $format), ); } @@ -548,22 +564,22 @@ * Helper function for fetching filter tips. */ function _filter_tips($format, $long = FALSE) { - if ($format == -1) { + if (empty($format)) { $formats = filter_formats(); } else { - $formats = array(db_query("SELECT * FROM {filter_format} WHERE format = :format", array(':format' => $format))->fetchObject()); + $formats = array($format); } $tips = array(); foreach ($formats as $format) { - $filters = filter_list_format($format->format); + $filters = filter_list_format($format->fid); $tips[$format->name] = array(); - foreach ($filters as $id => $filter) { - if ($tip = module_invoke($filter->module, 'filter_tips', $filter->delta, $format->format, $long)) { - $tips[$format->name][] = array('tip' => $tip, 'id' => $id); + foreach ($filters as $filter_id => $filter) { + if ($tip = module_invoke($filter->module, 'filter_tips', $filter_id, $format->fid, $long)) { + $tips[$format->name][] = array('tip' => $tip, 'id' => $filter_id); } } } @@ -588,7 +604,7 @@ */ function theme_filter_guidelines($format) { $name = isset($format->name) ? '' : ''; - return '
' . $name . theme('filter_tips', _filter_tips($format->format, FALSE)) . '
'; + return '
' . $name . theme('filter_tips', _filter_tips($format, FALSE)) . '
'; } /** @@ -598,9 +614,9 @@ */ /** - * Implement hook_filter(). + * Implement hook_filter_info(). * - * Set up a basic set of essential filters: + * Define a basic set of essential filters: * - Limit allowed HTML tags: * Restricts user-supplied HTML to certain tags, and removes dangerous * components in allowed tags. @@ -613,56 +629,39 @@ * - Escape all HTML: * Converts all HTML tags into visible text. */ -function filter_filter($op, $delta = 0, $format = -1, $text = '') { - switch ($op) { - case 'list': - return array(0 => t('Limit allowed HTML tags'), 1 => t('Convert line breaks'), 2 => t('Convert URLs into links'), 3 => t('Correct broken HTML'), 4 => t('Escape all HTML')); - - case 'description': - switch ($delta) { - case 0: - return t('Allows you to restrict the HTML tags the user can use. It will also remove harmful content such as JavaScript events, JavaScript URLs and CSS styles from those tags that are not removed.'); - case 1: - return t('Converts line breaks into HTML (i.e. <br> and <p>) tags.'); - case 2: - return t('Turns web and e-mail addresses into clickable links.'); - case 3: - return t('Corrects faulty and chopped off HTML in postings.'); - case 4: - return t('Escapes all HTML tags, so they will be visible instead of being effective.'); - default: - return; - } - - case 'process': - switch ($delta) { - case 0: - return _filter_html($text, $format); - case 1: - return _filter_autop($text); - case 2: - return _filter_url($text, $format); - case 3: - return _filter_htmlcorrector($text); - case 4: - return trim(check_plain($text)); - default: - return $text; - } - - case 'settings': - switch ($delta) { - case 0: - return _filter_html_settings($format); - case 2: - return _filter_url_settings($format); - default: - return; - } - - default: - return $text; - } +function filter_filter_info() { + $filters['filter_html'] = array( + 'name' => t('Limit allowed HTML tags'), + 'description' => t('Allows you to restrict the HTML tags the user can use. It will also remove harmful content such as JavaScript events, JavaScript URLs and CSS styles from those tags that are not removed.'), + 'process' => '_filter_html', + 'settings callback' => '_filter_html_settings', + 'tips callback' => '_filter_html_tips' + ); + $filters['filter_autop'] = array( + 'name' => t('Convert line breaks'), + 'description' => t('Converts line breaks into HTML (i.e. <br> and <p>) tags.'), + 'process' => '_filter_autop', + 'tips callback' => '_filter_autop_tips' + ); + $filters['filter_url'] = array( + 'name' => t('Convert URLs into links'), + 'description' => t('Turns web and e-mail addresses into clickable links.'), + 'process' => '_filter_url', + 'settings callback' => '_filter_url_settings', + 'tips callback' => '_filter_url_tips' + ); + $filters['filter_htmlcorrector'] = array( + 'name' => t('Correct broken HTML'), + 'description' => t('Corrects faulty and chopped off HTML in postings.'), + 'process' => '_filter_htmlcorrector', + 'tips callback' => 'filter_htmlcorrector_tips' + ); + $filters['filter_html_escape'] = array( + 'name' => t('Escape all HTML'), + 'description' => t('Escapes all HTML tags, so they will be visible instead of being effective.'), + 'process' => '_filter_html_escape', + ); + return $filters; } /** Index: modules/filter/filter.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.admin.inc,v retrieving revision 1.30 diff -u -r1.30 filter.admin.inc --- modules/filter/filter.admin.inc 12 Jun 2009 08:39:37 -0000 1.30 +++ modules/filter/filter.admin.inc 22 Jul 2009 13:17:32 -0000 @@ -111,7 +111,7 @@ * @see filter_admin_format_form_submit() */ function filter_admin_format_form(&$form_state, $format) { - $default = ($format->format == variable_get('filter_default_format', 1)); + $default = ($format->fid == 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); @@ -143,7 +143,7 @@ } // Table with filters $all = filter_list_all(); - $enabled = filter_list_format($format->format); + $enabled = filter_list_format($format->fid); $form['filters'] = array('#type' => 'fieldset', '#title' => t('Filters'), @@ -154,14 +154,14 @@ $form['filters'][$id] = array('#type' => 'checkbox', '#title' => $filter->name, '#default_value' => isset($enabled[$id]), - '#description' => module_invoke($filter->module, 'filter', 'description', $filter->delta), + '#description' => $filter->description, ); } - if (!empty($format->format)) { - $form['format'] = array('#type' => 'hidden', '#value' => $format->format); + if (!empty($format->fid)) { + $form['fid'] = array('#type' => 'hidden', '#value' => $format->fid); // Composition tips (guidelines) - $tips = _filter_tips($format->format, FALSE); + $tips = _filter_tips($format, FALSE); $tiplist = theme('filter_tips', $tips, FALSE); if (!$tiplist) { $tiplist = '

' . t('No guidelines available.') . '

'; @@ -346,7 +346,7 @@ * @ingroup forms */ function filter_admin_configure(&$form_state, $format) { - $list = filter_list_format($format->format); + $list = filter_list_format($format->fid); $form = array(); foreach ($list as $filter) { $form_module = module_invoke($filter->module, 'filter', 'settings', $filter->delta, $format->format); @@ -447,3 +447,15 @@ cache_clear_all($form_state['values']['format'] . ':', 'cache_filter', TRUE); } + +/** + * Implement hook_modules_uninstalled(). + */ +function filter_modules_uninstalled($modules) { + // Remove filters from unistalled modules. + foreach ($modules as $module) { + db_delete('format_filter') + ->condition('module', $module) + ->execute(); + } +} \ No newline at end of file Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.356 diff -u -r1.356 system.install --- modules/system/system.install 21 Jul 2009 07:27:00 -0000 1.356 +++ modules/system/system.install 22 Jul 2009 13:17:50 -0000 @@ -435,14 +435,14 @@ ->execute(); // Add text formats. - $filtered_html_format = db_insert('filter_format') + $filtered_html_fid = db_insert('format') ->fields(array( 'name' => 'Filtered HTML', 'roles' => ',' . DRUPAL_ANONYMOUS_RID . ',' . DRUPAL_AUTHENTICATED_RID . ',', 'cache' => 1, )) ->execute(); - $full_html_format = db_insert('filter_format') + $full_html_fid = db_insert('format') ->fields(array( 'name' => 'Full HTML', 'roles' => '', @@ -453,62 +453,62 @@ // Enable filters for each text format. // Filtered HTML: - db_insert('filter') - ->fields(array('format', 'module', 'delta', 'weight')) + db_insert('format_filter') + ->fields(array('fid', 'module', 'filter_id', 'weight')) // URL filter. ->values(array( - 'format' => $filtered_html_format, + 'fid' => $filtered_html_fid, 'module' => 'filter', - 'delta' => 2, + 'filter_id' => 'filter_url', 'weight' => 0, )) // HTML filter. ->values(array( - 'format' => $filtered_html_format, + 'fid' => $filtered_html_fid, 'module' => 'filter', - 'delta' => 0, + 'filter_id' => 'filter_html', 'weight' => 1, )) // Line break filter. ->values(array( - 'format' => $filtered_html_format, + 'fid' => $filtered_html_fid, 'module' => 'filter', - 'delta' => 1, + 'filter_id' => 'filter_autop', 'weight' => 2, )) // HTML corrector filter. ->values(array( - 'format' => $filtered_html_format, + 'fid' => $filtered_html_fid, 'module' => 'filter', - 'delta' => 3, + 'filter_id' => 'filter_htmlcorrector', 'weight' => 10, )) // Full HTML: // URL filter. ->values(array( - 'format' => $full_html_format, + 'fid' => $full_html_fid, 'module' => 'filter', - 'delta' => 2, + 'filter_id' => 'filter_url', 'weight' => 0, )) // Line break filter. ->values(array( - 'format' => $full_html_format, + 'fid' => $full_html_fid, 'module' => 'filter', - 'delta' => 1, + 'filter_id' => 'filter_autop', 'weight' => 1, )) // HTML corrector filter. ->values(array( - 'format' => $full_html_format, + 'fid' => $full_html_fid, 'module' => 'filter', - 'delta' => 3, + 'filter_id' => 'filter_htmlcorrector', 'weight' => 10, )) ->execute(); // Set the default input format to Filtered HTML. - variable_set('filter_default_format', $filtered_html_format); + variable_set('filter_default_format', $filtered_html_fid); variable_set('node_options_forum', array(0 => 'status'));