public function FilterHtml::getHTMLRestrictions in Markdown 8.2
Returns HTML allowed by this filter's configuration.
May be implemented by filters of the FilterInterface::TYPE_HTML_RESTRICTOR type, this won't be used for filters of other types; they should just return FALSE.
This callback function is only necessary for filters that strip away HTML tags (and possibly attributes) and allows other modules to gain insight in a generic manner into which HTML tags and attributes are allowed by a format.
Return value
array|false A nested array with *either* of the following keys:
- 'allowed': (optional) the allowed tags as keys, and for each of those
tags (keys) either of the following values:
- TRUE to indicate any attribute is allowed
- FALSE to indicate no attributes are allowed
- an array to convey attribute restrictions: the keys must be
attribute names (which may use a wildcard, e.g. "data-*"), the
possible values are similar to the above:
- TRUE to indicate any attribute value is allowed
- FALSE to indicate the attribute is forbidden
- an array to convey attribute value restrictions: the key must be attribute values (which may use a wildcard, e.g. "xsd:*"), the possible values are TRUE or FALSE: to mark the attribute value as allowed or forbidden, respectively
- 'forbidden_tags': (optional) the forbidden tags
There is one special case: the "wildcard tag", "*": any attribute restrictions on that pseudotag apply to all tags.
If no restrictions apply, then FALSE must be returned.
Here is a concrete example, for a very granular filter:
array(
'allowed' => array(
// Allows any attribute with any value on the <div> tag.
'div' => TRUE,
// Allows no attributes on the <p> tag.
'p' => FALSE,
// Allows the following attributes on the <a> tag:
// - 'href', with any value;
// - 'rel', with the value 'nofollow' value.
'a' => array(
'href' => TRUE,
'rel' => array(
'nofollow' => TRUE,
),
),
// Only allows the 'src' and 'alt' attributes on the <alt> tag,
// with any value.
'img' => array(
'src' => TRUE,
'alt' => TRUE,
),
// Allow RDFa on <span> tags, using only the dc, foaf, xsd and sioc
// vocabularies/namespaces.
'span' => array(
'property' => array(
'dc:*' => TRUE,
'foaf:*' => TRUE,
),
'datatype' => array(
'xsd:*' => TRUE,
),
'rel' => array(
'sioc:*' => TRUE,
),
),
// Forbid the 'style' and 'on*' ('onClick' etc.) attributes on any
// tag.
'*' => array(
'style' => FALSE,
'on*' => FALSE,
),
),
);
A simpler example, for a very coarse filter:
array(
'forbidden_tags' => array(
'iframe',
'script',
),
);
The simplest example possible: a filter that doesn't allow any HTML:
array(
'allowed' => array(),
);
And for a filter that applies no restrictions, i.e. allows any HTML:
FALSE;
Overrides FilterHtml::getHTMLRestrictions
See also
\Drupal\filter\Entity\FilterFormatInterface::getHtmlRestrictions()
File
- src/
Util/ FilterHtml.php, line 286
Class
- FilterHtml
- Extends FilterHtml to allow more more permissive global attributes.
Namespace
Drupal\markdown\UtilCode
public function getHTMLRestrictions() {
// phpcs:ignore
if ($this->restrictions) {
return $this->restrictions;
}
$activeTheme = \Drupal::theme()
->getActiveTheme();
$parser = $this
->getParser();
$allowedHtmlPlugins = $parser ? AllowedHtmlManager::create()
->appliesTo($parser, $activeTheme) : [];
$cacheTags = $parser ? $parser
->getCacheTags() : [];
$cid = 'markdown_allowed_html:' . Crypt::hashBase64(serialize(array_merge($cacheTags, $allowedHtmlPlugins)));
// Return cached HTML restrictions.
$discoveryCache = \Drupal::cache('discovery');
if (($cached = $discoveryCache
->get($cid)) && !empty($cached->data)) {
$this->restrictions = $cached->data;
return $this->restrictions;
}
$restrictions = parent::getHTMLRestrictions();
// Save the original global attributes.
$originalGlobalAttributes = $restrictions['allowed']['*'];
unset($restrictions['allowed']['*']);
// Determine if any user global attributes where provided (from a filter).
$addedGlobalAttributes = [];
if (isset($restrictions['allowed'][static::ASTERISK_PLACEHOLDER])) {
$addedGlobalAttributes['*'] = $restrictions['allowed'][static::ASTERISK_PLACEHOLDER];
$addedGlobalAttributes = static::normalizeTags($addedGlobalAttributes);
unset($restrictions['allowed'][static::ASTERISK_PLACEHOLDER]);
}
// Normalize the allowed tags.
$normalizedTags = static::normalizeTags($restrictions['allowed']);
// Merge in plugins allowed HTML tags.
foreach ($allowedHtmlPlugins as $plugin_id => $allowedHtml) {
// Retrieve the plugin's allowed HTML tags.
$tags = $allowedHtml
->allowedHtmlTags($parser, $activeTheme);
// Merge the plugin's global attributes with the user provided ones.
if (isset($tags['*'])) {
$addedGlobalAttributes = static::mergeAllowedTags($addedGlobalAttributes, [
'*' => $tags['*'],
]);
unset($tags['*']);
}
// Now merge the plugin's tags with the allowed HTML.
$normalizedTags = static::mergeAllowedTags($normalizedTags, $tags);
}
// Replace the allowed tags with the normalized/merged tags.
$restrictions['allowed'] = $normalizedTags;
// Restore the original global attributes.
$restrictions['allowed']['*'] = $originalGlobalAttributes;
// Now merge the added global attributes using the array union (+) operator.
// This ensures that the original core defined global attributes are never
// overridden so users cannot specify attributes like 'style' and 'on*'
// which are highly vulnerable to XSS.
if (!empty($addedGlobalAttributes['*'])) {
$restrictions['allowed']['*'] += $addedGlobalAttributes['*'];
}
$discoveryCache
->set($cid, $restrictions, CacheBackendInterface::CACHE_PERMANENT, $cacheTags);
$this->restrictions = $restrictions;
return $restrictions;
}