1 filter.module | filter_format_allowed_html($format) |
Get a complete list of allowed and forbidden tags for a text format.
Parameters
$format: The text format object for which the list will be generated.
Return value
array|TRUE: An array of allowed HTML with the following keys:
- allowed: A list of allowed tags keyed by tag name. The value is an array of attributes.
- forbidden: An unindexed array of tags that are not allowed.
For the full documentation on the return values of these two properties, see callback_filter_allowed_html(). If TRUE is returned, then there are no restrictions on this format's HTML content.
See also
callback_filter_allowed_html()
File
- core/
modules/ filter/ filter.module, line 494 - Framework for handling the filtering of content.
Code
function filter_format_allowed_html($format) {
$all_filter_info = filter_get_filters();
$all_html_allowed = TRUE;
$restrictions = array(
'allowed' => array(),
'forbidden' => array(),
);
foreach ($format->filters as $filter_name => $filter) {
// Skip disabled filters.
if (!$filter->status) {
continue;
}
// Skip non-existent filters.
if (!isset($all_filter_info[$filter_name])) {
continue;
}
// We're only concerned with filters that specify an allowed HTML callback.
$filter_info = $all_filter_info[$filter_name];
if (!isset($filter_info['allowed html callback'])) {
continue;
}
$allowed_html_callback = $filter_info['allowed html callback'];
$filter_restrictions = $allowed_html_callback($filter, $format);
if ($filter_restrictions) {
$all_html_allowed = FALSE;
}
else {
continue;
}
// Forbidden tags are simple in that they have no attributes to track, it's
// just a list of tags that are not allowed.
if (isset($filter_restrictions['forbidden'])) {
$restrictions['forbidden'] = array_unique(array_merge($restrictions['forbidden'], $filter_restrictions['forbidden']));
}
// Add any allowed tags that have not yet been specified and build a list
// of any that need to be intersected.
$intersected_tags = array();
foreach ($filter_restrictions['allowed'] as $tag => $attributes) {
if (!isset($restrictions['allowed'][$tag])) {
$restrictions['allowed'][$tag] = $attributes;
}
else {
$intersected_tags[$tag] = $attributes;
}
}
// Allowed tags are more complicated as different filters may allow
// different individual attributes. Track the intersection of all allowed
// attributes for each tag.
foreach ($intersected_tags as $tag => $attributes) {
$intersection = NULL;
$current_attributes = isset($restrictions['allowed'][$tag]) ? $restrictions['allowed'][$tag] : array();
$new_attributes = $filter_restrictions['allowed'][$tag];
// The current intersection does not allow any attributes, never allow.
if (!is_array($current_attributes) && $current_attributes == FALSE) {
continue;
}
// The new filter allows fewer attributes (all -> list or none).
elseif (!is_array($current_attributes) && $current_attributes == TRUE && ($new_attributes == FALSE || is_array($new_attributes))) {
$intersection = $new_attributes;
}
// The new filter allows fewer attributes (list -> none).
elseif (is_array($current_attributes) && $new_attributes == FALSE) {
$intersection = $new_attributes;
}
// The new filter allows more attributes; retain current.
elseif (is_array($current_attributes) && $new_attributes == TRUE) {
continue;
}
// The new filter allows the same attributes; retain current.
elseif ($current_attributes == $new_attributes) {
continue;
}
// Both list an array of attribute values; do an intersection,
// where we take into account that a value of:
// - TRUE means the attribute value is allowed;
// - FALSE means the attribute value is forbidden;
// hence we keep the ANDed result.
else {
$intersection = array_intersect_key($current_attributes, $new_attributes);
foreach (array_keys($intersection) as $attribute_value) {
$intersection[$attribute_value] = $intersection[$attribute_value] && $new_attributes[$attribute_value];
}
}
if (isset($intersection)) {
$restrictions['allowed'][$tag] = $intersection;
}
}
}
// Simplification: if we have both an (intersected) allowlist and a (unioned)
// denylist, then remove any tags from the allowlist that also exist in the
// denylist. Now the allowlist alone expresses all tag-level restrictions,
// and we can delete the denylist.
if (isset($restrictions['allowed']) && isset($restrictions['forbidden'])) {
foreach ($restrictions['forbidden'] as $tag) {
if (isset($restrictions['allowed'][$tag])) {
unset($restrictions['allowed'][$tag]);
}
}
$restrictions['forbidden'] = array();
}
// Simplification: if the only remaining allowed tag is the asterisk (which
// contains attribute restrictions that apply to all tags), and only allow
// filters were used, then effectively nothing is allowed.
if (isset($restrictions['allowed'])) {
if (count($restrictions['allowed']) === 1 && array_key_exists('*', $restrictions['allowed']) && !isset($restrictions['forbidden'])) {
$restrictions['allowed'] = array();
}
}
// If no filters specified restrictions, change the allowed values to be
// a Boolean.
if ($all_html_allowed) {
$restrictions = TRUE;
}
return $restrictions;
}