ui_icons-1.0.x-dev/modules/ui_icons_text/ui_icons_text.module
modules/ui_icons_text/ui_icons_text.module
<?php
/**
* @file
* Provides icon items.
*/
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_FORM_ID_alter().
*/
function ui_icons_text_form_filter_format_edit_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
// Add an additional validate callback so we can ensure the order of filters
// is correct.
$form['#validate'][] = 'ui_icons_text_filter_format_edit_form_validate';
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function ui_icons_text_form_filter_format_add_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
// Add an additional validate callback so we can ensure the order of filters
// is correct.
$form['#validate'][] = 'ui_icons_text_filter_format_edit_form_validate';
}
/**
* Validate callback to ensure filter order and allowed_html are compatible.
*
* This is a copy from media.module.
*/
function ui_icons_text_filter_format_edit_form_validate(array &$form, FormStateInterface $form_state): void {
$triggering_element = $form_state->getTriggeringElement();
if (!isset($triggering_element['#name']) || 'op' !== $triggering_element['#name']) {
return;
}
$allowed_html_path = [
'filters',
'filter_html',
'settings',
'allowed_html',
];
$filter_html_settings_path = [
'filters',
'filter_html',
'settings',
];
$filter_html_enabled = $form_state->getValue([
'filters',
'filter_html',
'status',
]);
$icon_embed_enabled = $form_state->getValue([
'filters',
'icon_embed',
'status',
]);
if (!$icon_embed_enabled) {
return;
}
$get_filter_label = function ($filter_plugin_id) use ($form) {
return (string) $form['filters']['order'][$filter_plugin_id]['filter']['#markup'];
};
if (!$filter_html_enabled || !$form_state->getValue($allowed_html_path)) {
return;
}
/** @var \Drupal\filter\Entity\FilterFormat $filter_format */
$filter_format = $form_state->getFormObject()->getEntity();
$filter_html = clone $filter_format->filters()->get('filter_html');
$filter_html->setConfiguration(['settings' => $form_state->getValue($filter_html_settings_path)]);
$restrictions = $filter_html->getHTMLRestrictions();
if (FALSE === $restrictions) {
return;
}
$allowed = $restrictions['allowed'];
// Require `<drupal-icon>` HTML tag if filter_html is enabled.
if (!isset($allowed['drupal-icon'])) {
$form_state->setError($form['filters']['settings']['filter_html']['allowed_html'], t('The %icon-embed-filter-label filter requires <code><drupal-icon data-icon-id data-icon-settings class aria-label aria-hidden role></code> among the allowed HTML tags.', [
'%icon-embed-filter-label' => $get_filter_label('icon_embed'),
]));
}
else {
$required_attributes = [
'data-icon-id',
'data-icon-settings',
'class',
'aria-label',
'aria-hidden',
'role',
];
// If there are no attributes, the allowed item is set to FALSE,
// otherwise, it is set to an array.
if ($allowed['drupal-icon'] === FALSE) {
$missing_attributes = $required_attributes;
}
elseif (isset($allowed['drupal-icon']['*'])) {
$missing_attributes = FALSE;
}
else {
$missing_attributes = array_diff($required_attributes, array_keys($allowed['drupal-icon']));
}
if ($missing_attributes) {
$form_state->setError($form['filters']['settings']['filter_html']['allowed_html'], t('The <code><drupal-icon></code> tag in the allowed HTML tags is missing the following attributes: <code>%list</code>.', [
'%list' => implode(' ', $missing_attributes),
]));
}
$filters = $form_state->getValue('filters');
// The icon filter must be after "filter_html", "filter_autop" and is
// canceled by "filter_html_escape".
$precedents = [
'filter_html',
'filter_autop',
];
$error_filters = [];
foreach ($precedents as $filter_name) {
// A filter that should run before icon embed filter.
$precedent = $filters[$filter_name];
if (empty($precedent['status']) || !isset($precedent['weight'])) {
continue;
}
if ($precedent['weight'] >= $filters['icon_embed']['weight']) {
$error_filters[$filter_name] = $get_filter_label($filter_name);
}
}
if (!empty($error_filters)) {
$error_message = \Drupal::translation()->formatPlural(
count($error_filters),
'The %icon-embed-filter-label filter needs to be placed after the %filter filter.',
'The %icon-embed-filter-label filter needs to be placed after the following filters: %filters.',
[
'%icon-embed-filter-label' => $get_filter_label('icon_embed'),
'%filter' => reset($error_filters),
'%filters' => implode(', ', $error_filters),
]
);
$form_state->setErrorByName('filters', $error_message);
}
if (isset($filters['filter_html_escape']['status']) && $filters['filter_html_escape']['status']) {
$error = t('The Embed icon will not work and should be removed if the %filter is enabled', ['%filter' => $get_filter_label('filter_html_escape')]);
$form_state->setErrorByName('filters', $error);
}
}
}
