summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/filter/filter.api.php328
-rw-r--r--modules/filter/filter.module12
2 files changed, 209 insertions, 131 deletions
diff --git a/modules/filter/filter.api.php b/modules/filter/filter.api.php
index 399d564a1..ca01eec44 100644
--- a/modules/filter/filter.api.php
+++ b/modules/filter/filter.api.php
@@ -14,114 +14,29 @@
/**
* Define content filters.
*
- * Content in Drupal is passed through a group of filters before it is output.
- * This lets a module modify content to the site administrator's liking.
- *
- * This hook allows modules to declare input filters they provide. A module can
- * contain as many filters as it wants.
- *
- * The overall, logical flow is as follows:
- * - hook_filter_info() is invoked to retrieve one or more filter definitions.
- * - The site administrator enables and configures the filter, where the
- * following properties may be used:
- * - 'title': The filter's title.
- * - 'description': The filter's short-description.
- * Additionally, if a filter is configurable:
- * - 'settings callback': A form builder function name providing a settings
- * form for the filter.
- * - 'default settings': An array containing default settings for the filter.
- * - When a form containing a text format-enabled text widget/textarea is
- * rendered, the following property are checked:
- * - 'tips callback': A function name providing filter guidelines to be
- * displayed in the text format widget.
- * - When a content using a text format is rendered, the following properties
- * may be used:
- * - 'prepare callback': A name of a function that escapes the to be filtered
- * content before the actual filtering happens.
- * - 'process callback': The name the function that performs the actual
- * filtering.
+ * User submitted content is passed through a group of filters before it is
+ * output in HTML, in order to remove insecure or unwanted parts, correct or
+ * enhance the formatting, transform special keywords, etc. A group of filters
+ * is referred to as a "text format". Administrators can create as many text
+ * formats as needed. Individual filters can be enabled and configured
+ * differently for each text format.
+ *
+ * This hook is invoked by filter_get_filters() and allows modules to register
+ * input filters they provide.
*
* Filtering is a two-step process. First, the content is 'prepared' by calling
* the 'prepare callback' function for every filter. The purpose of the 'prepare
* callback' is to escape HTML-like structures. For example, imagine a filter
* which allows the user to paste entire chunks of programming code without
- * requiring manual escaping of special HTML characters like @< or @&. If the
+ * requiring manual escaping of special HTML characters like < or &. If the
* programming code were left untouched, then other filters could think it was
- * HTML and change it. For most filters however, the prepare-step is not
- * necessary, and they can just return the input without changes.
- *
- * Filters should not use the 'prepare callback' step for anything other than
- * escaping, because that would short-circuit the control the user has over the
- * order in which filters are applied.
- *
- * The second step is the actual processing step. The result from the prepare
- * step gets passed to all the filters again, this time with the 'process
- * callback' function. It's here where filters should perform actual changing of
- * the content: transforming URLs into hyperlinks, converting smileys into
- * images, etc.
- *
- * An important aspect of the filtering system is 'text formats'. Every text
- * format is an entire filter setup: which filters to enable, in what order
- * and with what settings.
- *
- * Filters that require settings should provide the form controls to configure
- * the settings in a form builder function, specified in 'settings callback'.
- * The filter system stores the settings in the database per text format.
- *
- * If the filter's behavior depends on an extensive list and/or external data
- * (e.g. a list of smileys, a list of glossary terms) then filters are allowed
- * to provide a separate, global configuration page rather than provide settings
- * per format. In that case, there should be a link from the format-specific
- * settings to the separate settings page.
- *
- * The $filter object with the current settings is passed to the 'settings
- * callback' function. If 'default settings' were defined in hook_filter_info(),
- * those are passed as second argument to the 'settings callback'. Each filter
- * should apply either the default settings or the configured settings contained
- * in $filter->settings.
- *
- * 'settings callback' is invoked with the following arguments (most filter
- * implementations will only need $form_state, $filter and $defaults):
- * - $form: The prepopulated form array, which will usually have no use here.
- * - &$form_state: The form state of the (entire) configuration form.
- * - $filter: The filter object containing settings for the given format.
- * - $format: The format object being configured.
- * - $defaults: The default settings for the filter, as defined in 'default
- * settings' in hook_filter_info().
- * - $filters: Complete list of filter objects that are enabled for the given
- * format.
- *
- * @code
- * function mymodule_filter_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
- * $settings['mymodule_url_length'] = array(
- * '#type' => 'textfield',
- * '#title' => t('Maximum link text length'),
- * '#default_value' => isset($filter->settings['mymodule_url_length']) ? $filter->settings['mymodule_url_length'] : $defaults['mymodule_url_length'],
- * );
- * return $settings;
- * }
- * @endcode
- *
- * 'prepare callback' and 'process callback' are invoked with the following
- * arguments:
- * - $text: The text to be filtered.
- * - $filter: The filter object containing settings for the given format.
- * - $format: The format object of the text to be filtered.
- * - $langcode: (optional) The language code of the text to be filtered.
- * - $cache: Boolean whether check_markup() will cache the filtered $text in
- * {cache_filter}.
- * - $cache_id: The cache ID used for $text in {cache_filter} when $cache is
- * TRUE.
- *
- * @see check_markup()
+ * HTML and change it. For many filters, the prepare step is not necessary.
*
- * 'prepare callback' and 'process callback' functions may access the filter
- * settings in $filter->settings['mymodule_url_length'].
- *
- * 'tips callback' is invoked with the following parameters:
- * - $filter: The filter object containing settings for the given format.
- * - $format: The format object of the text to be filtered.
- * - $long: Boolean whether to return long or short filter guidelines.
+ * The second step is the actual processing step. The result from passing the
+ * text through all the filters' prepare steps gets passed to all the filters
+ * again, this time with the 'process callback' function. The process callbacks
+ * should then actually change the content: transform URLs into hyperlinks,
+ * convert smileys into images, etc.
*
* For performance reasons content is only filtered once; the result is stored
* in the cache table and retrieved from the cache the next time the same piece
@@ -131,36 +46,37 @@
* caching for the entire format, not just for one filter.
*
* Beware of the filter cache when developing your module: it is advised to set
- * your filter to 'cache' => FALSE while developing, but be sure to remove it
- * again if it's not needed. You can clear the cache by running the SQL query
- * 'DELETE * FROM cache_filter';
+ * your filter to 'cache' => FALSE while developing, but be sure to remove that
+ * setting if it's not needed, when you are no longer in development mode.
*
* @return
- * An array of filter items. Each filter item has a unique name, prefixed
- * with the name of the module that provides it. The item is an associative
- * array that may contain the following key-value pairs:
- * - 'title': (required) The administrative title of the filter.
- * - 'description': A short, administrative description of what this filter
- * does.
- * - 'prepare callback': A callback function to call in the 'prepare' step
- * of the filtering.
- * - 'process callback': (required) The callback function to call in the
- * 'process' step of the filtering.
- * - 'settings callback': A callback function that provides form controls
- * for the filter's settings. Each filter should apply either the default
- * settings or the configured settings contained in $filter->settings. The
- * user submitted values are stored in the database.
- * - 'default settings': An array containing default settings for a filter to
- * be applied when the filter has not been configured yet.
- * - 'tips callback': A callback function that provides tips for using the
- * filter. A module's tips should be informative and to the point. Short
- * tips are preferably one-liners.
- * - 'cache': Specifies whether the filtered text can be cached. TRUE by
- * default. Note that defining FALSE makes the entire text format not
+ * An associative array of filters, whose keys are internal filter names,
+ * which should be unique and therefore prefixed with the name of the module.
+ * Each value is an associative array describing the filter, with the
+ * following elements (all are optional except as noted):
+ * - title: (required) An administrative summary of what the filter does.
+ * - description: Additional administrative information about the filter's
+ * behavior, if needed for clarification.
+ * - settings callback: The name of a function that returns configuration form
+ * elements for the filter. See hook_filter_FILTER_settings() for details.
+ * - default settings: An associative array containing default settings for
+ * the filter, to be applied when the filter has not been configured yet.
+ * - prepare callback: The name of a function that escapes the content before
+ * the actual filtering happens. See hook_filter_FILTER_prepare() for
+ * details.
+ * - process callback: (required) The name the function that performs the
+ * actual filtering. See hook_filter_FILTER_process() for details.
+ * - cache (default TRUE): Specifies whether the filtered text can be cached.
+ * Note that setting this to FALSE makes the entire text format not
* cacheable, which may have an impact on the site's overall performance.
+ * See filter_format_allowcache() for details.
+ * - tips callback: The name of a function that returns end-user-facing filter
+ * usage guidelines for the filter. See hook_filter_FILTER_tips() for
+ * details.
+ * - weight: A default weight for the filter in new text formats.
*
- * For a detailed usage example, see filter_example.module. For an example of
- * using multiple filters in one module, see filter_filter_info().
+ * @see filter_example.module
+ * @see hook_filter_info_alter()
*/
function hook_filter_info() {
$filters['filter_html'] = array(
@@ -203,6 +119,164 @@ function hook_filter_info_alter(&$info) {
}
/**
+ * @} End of "addtogroup hooks".
+ */
+
+/**
+ * Settings callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'settings callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from filter_admin_format_form().
+ *
+ * This callback function is used to provide a settings form for filter
+ * settings, for filters that need settings on a per-text-format basis. This
+ * function should return the form elements for the settings; the filter
+ * module will take care of saving the settings in the database.
+ *
+ * If the filter's behavior depends on an extensive list and/or external data
+ * (e.g. a list of smileys, a list of glossary terms), then the filter module
+ * can choose to provide a separate, global configuration page rather than
+ * per-text-format settings. In that case, the settings callback function
+ * should provide a link to the separate settings page.
+ *
+ * @param $form
+ * The prepopulated form array of the filter administration form.
+ * @param $form_state
+ * The state of the (entire) configuration form.
+ * @param $filter
+ * The filter object containing the current settings for the given format,
+ * in $filter->settings.
+ * @param $format
+ * The format object being configured.
+ * @param $defaults
+ * The default settings for the filter, as defined in 'default settings' in
+ * hook_filter_info(). These should be combined with $filter->settings to
+ * define the form element defaults.
+ * @param $filters
+ * The complete list of filter objects that are enabled for the given format.
+ *
+ * @return
+ * An array of form elements defining settings for the filter. Array keys
+ * should match the array keys in $filter->settings and $defaults.
+ */
+function hook_filter_FILTER_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
+ $filter->settings += $defaults;
+
+ $elements = array();
+ $elements['nofollow'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Add rel="nofollow" to all links'),
+ '#default_value' => $filter->settings['nofollow'],
+ );
+ return $elements;
+}
+
+/**
+ * Prepare callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'prepare callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from check_markup().
+ *
+ * See hook_filter_info() for a description of the filtering process. Filters
+ * should not use the 'prepare callback' step for anything other than escaping,
+ * because that would short-circuit the control the user has over the order in
+ * which filters are applied.
+ *
+ * @param $text
+ * The text string to be filtered.
+ * @param $filter
+ * The filter object containing settings for the given format.
+ * @param $format
+ * The text format object assigned to the text to be filtered.
+ * @param $langcode
+ * The language code of the text to be filtered.
+ * @param $cache
+ * A Boolean indicating whether the filtered text is going to be cached in
+ * {cache_filter}.
+ * @param $cache_id
+ * The ID of the filtered text in {cache_filter}, if $cache is TRUE.
+ *
+ * @return
+ * The prepared, escaped text.
+ */
+function hook_filter_FILTER_prepare($text, $filter, $format, $langcode, $cache, $cache_id) {
+ // Escape <code> and </code> tags.
+ $text = preg_replace('|<code>(.+?)</code>|se', "[codefilter_code]$1[/codefilter_code]", $text);
+ return $text;
+}
+
+/**
+ * Process callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'process callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from check_markup().
+ *
+ * See hook_filter_info() for a description of the filtering process. This step
+ * is where the filter actually transforms the text.
+ *
+ * @param $text
+ * The text string to be filtered.
+ * @param $filter
+ * The filter object containing settings for the given format.
+ * @param $format
+ * The text format object assigned to the text to be filtered.
+ * @param $langcode
+ * The language code of the text to be filtered.
+ * @param $cache
+ * A Boolean indicating whether the filtered text is going to be cached in
+ * {cache_filter}.
+ * @param $cache_id
+ * The ID of the filtered text in {cache_filter}, if $cache is TRUE.
+ *
+ * @return
+ * The filtered text.
+ */
+function hook_filter_FILTER_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+ $text = preg_replace('|\[codefilter_code\](.+?)\[/codefilter_code\]|se', "<pre>$1</pre>", $text);
+
+ return $text;
+}
+
+/**
+ * Tips callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'tips callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from _filter_tips().
+ *
+ * A filter's tips should be informative and to the point. Short tips are
+ * preferably one-liners.
+ *
+ * @param $filter
+ * An object representing the filter.
+ * @param $format
+ * An object representing the text format the filter is contained in.
+ * @param $long
+ * Whether this callback should return a short tip to display in a form
+ * (FALSE), or whether a more elaborate filter tips should be returned for
+ * theme_filter_tips() (TRUE).
+ *
+ * @return
+ * Translated text to display as a tip.
+ */
+function hook_filter_FILTER_tips($filter, $format, $long) {
+ if ($long) {
+ return t('Lines and paragraphs are automatically recognized. The &lt;br /&gt; line break, &lt;p&gt; paragraph and &lt;/p&gt; close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.');
+ }
+ else {
+ return t('Lines and paragraphs break automatically.');
+ }
+}
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
* Perform actions when a new text format has been created.
*
* @param $format
diff --git a/modules/filter/filter.module b/modules/filter/filter.module
index 7babfc65f..0c0867a12 100644
--- a/modules/filter/filter.module
+++ b/modules/filter/filter.module
@@ -1195,22 +1195,24 @@ function filter_filter_info() {
* Settings callback for the HTML filter.
*/
function _filter_html_settings($form, &$form_state, $filter, $format, $defaults) {
+ $filter->settings += $defaults;
+
$settings['allowed_html'] = array(
'#type' => 'textfield',
'#title' => t('Allowed HTML tags'),
- '#default_value' => isset($filter->settings['allowed_html']) ? $filter->settings['allowed_html'] : $defaults['allowed_html'],
+ '#default_value' => $filter->settings['allowed_html'],
'#maxlength' => 1024,
'#description' => t('A list of HTML tags that can be used. JavaScript event attributes, JavaScript URLs, and CSS are always stripped.'),
);
$settings['filter_html_help'] = array(
'#type' => 'checkbox',
'#title' => t('Display basic HTML help in long filter tips'),
- '#default_value' => isset($filter->settings['filter_html_help']) ? $filter->settings['filter_html_help'] : $defaults['filter_html_help'],
+ '#default_value' => $filter->settings['filter_html_help'],
);
$settings['filter_html_nofollow'] = array(
'#type' => 'checkbox',
'#title' => t('Add rel="nofollow" to all links'),
- '#default_value' => isset($filter->settings['filter_html_nofollow']) ? $filter->settings['filter_html_nofollow'] : $defaults['filter_html_nofollow'],
+ '#default_value' => $filter->settings['filter_html_nofollow'],
);
return $settings;
}
@@ -1336,10 +1338,12 @@ function _filter_html_tips($filter, $format, $long = FALSE) {
* Settings callback for URL filter.
*/
function _filter_url_settings($form, &$form_state, $filter, $format, $defaults) {
+ $filter->settings += $defaults;
+
$settings['filter_url_length'] = array(
'#type' => 'textfield',
'#title' => t('Maximum link text length'),
- '#default_value' => isset($filter->settings['filter_url_length']) ? $filter->settings['filter_url_length'] : $defaults['filter_url_length'],
+ '#default_value' => $filter->settings['filter_url_length'],
'#size' => 5,
'#maxlength' => 4,
'#field_suffix' => t('characters'),