From 7f90ee63ab5023792fb8f3753111a06d7ac2ef8e Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Thu, 9 Apr 2015 12:29:20 +0100 Subject: [PATCH] Issue #2456709 by dawehner, rteijeiro: File views handlers need to be replaced with entity-aware formatters --- .../file/config/optional/views.view.files.yml | 86 +++++++-- .../file/config/schema/file.schema.yml | 31 ++++ .../file/config/schema/file.views.schema.yml | 4 - core/modules/file/src/FileViewsData.php | 20 +- .../BaseFieldFileFormatterBase.php | 94 ++++++++++ .../FieldFormatter/DefaultFileFormatter.php | 51 ++++++ .../FieldFormatter/FileExtensionFormatter.php | 80 ++++++++ .../Plugin/Field/FieldFormatter/FileSize.php | 47 +++++ .../Field/FieldFormatter/FileUriFormatter.php | 70 +++++++ .../FieldFormatter/FilemimeFormatter.php | 76 ++++++++ .../file/src/Plugin/views/field/Extension.php | 69 ------- .../file/src/Plugin/views/field/FileMime.php | 53 ------ .../file/src/Plugin/views/field/Status.php | 30 --- .../file/src/Plugin/views/field/Uri.php | 47 ----- .../file/src/Plugin/views/wizard/File.php | 4 +- .../Formatter/FileEntityFormatterTest.php | 173 ++++++++++++++++++ .../Tests/Views/ExtensionViewsFieldTest.php | 71 +++---- .../Tests/Views/FileViewsFieldAccessTest.php | 14 +- .../views.view.file_extension_view.yml | 41 ++--- 19 files changed, 768 insertions(+), 293 deletions(-) create mode 100644 core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php create mode 100644 core/modules/file/src/Plugin/Field/FieldFormatter/DefaultFileFormatter.php create mode 100644 core/modules/file/src/Plugin/Field/FieldFormatter/FileExtensionFormatter.php create mode 100644 core/modules/file/src/Plugin/Field/FieldFormatter/FileSize.php create mode 100644 core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php create mode 100644 core/modules/file/src/Plugin/Field/FieldFormatter/FilemimeFormatter.php delete mode 100644 core/modules/file/src/Plugin/views/field/Extension.php delete mode 100644 core/modules/file/src/Plugin/views/field/FileMime.php delete mode 100644 core/modules/file/src/Plugin/views/field/Status.php delete mode 100644 core/modules/file/src/Plugin/views/field/Uri.php create mode 100644 core/modules/file/src/Tests/Formatter/FileEntityFormatterTest.php diff --git a/core/modules/file/config/optional/views.view.files.yml b/core/modules/file/config/optional/views.view.files.yml index 526d9fdd4257..23bfd821e54a 100644 --- a/core/modules/file/config/optional/views.view.files.yml +++ b/core/modules/file/config/optional/views.view.files.yml @@ -159,7 +159,6 @@ display: html: false hide_empty: false empty_zero: false - link_to_file: false relationship: none group_type: group admin_label: '' @@ -175,30 +174,45 @@ display: element_default_classes: true empty: '' hide_alter_empty: true - plugin_id: file + plugin_id: field entity_type: file entity_field: fid filename: id: filename table: file_managed field: filename + relationship: none + group_type: group + admin_label: '' + label: Name + exclude: false alter: alter_text: false + text: '' make_link: false + path: '' absolute: false - trim: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 word_boundary: false ellipsis: false + more_link: false + more_link_text: '' + more_link_path: '' strip_tags: false + trim: false + preserve_tags: '' html: false - hide_empty: false - empty_zero: false - link_to_file: true - relationship: none - group_type: group - admin_label: '' - label: Name - exclude: false element_type: '' element_class: '' element_label_type: '' @@ -208,8 +222,22 @@ display: element_wrapper_class: '' element_default_classes: true empty: '' + hide_empty: false + empty_zero: false hide_alter_empty: true - plugin_id: file + click_sort_column: value + type: file_link + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: 0 + plugin_id: field entity_type: file entity_field: filename filemime: @@ -260,9 +288,8 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - link_to_file: false - filemime_image: false - plugin_id: file_filemime + type: file_filemime + plugin_id: field entity_type: file entity_field: filemime filesize: @@ -313,8 +340,8 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - file_size_display: formatted - plugin_id: file_size + type: file_size + plugin_id: field entity_type: file entity_field: filesize status: @@ -365,7 +392,12 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - plugin_id: file_status + type: boolean + settings: + format: custom + format_custom_false: 'Temporary' + format_custom_true: 'Permanent' + plugin_id: field entity_type: file entity_field: status created: @@ -679,6 +711,12 @@ display: arguments: { } group_by: true show_admin_links: true + display_extenders: { } + cache_metadata: + contexts: + - languages + - url + cacheable: false page_1: display_plugin: page id: page_1 @@ -706,6 +744,12 @@ display: group_type: group admin_label: 'File usage' required: false + display_extenders: { } + cache_metadata: + contexts: + - languages + - url + cacheable: false page_2: display_plugin: page id: page_2 @@ -1054,3 +1098,9 @@ display: group_type: group admin_label: 'File usage' required: true + display_extenders: { } + cache_metadata: + contexts: + - languages + - url + cacheable: false diff --git a/core/modules/file/config/schema/file.schema.yml b/core/modules/file/config/schema/file.schema.yml index e5892e57d417..b9f8918f6331 100644 --- a/core/modules/file/config/schema/file.schema.yml +++ b/core/modules/file/config/schema/file.schema.yml @@ -90,3 +90,34 @@ field.widget.settings.file_generic: progress_indicator: type: string label: 'Progress indicator' + +field_formatter_settings_base_file: + type: mapping + mapping: + link_to_file: + type: boolean + label: 'Link to file' + +field.formatter.settings.file_link: + type: field_formatter_settings_base_file + +field.formatter.settings.file_uri: + type: field_formatter_settings_base_file + mapping: + file_download_path: + type: boolean + label: 'Display download path' + +field.formatter.settings.file_filemime: + type: field_formatter_settings_base_file + mapping: + filemime_image: + type: boolean + label: 'Display the filemime as icon' + +field.formatter.settings.file_extension: + type: field_formatter_settings_base_file + mapping: + extension_detect_tar: + type: boolean + label: 'Detect tar' diff --git a/core/modules/file/config/schema/file.views.schema.yml b/core/modules/file/config/schema/file.views.schema.yml index 2f63384037b9..e04b5d730974 100644 --- a/core/modules/file/config/schema/file.views.schema.yml +++ b/core/modules/file/config/schema/file.views.schema.yml @@ -29,10 +29,6 @@ views.field.file_filemime: type: boolean label: 'Display an icon representing the file type, instead of the MIME text (such as "image/jpeg")' -views.field.file_status: - type: views_field - label: 'File status' - views.field.file_uri: type: views.field.file label: 'File URI' diff --git a/core/modules/file/src/FileViewsData.php b/core/modules/file/src/FileViewsData.php index fdd8fc62b9bb..7acbabc5d163 100644 --- a/core/modules/file/src/FileViewsData.php +++ b/core/modules/file/src/FileViewsData.php @@ -25,7 +25,6 @@ public function getViewsData() { $data['file_managed']['table']['base']['defaults']['field'] = 'filename'; $data['file_managed']['table']['wizard_id'] = 'file_managed'; - $data['file_managed']['fid']['field']['id'] ='file'; $data['file_managed']['fid']['argument'] = array( 'id' => 'file_fid', // The field to display in the summary. @@ -42,25 +41,30 @@ public function getViewsData() { 'label' => t('File usage'), ); - $data['file_managed']['filename']['field']['id'] = 'file'; + $data['file_managed']['uri']['field']['default_formatter'] = 'file_uri'; - $data['file_managed']['uri']['field']['id'] = 'file_uri'; - - $data['file_managed']['filemime']['field']['id'] = 'file_filemime'; + $data['file_managed']['filemime']['field']['default_formatter'] = 'file_filemime'; $data['file_managed']['extension'] = array( 'title' => t('Extension'), 'help' => t('The extension of the file.'), 'real field' => 'filename', 'field' => array( - 'id' => 'file_extension', + 'entity_type' => 'file', + 'field_name' => 'filename', + 'default_formatter' => 'file_extension', + 'id' => 'field', 'click sortable' => FALSE, ), ); - $data['file_managed']['filesize']['field']['id'] = 'file_size'; + $data['file_managed']['filesize']['field']['default_formatter'] = 'file_size'; - $data['file_managed']['status']['field']['id'] = 'file_status'; + $data['file_managed']['status']['field']['default_formatter_settings'] = [ + 'format' => 'custom', + 'format_custom_false' => $this->t('Temporary'), + 'format_custom_true' => t('Permanent'), + ]; $data['file_managed']['status']['filter']['id'] = 'file_status'; $data['file_managed']['uid']['relationship']['title'] = t('User who uploaded'); diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php b/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php new file mode 100644 index 000000000000..865471200a9e --- /dev/null +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php @@ -0,0 +1,94 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Plugin\Field\FieldFormatter\BaseFieldFileFormatterBase. + */ + +namespace Drupal\file\Plugin\Field\FieldFormatter; + +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Field\FormatterBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; + +/** + * Base class for file formatters, which allow to link to the file download URL. + */ +abstract class BaseFieldFileFormatterBase extends FormatterBase { + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + $settings['link_to_file'] = FALSE; + + return $settings; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + + $form['link_to_file'] = [ + '#title' => $this->t('Link this field to the file download URL'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('link_to_file'), + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items) { + $elements = []; + + $url = NULL; + // Add support to link to the entity itself. + if ($this->getSetting('link_to_file')) { + $url = file_create_url($items->getEntity()->uri->value); + } + + foreach ($items as $delta => $item) { + $string = $this->viewValue($item); + + if ($url) { + $elements[$delta] = [ + '#type' => 'link', + '#title' => $string, + '#url' => Url::fromUri($url), + ]; + } + else { + $elements[$delta] = is_array($string) ? $string : ['#markup' => $string]; + } + } + + return $elements; + } + + /** + * Generate the output appropriate for one field item. + * + * @param \Drupal\Core\Field\FieldItemInterface $item + * One field item. + * + * @return mixed + * The textual output generated. + */ + abstract protected function viewValue(FieldItemInterface $item); + + /** + * {@inheritdoc} + */ + public static function isApplicable(FieldDefinitionInterface $field_definition) { + return $field_definition->getTargetEntityTypeId() === 'file'; + } + +} diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/DefaultFileFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/DefaultFileFormatter.php new file mode 100644 index 000000000000..18375aa329cb --- /dev/null +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/DefaultFileFormatter.php @@ -0,0 +1,51 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Plugin\Field\FieldFormatter\DefaultFileFormatter. + */ + +namespace Drupal\file\Plugin\Field\FieldFormatter; + +use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\Form\FormStateInterface; + +/** + * Formatter for a text field on a file entity that links the field to the file. + * + * @FieldFormatter( + * id = "file_link", + * label = @Translation("File link"), + * field_types = { + * "string" + * } + * ) + */ +class DefaultFileFormatter extends BaseFieldFileFormatterBase { + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + $settings = parent::defaultSettings(); + $settings['link_to_file'] = TRUE; + + return $settings; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + // We don't call the parent in order to bypass the link to file form. + return $form; + } + + /** + * {@inheritdoc} + */ + protected function viewValue(FieldItemInterface $item) { + return $item->value; + } + +} diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileExtensionFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileExtensionFormatter.php new file mode 100644 index 000000000000..626582e114ea --- /dev/null +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileExtensionFormatter.php @@ -0,0 +1,80 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Plugin\Field\FieldFormatter\FileExtensionFormatter. + */ + +namespace Drupal\file\Plugin\Field\FieldFormatter; + +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\Form\FormStateInterface; + +/** + * Formatter to render a filename as file extension. + * + * @FieldFormatter( + * id = "file_extension", + * label = @Translation("File extension"), + * field_types = { + * "string" + * } + * ) + */ +class FileExtensionFormatter extends BaseFieldFileFormatterBase { + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + $settings = parent::defaultSettings(); + + $settings['extension_detect_tar'] = FALSE; + return $settings; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + $form['extension_detect_tar'] = array( + '#type' => 'checkbox', + '#title' => $this->t('Include tar in extension'), + '#description' => $this->t("If the part of the filename just before the extension is '.tar', include this in the extension output."), + '#default_value' => $this->getSetting('extension_detect_tar'), + ); + return $form; + } + + /** + * {@inheritdoc} + */ + protected function viewValue(FieldItemInterface $item) { + $filename = $item->value; + if (!$this->getSetting('extension_detect_tar')) { + return pathinfo($filename, PATHINFO_EXTENSION); + } + else { + $file_parts = explode('.', basename($filename)); + if (count($file_parts) > 1) { + $extension = array_pop($file_parts); + $last_part_in_name = array_pop($file_parts); + if ($last_part_in_name === 'tar') { + $extension = 'tar.' . $extension; + } + return $extension; + } + } + } + + /** + * {@inheritdoc} + */ + public static function isApplicable(FieldDefinitionInterface $field_definition) { + // Just show this file extension formatter on the filename field. + return parent::isApplicable($field_definition) && $field_definition->getName() === 'filename'; + } + +} diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileSize.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileSize.php new file mode 100644 index 000000000000..27973da720a9 --- /dev/null +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileSize.php @@ -0,0 +1,47 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Plugin\Field\FieldFormatter\FileSize. + */ + +namespace Drupal\file\Plugin\Field\FieldFormatter; + +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Field\FormatterBase; + +/** + * Formatter that shows the file size in a human readable way. + * + * @FieldFormatter( + * id = "file_size", + * label = @Translation("File size"), + * field_types = { + * "integer" + * } + * ) + */ +class FileSize extends FormatterBase { + + /** + * {@inheritdoc} + */ + public static function isApplicable(FieldDefinitionInterface $field_definition) { + return parent::isApplicable($field_definition) && $field_definition->getName() === 'filesize'; + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items) { + $elements = []; + + foreach ($items as $delta => $item) { + $elements[$delta] = ['#markup' => format_size($item->value)]; + } + + return $elements; + } + +} diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php new file mode 100644 index 000000000000..0a2a855bcdfa --- /dev/null +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php @@ -0,0 +1,70 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Plugin\Field\FieldFormatter\FileUriFormatter. + */ + +namespace Drupal\file\Plugin\Field\FieldFormatter; + +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\Form\FormStateInterface; + +/** + * Formatter to render the file URI to its download path. + * + * @FieldFormatter( + * id = "file_uri", + * label = @Translation("File URI"), + * field_types = { + * "uri" + * } + * ) + */ +class FileUriFormatter extends BaseFieldFileFormatterBase { + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + $settings = parent::defaultSettings(); + + $settings['file_download_path'] = FALSE; + return $settings; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + + $form['file_download_path'] = [ + '#title' => $this->t('Display the file download URI'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('file_download_path'), + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + protected function viewValue(FieldItemInterface $item) { + $value = $item->value; + if ($this->getSetting('file_download_path')) { + $value = file_create_url($value); + } + return $value; + } + + /** + * {@inheritdoc} + */ + public static function isApplicable(FieldDefinitionInterface $field_definition) { + return parent::isApplicable($field_definition) && $field_definition->getName() === 'uri'; + } + +} diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FilemimeFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FilemimeFormatter.php new file mode 100644 index 000000000000..5e2925117570 --- /dev/null +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FilemimeFormatter.php @@ -0,0 +1,76 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Plugin\Field\FieldFormatter\FilemimeFormatter. + */ + +namespace Drupal\file\Plugin\Field\FieldFormatter; + +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\Form\FormStateInterface; + +/** + * Formatter to render the file mime type, with an optional icon. + * + * @FieldFormatter( + * id = "file_filemime", + * label = @Translation("File mime"), + * field_types = { + * "string" + * } + * ) + */ +class FilemimeFormatter extends BaseFieldFileFormatterBase { + + /** + * {@inheritdoc} + */ + public static function isApplicable(FieldDefinitionInterface $field_definition) { + return parent::isApplicable($field_definition) && $field_definition->getName() === 'filemime'; + } + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + $settings = parent::defaultSettings(); + + $settings['filemime_image'] = FALSE; + + return $settings; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + + $form['filemime_image'] = array( + '#title' => $this->t('Display an icon'), + '#description' => $this->t('The icon is representing the file type, instead of the MIME text (such as "image/jpeg")'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('filemime_image'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + protected function viewValue(FieldItemInterface $item) { + $value = $item->value; + if ($this->getSetting('filemime_image') && $value) { + $file_icon = [ + '#theme' => 'image__file_icon', + '#file' => $item->getEntity(), + ]; + return $file_icon; + } + return $value; + } + +} diff --git a/core/modules/file/src/Plugin/views/field/Extension.php b/core/modules/file/src/Plugin/views/field/Extension.php deleted file mode 100644 index 1b0bd738bdd2..000000000000 --- a/core/modules/file/src/Plugin/views/field/Extension.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php - -/** - * @file - * Definition of views_handler_field_file_extension. - */ - -namespace Drupal\file\Plugin\views\field; - -use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\views\field\FieldPluginBase; -use Drupal\views\ResultRow; - -/** - * Returns a pure file extension of the file, for example 'module'. - * - * @ingroup views_field_handlers - * - * @ViewsField("file_extension") - */ -class Extension extends FieldPluginBase { - - /** - * {@inheritdoc} - */ - protected function defineOptions() { - $options = parent::defineOptions(); - $options['extension_detect_tar'] = array('default' => FALSE); - return $options; - } - - /** - * {@inheritdoc} - */ - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - parent::buildOptionsForm($form, $form_state); - $form['extension_detect_tar'] = array( - '#type' => 'checkbox', - '#title' => $this->t('Detect if tar is part of the extension'), - '#description' => $this->t("See if the previous extension is '.tar' and if so, add that, so we see 'tar.gz' or 'tar.bz2' instead of just 'gz'."), - '#default_value' => $this->options['extension_detect_tar'], - ); - } - - /** - * {@inheritdoc} - */ - public function render(ResultRow $values) { - $value = $this->getValue($values); - if (!$this->options['extension_detect_tar']) { - if (preg_match('/\.([^\.]+)$/', $value, $match)) { - return $this->sanitizeValue($match[1]); - } - } - else { - $file_parts = explode('.', basename($value)); - // If there is an extension. - if (count($file_parts) > 1) { - $extension = array_pop($file_parts); - $last_part_in_name = array_pop($file_parts); - if ($last_part_in_name === 'tar') { - $extension = 'tar.' . $extension; - } - return $this->sanitizeValue($extension); - } - } - } - -} diff --git a/core/modules/file/src/Plugin/views/field/FileMime.php b/core/modules/file/src/Plugin/views/field/FileMime.php deleted file mode 100644 index 4652f177dbb4..000000000000 --- a/core/modules/file/src/Plugin/views/field/FileMime.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/** - * @file - * Definition of Drupal\file\Plugin\views\field\FileMime. - */ - -namespace Drupal\file\Plugin\views\field; - -use Drupal\Core\Form\FormStateInterface; -use Drupal\views\ResultRow; - -/** - * Field handler to add rendering MIME type images as an option on the filemime field. - * - * @ingroup views_field_handlers - * - * @ViewsField("file_filemime") - */ -class FileMime extends File { - - protected function defineOptions() { - $options = parent::defineOptions(); - $options['filemime_image'] = array('default' => FALSE); - return $options; - } - - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['filemime_image'] = array( - '#title' => $this->t('Display an icon representing the file type, instead of the MIME text (such as "image/jpeg")'), - '#type' => 'checkbox', - '#default_value' => !empty($this->options['filemime_image']), - ); - parent::buildOptionsForm($form, $form_state); - } - - /** - * {@inheritdoc} - */ - public function render(ResultRow $values) { - $data = $values->{$this->field_alias}; - if (!empty($this->options['filemime_image']) && $data !== NULL && $data !== '') { - $file_icon = array( - '#theme' => 'image__file_icon', - '#file' => $values->_entity, - ); - $data = drupal_render($file_icon); - } - - return $this->renderLink($data, $values); - } - -} diff --git a/core/modules/file/src/Plugin/views/field/Status.php b/core/modules/file/src/Plugin/views/field/Status.php deleted file mode 100644 index a18209982821..000000000000 --- a/core/modules/file/src/Plugin/views/field/Status.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -/** - * @file - * Definition of Drupal\file\Plugin\views\field\Status. - */ - -namespace Drupal\file\Plugin\views\field; - -use Drupal\views\Plugin\views\field\FieldPluginBase; -use Drupal\views\ResultRow; - -/** - * Field handler to translate a node type into its readable form. - * - * @ingroup views_field_handlers - * - * @ViewsField("file_status") - */ -class Status extends FieldPluginBase { - - /** - * {@inheritdoc} - */ - public function render(ResultRow $values) { - $value = $this->getValue($values); - return _views_file_status($value); - } - -} diff --git a/core/modules/file/src/Plugin/views/field/Uri.php b/core/modules/file/src/Plugin/views/field/Uri.php deleted file mode 100644 index 1df8c25a40a1..000000000000 --- a/core/modules/file/src/Plugin/views/field/Uri.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -/** - * @file - * Definition of Drupal\file\Plugin\views\field\Uri. - */ - -namespace Drupal\file\Plugin\views\field; - -use Drupal\Core\Form\FormStateInterface; -use Drupal\views\ResultRow; - -/** - * Field handler to add rendering file paths as file URLs instead of as internal file URIs. - * - * @ViewsField("file_uri") - */ -class Uri extends File { - - protected function defineOptions() { - $options = parent::defineOptions(); - $options['file_download_path'] = array('default' => FALSE); - return $options; - } - - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['file_download_path'] = array( - '#title' => $this->t('Display download path instead of file storage URI'), - '#description' => $this->t('This will provide the full download URL rather than the internal filestream address.'), - '#type' => 'checkbox', - '#default_value' => !empty($this->options['file_download_path']), - ); - parent::buildOptionsForm($form, $form_state); - } - - /** - * {@inheritdoc} - */ - public function render(ResultRow $values) { - $data = $values->{$this->field_alias}; - if (!empty($this->options['file_download_path']) && $data !== NULL && $data !== '') { - $data = file_create_url($data); - } - return $this->renderLink($data, $values); - } - -} diff --git a/core/modules/file/src/Plugin/views/wizard/File.php b/core/modules/file/src/Plugin/views/wizard/File.php index 36f57ac15c96..5b64f8445319 100644 --- a/core/modules/file/src/Plugin/views/wizard/File.php +++ b/core/modules/file/src/Plugin/views/wizard/File.php @@ -54,8 +54,8 @@ protected function defaultDisplayOptions() { $display_options['fields']['filename']['alter']['html'] = 0; $display_options['fields']['filename']['hide_empty'] = 0; $display_options['fields']['filename']['empty_zero'] = 0; - $display_options['fields']['filename']['link_to_file'] = 1; - $display_options['fields']['filename']['plugin_id'] = 'file'; + $display_options['fields']['filename']['plugin_id'] = 'field'; + $display_options['fields']['filename']['type'] = 'file_link'; return $display_options; } diff --git a/core/modules/file/src/Tests/Formatter/FileEntityFormatterTest.php b/core/modules/file/src/Tests/Formatter/FileEntityFormatterTest.php new file mode 100644 index 000000000000..1c9a275f77fe --- /dev/null +++ b/core/modules/file/src/Tests/Formatter/FileEntityFormatterTest.php @@ -0,0 +1,173 @@ +<?php + +/** + * @file + * Contains \Drupal\file\Tests\Formatter\FileEntityFormatterTest. + */ + +namespace Drupal\file\Tests\Formatter; + +use Drupal\Core\Entity\Entity\EntityViewDisplay; +use Drupal\Core\Url; +use Drupal\file\Entity\File; +use Drupal\simpletest\KernelTestBase; + +/** + * Tests the default file formatter. + * + * @group field + */ +class FileEntityFormatterTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = ['file', 'user']; + + /** + * The files. + * + * @var array + */ + protected $files; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->installEntitySchema('file'); + + $this->files = []; + file_put_contents('public://file.png', str_repeat('t', 10)); + $file = File::create([ + 'uri' => 'public://file.png', + 'filename' => 'file.png', + ]); + $file->save(); + $this->files[] = $file; + + file_put_contents('public://file.tar', str_repeat('t', 200)); + $file = File::create([ + 'uri' => 'public://file.tar', + 'filename' => 'file.tar', + ]); + $file->save(); + $this->files[] = $file; + + file_put_contents('public://file.tar.gz', str_repeat('t', 40000)); + $file = File::create([ + 'uri' => 'public://file.tar.gz', + 'filename' => 'file.tar.gz', + ]); + $file->save(); + $this->files[] = $file; + + file_put_contents('public://file', str_repeat('t', 8000000)); + $file = File::create([ + 'uri' => 'public://file', + 'filename' => 'file', + ]); + $file->save(); + $this->files[] = $file; + } + + /** + * Tests the file_link field formatter. + */ + public function testFormatterFileLink() { + $entity_display = EntityViewDisplay::create([ + 'targetEntityType' => 'file', + 'bundle' => 'file', + ]); + $entity_display->setComponent('filename', ['type' => 'file_link']); + + $build = $entity_display->buildMultiple($this->files)[0]['filename'][0]; + $this->assertEqual('file.png', $build['#title']); + $this->assertEqual(Url::fromUri(file_create_url('public://file.png')), $build['#url']); + } + + /** + * Tests the file_link field formatter. + */ + public function testFormatterFileUri() { + $entity_display = EntityViewDisplay::create([ + 'targetEntityType' => 'file', + 'bundle' => 'file', + ]); + $entity_display->setComponent('uri', ['type' => 'file_uri']); + + $build = $entity_display->buildMultiple($this->files)[0]['uri'][0]; + $this->assertEqual('public://file.png', $build['#markup']); + + $entity_display->setComponent('uri', ['type' => 'file_uri', 'settings' => ['file_download_path' => TRUE]]); + $build = $entity_display->buildMultiple($this->files)[0]['uri'][0]; + $this->assertEqual(file_create_url('public://file.png'), $build['#markup']); + + $entity_display->setComponent('uri', ['type' => 'file_uri', 'settings' => ['file_download_path' => TRUE, 'link_to_file' => TRUE]]); + $build = $entity_display->buildMultiple($this->files)[0]['uri'][0]; + $this->assertEqual(file_create_url('public://file.png'), $build['#title']); + $this->assertEqual(Url::fromUri(file_create_url('public://file.png')), $build['#url']); + } + + /** + * Tests the file_extension field formatter. + */ + public function testFormatterFileExtension() { + $entity_display = EntityViewDisplay::create([ + 'targetEntityType' => 'file', + 'bundle' => 'file', + ]); + $entity_display->setComponent('filename', ['type' => 'file_extension']); + + $expected = ['png', 'tar', 'gz', '']; + foreach (array_values($this->files) as $i => $file) { + $build = $entity_display->build($file); + $this->assertEqual($expected[$i], $build['filename'][0]['#markup']); + } + + $entity_display->setComponent('filename', ['type' => 'file_extension', 'settings' => ['extension_detect_tar' => TRUE]]); + + $expected = ['png', 'tar', 'tar.gz', '']; + foreach (array_values($this->files) as $i => $file) { + $build = $entity_display->build($file); + $this->assertEqual($expected[$i], $build['filename'][0]['#markup']); + } + } + + /** + * Tests the file_extension field formatter. + */ + public function testFormatterFileMime() { + $entity_display = EntityViewDisplay::create([ + 'targetEntityType' => 'file', + 'bundle' => 'file', + ]); + $entity_display->setComponent('filemime', ['type' => 'file_filemime', 'settings' => ['filemime_image' => TRUE]]); + + foreach (array_values($this->files) as $i => $file) { + $build = $entity_display->build($file); + $this->assertEqual('image__file_icon', $build['filemime'][0]['#theme']); + $this->assertEqual(spl_object_hash($file), spl_object_hash($build['filemime'][0]['#file'])); + } + } + + /** + * Tests the file_size field formatter. + */ + public function testFormatterFileSize() { + $entity_display = EntityViewDisplay::create([ + 'targetEntityType' => 'file', + 'bundle' => 'file', + ]); + $entity_display->setComponent('filesize', ['type' => 'file_size']); + + $expected = ['10 bytes', '200 bytes', '39.06 KB', '7.63 MB']; + foreach (array_values($this->files) as $i => $file) { + $build = $entity_display->build($file); + $this->assertEqual($expected[$i], $build['filesize'][0]['#markup']); + } + } + +} diff --git a/core/modules/file/src/Tests/Views/ExtensionViewsFieldTest.php b/core/modules/file/src/Tests/Views/ExtensionViewsFieldTest.php index 7a01bc7d931e..75623f4e5a6d 100644 --- a/core/modules/file/src/Tests/Views/ExtensionViewsFieldTest.php +++ b/core/modules/file/src/Tests/Views/ExtensionViewsFieldTest.php @@ -7,6 +7,7 @@ namespace Drupal\file\Tests\Views; +use Drupal\file\Entity\File; use Drupal\views\Views; use Drupal\views\Tests\ViewUnitTestBase; use Drupal\views\Tests\ViewTestData; @@ -36,30 +37,32 @@ class ExtensionViewsFieldTest extends ViewUnitTestBase { protected function setUp() { parent::setUp(); ViewTestData::createTestViews(get_class($this), array('file_test_views')); - } - /** - * {@inheritdoc} - */ - protected function dataSet() { - $data = parent::dataSet(); - $data[0]['name'] = 'file.png'; - $data[1]['name'] = 'file.tar'; - $data[2]['name'] = 'file.tar.gz'; - $data[3]['name'] = 'file'; - - return $data; - } + $this->installEntitySchema('file'); - /** - * {@inheritdoc} - */ - protected function viewsData() { - $data = parent::viewsData(); - $data['views_test_data']['name']['field']['id'] = 'file_extension'; - $data['views_test_data']['name']['real field'] = 'name'; + file_put_contents('public://file.png', ''); + File::create([ + 'uri' => 'public://file.png', + 'filename' => 'file.png', + ])->save(); + + file_put_contents('public://file.tar', ''); + File::create([ + 'uri' => 'public://file.tar', + 'filename' => 'file.tar', + ])->save(); - return $data; + file_put_contents('public://file.tar.gz', ''); + File::create([ + 'uri' => 'public://file.tar.gz', + 'filename' => 'file.tar.gz', + ])->save(); + + file_put_contents('public://file', ''); + File::create([ + 'uri' => 'public://file', + 'filename' => 'file', + ])->save(); } /** @@ -68,20 +71,26 @@ protected function viewsData() { public function testFileExtensionTarOption() { $view = Views::getView('file_extension_view'); $view->setDisplay(); - $this->executeView($view); // Test without the tar option. - $this->assertEqual($view->field['name']->advancedRender($view->result[0]), 'png'); - $this->assertEqual($view->field['name']->advancedRender($view->result[1]), 'tar'); - $this->assertEqual($view->field['name']->advancedRender($view->result[2]), 'gz'); - $this->assertEqual($view->field['name']->advancedRender($view->result[3]), ''); + $this->assertEqual($view->field['extension']->advancedRender($view->result[0]), 'png'); + $this->assertEqual($view->field['extension']->advancedRender($view->result[1]), 'tar'); + $this->assertEqual($view->field['extension']->advancedRender($view->result[2]), 'gz'); + $this->assertEqual($view->field['extension']->advancedRender($view->result[3]), ''); // Test with the tar option. - $view->field['name']->options['extension_detect_tar'] = TRUE; - $this->assertEqual($view->field['name']->advancedRender($view->result[0]), 'png'); - $this->assertEqual($view->field['name']->advancedRender($view->result[1]), 'tar'); - $this->assertEqual($view->field['name']->advancedRender($view->result[2]), 'tar.gz'); - $this->assertEqual($view->field['name']->advancedRender($view->result[3]), ''); + + $view = Views::getView('file_extension_view'); + $view->setDisplay(); + $view->initHandlers(); + + $view->field['extension']->options['settings']['extension_detect_tar'] = TRUE; + $this->executeView($view); + + $this->assertEqual($view->field['extension']->advancedRender($view->result[0]), 'png'); + $this->assertEqual($view->field['extension']->advancedRender($view->result[1]), 'tar'); + $this->assertEqual($view->field['extension']->advancedRender($view->result[2]), 'tar.gz'); + $this->assertEqual($view->field['extension']->advancedRender($view->result[3]), ''); } } diff --git a/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php b/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php index b448e0e2868f..74baac34e7f5 100644 --- a/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php +++ b/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php @@ -9,8 +9,6 @@ use Drupal\file\Entity\File; use Drupal\language\Entity\ConfigurableLanguage; -use Drupal\node\Entity\Node; -use Drupal\node\Entity\NodeType; use Drupal\user\Entity\User; use Drupal\views\Tests\Handler\FieldFieldAccessTestBase; @@ -61,15 +59,15 @@ public function testFileFields() { // @todo Expand the test coverage in https://www.drupal.org/node/2464635 - // $this->assertFieldAccess('file', 'fid', $file->id()); + $this->assertFieldAccess('file', 'fid', $file->id()); // $this->assertFieldAccess('file', 'uuid', $file->uuid()); $this->assertFieldAccess('file', 'langcode', $file->language()->getName()); $this->assertFieldAccess('file', 'uid', 'test user'); - // $this->assertFieldAccess('file', 'filename', $file->getFilename()); - // $this->assertFieldAccess('file', 'uri', $file->getFileUri()); - // $this->assertFieldAccess('file', 'filemime', $file->filemime->value); - // $this->assertFieldAccess('file', 'size', '4 Bytes'); - // $this->assertFieldAccess('file', 'status', 'On'); + $this->assertFieldAccess('file', 'filename', $file->getFilename()); + $this->assertFieldAccess('file', 'uri', $file->getFileUri()); + $this->assertFieldAccess('file', 'filemime', $file->filemime->value); + $this->assertFieldAccess('file', 'filesize', '4 bytes'); + $this->assertFieldAccess('file', 'status', t('Permanent')); // $this->assertFieldAccess('file', 'created', \Drupal::service('date.formatter')->format(123456)); // $this->assertFieldAccess('file', 'changed', \Drupal::service('date.formatter')->format(REQUEST_TIME)); } diff --git a/core/modules/file/tests/modules/file_test_views/test_views/views.view.file_extension_view.yml b/core/modules/file/tests/modules/file_test_views/test_views/views.view.file_extension_view.yml index a8351f71bcdb..f870fb3df84d 100644 --- a/core/modules/file/tests/modules/file_test_views/test_views/views.view.file_extension_view.yml +++ b/core/modules/file/tests/modules/file_test_views/test_views/views.view.file_extension_view.yml @@ -6,8 +6,8 @@ label: 'Test view for file extension views field handler' module: views description: '' tag: '' -base_table: views_test_data -base_field: nid +base_table: file_managed +base_field: fid core: '8' display: default: @@ -17,36 +17,31 @@ display: pager: false sorts: false fields: - age: - field: age - id: age + fid: + field: fid + id: fid relationship: none - table: views_test_data - plugin_id: numeric - id: - field: id - id: id + table: file_managed + plugin_id: field + extension: + field: extension + id: extension relationship: none - table: views_test_data - plugin_id: numeric - name: - field: name - id: file_extension - relationship: none - table: views_test_data - plugin_id: string + table: file_managed + plugin_id: field + type: file_extension pager: options: offset: 0 type: none sorts: - id: - field: id - id: id + fid: + field: fid + id: fid order: ASC relationship: none - table: views_test_data - plugin_id: numeric + table: file_managed + plugin_id: standard display_plugin: default display_title: Master id: default -- GitLab