1 ckeditor.module | ckeditor_get_acf_settings($format) |
Builds the ACF part of the CKEditor JS settings.
This ensures that CKEditor obeys the HTML restrictions defined by Backdrop's filter system, by enabling CKEditor's Advanced Content Filter (ACF) functionality: http://ckeditor.com/blog/CKEditor-4.1-RC-Released.
Parameters
$format: The text format object
Return value
array: An array with two values:
- the first value is the "allowedContent" setting: a well-formatted array or TRUE. The latter indicates that anything is allowed.
- the second value is the "disallowedContent" setting: a well-formatted array or FALSE. The latter indicates that nothing is disallowed.
File
- core/
modules/ ckeditor/ ckeditor.module, line 574 - Provides integration with the CKEditor WYSIWYG editor.
Code
function ckeditor_get_acf_settings($format) {
$html_restrictions = filter_format_allowed_html($format);
// When all HTML is allowed, also set allowedContent to true and
// disallowedContent to false.
if ($html_restrictions === TRUE) {
return array(TRUE, FALSE);
}
/**
* Converts Backdrop-stored attribute values to CKEditor attribute lists.
*/
$get_attribute_values = function($attribute_values, $allowed_values) {
$values = array_keys(array_filter($attribute_values, function($value) use ($allowed_values) {
if ($allowed_values) {
return $value !== FALSE;
}
else {
return $value === FALSE;
}
}));
if (count($values)) {
return implode(',', $values);
}
else {
return NULL;
}
};
$allowed = array();
$disallowed = array();
if (isset($html_restrictions['forbidden'])) {
foreach ($html_restrictions['forbidden'] as $tag) {
$disallowed[$tag] = TRUE;
}
}
foreach ($html_restrictions['allowed'] as $tag => $attributes) {
// Tell CKEditor the tag is allowed, but no attributes.
if ($attributes === FALSE) {
$allowed[$tag] = array(
'attributes' => FALSE,
'styles' => FALSE,
'classes' => FALSE,
);
}
// Tell CKEditor the tag is allowed, as well as any attribute on it. The
// "style" and "class" attributes are handled separately by CKEditor:
// they are disallowed even if you specify it in the list of allowed
// attributes, unless you state specific values for them that are
// allowed. Or, in this case: any value for them is allowed.
elseif ($attributes === TRUE) {
$allowed[$tag] = array(
'attributes' => TRUE,
'styles' => TRUE,
'classes' => TRUE,
);
// We've just marked that any value for the "style" and "class"
// attributes is allowed. However, that may not be the case: the "*"
// tag may still apply restrictions.
// Since CKEditor's ACF follows the following principle:
// Once validated, an element or its property cannot be
// invalidated by another rule.
// That means that the most permissive setting wins. Which means that
// it will still be allowed by CKEditor to e.g. define any style, no
// matter what the "*" tag's restrictions may be. If there's a setting
// for either the "style" or "class" attribute, it cannot possibly be
// more permissive than what was set above. Hence: inherit from the
// "*" tag where possible.
if (isset($html_restrictions['allowed']['*'])) {
$wildcard = $html_restrictions['allowed']['*'];
if (isset($wildcard['style'])) {
if (!is_array($wildcard['style'])) {
$allowed[$tag]['styles'] = $wildcard['style'];
}
else {
$allowed_styles = $get_attribute_values($wildcard['style'], TRUE);
if (isset($allowed_styles)) {
$allowed[$tag]['styles'] = $allowed_styles;
}
else {
unset($allowed[$tag]['styles']);
}
}
}
if (isset($wildcard['class'])) {
if (!is_array($wildcard['class'])) {
$allowed[$tag]['classes'] = $wildcard['class'];
}
else {
$allowed_classes = $get_attribute_values($wildcard['class'], TRUE);
if (isset($allowed_classes)) {
$allowed[$tag]['classes'] = $allowed_classes;
}
else {
unset($allowed[$tag]['classes']);
}
}
}
}
}
// Tell CKEditor the tag is allowed, along with some tags.
elseif (is_array($attributes)) {
// Configure allowed attributes, allowed "style" attribute values and
// allowed "class" attribute values.
// CKEditor only allows specific values for the "class" and "style"
// attributes; so ignore restrictions on other attributes, which
// Drupal filters may provide.
// NOTE: A Drupal contrib module can subclass this class, override the
// getConfig() method, and override the JavaScript at
// Drupal.editors.ckeditor to somehow make validation of values for
// attributes other than "class" and "style" work.
$allowed_attributes = array_filter($attributes, function($value) {
return $value !== FALSE;
});
if (count($allowed_attributes)) {
$allowed[$tag]['attributes'] = implode(',', array_keys($allowed_attributes));
}
if (isset($allowed_attributes['style']) && is_array($allowed_attributes['style'])) {
$allowed_styles = $get_attribute_values($allowed_attributes['style'], TRUE);
if (isset($allowed_styles)) {
$allowed[$tag]['styles'] = $allowed_styles;
}
}
if (isset($allowed_attributes['class']) && is_array($allowed_attributes['class'])) {
$allowed_classes = $get_attribute_values($allowed_attributes['class'], TRUE);
if (isset($allowed_classes)) {
$allowed[$tag]['classes'] = $allowed_classes;
}
}
// Handle disallowed attributes analogously. However, to handle *dis-
// allowed* attribute values, we must look at *allowed* attributes'
// disallowed attribute values! After all, a disallowed attribute
// implies that all of its possible attribute values are disallowed,
// thus we must look at the disallowed attribute values on allowed
// attributes.
$disallowed_attributes = array_filter($attributes, function($value) {
return $value === FALSE;
});
if (count($disallowed_attributes)) {
// No need to disallow the 'class' or 'style' attributes; CKEditor
// handles them separately (if no specific class or style attribute
// values are allowed, then those attributes are disallowed).
if (isset($disallowed_attributes['class'])) {
unset($disallowed_attributes['class']);
}
if (isset($disallowed_attributes['style'])) {
unset($disallowed_attributes['style']);
}
$disallowed[$tag]['attributes'] = implode(',', array_keys($disallowed_attributes));
}
if (isset($allowed_attributes['style']) && is_array($allowed_attributes['style'])) {
$disallowed_styles = $get_attribute_values($allowed_attributes['style'], FALSE);
if (isset($disallowed_styles)) {
$disallowed[$tag]['styles'] = $disallowed_styles;
}
}
if (isset($allowed_attributes['class']) && is_array($allowed_attributes['class'])) {
$disallowed_classes = $get_attribute_values($allowed_attributes['class'], FALSE);
if (isset($disallowed_classes)) {
$disallowed[$tag]['classes'] = $disallowed_classes;
}
}
}
}
return array($allowed, $disallowed);
}