2004-01-05 19:19:05 +00:00
<?php
// $Id$
2004-08-21 06:42:38 +00:00
/**
* @file
* Framework for handling filtering of content.
*/
2008-04-11 02:55:55 +00:00
/**
* Special format ID which means "use the default format".
*
* This value can be passed to the filter APIs as a format ID: this is
* equivalent to not passing an explicit format at all.
*/
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
define('FILTER_FORMAT_DEFAULT', 0);
2004-05-17 22:00:06 +00:00
/**
* Implementation of hook_help().
*/
2007-06-30 19:46:58 +00:00
function filter_help($path, $arg) {
switch ($path) {
2005-11-01 10:17:34 +00:00
case 'admin/help#filter':
2008-04-14 17:48:46 +00:00
$output = '<p>' . t("The filter module allows administrators to configure text input formats for use on your site. An input 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 input formats included by default are <em>Filtered HTML</em> (which allows only an administrator-approved subset of HTML tags) and <em>Full HTML</em> (which allows the full set of HTML tags). Additional input formats may be created by an administrator.") . '</p>';
$output .= '<p>' . t('Each input format uses filters to manipulate text, and most input 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.') . '</p>';
$output .= '<p>' . t('Users with access to more than one input format can use the <em>Input format</em> fieldset to choose between available input formats when creating or editing multi-line content. Administrators determine the input formats available to each user role, select a default input format, and control the order of formats listed in the <em>Input format</em> fieldset.') . '</p>';
$output .= '<p>' . t('For more information, see the online handbook entry for <a href="@filter">Filter module</a>.', array('@filter' => 'http://drupal.org/handbook/modules/filter/')) . '</p>';
2005-11-01 10:17:34 +00:00
return $output;
2006-07-31 11:25:55 +00:00
case 'admin/settings/filters':
2008-04-14 17:48:46 +00:00
$output = '<p>' . t('Use the list below to review the input formats available to each user role, to select a default input format, and to control the order of formats listed in the <em>Input format</em> fieldset. (The <em>Input format</em> fieldset is displayed below textareas when users with access to more than one input format create multi-line content.) The input format selected as <em>Default</em> is available to all users and, unless another format is selected, is applied to all content. All input formats are available to users in roles with the "administer filters" permission.') . '</p>';
$output .= '<p>' . t('Since input 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 input format, grab a drag-and-drop handle under the <em>Name</em> 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 <em>Save changes</em> button at the bottom of the page.') . '</p>';
2007-12-19 20:33:47 +00:00
return $output;
2007-06-30 19:46:58 +00:00
case 'admin/settings/filters/%':
2008-04-14 17:48:46 +00:00
return '<p>' . t('Every <em>filter</em> 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 input format. If you notice some filters are causing conflicts in the output, you can <a href="@rearrange">rearrange them</a>.', array('@rearrange' => url('admin/settings/filters/' . $arg[3] . '/order'))) . '</p>';
2007-06-30 19:46:58 +00:00
case 'admin/settings/filters/%/configure':
2008-05-02 15:15:32 +00:00
return '<p>' . t('If you cannot find the settings for a certain filter, make sure you have enabled it on the <a href="@url">edit tab</a> first.', array('@url' => url('admin/settings/filters/' . $arg[3]))) . '</p>';
2007-06-30 19:46:58 +00:00
case 'admin/settings/filters/%/order':
2008-04-14 17:48:46 +00:00
$output = '<p>' . t('Because of the flexible filtering system, you might encounter a situation where one filter prevents another from doing its job. For example: a word in an URL gets converted into a glossary term, before the URL can be converted to a clickable link. When this happens, rearrange the order of the filters.') . '</p>';
$output .= '<p>' . t("Filters are executed from top-to-bottom. To change the order of the filters, modify the values in the <em>Weight</em> column or grab a drag-and-drop handle under the <em>Name</em> column and drag filters to new locations 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 <em>Save configuration</em> button at the bottom of the page.") . '</p>';
2007-12-19 20:33:47 +00:00
return $output;
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
}
}
2007-04-06 13:27:23 +00:00
/**
2008-07-24 16:25:19 +00:00
* Implementation of hook_theme().
2007-04-06 13:27:23 +00:00
*/
function filter_theme() {
return array(
'filter_admin_overview' => array(
'arguments' => array('form' => NULL),
2007-09-14 12:17:58 +00:00
'file' => 'filter.admin.inc',
2007-04-06 13:27:23 +00:00
),
'filter_admin_order' => array(
'arguments' => array('form' => NULL),
2007-09-14 12:17:58 +00:00
'file' => 'filter.admin.inc',
2007-04-06 13:27:23 +00:00
),
'filter_tips' => array(
2008-12-03 19:43:21 +00:00
'arguments' => array('tips' => NULL, 'long' => FALSE),
2007-09-14 12:17:58 +00:00
'file' => 'filter.pages.inc',
2007-04-06 13:27:23 +00:00
),
'filter_tips_more_info' => array(
'arguments' => array(),
),
);
}
2006-03-04 18:12:10 +00:00
/**
* Implementation of hook_menu().
*/
2007-01-24 14:48:36 +00:00
function filter_menu() {
$items['admin/settings/filters'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'Input formats',
'description' => 'Configure how content input by users is filtered, including allowed HTML tags. Also allows enabling of module-provided filters.',
2007-01-24 14:48:36 +00:00
'page callback' => 'drupal_get_form',
'page arguments' => array('filter_admin_overview'),
'access arguments' => array('administer filters'),
);
$items['admin/settings/filters/list'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'List',
2007-01-24 14:48:36 +00:00
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/settings/filters/add'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'Add input format',
2007-09-17 09:16:48 +00:00
'page callback' => 'filter_admin_format_page',
2008-04-23 20:01:56 +00:00
'access arguments' => array('administer filters'),
2007-01-24 14:48:36 +00:00
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['admin/settings/filters/delete'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'Delete input format',
2007-01-24 14:48:36 +00:00
'page callback' => 'drupal_get_form',
'page arguments' => array('filter_admin_delete'),
2008-04-23 20:01:56 +00:00
'access arguments' => array('administer filters'),
2007-01-24 14:48:36 +00:00
'type' => MENU_CALLBACK,
);
$items['filter/tips'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'Compose tips',
2007-01-24 14:48:36 +00:00
'page callback' => 'filter_tips_long',
'access callback' => TRUE,
'type' => MENU_SUGGESTED_ITEM,
);
2007-02-11 09:30:51 +00:00
$items['admin/settings/filters/%filter_format'] = array(
2007-01-24 14:48:36 +00:00
'type' => MENU_CALLBACK,
2007-12-27 14:03:37 +00:00
'title callback' => 'filter_admin_format_title',
'title arguments' => array(3),
2007-09-17 09:16:48 +00:00
'page callback' => 'filter_admin_format_page',
'page arguments' => array(3),
2007-01-24 14:48:36 +00:00
'access arguments' => array('administer filters'),
);
2007-09-17 09:16:48 +00:00
$items['admin/settings/filters/%filter_format/edit'] = array(
'title' => 'Edit',
2007-01-24 14:48:36 +00:00
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
2007-02-11 09:30:51 +00:00
$items['admin/settings/filters/%filter_format/configure'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'Configure',
2007-09-17 09:16:48 +00:00
'page callback' => 'filter_admin_configure_page',
'page arguments' => array(3),
2008-04-23 20:01:56 +00:00
'access arguments' => array('administer filters'),
2007-01-24 14:48:36 +00:00
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
2007-02-11 09:30:51 +00:00
$items['admin/settings/filters/%filter_format/order'] = array(
2007-04-30 17:03:29 +00:00
'title' => 'Rearrange',
2007-09-17 09:16:48 +00:00
'page callback' => 'filter_admin_order_page',
'page arguments' => array(3),
2008-04-23 20:01:56 +00:00
'access arguments' => array('administer filters'),
2007-01-24 14:48:36 +00:00
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
2006-03-04 18:12:10 +00:00
return $items;
}
2007-02-11 09:30:51 +00:00
function filter_format_load($arg) {
return filter_formats($arg);
}
2007-12-27 14:03:37 +00:00
/**
* Display a filter format form title.
*/
function filter_admin_format_title($format) {
return $format->name;
}
2006-03-04 18:12:10 +00:00
/**
* Implementation of hook_perm().
*/
function filter_perm() {
2008-02-20 13:46:43 +00:00
return array(
2008-10-09 15:15:55 +00:00
'administer filters' => array(
'title' => t('Administer filters'),
'description' => t('Manage input 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.'))),
),
2008-02-20 13:46:43 +00:00
);
2006-03-04 18:12:10 +00:00
}
2006-08-30 08:46:17 +00:00
/**
* Implementation of hook_cron().
*
* Expire outdated filter cache entries
*/
function filter_cron() {
cache_clear_all(NULL, 'cache_filter');
}
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
/**
2004-08-10 21:25:39 +00:00
* Implementation of hook_filter_tips().
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
*/
2006-07-05 11:45:51 +00:00
function filter_filter_tips($delta, $format, $long = FALSE) {
2005-01-03 01:09:02 +00:00
global $base_url;
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
switch ($delta) {
case 0:
2008-08-31 17:19:06 +00:00
if ($allowed_html = variable_get("allowed_html_$format", '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>')) {
2008-04-11 02:55:55 +00:00
switch ($long) {
case 0:
return t('Allowed HTML tags: @tags', array('@tags' => $allowed_html));
case 1:
2008-04-14 17:48:46 +00:00
$output = '<p>' . t('Allowed HTML tags: @tags', array('@tags' => $allowed_html)) . '</p>';
2008-04-11 02:55:55 +00:00
if (!variable_get("filter_html_help_$format", 1)) {
return $output;
}
2008-04-14 17:48:46 +00:00
$output .= '<p>' . t('This site allows HTML content. While learning all of HTML may feel intimidating, learning how to use a very small number of the most basic HTML "tags" is very easy. This table provides examples for each tag that is enabled on this site.') . '</p>';
$output .= '<p>' . t('For more information see W3C\'s <a href="@html-specifications">HTML Specifications</a> or use your favorite search engine to find other sites that explain HTML.', array('@html-specifications' => 'http://www.w3.org/TR/html/')) . '</p>';
2008-04-11 02:55:55 +00:00
$tips = array(
2008-04-14 17:48:46 +00:00
'a' => array( t('Anchors are used to make links to other pages.'), '<a href="' . $base_url . '">' . variable_get('site_name', 'Drupal') . '</a>'),
2008-04-11 02:55:55 +00:00
'br' => array( t('By default line break tags are automatically added, so use this tag to add additional ones. Use of this tag is different because it is not used with an open/close pair like all the others. Use the extra " /" inside the tag to maintain XHTML 1.0 compatibility'), t('Text with <br />line break')),
2008-04-14 17:48:46 +00:00
'p' => array( t('By default paragraph tags are automatically added, so use this tag to add additional ones.'), '<p>' . t('Paragraph one.') . '</p> <p>' . t('Paragraph two.') . '</p>'),
'strong' => array( t('Strong'), '<strong>' . t('Strong') . '</strong>'),
'em' => array( t('Emphasized'), '<em>' . t('Emphasized') . '</em>'),
'cite' => array( t('Cited'), '<cite>' . t('Cited') . '</cite>'),
'code' => array( t('Coded text used to show programming source code'), '<code>' . t('Coded') . '</code>'),
'b' => array( t('Bolded'), '<b>' . t('Bolded') . '</b>'),
'u' => array( t('Underlined'), '<u>' . t('Underlined') . '</u>'),
'i' => array( t('Italicized'), '<i>' . t('Italicized') . '</i>'),
2008-04-11 02:55:55 +00:00
'sup' => array( t('Superscripted'), t('<sup>Super</sup>scripted')),
'sub' => array( t('Subscripted'), t('<sub>Sub</sub>scripted')),
2008-04-14 17:48:46 +00:00
'pre' => array( t('Preformatted'), '<pre>' . t('Preformatted') . '</pre>'),
2008-04-11 02:55:55 +00:00
'abbr' => array( t('Abbreviation'), t('<abbr title="Abbreviation">Abbrev.</abbr>')),
'acronym' => array( t('Acronym'), t('<acronym title="Three-Letter Acronym">TLA</acronym>')),
2008-04-14 17:48:46 +00:00
'blockquote' => array( t('Block quoted'), '<blockquote>' . t('Block quoted') . '</blockquote>'),
'q' => array( t('Quoted inline'), '<q>' . t('Quoted inline') . '</q>'),
2008-04-11 02:55:55 +00:00
// Assumes and describes tr, td, th.
2008-04-14 17:48:46 +00:00
'table' => array( t('Table'), '<table> <tr><th>' . t('Table header') . '</th></tr> <tr><td>' . t('Table cell') . '</td></tr> </table>'),
2008-04-11 02:55:55 +00:00
'tr' => NULL, 'td' => NULL, 'th' => NULL,
2008-04-14 17:48:46 +00:00
'del' => array( t('Deleted'), '<del>' . t('Deleted') . '</del>'),
'ins' => array( t('Inserted'), '<ins>' . t('Inserted') . '</ins>'),
2008-04-11 02:55:55 +00:00
// Assumes and describes li.
2008-04-14 17:48:46 +00:00
'ol' => array( t('Ordered list - use the <li> to begin each list item'), '<ol> <li>' . t('First item') . '</li> <li>' . t('Second item') . '</li> </ol>'),
'ul' => array( t('Unordered list - use the <li> to begin each list item'), '<ul> <li>' . t('First item') . '</li> <li>' . t('Second item') . '</li> </ul>'),
2008-04-11 02:55:55 +00:00
'li' => NULL,
// Assumes and describes dt and dd.
2008-04-14 17:48:46 +00:00
'dl' => array( t('Definition lists are similar to other HTML lists. <dl> begins the definition list, <dt> begins the definition term and <dd> begins the definition description.'), '<dl> <dt>' . t('First term') . '</dt> <dd>' . t('First definition') . '</dd> <dt>' . t('Second term') . '</dt> <dd>' . t('Second definition') . '</dd> </dl>'),
2008-04-11 02:55:55 +00:00
'dt' => NULL, 'dd' => NULL,
2008-05-02 17:28:09 +00:00
'h1' => array( t('Heading'), '<h1>' . t('Title') . '</h1>'),
'h2' => array( t('Heading'), '<h2>' . t('Subtitle') . '</h2>'),
'h3' => array( t('Heading'), '<h3>' . t('Subtitle three') . '</h3>'),
'h4' => array( t('Heading'), '<h4>' . t('Subtitle four') . '</h4>'),
'h5' => array( t('Heading'), '<h5>' . t('Subtitle five') . '</h5>'),
'h6' => array( t('Heading'), '<h6>' . t('Subtitle six') . '</h6>')
2008-04-11 02:55:55 +00:00
);
$header = array(t('Tag Description'), t('You Type'), t('You Get'));
preg_match_all('/<([a-z0-9]+)[^a-z0-9]/i', $allowed_html, $out);
foreach ($out[1] as $tag) {
if (array_key_exists($tag, $tips)) {
if ($tips[$tag]) {
2005-11-29 20:17:10 +00:00
$rows[] = array(
2008-04-11 02:55:55 +00:00
array('data' => $tips[$tag][0], 'class' => 'description'),
2008-04-14 17:48:46 +00:00
array('data' => '<code>' . check_plain($tips[$tag][1]) . '</code>', 'class' => 'type'),
2008-04-11 02:55:55 +00:00
array('data' => $tips[$tag][1], 'class' => 'get')
2005-11-29 20:17:10 +00:00
);
}
}
2008-04-11 02:55:55 +00:00
else {
2005-11-29 20:17:10 +00:00
$rows[] = array(
2008-04-11 02:55:55 +00:00
array('data' => t('No help provided for tag %tag.', array('%tag' => $tag)), 'class' => 'description', 'colspan' => 3),
2005-01-03 01:09:02 +00:00
);
2005-11-29 20:17:10 +00:00
}
2008-04-11 02:55:55 +00:00
}
$output .= theme('table', $header, $rows);
2008-04-14 17:48:46 +00:00
$output .= '<p>' . t('Most unusual characters can be directly entered without any problems.') . '</p>';
$output .= '<p>' . t('If you do encounter problems, try using HTML character entities. A common example looks like &amp; for an ampersand & character. For a full list of entities see HTML\'s <a href="@html-entities">entities</a> page. Some of the available characters include:', array('@html-entities' => 'http://www.w3.org/TR/html4/sgml/entities.html')) . '</p>';
2008-04-11 02:55:55 +00:00
$entities = array(
array( t('Ampersand'), '&'),
array( t('Greater than'), '>'),
array( t('Less than'), '<'),
array( t('Quotation mark'), '"'),
);
$header = array(t('Character Description'), t('You Type'), t('You Get'));
unset($rows);
foreach ($entities as $entity) {
$rows[] = array(
array('data' => $entity[0], 'class' => 'description'),
2008-04-14 17:48:46 +00:00
array('data' => '<code>' . check_plain($entity[1]) . '</code>', 'class' => 'type'),
2008-04-11 02:55:55 +00:00
array('data' => $entity[1], 'class' => 'get')
);
}
$output .= theme('table', $header, $rows);
return $output;
2005-11-29 20:17:10 +00:00
}
2004-01-27 22:10:47 +00:00
}
break;
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
case 1:
2005-01-03 01:09:02 +00:00
switch ($long) {
case 0:
return t('Lines and paragraphs break automatically.');
case 1:
return t('Lines and paragraphs are automatically recognized. The <br /> line break, <p> paragraph and </p> close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.');
}
2007-04-24 10:54:35 +00:00
break;
2008-04-11 02:55:55 +00:00
2007-04-24 10:54:35 +00:00
case 2:
2007-12-08 14:06:23 +00:00
return t('Web page addresses and e-mail addresses turn into links automatically.');
2008-04-11 02:55:55 +00:00
break;
case 4:
return t('No HTML tags allowed');
break;
2004-01-05 19:19:05 +00:00
}
}
2004-05-17 22:00:06 +00:00
/**
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
* Retrieve a list of input formats.
2004-05-17 22:00:06 +00:00
*/
2007-01-24 14:48:36 +00:00
function filter_formats($index = NULL) {
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
global $user;
static $formats;
// Administrators can always use all input formats.
$all = user_access('administer filters');
if (!isset($formats)) {
$formats = array();
2008-12-03 16:32:22 +00:00
$query = db_select('filter_format', 'f');
2008-08-21 19:36:39 +00:00
$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');
2004-01-05 19:19:05 +00:00
2004-08-10 21:25:39 +00:00
// Build query for selecting the format(s) based on the user's roles.
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
if (!$all) {
2008-08-21 19:36:39 +00:00
$or = db_or()->condition('format', variable_get('filter_default_format', 1));
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
foreach ($user->roles as $rid => $role) {
2008-08-21 19:36:39 +00:00
$or->condition('roles', '%'. (int)$rid .'%', 'LIKE');
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
}
2008-08-21 19:36:39 +00:00
$query->condition($or);
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
}
2008-08-21 19:36:39 +00:00
$formats = $query->execute()->fetchAllAssoc('format');
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
}
2007-01-24 14:48:36 +00:00
if (isset($index)) {
return isset($formats[$index]) ? $formats[$index] : FALSE;
}
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
return $formats;
}
2004-01-05 19:19:05 +00:00
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
/**
* Build a list of all filters.
*/
function filter_list_all() {
$filters = array();
2008-11-15 11:45:04 +00:00
foreach (module_implements('filter') as $module) {
$function = $module . '_filter';
$list = $function('list');
2005-12-14 20:10:45 +00:00
if (isset($list) && is_array($list)) {
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
foreach ($list as $delta => $name) {
2008-04-14 17:48:46 +00:00
$filters[$module . '/' . $delta] = (object)array('module' => $module, 'delta' => $delta, 'name' => $name);
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
}
2004-02-06 19:07:56 +00:00
}
}
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
uasort($filters, '_filter_list_cmp');
return $filters;
}
/**
* Helper function for sorting the filter list by filter name.
*/
function _filter_list_cmp($a, $b) {
return strcmp($a->name, $b->name);
2004-02-06 19:07:56 +00:00
}
2006-04-03 23:59:48 +00:00
/**
* Resolve a format id, including the default format.
*/
function filter_resolve_format($format) {
return $format == FILTER_FORMAT_DEFAULT ? variable_get('filter_default_format', 1) : $format;
}
2004-05-17 22:00:06 +00:00
/**
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
* Check if text in a certain input format is allowed to be cached.
2004-05-17 22:00:06 +00:00
*/
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
function filter_format_allowcache($format) {
static $cache = array();
2006-04-03 23:59:48 +00:00
$format = filter_resolve_format($format);
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
if (!isset($cache[$format])) {
2008-12-03 16:32:22 +00:00
$cache[$format] = db_result(db_query('SELECT cache FROM {filter_format} WHERE format = %d', $format));
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
}
return $cache[$format];
}
/**
* Retrieve a list of filters for a certain format.
*/
function filter_list_format($format) {
static $filters = array();
2006-02-23 04:01:14 +00:00
if (!isset($filters[$format])) {
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
$filters[$format] = array();
2008-12-03 16:32:22 +00:00
$result = db_query("SELECT * FROM {filter} WHERE format = %d ORDER BY weight, module, delta", $format);
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
while ($filter = db_fetch_object($result)) {
$list = module_invoke($filter->module, 'filter', 'list');
2005-12-14 20:10:45 +00:00
if (isset($list) && is_array($list) && isset($list[$filter->delta])) {
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
$filter->name = $list[$filter->delta];
2008-04-14 17:48:46 +00:00
$filters[$format][$filter->module . '/' . $filter->delta] = $filter;
2004-02-06 19:07:56 +00:00
}
}
}
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
return $filters[$format];
2004-01-05 19:19:05 +00:00
}
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
/**
* @name Filtering functions
2004-09-09 05:51:08 +00:00
* @{
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
* Modules which need to have content filtered can use these functions to
* interact with the filter system.
2005-06-29 19:53:14 +00:00
*
* For more info, see the hook_filter() documentation.
*
* Note: because filters can inject JavaScript or execute PHP code, security is
* vital here. When a user supplies a $format, you should validate it with
* filter_access($format) before accepting/using it. This is normally done in
* the validation stage of the node system. You should for example never make a
* preview of content in a disallowed format.
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
*/
2004-05-17 22:00:06 +00:00
/**
* Run all the enabled filters on a piece of text.
2005-06-29 19:53:14 +00:00
*
* @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.
2008-11-08 20:43:54 +00:00
* @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
* text replacement can be implemented.
2005-06-29 19:53:14 +00:00
* @param $check
* Whether to check the $format with filter_access() first. Defaults to TRUE.
* Note that this will check the permissions of the current user, so you
2006-05-07 00:08:36 +00:00
* should specify $check = FALSE when viewing other people's content. When
2005-06-29 19:53:14 +00:00
* showing content that is not (yet) stored in the database (eg. upon preview),
* set to TRUE so the user's permissions are checked.
2004-05-17 22:00:06 +00:00
*/
2008-11-08 20:43:54 +00:00
function check_markup($text, $format = FILTER_FORMAT_DEFAULT, $langcode = '', $check = TRUE) {
2006-07-05 11:45:51 +00:00
// When $check = TRUE, do an access check on $format.
2005-06-29 19:53:14 +00:00
if (isset($text) && (!$check || filter_access($format))) {
2006-04-03 23:59:48 +00:00
$format = filter_resolve_format($format);
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
2004-08-10 21:25:39 +00:00
// Check for a cached version of this piece of text.
2008-11-08 20:43:54 +00:00
$cache_id = $format . ':' . $langcode . ':' . md5($text);
2007-12-20 21:55:57 +00:00
if ($cached = cache_get($cache_id, 'cache_filter')) {
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
return $cached->data;
}
2004-08-10 21:25:39 +00:00
// See if caching is allowed for this format.
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
$cache = filter_format_allowcache($format);
2004-06-15 18:02:52 +00:00
// Convert all Windows and Mac newlines to a single newline,
2004-08-10 21:25:39 +00:00
// so filters only need to deal with one possibility.
2004-06-15 18:02:52 +00:00
$text = str_replace(array("\r\n", "\r"), "\n", $text);
2004-08-10 21:25:39 +00:00
// Get a complete list of filters, ordered properly.
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
$filters = filter_list_format($format);
2004-02-06 19:07:56 +00:00
2004-05-17 22:00:06 +00:00
// Give filters the chance to escape HTML-like data such as code or formulas.
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
foreach ($filters as $filter) {
2008-11-08 20:43:54 +00:00
$text = module_invoke($filter->module, 'filter', 'prepare', $filter->delta, $format, $text, $langcode, $cache_id);
2004-02-06 19:07:56 +00:00
}
2004-01-05 19:19:05 +00:00
2004-08-10 21:25:39 +00:00
// Perform filtering.
The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.
Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.
The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.
2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.
3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.
4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.
5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.
Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.
6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.
7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.
8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
2004-08-10 18:34:29 +00:00
foreach ($filters as $filter) {
2008-11-08 20:43:54 +00:00
$text = module_invoke($filter->module, 'filter', 'process', $filter->delta, $format, $text, $langcode, $cache_id);
2004-01-05 19:19:05 +00:00
}
2004-09-15 20:34:35 +00:00
// Store in cache with a minimum expiration time of 1 day.
2005-08-14 17:50:35 +00:00
if ($cache) {
2008-09-17 07:11:59 +00:00
cache_set($cache_id, $text, 'cache_filter', REQUEST_TIME + (60 * 60 * 24));
2005-08-14 17:50:35 +00:00
}
}
else {
2006-07-29 17:56:41 +00:00
$text = t('n/a');
2005-08-14 17:50:35 +00:00
}
return $text;
}
/**
* Generate a selector for choosing a format in a form.
*
2007-09-14 12:17:58 +00:00
* @ingroup forms
2008-01-08 10:35:43 +00:00
* @see filter_form_validate()
2005-08-14 17:50:35 +00:00
* @param $value
* The ID of the format that is currently selected.
2006-03-04 17:51:34 +00:00
* @param $weight
* The weight of the input format.
* @param $parents
* Required when defining multiple input formats on a single node or having a different parent than 'format'.
2005-08-14 17:50:35 +00:00
* @return
* HTML for the form element.
*/
- Patch #45530 by Morbus: filter_form shouldn't default to #weight 0
When a form element doesn't specify a #weight, it is assumed internally as #weight 0. However, to ensure that our form elements display visually *as they were defined in the array* we, in form_builder, count the number of elements, divide by 1000, and set that as the weight:
# Assign a decimal placeholder weight to preserve original array order
if (!isset($form[$key]['#weight'])) {
$form[$key]['#weight'] = $count/1000;
}
The above code will set the #weights of elements that have not defined a weight to something like 0 (first element in array definition), 0.001, 0.002, and so on. However, anytime a form element *explicitly* defines a #weight of 0, that #weight is kept at exactly 0, which would cause that form element to appear BEFORE the elements that didn't have a #weight defined (and thus received a #weight such as 0.002).
Consider the following pseudo example:
$form['game_title'] = array(
'#type' => 'textfield',
...
);
$form['game_description'] = array(
'#type' => 'textarea',
...
);
$form['game_format'] = filter_form(variable_get('game_format', NULL));
return $form;
Here, we're not definiing weights on our two textfields. We then add an filter_form. The second parameter of the filter_form is $weight, which defaults to 0. After this $form hits form_builder, we have weights 0 (game_title), 0.001 (game_description), and 0 (filter_form) respectively. This is then sorted by weight, which causes filter_form (the third element in the array) to appear BEFORE game_description (0 is lighter than 0.001).
The short lesson is: explicitly defining #weight 0 for a form element is probably a bad idea. This patch changes the default #weight of filter_form to NULL, instead of 0, and also removes any other explicit setting of #weight to 0 in core.
2006-01-20 09:04:34 +00:00
function filter_form($value = FILTER_FORMAT_DEFAULT, $weight = NULL, $parents = array('format')) {
2006-04-04 00:32:52 +00:00
$value = filter_resolve_format($value);
2005-08-14 17:50:35 +00:00
$formats = filter_formats();
2006-10-04 06:13:33 +00:00
$extra = theme('filter_tips_more_info');
2005-08-14 17:50:35 +00:00
if (count($formats) > 1) {
2005-12-14 13:56:54 +00:00
$form = array(
2005-12-05 09:11:33 +00:00
'#type' => 'fieldset',
'#title' => t('Input format'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => $weight,
2007-05-14 13:43:38 +00:00
'#element_validate' => array('filter_form_validate'),
2005-12-05 09:11:33 +00:00
);
2005-08-14 17:50:35 +00:00
// Multiple formats available: display radio buttons with tips.
foreach ($formats as $format) {
2007-09-11 17:23:58 +00:00
// Generate the parents as the autogenerator does, so we will have a
// unique id for each radio button.
$parents_for_id = array_merge($parents, array($format->format));
2005-12-14 13:56:54 +00:00
$form[$format->format] = array(
2005-12-05 09:11:33 +00:00
'#type' => 'radio',
2005-12-03 09:44:50 +00:00
'#title' => $format->name,
'#default_value' => $value,
'#return_value' => $format->format,
2005-12-14 13:56:54 +00:00
'#parents' => $parents,
2006-07-05 11:45:51 +00:00
'#description' => theme('filter_tips', _filter_tips($format->format, FALSE)),
2008-04-14 17:48:46 +00:00
'#id' => form_clean_id('edit-' . implode('-', $parents_for_id)),
2005-12-03 09:44:50 +00:00
);
2005-08-14 17:50:35 +00:00
}
}
else {
// Only one format available: use a hidden form item and only show tips.
$format = array_shift($formats);
2006-04-03 23:59:48 +00:00
$form[$format->format] = array('#type' => 'value', '#value' => $format->format, '#parents' => $parents);
2006-07-05 11:45:51 +00:00
$tips = _filter_tips(variable_get('filter_default_format', 1), FALSE);
2005-12-10 19:35:13 +00:00
$form['format']['guidelines'] = array(
2005-12-05 09:11:33 +00:00
'#title' => t('Formatting guidelines'),
2008-12-03 19:43:21 +00:00
'#markup' => theme('filter_tips', $tips, FALSE),
2005-12-05 09:11:33 +00:00
);
2005-08-14 17:50:35 +00:00
}
2008-07-16 21:59:29 +00:00
$form[] = array('#markup' => $extra);
2005-12-05 09:11:33 +00:00
return $form;
2005-08-14 17:50:35 +00:00
}
2006-03-05 02:46:55 +00:00
function filter_form_validate($form) {
foreach (element_children($form) as $key) {
if ($form[$key]['#value'] == $form[$key]['#return_value']) {
return;
}
}
form_error($form, t('An illegal choice has been detected. Please contact the site administrator.'));
2007-04-24 13:53:15 +00:00
watchdog('form', 'Illegal choice %choice in %name element.', array('%choice' => $form[$key]['#value'], '%name' => empty($form['#title']) ? $form['#parents'][0] : $form['#title']), WATCHDOG_ERROR);
2006-03-05 02:46:55 +00:00
}
2005-08-14 17:50:35 +00:00
/**
2006-07-05 11:45:51 +00:00
* Returns TRUE if the user is allowed to access this format.
2005-08-14 17:50:35 +00:00
*/
function filter_access($format) {
2006-04-03 23:59:48 +00:00
$format = filter_resolve_format($format);
if (user_access('administer filters') || ($format == variable_get('filter_default_format', 1))) {
2006-07-05 11:45:51 +00:00
return TRUE;
2005-08-14 17:50:35 +00:00
}
else {
$formats = filter_formats();
return isset($formats[$format]);
}
}
2007-01-24 14:48:36 +00:00
2005-08-14 17:50:35 +00:00
/**
* @} End of "Filtering functions".
*/
/**
* Helper function for fetching filter tips.
*/
2006-07-05 11:45:51 +00:00
function _filter_tips($format, $long = FALSE) {
2005-08-14 17:50:35 +00:00
if ($format == -1) {
$formats = filter_formats();
}
else {
2008-12-03 16:32:22 +00:00
$formats = array(db_fetch_object(db_query("SELECT * FROM {filter_format} WHERE format = %d", $format)));
2005-08-14 17:50:35 +00:00
}
$tips = array();
foreach ($formats as $format) {
$filters = filter_list_format($format->format);
$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);
}
}
}
return $tips;
}
2006-10-04 06:13:33 +00:00
/**
* Format a link to the more extensive filter tips.
*
* @ingroup themeable
*/
function theme_filter_tips_more_info() {
2008-04-14 17:48:46 +00:00
return '<p>' . l(t('More information about formatting options'), 'filter/tips') . '</p>';
2006-10-04 06:13:33 +00:00
}
2005-08-14 17:50:35 +00:00
/**
* @name Standard filters
* @{
* Filters implemented by the filter.module.
*/
/**
* Implementation of hook_filter(). Contains a basic set of essential filters.
* - HTML filter:
* Validates user-supplied HTML, transforming it as necessary.
* - Line break converter:
* Converts newlines into paragraph and break tags.
2007-04-24 10:54:35 +00:00
* - URL and e-mail address filter:
* Converts newlines into paragraph and break tags.
2005-08-14 17:50:35 +00:00
*/
function filter_filter($op, $delta = 0, $format = -1, $text = '') {
switch ($op) {
case 'list':
2008-04-11 02:55:55 +00:00
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'));
2005-08-14 17:50:35 +00:00
case 'description':
switch ($delta) {
case 0:
2008-04-11 02:55:55 +00:00
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.');
2005-08-14 17:50:35 +00:00
case 1:
2008-04-11 02:55:55 +00:00
return t('Converts line breaks into HTML (i.e. <br> and <p>) tags.');
2007-04-24 10:54:35 +00:00
case 2:
2006-08-31 02:23:55 +00:00
return t('Turns web and e-mail addresses into clickable links.');
2007-05-20 16:44:35 +00:00
case 3:
return t('Corrects faulty and chopped off HTML in postings.');
2008-04-11 02:55:55 +00:00
case 4:
return t('Escapes all HTML tags, so they will be visible instead of being effective.');
2005-08-14 17:50:35 +00:00
default:
return;
}
case 'process':
switch ($delta) {
case 0:
return _filter_html($text, $format);
case 1:
return _filter_autop($text);
2007-04-24 10:54:35 +00:00
case 2:
2006-08-31 02:23:55 +00:00
return _filter_url($text, $format);
2007-05-20 16:44:35 +00:00
case 3:
return _filter_htmlcorrector($text);
2008-04-11 02:55:55 +00:00
case 4:
return trim(check_plain($text));
2005-08-14 17:50:35 +00:00
default:
return $text;
}
case 'settings':
switch ($delta) {
case 0:
return _filter_html_settings($format);
2007-04-24 10:54:35 +00:00
case 2:
2006-08-31 02:23:55 +00:00
return _filter_url_settings($format);
2005-08-14 17:50:35 +00:00
default:
return;
}
default:
return $text;
}
}
/**
* Settings for the HTML filter.
*/
function _filter_html_settings($format) {
2006-12-11 17:13:45 +00:00
$form['filter_html'] = array(
'#type' => 'fieldset',
'#title' => t('HTML filter'),
'#collapsible' => TRUE,
);
$form['filter_html']["allowed_html_$format"] = array(
'#type' => 'textfield',
'#title' => t('Allowed HTML tags'),
2008-08-31 17:19:06 +00:00
'#default_value' => variable_get("allowed_html_$format", '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>'),
2006-12-11 17:13:45 +00:00
'#size' => 64,
2008-08-11 18:01:51 +00:00
'#maxlength' => 1024,
2008-05-02 15:15:32 +00:00
'#description' => t('Specify a list of tags which should not be stripped. (Note that JavaScript event attributes are always stripped.)'),
2006-12-11 17:13:45 +00:00
);
$form['filter_html']["filter_html_help_$format"] = array(
'#type' => 'checkbox',
'#title' => t('Display HTML help'),
'#default_value' => variable_get("filter_html_help_$format", 1),
'#description' => t('If enabled, Drupal will display some basic HTML help in the long filter tips.'),
);
$form['filter_html']["filter_html_nofollow_$format"] = array(
'#type' => 'checkbox',
'#title' => t('Spam link deterrent'),
'#default_value' => variable_get("filter_html_nofollow_$format", FALSE),
'#description' => t('If enabled, Drupal will add rel="nofollow" to all links, as a measure to reduce the effectiveness of spam links. Note: this will also prevent valid links from being followed by search engines, therefore it is likely most effective when enabled for anonymous users.'),
);
2005-10-07 06:11:12 +00:00
return $form;
2005-08-14 17:50:35 +00:00
}
/**
* HTML filter. Provides filtering of input into accepted HTML.
*/
function _filter_html($text, $format) {
2008-08-31 17:19:06 +00:00
$allowed_tags = preg_split('/\s+|<|>/', variable_get("allowed_html_$format", '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>'), -1, PREG_SPLIT_NO_EMPTY);
2008-04-11 02:55:55 +00:00
$text = filter_xss($text, $allowed_tags);
2005-08-14 17:50:35 +00:00
if (variable_get("filter_html_nofollow_$format", FALSE)) {
$text = preg_replace('/<a([^>]+)>/i', '<a\\1 rel="nofollow">', $text);
}
return trim($text);
}
2006-08-31 02:23:55 +00:00
/**
* Settings for URL filter.
*/
function _filter_url_settings($format) {
$form['filter_urlfilter'] = array(
'#type' => 'fieldset',
'#title' => t('URL filter'),
'#collapsible' => TRUE,
);
2008-04-14 17:48:46 +00:00
$form['filter_urlfilter']['filter_url_length_' . $format] = array(
2006-08-31 02:23:55 +00:00
'#type' => 'textfield',
'#title' => t('Maximum link text length'),
2008-04-14 17:48:46 +00:00
'#default_value' => variable_get('filter_url_length_' . $format, 72),
2006-08-31 02:23:55 +00:00
'#maxlength' => 4,
2006-11-26 23:01:42 +00:00
'#description' => t('URLs longer than this number of characters will be truncated to prevent long strings that break formatting. The link itself will be retained; just the text portion of the link will be truncated.'),
2006-08-31 02:23:55 +00:00
);
return $form;
}
/**
* URL filter. Automatically converts text web addresses (URLs, e-mail addresses,
* ftp links, etc.) into hyperlinks.
*/
function _filter_url($text, $format) {
// Pass length to regexp callback
2008-04-14 17:48:46 +00:00
_filter_url_trim(NULL, variable_get('filter_url_length_' . $format, 72));
2006-08-31 02:23:55 +00:00
2008-04-14 17:48:46 +00:00
$text = ' ' . $text . ' ';
2006-08-31 02:23:55 +00:00
// Match absolute URLs.
2007-01-12 07:27:21 +00:00
$text = preg_replace_callback("`(<p>|<li>|<br\s*/?>|[ \n\r\t\(])((http://|https://|ftp://|mailto:|smb://|afp://|file://|gopher://|news://|ssl://|sslv2://|sslv3://|tls://|tcp://|udp://)([a-zA-Z0-9@:%_+*~#?&=.,/;-]*[a-zA-Z0-9@:%_+*~#&=/;-]))([.,?!]*?)(?=(</p>|</li>|<br\s*/?>|[ \n\r\t\)]))`i", '_filter_url_parse_full_links', $text);
2006-08-31 07:21:43 +00:00
2006-08-31 02:23:55 +00:00
// Match e-mail addresses.
2007-01-12 07:27:21 +00:00
$text = preg_replace("`(<p>|<li>|<br\s*/?>|[ \n\r\t\(])([A-Za-z0-9._-]+@[A-Za-z0-9._+-]+\.[A-Za-z]{2,4})([.,?!]*?)(?=(</p>|</li>|<br\s*/?>|[ \n\r\t\)]))`i", '\1<a href="mailto:\2">\2</a>\3', $text);
2006-08-31 02:23:55 +00:00
// Match www domains/addresses.
2007-01-12 07:27:21 +00:00
$text = preg_replace_callback("`(<p>|<li>|[ \n\r\t\(])(www\.[a-zA-Z0-9@:%_+*~#?&=.,/;-]*[a-zA-Z0-9@:%_+~#\&=/;-])([.,?!]*?)(?=(</p>|</li>|<br\s*/?>|[ \n\r\t\)]))`i", '_filter_url_parse_partial_links', $text);
2006-08-31 02:23:55 +00:00
$text = substr($text, 1, -1);
return $text;
}
2007-05-20 16:44:35 +00:00
/**
* Scan input and make sure that all HTML tags are properly closed and nested.
*/
function _filter_htmlcorrector($text) {
// Prepare tag lists.
static $no_nesting, $single_use;
if (!isset($no_nesting)) {
// Tags which cannot be nested but are typically left unclosed.
$no_nesting = drupal_map_assoc(array('li', 'p'));
// Single use tags in HTML4
$single_use = drupal_map_assoc(array('base', 'meta', 'link', 'hr', 'br', 'param', 'img', 'area', 'input', 'col', 'frame'));
}
// Properly entify angles.
$text = preg_replace('!<([^a-zA-Z/])!', '<\1', $text);
// Split tags from text.
$split = preg_split('/<([^>]+?)>/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
// Note: PHP ensures the array consists of alternating delimiters and literals
// and begins and ends with a literal (inserting $null as required).
2008-09-19 07:53:59 +00:00
$tag = FALSE; // Odd/even counter. Tag or no tag.
2007-05-20 16:44:35 +00:00
$stack = array();
$output = '';
foreach ($split as $value) {
// Process HTML tags.
if ($tag) {
list($tagname) = explode(' ', strtolower($value), 2);
// Closing tag
if ($tagname{0} == '/') {
$tagname = substr($tagname, 1);
// Discard XHTML closing tags for single use tags.
if (!isset($single_use[$tagname])) {
// See if we possibly have a matching opening tag on the stack.
if (in_array($tagname, $stack)) {
// Close other tags lingering first.
do {
2008-04-14 17:48:46 +00:00
$output .= '</' . $stack[0] . '>';
2007-05-20 16:44:35 +00:00
} while (array_shift($stack) != $tagname);
}
// Otherwise, discard it.
}
}
// Opening tag
else {
// See if we have an identical 'no nesting' tag already open and close it if found.
if (count($stack) && ($stack[0] == $tagname) && isset($no_nesting[$stack[0]])) {
2008-04-14 17:48:46 +00:00
$output .= '</' . array_shift($stack) . '>';
2007-05-20 16:44:35 +00:00
}
// Push non-single-use tags onto the stack
if (!isset($single_use[$tagname])) {
array_unshift($stack, $tagname);
}
// Add trailing slash to single-use tags as per X(HT)ML.
else {
2008-04-14 17:48:46 +00:00
$value = rtrim($value, ' /') . ' /';
2007-05-20 16:44:35 +00:00
}
2008-04-14 17:48:46 +00:00
$output .= '<' . $value . '>';
2007-05-20 16:44:35 +00:00
}
}
else {
// Passthrough all text.
$output .= $value;
}
$tag = !$tag;
}
// Close remaining tags.
while (count($stack) > 0) {
2008-04-14 17:48:46 +00:00
$output .= '</' . array_shift($stack) . '>';
2007-05-20 16:44:35 +00:00
}
return $output;
}
2006-08-31 02:23:55 +00:00
/**
2006-08-31 07:21:43 +00:00
* Make links out of absolute URLs.
2006-08-31 02:23:55 +00:00
*/
function _filter_url_parse_full_links($match) {
$match[2] = decode_entities($match[2]);
$caption = check_plain(_filter_url_trim($match[2]));
$match[2] = check_url($match[2]);
2008-04-14 17:48:46 +00:00
return $match[1] . '<a href="' . $match[2] . '" title="' . $match[2] . '">' . $caption . '</a>' . $match[5];
2006-08-31 02:23:55 +00:00
}
/**
* Make links out of domain names starting with "www."
*/
function _filter_url_parse_partial_links($match) {
$match[2] = decode_entities($match[2]);
$caption = check_plain(_filter_url_trim($match[2]));
$match[2] = check_plain($match[2]);
2008-04-14 17:48:46 +00:00
return $match[1] . '<a href="http://' . $match[2] . '" title="' . $match[2] . '">' . $caption . '</a>' . $match[3];
2006-08-31 02:23:55 +00:00
}
/**
* Shortens long URLs to http://www.example.com/long/url...
*/
function _filter_url_trim($text, $length = NULL) {
static $_length;
if ($length !== NULL) {
$_length = $length;
}
2007-09-06 12:40:47 +00:00
// Use +3 for '...' string length.
if (strlen($text) > $_length + 3) {
2008-04-14 17:48:46 +00:00
$text = substr($text, 0, $_length) . '...';
2006-08-31 02:23:55 +00:00
}
return $text;
}
2005-08-14 17:50:35 +00:00
/**
* Convert line breaks into <p> and <br> in an intelligent fashion.
* Based on: http://photomatt.net/scripts/autop
*/
function _filter_autop($text) {
2006-04-12 14:36:24 +00:00
// All block level tags
2008-01-21 15:08:24 +00:00
$block = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|p|h[1-6]|hr)';
2006-04-17 20:48:26 +00:00
2005-08-14 17:50:35 +00:00
// Split at <pre>, <script>, <style> and </pre>, </script>, </style> tags.
// We don't apply any processing to the contents of these tags to avoid messing
// up code. We look for matched pairs and allow basic nesting. For example:
// "processed <pre> ignored <script> ignored </script> ignored </pre> processed"
2007-09-28 08:09:25 +00:00
$chunks = preg_split('@(</?(?:pre|script|style|object)[^>]*>)@i', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
2005-08-14 17:50:35 +00:00
// Note: PHP ensures the array consists of alternating delimiters and literals
// and begins and ends with a literal (inserting NULL as required).
2006-07-05 11:45:51 +00:00
$ignore = FALSE;
2005-08-14 17:50:35 +00:00
$ignoretag = '';
$output = '';
foreach ($chunks as $i => $chunk) {
if ($i % 2) {
// Opening or closing tag?
2006-01-15 07:14:14 +00:00
$open = ($chunk[1] != '/');
2008-09-05 09:25:52 +00:00
list($tag) = preg_split('/[ >]/', substr($chunk, 2 - $open), 2);
2005-08-14 17:50:35 +00:00
if (!$ignore) {
if ($open) {
2006-07-05 11:45:51 +00:00
$ignore = TRUE;
2005-08-14 17:50:35 +00:00
$ignoretag = $tag;
}
}
// Only allow a matching tag to close it.
2008-10-12 04:30:09 +00:00
elseif (!$open && $ignoretag == $tag) {
2006-07-05 11:45:51 +00:00
$ignore = FALSE;
2005-08-14 17:50:35 +00:00
$ignoretag = '';
}
}
2008-10-12 04:30:09 +00:00
elseif (!$ignore) {
2008-04-14 17:48:46 +00:00
$chunk = preg_replace('|\n*$|', '', $chunk) . "\n\n"; // just to make things a little easier, pad the end
2005-08-14 17:50:35 +00:00
$chunk = preg_replace('|<br />\s*<br />|', "\n\n", $chunk);
2008-04-14 17:48:46 +00:00
$chunk = preg_replace('!(<' . $block . '[^>]*>)!', "\n$1", $chunk); // Space things out a little
$chunk = preg_replace('!(</' . $block . '>)!', "$1\n\n", $chunk); // Space things out a little
2005-08-14 17:50:35 +00:00
$chunk = preg_replace("/\n\n+/", "\n\n", $chunk); // take care of duplicates
$chunk = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $chunk); // make paragraphs, including one at the end
2007-06-01 09:39:10 +00:00
$chunk = preg_replace('|<p>\s*</p>\n|', '', $chunk); // under certain strange conditions it could create a P of entirely whitespace
2005-08-14 17:50:35 +00:00
$chunk = preg_replace("|<p>(<li.+?)</p>|", "$1", $chunk); // problem with nested lists
$chunk = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $chunk);
$chunk = str_replace('</blockquote></p>', '</p></blockquote>', $chunk);
2008-04-14 17:48:46 +00:00
$chunk = preg_replace('!<p>\s*(</?' . $block . '[^>]*>)!', "$1", $chunk);
$chunk = preg_replace('!(</?' . $block . '[^>]*>)\s*</p>!', "$1", $chunk);
2005-08-14 17:50:35 +00:00
$chunk = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $chunk); // make line breaks
2008-04-14 17:48:46 +00:00
$chunk = preg_replace('!(</?' . $block . '[^>]*>)\s*<br />!', "$1", $chunk);
2005-08-14 17:50:35 +00:00
$chunk = preg_replace('!<br />(\s*</?(?:p|li|div|th|pre|td|ul|ol)>)!', '$1', $chunk);
2005-12-31 04:01:38 +00:00
$chunk = preg_replace('/&([^#])(?![A-Za-z0-9]{1,8};)/', '&$1', $chunk);
2005-08-14 17:50:35 +00:00
}
$output .= $chunk;
}
return $output;
}
2006-04-07 15:32:17 +00:00
/**
* Very permissive XSS/HTML filter for admin-only use.
*
2006-04-17 20:48:26 +00:00
* Use only for fields where it is impractical to use the
2006-04-07 15:32:17 +00:00
* whole filter system, but where some (mainly inline) mark-up
* is desired (so check_plain() is not acceptable).
*
* Allows all tags that can be used inside an HTML body, save
2006-04-17 20:48:26 +00:00
* for scripts and styles.
2006-04-07 15:32:17 +00:00
*/
function filter_xss_admin($string) {
2008-08-25 07:44:16 +00:00
return filter_xss($string, array('a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'));
2006-04-07 15:32:17 +00:00
}
2005-11-29 20:17:10 +00:00
/**
* Filters XSS. Based on kses by Ulf Harnhammar, see
* http://sourceforge.net/projects/kses
*
* For examples of various XSS attacks, see:
* http://ha.ckers.org/xss.html
*
* This code does four things:
* - Removes characters and constructs that can trick browsers
* - Makes sure all HTML entities are well-formed
* - Makes sure all HTML tags and attributes are well-formed
* - Makes sure no HTML tags contain URLs with a disallowed protocol (e.g. javascript:)
*
* @param $string
* The string with raw HTML in it. It will be stripped of everything that can cause
* an XSS attack.
2005-11-30 15:31:23 +00:00
* @param $allowed_tags
* An array of allowed tags.
2005-11-29 20:17:10 +00:00
*/
2008-08-31 17:19:06 +00:00
function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd')) {
2008-01-10 22:47:17 +00:00
// Only operate on valid UTF-8 strings. This is necessary to prevent cross
// site scripting issues on Internet Explorer 6.
if (!drupal_validate_utf8($string)) {
return '';
}
2005-11-29 20:17:10 +00:00
// Store the input format
2005-11-30 15:31:23 +00:00
_filter_xss_split($allowed_tags, TRUE);
2005-11-29 20:17:10 +00:00
// Remove NUL characters (ignored by some browsers)
$string = str_replace(chr(0), '', $string);
// Remove Netscape 4 JS entities
$string = preg_replace('%&\s*\{[^}]*(\}\s*;?|$)%', '', $string);
// Defuse all HTML entities
$string = str_replace('&', '&', $string);
// Change back only well-formed entities in our whitelist
// Named entities
$string = preg_replace('/&([A-Za-z][A-Za-z0-9]*;)/', '&\1', $string);
// Decimal numeric entities
$string = preg_replace('/&#([0-9]+;)/', '&#\1', $string);
// Hexadecimal numeric entities
$string = preg_replace('/&#[Xx]0*((?:[0-9A-Fa-f]{2})+;)/', '&#x\1', $string);
return preg_replace_callback('%
(
2006-12-16 01:05:11 +00:00
<(?=[^a-zA-Z!/]) # a lone <
2006-12-07 16:34:59 +00:00
| # or
2008-08-14 11:58:06 +00:00
<[^>]*(>|$) # a string that starts with a <, up until the > or the end of the string
2006-12-07 16:34:59 +00:00
| # or
> # just a >
2005-11-30 00:12:23 +00:00
)%x', '_filter_xss_split', $string);
2005-11-29 20:17:10 +00:00
}
/**
* Processes an HTML tag.
*
2008-11-01 19:51:06 +00:00
* @param $m
2005-11-30 15:31:23 +00:00
* An array with various meaning depending on the value of $store.
* If $store is TRUE then the array contains the allowed tags.
* If $store is FALSE then the array has one element, the HTML tag to process.
* @param $store
* Whether to store $m.
2005-11-29 20:17:10 +00:00
* @return
2005-11-30 15:31:23 +00:00
* If the element isn't allowed, an empty string. Otherwise, the cleaned up
* version of the HTML element.
2005-11-29 20:17:10 +00:00
*/
2005-11-30 15:31:23 +00:00
function _filter_xss_split($m, $store = FALSE) {
2005-11-29 20:17:10 +00:00
static $allowed_html;
2005-11-30 15:31:23 +00:00
if ($store) {
$allowed_html = array_flip($m);
2005-11-29 20:17:10 +00:00
return;
}
2005-11-30 00:12:23 +00:00
$string = $m[1];
2005-11-29 20:17:10 +00:00
if (substr($string, 0, 1) != '<') {
// We matched a lone ">" character
return '>';
}
2008-10-12 04:30:09 +00:00
elseif (strlen($string) == 1) {
2006-12-07 16:34:59 +00:00
// We matched a lone "<" character
return '<';
}
2005-11-29 20:17:10 +00:00
if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches)) {
// Seriously malformed
return '';
}
$slash = trim($matches[1]);
$elem = &$matches[2];
$attrlist = &$matches[3];
if (!isset($allowed_html[strtolower($elem)])) {
// Disallowed HTML element
return '';
}
if ($slash != '') {
return "</$elem>";
}
2006-01-25 19:20:28 +00:00
2005-11-29 20:17:10 +00:00
// Is there a closing XHTML slash at the end of the attributes?
2008-11-01 19:51:06 +00:00
$attrlist = preg_replace('%(\s?)/\s*$%', '\1', $attrlist, -1, $count);
$xhtml_slash = $count ? ' /' : '';
2008-11-11 16:49:38 +00:00
2005-11-29 20:17:10 +00:00
// Clean up attributes
$attr2 = implode(' ', _filter_xss_attributes($attrlist));
$attr2 = preg_replace('/[<>]/', '', $attr2);
2008-04-14 17:48:46 +00:00
$attr2 = strlen($attr2) ? ' ' . $attr2 : '';
2005-11-29 20:17:10 +00:00
2005-12-28 18:43:42 +00:00
return "<$elem$attr2$xhtml_slash>";
2005-11-29 20:17:10 +00:00
}
/**
* Processes a string of HTML attributes.
*
* @return
* Cleaned up version of the HTML attributes.
*/
function _filter_xss_attributes($attr) {
$attrarr = array();
$mode = 0;
$attrname = '';
while (strlen($attr) != 0) {
// Was the last operation successful?
$working = 0;
switch ($mode) {
case 0:
// Attribute name, href for instance
if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) {
$attrname = strtolower($match[1]);
$skip = ($attrname == 'style' || substr($attrname, 0, 2) == 'on');
$working = $mode = 1;
$attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
}
break;
case 1:
// Equals sign or valueless ("selected")
if (preg_match('/^\s*=\s*/', $attr)) {
$working = 1; $mode = 2;
$attr = preg_replace('/^\s*=\s*/', '', $attr);
break;
}
if (preg_match('/^\s+/', $attr)) {
$working = 1; $mode = 0;
if (!$skip) {
$attrarr[] = $attrname;
}
$attr = preg_replace('/^\s+/', '', $attr);
}
break;
case 2:
// Attribute value, a URL after href= for instance
if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) {
$thisval = filter_xss_bad_protocol($match[1]);
if (!$skip) {
$attrarr[] = "$attrname=\"$thisval\"";
}
$working = 1;
$mode = 0;
$attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr);
break;
}
if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) {
$thisval = filter_xss_bad_protocol($match[1]);
if (!$skip) {
2008-10-14 20:44:57 +00:00
$attrarr[] = "$attrname='$thisval'";
2005-11-29 20:17:10 +00:00
}
$working = 1; $mode = 0;
$attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr);
break;
}
if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) {
$thisval = filter_xss_bad_protocol($match[1]);
if (!$skip) {
$attrarr[] = "$attrname=\"$thisval\"";
}
$working = 1; $mode = 0;
$attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr);
}
break;
}
if ($working == 0) {
// not well formed, remove and try again
$attr = preg_replace('/
^
(
"[^"]*("|$) # - a string that starts with a double quote, up until the next double quote or the end of the string
| # or
\'[^\']*(\'|$)| # - a string that starts with a quote, up until the next quote or the end of the string
| # or
\S # - a non-whitespace character
)* # any number of the above three
\s* # any number of whitespaces
/x', '', $attr);
$mode = 0;
}
}
// the attribute list ends with a valueless attribute like "selected"
if ($mode == 1) {
$attrarr[] = $attrname;
}
return $attrarr;
}
/**
* Processes an HTML attribute value and ensures it does not contain an URL
* with a disallowed protocol (e.g. javascript:)
*
* @param $string
* The string with the attribute value.
* @param $decode
* Whether to decode entities in the $string. Set to FALSE if the $string
* is in plain text, TRUE otherwise. Defaults to TRUE.
* @return
* Cleaned up and HTML-escaped version of $string.
*/
function filter_xss_bad_protocol($string, $decode = TRUE) {
2005-12-08 09:05:30 +00:00
static $allowed_protocols;
if (!isset($allowed_protocols)) {
2008-07-19 20:06:25 +00:00
$allowed_protocols = array_flip(variable_get('filter_allowed_protocols', array('ftp', 'http', 'https', 'irc', 'mailto', 'news', 'nntp', 'rtsp', 'sftp', 'ssh', 'telnet', 'webcal')));
2005-12-08 09:05:30 +00:00
}
2007-01-09 08:30:31 +00:00
// Get the plain text representation of the attribute value (i.e. its meaning).
2005-11-29 20:17:10 +00:00
if ($decode) {
$string = decode_entities($string);
}
2007-01-09 08:30:31 +00:00
// Iteratively remove any invalid protocol found.
2005-12-08 09:05:30 +00:00
2005-11-29 20:17:10 +00:00
do {
$before = $string;
2005-12-08 09:05:30 +00:00
$colonpos = strpos($string, ':');
if ($colonpos > 0) {
2007-01-09 08:30:31 +00:00
// We found a colon, possibly a protocol. Verify.
2005-12-08 09:05:30 +00:00
$protocol = substr($string, 0, $colonpos);
2007-01-09 08:30:31 +00:00
// If a colon is preceded by a slash, question mark or hash, it cannot
// possibly be part of the URL scheme. This must be a relative URL,
// which inherits the (safe) protocol of the base document.
if (preg_match('![/?#]!', $protocol)) {
break;
}
2007-03-12 01:34:28 +00:00
// Per RFC2616, section 3.2.3 (URI Comparison) scheme comparison must be case-insensitive
2007-01-09 08:30:31 +00:00
// Check if this is a disallowed protocol.
2007-03-12 01:34:28 +00:00
if (!isset($allowed_protocols[strtolower($protocol)])) {
2005-12-08 09:05:30 +00:00
$string = substr($string, $colonpos + 1);
}
}
2005-11-29 20:17:10 +00:00
} while ($before != $string);
return check_plain($string);
}
2005-08-14 17:50:35 +00:00
/**
* @} End of "Standard filters".
*/