From 8cf78305aff9dd30696e61392d80f32fdb52321f Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sun, 21 Jul 2013 09:17:17 +0100 Subject: [PATCH] Issue #2005166 by slashrsm, dawehner: Create simple file listing under admin/content/file. --- .../file/config/views.view.file_usage.yml | 378 ++++++++++++ core/modules/file/config/views.view.files.yml | 579 ++++++++++++++++++ core/modules/file/file.module | 37 ++ core/modules/file/file.views.inc | 22 +- .../lib/Drupal/file/Tests/FileListingTest.php | 117 ++++ .../views/Plugin/views/field/EntityLabel.php | 133 ++++ 6 files changed, 1253 insertions(+), 13 deletions(-) create mode 100755 core/modules/file/config/views.view.file_usage.yml create mode 100755 core/modules/file/config/views.view.files.yml create mode 100644 core/modules/file/lib/Drupal/file/Tests/FileListingTest.php create mode 100644 core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php diff --git a/core/modules/file/config/views.view.file_usage.yml b/core/modules/file/config/views.view.file_usage.yml new file mode 100755 index 00000000000..8b768724dd1 --- /dev/null +++ b/core/modules/file/config/views.view.file_usage.yml @@ -0,0 +1,378 @@ +base_field: fid +base_table: file_managed +core: 8.x +description: 'Displays file usage information for a given file.' +status: '1' +display: + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: '1' + display_options: + path: admin/content/files/usage/% + menu: + type: none + title: 'File usage' + description: 'Usages list for a given file.' + name: admin + weight: '0' + context: '0' + default: + display_plugin: default + id: default + display_title: Master + position: '1' + display_options: + access: + type: perm + options: + perm: 'access files overview' + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: '0' + distinct: '0' + slave: '0' + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: '0' + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: '1' + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: '10' + offset: '0' + id: '0' + total_pages: '' + expose: + items_per_page: '0' + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: '0' + items_per_page_options_all_label: '- All -' + offset: '0' + offset_label: Offset + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + quantity: '9' + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: '1' + row_class_special: '1' + override: '1' + sticky: '0' + summary: '' + columns: + entity_label: entity_label + type: type + module: module + count: count + info: + entity_label: + sortable: '1' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: '' + type: + sortable: '1' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: 'priority-medium' + module: + sortable: '0' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: 'priority-low' + count: + sortable: '0' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: '' + default: 'entity_label' + empty_table: '1' + row: + type: fields + fields: + entity_label: + id: entity_label + table: file_usage + field: entity_label + relationship: none + group_type: group + admin_label: '' + label: 'Entity' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + link_to_entity: '1' + plugin_id: file_usage_entity_label + type: + id: type + table: file_usage + field: type + relationship: none + group_type: group + admin_label: '' + label: 'Entity type' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + plugin_id: standard + module: + id: module + table: file_usage + field: module + relationship: none + group_type: group + admin_label: '' + label: 'Registering module' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + plugin_id: standard + count: + id: count + table: file_usage + field: count + relationship: none + group_type: group + admin_label: '' + label: 'Use count' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + set_precision: '0' + precision: '0' + decimal: . + separator: ',' + format_plural: '0' + format_plural_singular: '1' + format_plural_plural: '@count' + prefix: '' + suffix: '' + plugin_id: numeric + filters: { } + sorts: { } + title: 'File usage' + header: { } + footer: { } + empty: { } + relationships: { } + arguments: + fid: + id: fid + table: file_managed + field: fid + relationship: none + group_type: group + admin_label: '' + default_action: 'not found' + exception: + value: all + title_enable: '0' + title: All + title_enable: '1' + title: 'File usage information for %1' + breadcrumb_enable: '0' + breadcrumb: '' + default_argument_type: fixed + default_argument_options: + argument: '' + default_argument_skip_url: '0' + summary_options: + base_path: '' + count: '1' + items_per_page: '25' + override: '0' + summary: + sort_order: asc + number_of_records: '0' + format: default_summary + specify_validation: '0' + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: '0' + not: '0' + plugin_id: file_fid +label: 'File usage' +module: file +id: file_usage +tag: 'default' +uuid: 360a2cdb-a14c-4b41-9827-3930a483caf8 +langcode: en diff --git a/core/modules/file/config/views.view.files.yml b/core/modules/file/config/views.view.files.yml new file mode 100755 index 00000000000..b0b182decd8 --- /dev/null +++ b/core/modules/file/config/views.view.files.yml @@ -0,0 +1,579 @@ +base_field: fid +base_table: file_managed +core: 8.x +description: 'Find and manage files.' +status: '1' +display: + default: + display_plugin: default + id: default + display_title: Master + position: '1' + display_options: + access: + type: perm + options: + perm: 'access files overview' + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: '0' + distinct: '0' + slave: '0' + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Filter + reset_button: '0' + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: '1' + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: '50' + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: '1' + row_class_special: '1' + override: '1' + sticky: '0' + summary: '' + columns: + filename: filename + filemime: filemime + filesize: filesize + status: status + timestamp: timestamp + count: count + info: + filename: + sortable: '1' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: '' + filemime: + sortable: '1' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: priority-medium + filesize: + sortable: '1' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: priority-low + status: + sortable: '0' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: priority-low + timestamp: + sortable: '1' + default_sort_order: desc + align: '' + separator: '' + empty_column: '0' + responsive: '' + count: + sortable: '0' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: priority-medium + default: timestamp + empty_table: '1' + row: + type: fields + fields: + fid: + id: fid + table: file_managed + field: fid + alter: + alter_text: '0' + make_link: '0' + absolute: '0' + trim: '0' + word_boundary: '0' + ellipsis: '0' + strip_tags: '0' + html: '0' + hide_empty: '0' + empty_zero: '0' + link_to_file: '0' + relationship: none + group_type: group + admin_label: '' + label: Fid + exclude: '1' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_alter_empty: '1' + filename: + id: filename + table: file_managed + field: filename + alter: + alter_text: '0' + make_link: '0' + absolute: '0' + trim: '0' + word_boundary: '0' + ellipsis: '0' + strip_tags: '0' + html: '0' + hide_empty: '0' + empty_zero: '0' + link_to_file: '1' + relationship: none + group_type: group + admin_label: '' + label: Name + exclude: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_alter_empty: '1' + filemime: + id: filemime + table: file_managed + field: filemime + relationship: none + group_type: group + admin_label: '' + label: 'Mime type' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + link_to_file: '0' + filemime_image: '0' + plugin_id: file_filemime + filesize: + id: filesize + table: file_managed + field: filesize + relationship: none + group_type: group + admin_label: '' + label: Size + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + file_size_display: formatted + plugin_id: file_size + status: + id: status + table: file_managed + field: status + relationship: none + group_type: group + admin_label: '' + label: Status + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + plugin_id: file_status + timestamp: + id: timestamp + table: file_managed + field: timestamp + relationship: none + group_type: group + admin_label: '' + label: 'Upload date' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '0' + path: '' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + date_format: medium + custom_date_format: '' + timezone: '' + plugin_id: date + count: + id: count + table: file_usage + field: count + relationship: none + group_type: sum + admin_label: '' + label: 'Used in' + exclude: '0' + alter: + alter_text: '0' + text: '' + make_link: '1' + path: 'admin/content/files/usage/[fid]' + absolute: '0' + external: '0' + replace_spaces: '0' + path_case: none + trim_whitespace: '0' + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: '0' + max_length: '' + word_boundary: '1' + ellipsis: '1' + more_link: '0' + more_link_text: '' + more_link_path: '' + strip_tags: '0' + trim: '0' + preserve_tags: '' + html: '0' + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: '1' + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: '1' + empty: '' + hide_empty: '0' + empty_zero: '0' + hide_alter_empty: '1' + set_precision: '0' + precision: '0' + decimal: . + separator: ',' + format_plural: '1' + format_plural_singular: '1 place' + format_plural_plural: '@count places' + prefix: '' + suffix: '' + plugin_id: numeric + filters: + filename: + id: filename + table: file_managed + field: filename + relationship: none + group_type: group + admin_label: '' + operator: word + value: '' + group: '1' + exposed: '1' + expose: + operator_id: filemime_op + label: 'Filename' + description: '' + use_operator: '0' + operator: filename_op + identifier: filename + required: '0' + remember: '0' + multiple: '0' + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: '0' + group_info: + label: '' + description: '' + identifier: '' + optional: '1' + widget: select + multiple: '0' + remember: '0' + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: string + filemime: + id: filemime + table: file_managed + field: filemime + relationship: none + group_type: group + admin_label: '' + operator: word + value: '' + group: '1' + exposed: '1' + expose: + operator_id: filemime_op + label: 'Mime type' + description: '' + use_operator: '0' + operator: filemime_op + identifier: filemime + required: '0' + remember: '0' + multiple: '0' + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: '0' + group_info: + label: '' + description: '' + identifier: '' + optional: '1' + widget: select + multiple: '0' + remember: '0' + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: string + status: + id: status + table: file_managed + field: status + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: '1' + exposed: '1' + expose: + operator_id: status_op + label: Status + description: '' + use_operator: '0' + operator: status_op + identifier: status + required: '0' + remember: '0' + multiple: '0' + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: '0' + is_grouped: '0' + group_info: + label: '' + description: '' + identifier: '' + optional: '1' + widget: select + multiple: '0' + remember: '0' + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: file_status + sorts: { } + title: Files + header: { } + footer: { } + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + empty: '1' + content: 'No files available.' + plugin_id: text_custom + relationships: { } + arguments: { } + group_by: '1' + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: '1' + display_options: + path: admin/content/files + menu: + type: tab + title: Files + description: '' + name: admin + weight: '0' + context: '0' +label: Files +module: file +id: files +tag: default +uuid: 4b47e09e-16e0-494b-b447-7166191dbb6e +langcode: en diff --git a/core/modules/file/file.module b/core/modules/file/file.module index b5973dcd7de..70dfdb43ea6 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -1660,3 +1660,40 @@ function file_library_info() { return $libraries; } + +/** + * Implements hook_permission(). + */ +function file_permission() { + $perms = array( + 'access files overview' => array( + 'title' => t('Access the Files overview page'), + 'description' => user_access('access files overview') + ? t('Get an overview of all files.', array('@url' => url('admin/content/files'))) + : t('Get an overview of all files.'), + ), + ); + + return $perms; +} + +/** + * Formats human-readable version of file status. + * + * @param int $choice + * integer Status code. + * @return string + * string Text-represented file status. + */ +function _views_file_status($choice = NULL) { + $status = array( + 0 => t('Temporary'), + FILE_STATUS_PERMANENT => t('Permanent'), + ); + + if (isset($choice)) { + return isset($status[$choice]) ? $status[$choice] : t('Unknown'); + } + + return $status; +} diff --git a/core/modules/file/file.views.inc b/core/modules/file/file.views.inc index 5c2743f6d47..db18c462734 100644 --- a/core/modules/file/file.views.inc +++ b/core/modules/file/file.views.inc @@ -439,6 +439,15 @@ function file_views_data() { 'id' => 'standard', ), ); + $data['file_usage']['entity_label'] = array( + 'title' => t('Entity label'), + 'help' => t('The label of the entity that is related to the file.'), + 'real field' => 'id', + 'field' => array( + 'id' => 'entity_label', + 'entity type field' => 'type', + ), + ); return $data; } @@ -507,16 +516,3 @@ function file_field_views_data_views_data_alter(&$data, $field) { ); } } - -function _views_file_status($choice = NULL) { - $status = array( - 0 => t('Temporary'), - FILE_STATUS_PERMANENT => t('Permanent'), - ); - - if (isset($choice)) { - return isset($status[$choice]) ? $status[$choice] : t('Unknown'); - } - - return $status; -} diff --git a/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php b/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php new file mode 100644 index 00000000000..b533ddd8d0d --- /dev/null +++ b/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php @@ -0,0 +1,117 @@ + 'File listing', + 'description' => 'Tests file listing page functionality.', + 'group' => 'File', + ); + } + + function setUp() { + parent::setUp(); + + $this->admin_user = $this->drupalCreateUser(array('access files overview', 'bypass node access')); + $this->base_user = $this->drupalCreateUser(); + $this->createFileField('file', 'article', array(), array('file_extensions' => 'txt png')); + } + + /** + * Calculates total count of usages for a file. + * + * @param $usage array + * Array of file usage information as returned from file_usage subsystem. + * @return int + * Total usage count. + */ + protected function sumUsages($usage) { + $count = 0; + foreach ($usage as $module) { + foreach ($module as $entity_type) { + foreach ($entity_type as $entity) { + $count += $entity; + } + } + } + + return $count; + } + + /** + * Tests file overview with different user permissions. + */ + function testFileListingPages() { + // Users without sufficent permissions should not see file listing. + $this->drupalLogin($this->base_user); + $this->drupalGet('admin/content/files'); + $this->assertResponse(403); + + // Login with user with right permissions and test listing. + $this->drupalLogin($this->admin_user); + + for ($i = 0; $i < 5; $i++) { + $nodes[] = $this->drupalCreateNode(array('type' => 'article')); + } + + foreach ($nodes as &$node) { + $this->drupalGet('node/' . $node->nid . '/edit'); + $file = $this->getTestFile('image'); + + $edit = array( + 'files[file_' . Language::LANGCODE_NOT_SPECIFIED . '_' . 0 . ']' => drupal_realpath($file->getFileUri()), + ); + $this->drupalPost(NULL, $edit, t('Save')); + $node = entity_load('node', $node->nid)->getNGEntity(); + } + + $this->drupalGet('admin/content/files'); + $this->assertResponse(200); + + foreach ($nodes as $node) { + $file = entity_load('file', $node->file->target_id); + $this->assertText($file->getFilename()); + $this->assertLinkByHref(file_create_url($file->getFileUri())); + $this->assertLinkByHref('admin/content/files/usage/' . $file->id()); + } + $this->assertFalse(preg_match('/views-field-status priority-low\">\s*' . t('Temporary') . '/', $this->drupalGetContent()), t('All files are stored as permanent.')); + + // Use one file two times and check usage information. + $orphaned_file = $nodes[1]->file->target_id; + $used_file = $nodes[0]->file->target_id; + $nodes[1]->file->target_id = $used_file; + $nodes[1]->save(); + + $this->drupalGet('admin/content/files'); + $file = entity_load('file', $orphaned_file); + $usage = $this->sumUsages(file_usage()->listUsage($file)); + $this->assertRaw('admin/content/files/usage/' . $file->id() . '">' . $usage); + + $file = entity_load('file', $used_file); + $usage = $this->sumUsages(file_usage()->listUsage($file)); + $this->assertRaw('admin/content/files/usage/' . $file->id() . '">' . $usage); + + $result = $this->xpath("//td[contains(@class, 'views-field-status') and contains(text(), :value)]", array(':value' => t('Temporary'))); + $this->assertEqual(1, count($result), t('Unused file marked as temporary.')); + } +} diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php new file mode 100644 index 00000000000..7ecf18ecb85 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php @@ -0,0 +1,133 @@ +entityManager = $manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('plugin.manager.entity') + ); + } + + /** + * {@inheritdoc} + */ + public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + parent::init($view, $display, $options); + $this->additional_fields[$this->definition['entity type field']] = $this->definition['entity type field']; + } + + /** + * {@inheritdoc} + */ + protected function defineOptions() { + $options = parent::defineOptions(); + $options['link_to_entity'] = array('default' => FALSE); + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + $form['link_to_entity'] = array( + '#title' => t('Link to entity'), + '#description' => t('Make entity label a link to entity page.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_entity']), + ); + parent::buildOptionsForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function render($values) { + $entity = $this->loadedReferencers[$this->getValue($values, $this->definition['entity type field'])][$this->getValue($values)]; + + if (empty($entity)) { + return NULL; + } + + if (!empty($this->options['link_to_entity'])) { + $uri = $entity->uri(); + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = $uri['path']; + } + + return $this->sanitizeValue($entity->label()); + } + + /** + * {@inheritdoc} + */ + public function preRender(&$values) { + parent::preRender($values); + + $entity_ids_per_type = array(); + foreach ($values as $value) { + $entity_ids_per_type[$this->getValue($value, 'type')][] = $this->getValue($value); + } + + foreach ($entity_ids_per_type as $type => $ids) { + $this->loadedReferencers[$type] = $this->entityManager->getStorageController($type)->loadMultiple($ids); + } + } + +}