210 lines
6.7 KiB
PHP
210 lines
6.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @file
|
||
|
|
*/
|
||
|
|
|
||
|
|
use Drupal\Core\Form\FormStateInterface;
|
||
|
|
use Drupal\Core\Hook\Attribute\ProceduralHookScanStop;
|
||
|
|
use Drupal\Core\Render\Element;
|
||
|
|
use Drupal\Core\Render\Element\RenderElementBase;
|
||
|
|
use Drupal\Core\Template\Attribute;
|
||
|
|
use Drupal\Core\Url;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Prepares variables for media templates.
|
||
|
|
*
|
||
|
|
* Default template: media.html.twig.
|
||
|
|
*
|
||
|
|
* @param array $variables
|
||
|
|
* An associative array containing:
|
||
|
|
* - elements: An array of elements to display in view mode.
|
||
|
|
* - media: The media item.
|
||
|
|
* - name: The label for the media item.
|
||
|
|
* - view_mode: View mode; e.g., 'full', 'teaser', etc.
|
||
|
|
*/
|
||
|
|
function template_preprocess_media(array &$variables): void {
|
||
|
|
$variables['media'] = $variables['elements']['#media'];
|
||
|
|
$variables['view_mode'] = $variables['elements']['#view_mode'];
|
||
|
|
$variables['name'] = $variables['media']->label();
|
||
|
|
|
||
|
|
// Helpful $content variable for templates.
|
||
|
|
foreach (Element::children($variables['elements']) as $key) {
|
||
|
|
$variables['content'][$key] = $variables['elements'][$key];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Implements hook_preprocess_HOOK() for media reference widgets.
|
||
|
|
*/
|
||
|
|
function media_preprocess_media_reference_help(&$variables): void {
|
||
|
|
// Most of these attribute checks are copied from
|
||
|
|
// template_preprocess_fieldset(). Our template extends
|
||
|
|
// field-multiple-value-form.html.twig to provide our help text, but also
|
||
|
|
// groups the information within a semantic fieldset with a legend. So, we
|
||
|
|
// incorporate parity for both.
|
||
|
|
$element = $variables['element'];
|
||
|
|
Element::setAttributes($element, ['id']);
|
||
|
|
RenderElementBase::setAttributes($element);
|
||
|
|
$variables['attributes'] = $element['#attributes'] ?? [];
|
||
|
|
$variables['legend_attributes'] = new Attribute();
|
||
|
|
$variables['header_attributes'] = new Attribute();
|
||
|
|
$variables['description']['attributes'] = new Attribute();
|
||
|
|
$variables['legend_span_attributes'] = new Attribute();
|
||
|
|
|
||
|
|
if (!empty($element['#media_help'])) {
|
||
|
|
foreach ($element['#media_help'] as $key => $text) {
|
||
|
|
$variables[substr($key, 1)] = $text;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the appropriate URL to add media for the current user.
|
||
|
|
*
|
||
|
|
* @todo Remove in https://www.drupal.org/project/drupal/issues/2938116
|
||
|
|
*
|
||
|
|
* @param string[] $allowed_bundles
|
||
|
|
* An array of bundles that should be checked for create access.
|
||
|
|
*
|
||
|
|
* @return bool|\Drupal\Core\Url
|
||
|
|
* The URL to add media, or FALSE if the user cannot create any media.
|
||
|
|
*
|
||
|
|
* @internal
|
||
|
|
* This function is internal and may be removed in a minor release.
|
||
|
|
*/
|
||
|
|
#[ProceduralHookScanStop]
|
||
|
|
function _media_get_add_url($allowed_bundles) {
|
||
|
|
$access_handler = \Drupal::entityTypeManager()->getAccessControlHandler('media');
|
||
|
|
$create_bundles = array_filter($allowed_bundles, [$access_handler, 'createAccess']);
|
||
|
|
|
||
|
|
// Add a section about how to create media if the user has access to do so.
|
||
|
|
if (count($create_bundles) === 1) {
|
||
|
|
return Url::fromRoute('entity.media.add_form', ['media_type' => reset($create_bundles)])->toString();
|
||
|
|
}
|
||
|
|
elseif (count($create_bundles) > 1) {
|
||
|
|
return Url::fromRoute('entity.media.add_page')->toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate callback to ensure filter order and allowed_html are compatible.
|
||
|
|
*/
|
||
|
|
function media_filter_format_edit_form_validate($form, FormStateInterface $form_state): void {
|
||
|
|
if ($form_state->getTriggeringElement()['#name'] !== 'op') {
|
||
|
|
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',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$media_embed_enabled = $form_state->getValue([
|
||
|
|
'filters',
|
||
|
|
'media_embed',
|
||
|
|
'status',
|
||
|
|
]);
|
||
|
|
|
||
|
|
if (!$media_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)) {
|
||
|
|
/** @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();
|
||
|
|
$allowed = $restrictions['allowed'];
|
||
|
|
|
||
|
|
// Require `<drupal-media>` HTML tag if filter_html is enabled.
|
||
|
|
if (!isset($allowed['drupal-media'])) {
|
||
|
|
$form_state->setError($form['filters']['settings']['filter_html']['allowed_html'], t('The %media-embed-filter-label filter requires <code><drupal-media></code> among the allowed HTML tags.', [
|
||
|
|
'%media-embed-filter-label' => $get_filter_label('media_embed'),
|
||
|
|
]));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$required_attributes = [
|
||
|
|
'data-entity-type',
|
||
|
|
'data-entity-uuid',
|
||
|
|
];
|
||
|
|
|
||
|
|
// If there are no attributes, the allowed item is set to FALSE,
|
||
|
|
// otherwise, it is set to an array.
|
||
|
|
if ($allowed['drupal-media'] === FALSE) {
|
||
|
|
$missing_attributes = $required_attributes;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$missing_attributes = array_diff($required_attributes, array_keys($allowed['drupal-media']));
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($missing_attributes) {
|
||
|
|
$form_state->setError($form['filters']['settings']['filter_html']['allowed_html'], t('The <code><drupal-media></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 "media_embed" filter must run after "filter_align", "filter_caption",
|
||
|
|
// and "filter_html_image_secure".
|
||
|
|
$precedents = [
|
||
|
|
'filter_align',
|
||
|
|
'filter_caption',
|
||
|
|
'filter_html_image_secure',
|
||
|
|
];
|
||
|
|
|
||
|
|
$error_filters = [];
|
||
|
|
foreach ($precedents as $filter_name) {
|
||
|
|
// A filter that should run before media embed filter.
|
||
|
|
$precedent = $filters[$filter_name];
|
||
|
|
|
||
|
|
if (empty($precedent['status']) || !isset($precedent['weight'])) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($precedent['weight'] >= $filters['media_embed']['weight']) {
|
||
|
|
$error_filters[$filter_name] = $get_filter_label($filter_name);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($error_filters)) {
|
||
|
|
$error_message = \Drupal::translation()->formatPlural(
|
||
|
|
count($error_filters),
|
||
|
|
'The %media-embed-filter-label filter needs to be placed after the %filter filter.',
|
||
|
|
'The %media-embed-filter-label filter needs to be placed after the following filters: %filters.',
|
||
|
|
[
|
||
|
|
'%media-embed-filter-label' => $get_filter_label('media_embed'),
|
||
|
|
'%filter' => reset($error_filters),
|
||
|
|
'%filters' => implode(', ', $error_filters),
|
||
|
|
]
|
||
|
|
);
|
||
|
|
|
||
|
|
$form_state->setErrorByName('filters', $error_message);
|
||
|
|
}
|
||
|
|
}
|