From 2549e5068e795986601d10b77ab0f5bc57108eb1 Mon Sep 17 00:00:00 2001
From: Dries Buytaert and $1 \s*? ( ", $chunk);
+ $chunk = str_replace('
is not output?
+ $output .= '';
+ }
+ foreach ($tips as $name => $tiplist) {
+ if ($multiple) {
+ $output .= '
';
+ }
+ }
+
+ return $output;
+}
+
+/**
+ * @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.
+ * - PHP evaluator:
+ * Executes PHP code.
+ * - Line break converter:
+ * Converts newlines into paragraph and break tags.
+ */
+function filter_filter($op, $delta = 0, $format = -1, $text = '') {
+ switch ($op) {
+ case 'list':
+ return array(0 => t('HTML filter'), 1 => t('PHP evaluator'), 2 => t('Line break converter'));
+
+ case 'no cache':
+ return $delta == 1; // No caching for the PHP evaluator.
+
+ case 'description':
+ switch ($delta) {
+ case 0:
+ return t('Allows you to restrict if users can post HTML and which tags to filter out.');
+ case 1:
+ return t('Runs a piece of PHP code. The usage of this filter should be restricted to administrators only!');
+ case 2:
+ return t('Converts line breaks into HTML (i.e. <br> and <p> tags).');
+ default:
+ return;
+ }
+
+ case 'process':
+ switch ($delta) {
+ case 0:
+ return _filter_html($text, $format);
+ case 1:
+ return drupal_eval($text);
+ case 2:
+ return _filter_autop($text);
+ default:
+ return $text;
+ }
+
+ case 'settings':
+ switch ($delta) {
+ case 0:
+ return _filter_html_settings($format);
+ default:
+ return;
+ }
+
+ default:
+ return $text;
+ }
+}
+
+/**
+ * Settings for the HTML filter.
+ */
+function _filter_html_settings($format) {
+ $group = form_radios(t('Filter HTML tags'), "filter_html_$format", variable_get("filter_html_$format", FILTER_HTML_STRIP), array(FILTER_HTML_STRIP => t('Strip tags'), FILTER_HTML_ESCAPE => t('Escape tags')), t('How to deal with HTML tags in user-contributed content. If set to "Strip tags", dangerous tags are removed (see below). If set to "Escape tags", all HTML is escaped and presented as it was typed.'));
+ $group .= form_textfield(t('Allowed HTML tags'), "allowed_html_$format", variable_get("allowed_html_$format", '
';
+ }
+
+ $tips = '';
+ foreach ($tiplist as $tip) {
+ $tips .= '$tips
";
+ }
+
+ if ($multiple) {
+ $output .= '';
+ }
+ }
+ if ($multiple) {
+ $output .= '
in an intelligent fashion.
+ * Based on: http://photomatt.net/scripts/autop
+ */
+function _filter_autop($text) {
+ // Split at , , 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
ignored ignored
processed"
+ $chunks = preg_split('@(?(?:pre|script|style)[^>]*>)@i', $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).
+ $ignore = false;
+ $ignoretag = '';
+ $output = '';
+ foreach ($chunks as $i => $chunk) {
+ if ($i % 2) {
+ // Opening or closing tag?
+ $open = ($chunk{1} != '/');
+ list($tag) = split('[ >]', substr($chunk, 2 - $open), 2);
+ if (!$ignore) {
+ if ($open) {
+ $ignore = true;
+ $ignoretag = $tag;
+ }
+ }
+ // Only allow a matching tag to close it.
+ else if (!$open && $ignoretag == $tag) {
+ $ignore = false;
+ $ignoretag = '';
+ }
+ }
+ else if (!$ignore) {
+ $chunk = preg_replace('|\n*$|', '', $chunk) ."\n\n"; // just to make things a little easier, pad the end
+ $chunk = preg_replace('|
\s*
|', "\n\n", $chunk);
+ $chunk = preg_replace('!(<(?:table|ul|ol|li|pre|form|blockquote|h[1-6])[^>]*>)!', "\n$1", $chunk); // Space things out a little
+ $chunk = preg_replace('!((?:table|ul|ol|li|pre|form|blockquote|h[1-6])>)!', "$1\n", $chunk); // Space things out a little
+ $chunk = preg_replace("/\n\n+/", "\n\n", $chunk); // take care of duplicates
+ $chunk = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "]*)>|i', "
\s*(?(?:table|tr|td|th|div|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)!', "$1", $chunk); + $chunk = preg_replace('!(?(?:table|tr|td|th|div|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)\s*
!', "$1", $chunk); + $chunk = preg_replace('|(?)\s*\n|', " -
-
- '), 60, 255, t('If "Strip tags" is selected, optionally specify tags which should not be stripped. Javascript event attributes are always stripped.'));
+ $group .= form_checkbox(t('Display HTML help'), "filter_html_help_$format", 1, variable_get("filter_html_help_$format", 1), t('If enabled, Drupal will display some basic HTML help in the long filter tips.'));
+ $group .= form_radios(t('HTML style attributes'), "filter_style_$format", variable_get("filter_style_$format", FILTER_STYLE_STRIP), array(FILTER_STYLE_ALLOW => t('Allowed'), FILTER_STYLE_STRIP => t('Removed')), t('If "Strip tags" is selected, you can choose whether "STYLE" attributes are allowed or removed from input.'));
+ $group .= form_checkbox(t('Spam link deterrent'), "filter_html_nofollow_$format", 1, variable_get("filter_html_nofollow_$format", FALSE), 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.'));
+ $output .= form_group(t('HTML filter'), $group);
+
+ return $output;
+}
+
+/**
+ * HTML filter. Provides filtering of input into accepted HTML.
+ */
+function _filter_html($text, $format) {
+ if (variable_get("filter_html_$format", FILTER_HTML_STRIP) == FILTER_HTML_STRIP) {
+ // Allow users to enter HTML, but filter it
+ $text = strip_tags($text, variable_get("allowed_html_$format", '
-
-
- '));
+ if (variable_get("filter_style_$format", FILTER_STYLE_STRIP)) {
+ $text = preg_replace('/\Wstyle\s*=[^>]+?>/i', '>', $text);
+ }
+ $text = preg_replace('/\Won[a-z]+\s*=[^>]+?>/i', '>', $text);
+ }
+
+ if (variable_get("filter_html_$format", FILTER_HTML_STRIP) == FILTER_HTML_ESCAPE) {
+ // Escape HTML
+ $text = check_plain($text);
+ }
+
+ if (variable_get("filter_html_nofollow_$format", FALSE)) {
+ $text = preg_replace('/]+)>/i', '', $text);
+ }
+
+ return trim($text);
+}
+
+/**
+ * Convert line breaks into
and
in an intelligent fashion.
+ * Based on: http://photomatt.net/scripts/autop
+ */
+function _filter_autop($text) {
+ // Split at
, , 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 ignored ignored
processed"
+ $chunks = preg_split('@(?(?:pre|script|style)[^>]*>)@i', $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).
+ $ignore = false;
+ $ignoretag = '';
+ $output = '';
+ foreach ($chunks as $i => $chunk) {
+ if ($i % 2) {
+ // Opening or closing tag?
+ $open = ($chunk{1} != '/');
+ list($tag) = split('[ >]', substr($chunk, 2 - $open), 2);
+ if (!$ignore) {
+ if ($open) {
+ $ignore = true;
+ $ignoretag = $tag;
+ }
+ }
+ // Only allow a matching tag to close it.
+ else if (!$open && $ignoretag == $tag) {
+ $ignore = false;
+ $ignoretag = '';
+ }
+ }
+ else if (!$ignore) {
+ $chunk = preg_replace('|\n*$|', '', $chunk) ."\n\n"; // just to make things a little easier, pad the end
+ $chunk = preg_replace('|
\s*
|', "\n\n", $chunk);
+ $chunk = preg_replace('!(<(?:table|ul|ol|li|pre|form|blockquote|h[1-6])[^>]*>)!', "\n$1", $chunk); // Space things out a little
+ $chunk = preg_replace('!((?:table|ul|ol|li|pre|form|blockquote|h[1-6])>)!', "$1\n", $chunk); // Space things out a little
+ $chunk = preg_replace("/\n\n+/", "\n\n", $chunk); // take care of duplicates
+ $chunk = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "$1
\n", $chunk); // make paragraphs, including one at the end
+ $chunk = preg_replace('|\s*?
|', '', $chunk); // under certain strange conditions it could create a P of entirely whitespace
+ $chunk = preg_replace("|(
|", "$1", $chunk); // problem with nested lists
+ $chunk = preg_replace('|]*)>|i', "", $chunk);
+ $chunk = str_replace('
', '
', $chunk);
+ $chunk = preg_replace('!\s*(?(?:table|tr|td|th|div|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)!', "$1", $chunk);
+ $chunk = preg_replace('!(?(?:table|tr|td|th|div|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)\s*
!', "$1", $chunk);
+ $chunk = preg_replace('|(?)\s*\n|', "
\n", $chunk); // make line breaks
+ $chunk = preg_replace('!(?(?:table|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)\s*
!', "$1", $chunk);
+ $chunk = preg_replace('!
(\s*?(?:p|li|div|th|pre|td|ul|ol)>)!', '$1', $chunk);
+ $chunk = preg_replace('/&([^#])(?![a-z]{1,8};)/', '&$1', $chunk);
+ }
+ $output .= $chunk;
+ }
+ return $output;
+}
+
+/**
+ * @} End of "Standard filters".
+ */
+
+?>
--
cgit v1.2.3