diff -u b/core/lib/Drupal/Core/Field/MediaFormatterTrait.php b/core/lib/Drupal/Core/Field/MediaFormatterTrait.php --- b/core/lib/Drupal/Core/Field/MediaFormatterTrait.php +++ b/core/lib/Drupal/Core/Field/MediaFormatterTrait.php @@ -2,10 +2,8 @@ namespace Drupal\Core\Field; -use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Template\Attribute; -use Drupal\Core\Field\MediaFormatterTrait; /** * Useful methods for media formatters. @@ -18,0 +17,157 @@ + */ + public static function defaultSettings() { + return [ + 'controls' => TRUE, + 'autoplay' => FALSE, + 'loop' => FALSE, + 'multiple_file_display_type' => 'tags', + ] + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + return [ + 'controls' => [ + '#title' => $this->t('Show playback controls'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('controls'), + ], + 'autoplay' => [ + '#title' => $this->t('Autoplay'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('autoplay'), + ], + 'loop' => [ + '#title' => $this->t('Loop'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('loop'), + ], + 'multiple_file_display_type' => [ + '#title' => $this->t('Display of multiple files'), + '#type' => 'radios', + '#options' => [ + 'tags' => $this->t('Use multiple @tag tags, each with a single source.', ['@tag' => '<' . $this->getHtmlTag() . '>']), + 'sources' => $this->t('Use multiple sources within a single @tag tag.', ['@tag' => '<' . $this->getHtmlTag() . '>']), + ], + '#default_value' => $this->getSetting('multiple_file_display_type'), + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = []; + $summary[] = $this->t('Playback controls: %controls', ['%controls' => $this->getSetting('controls') ? $this->t('visible') : $this->t('hidden')]); + $summary[] = $this->t('Autoplay: %autoplay', ['%autoplay' => $this->getSetting('autoplay') ? $this->t('yes') : $this->t('no')]); + $summary[] = $this->t('Loop: %loop', ['%loop' => $this->getSetting('loop') ? $this->t('yes') : $this->t('no')]); + switch ($this->getSetting('multiple_file_display_type')) { + case 'tags': + $summary[] = $this->t('Multiple file display: Multiple HTML tags'); + break; + + case 'sources': + $summary[] = $this->t('Multiple file display: One HTML tag with multiple sources'); + break; + } + return $summary; + } + + /** + * Gets the HTML tag for the formatter. + * + * @return string + * The HTML tag of this formatter. + */ + protected function getHtmlTag() { + return static::getMediaType(); + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items, $langcode) { + $elements = []; + + $source_files = $this->getSourceFiles($items, $langcode); + if (empty($source_files)) { + return $elements; + } + + $attributes = $this->prepareAttributes(); + foreach ($source_files as $delta => $files) { + $elements[$delta] = [ + '#theme' => 'file_' . $this->getHtmlTag(), + '#attributes' => $attributes, + '#files' => $files, + ]; + } + return $elements; + } + + /** + * Prepare the attributes according to the settings. + * + * @param string[] $additional_attributes + * Additional attributes to be applied to the HTML element. Attribute names + * will be used as key and value in the HTML element. + * + * @return \Drupal\Core\Template\Attribute + * Container with all the attributes for the HTML tag. + */ + protected function prepareAttributes(array $additional_attributes = []) { + $attributes = new Attribute(); + foreach (['controls', 'autoplay', 'loop'] + $additional_attributes as $attribute) { + if ($this->getSetting($attribute)) { + $attributes->setAttribute($attribute, $attribute); + } + } + return $attributes; + } + + /** + * Check if given MIME type applies to the media type of the formatter. + * + * @param string $mime_type + * The complete MIME type. + * + * @return bool + * TRUE if the MIME type applies, FALSE otherwise. + */ + protected static function mimeTypeApplies($mime_type) { + list($type) = explode('/', $mime_type, 2); + return $type === static::getMediaType(); + } + +} +getSetting('file_extensions'))); + + foreach ($extension_list as $extension) { + $mime_type = $extension_mime_type_guesser->guess('fakedFile.' . $extension); + + if (static::mimeTypeApplies($mime_type)) { + return TRUE; + } + } + return FALSE; + } + + /** + * {@inheritdoc} + */ @@ -80,14 +256,4 @@ /** - * Gets the HTML tag for the formatter. - * - * @return string - * The HTML tag of this formatter. - */ - protected function getHtmlTag() { - return static::getMediaType(); - } - - /** * {@inheritdoc} */ @@ -102,11 +268,19 @@ $attributes = $this->prepareAttributes(); foreach ($source_files as $delta => $files) { $elements[$delta] = [ - '#theme' => 'file_' . $this->getHtmlTag(), + '#theme' => $this->getPluginId(), '#attributes' => $attributes, '#files' => $files, + '#cache' => ['tags' => []], ]; + + $cache_tags = []; + foreach ($files as $file) { + $cache_tags = Cache::mergeTags($cache_tags, $file['file']->getCacheTags()); + } + $elements[$delta]['#cache']['tags'] = $cache_tags; } + return $elements; } @@ -132,2 +306,60 @@ + /** + * Check if given MIME type applies to the media type of the formatter. + * + * @param string $mime_type + * The complete MIME type. + * + * @return bool + * TRUE if the MIME type applies, FALSE otherwise. + */ + protected static function mimeTypeApplies($mime_type) { + list($type) = explode('/', $mime_type, 2); + return $type === static::getMediaType(); + } + + /** + * Gets source files with attributes. + * + * @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items + * The item list. + * @param string $langcode + * The language code of the referenced entities to display. + * + * @return array + * Numerically indexed array, which again contains an associative array with + * the following key/values: + * - file => \Drupal\file\Entity\File + * - source_attributes => \Drupal\Core\Template\Attribute + */ + protected function getSourceFiles(EntityReferenceFieldItemListInterface $items, $langcode) { + $source_files = []; + // Because we can have the files grouped in a single media tag, we do a + // grouping in case the multiple file behavior is not 'tags'. + /** @var \Drupal\file\Entity\File $file */ + foreach ($this->getEntitiesToView($items, $langcode) as $file) { + if (static::mimeTypeApplies($file->getMimeType())) { + $source_attributes = new Attribute(); + $source_attributes + ->setAttribute('src', file_url_transform_relative(file_create_url($file->getFileUri()))) + ->setAttribute('type', $file->getMimeType()); + if ($this->getSetting('multiple_file_display_type') === 'tags') { + $source_files[] = [ + [ + 'file' => $file, + 'source_attributes' => $source_attributes, + ], + ]; + } + else { + $source_files[0][] = [ + 'file' => $file, + 'source_attributes' => $source_attributes, + ]; + } + } + } + return $source_files; + } + } only in patch2: unchanged: --- a/core/modules/file/src/Plugin/Field/FieldFormatter/FileMediaFormatterBase.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileMediaFormatterBase.php @@ -6,6 +6,7 @@ use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Field\MediaFormatterTrait; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Template\Attribute; @@ -14,59 +15,7 @@ */ abstract class FileMediaFormatterBase extends FileFormatterBase implements FileMediaFormatterInterface { - /** - * Gets the HTML tag for the formatter. - * - * @return string - * The HTML tag of this formatter. - */ - protected function getHtmlTag() { - return static::getMediaType(); - } - - /** - * {@inheritdoc} - */ - public static function defaultSettings() { - return [ - 'controls' => TRUE, - 'autoplay' => FALSE, - 'loop' => FALSE, - 'multiple_file_display_type' => 'tags', - ] + parent::defaultSettings(); - } - - /** - * {@inheritdoc} - */ - public function settingsForm(array $form, FormStateInterface $form_state) { - return [ - 'controls' => [ - '#title' => $this->t('Show playback controls'), - '#type' => 'checkbox', - '#default_value' => $this->getSetting('controls'), - ], - 'autoplay' => [ - '#title' => $this->t('Autoplay'), - '#type' => 'checkbox', - '#default_value' => $this->getSetting('autoplay'), - ], - 'loop' => [ - '#title' => $this->t('Loop'), - '#type' => 'checkbox', - '#default_value' => $this->getSetting('loop'), - ], - 'multiple_file_display_type' => [ - '#title' => $this->t('Display of multiple files'), - '#type' => 'radios', - '#options' => [ - 'tags' => $this->t('Use multiple @tag tags, each with a single source.', ['@tag' => '<' . $this->getHtmlTag() . '>']), - 'sources' => $this->t('Use multiple sources within a single @tag tag.', ['@tag' => '<' . $this->getHtmlTag() . '>']), - ], - '#default_value' => $this->getSetting('multiple_file_display_type'), - ], - ]; - } + use MediaFormatterTrait; /** * {@inheritdoc} @@ -89,26 +38,6 @@ public static function isApplicable(FieldDefinitionInterface $field_definition) return FALSE; } - /** - * {@inheritdoc} - */ - public function settingsSummary() { - $summary = []; - $summary[] = $this->t('Playback controls: %controls', ['%controls' => $this->getSetting('controls') ? $this->t('visible') : $this->t('hidden')]); - $summary[] = $this->t('Autoplay: %autoplay', ['%autoplay' => $this->getSetting('autoplay') ? $this->t('yes') : $this->t('no')]); - $summary[] = $this->t('Loop: %loop', ['%loop' => $this->getSetting('loop') ? $this->t('yes') : $this->t('no')]); - switch ($this->getSetting('multiple_file_display_type')) { - case 'tags': - $summary[] = $this->t('Multiple file display: Multiple HTML tags'); - break; - - case 'sources': - $summary[] = $this->t('Multiple file display: One HTML tag with multiple sources'); - break; - } - return $summary; - } - /** * {@inheritdoc} */ @@ -135,44 +64,9 @@ public function viewElements(FieldItemListInterface $items, $langcode) { } $elements[$delta]['#cache']['tags'] = $cache_tags; } - return $elements; } - /** - * Prepare the attributes according to the settings. - * - * @param string[] $additional_attributes - * Additional attributes to be applied to the HTML element. Attribute names - * will be used as key and value in the HTML element. - * - * @return \Drupal\Core\Template\Attribute - * Container with all the attributes for the HTML tag. - */ - protected function prepareAttributes(array $additional_attributes = []) { - $attributes = new Attribute(); - foreach (['controls', 'autoplay', 'loop'] + $additional_attributes as $attribute) { - if ($this->getSetting($attribute)) { - $attributes->setAttribute($attribute, $attribute); - } - } - return $attributes; - } - - /** - * Check if given MIME type applies to the media type of the formatter. - * - * @param string $mime_type - * The complete MIME type. - * - * @return bool - * TRUE if the MIME type applies, FALSE otherwise. - */ - protected static function mimeTypeApplies($mime_type) { - list($type) = explode('/', $mime_type, 2); - return $type === static::getMediaType(); - } - /** * Gets source files with attributes. *