diff --git a/core/modules/media/src/MediaViewsData.php b/core/modules/media/src/MediaViewsData.php index 393548be84c6c94ce6118ee6d62a842e0db64b60..2dc16496866b28b736917814fbe85afe7f1c50bf 100644 --- a/core/modules/media/src/MediaViewsData.php +++ b/core/modules/media/src/MediaViewsData.php @@ -18,6 +18,13 @@ public function getViewsData() { $data['media_field_data']['table']['wizard_id'] = 'media'; $data['media_field_revision']['table']['wizard_id'] = 'media_revision'; + $data['media_revision']['revision_user']['help'] = $this->t('The user who created the revision.'); + $data['media_revision']['revision_user']['relationship']['label'] = $this->t('revision user'); + $data['media_revision']['revision_user']['filter']['id'] = 'user_name'; + + $data['media_revision']['table']['join']['media_field_data']['left_field'] = 'vid'; + $data['media_revision']['table']['join']['media_field_data']['field'] = 'vid'; + $data['media_field_data']['status_extra'] = [ 'title' => $this->t('Published status or admin user'), 'help' => $this->t('Filters out unpublished media if the current user cannot view it.'), diff --git a/core/modules/media/tests/modules/media_test_views/test_views/views.view.test_media_revision_uid.yml b/core/modules/media/tests/modules/media_test_views/test_views/views.view.test_media_revision_uid.yml new file mode 100644 index 0000000000000000000000000000000000000000..af5e588a760c26fd44a16415e8eb1ee59a4cb803 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_views/test_views/views.view.test_media_revision_uid.yml @@ -0,0 +1,388 @@ +langcode: en +status: true +dependencies: + module: + - media + - user +id: test_media_revision_uid +label: 'Test Media revision uid' +module: views +description: '' +tag: '' +base_table: media_field_data +base_field: mid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: none + options: + offset: 0 + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + mid: + id: mid + table: media_field_data + field: mid + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: 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: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: false + 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: false + entity_type: media + entity_field: mid + plugin_id: field + vid: + id: vid + table: media_field_data + field: vid + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: 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: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: false + 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: false + entity_type: media + entity_field: vid + plugin_id: field + uid: + id: uid + table: media_field_data + field: uid + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: 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: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: false + group_column: target_id + 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: false + entity_type: media + entity_field: uid + plugin_id: field + revision_user: + id: revision_user + table: media_revision + field: revision_user + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: 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: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: false + group_column: target_id + 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: false + entity_type: media + entity_field: revision_user + plugin_id: field + filters: + revision_user: + id: revision_user + table: media_revision + field: revision_user + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: revision_user_op + label: 'Revision user' + description: '' + use_operator: false + operator: revision_user_op + operator_limit_selection: false + operator_list: { } + identifier: revision_user + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: media + entity_field: revision_user + plugin_id: user_name + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + filter_groups: + operator: AND + groups: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - user.permissions + tags: { } diff --git a/core/modules/media/tests/src/Kernel/Views/RevisionUserTest.php b/core/modules/media/tests/src/Kernel/Views/RevisionUserTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c438c198f72e6bba7f90af07f9290000c8599a36 --- /dev/null +++ b/core/modules/media/tests/src/Kernel/Views/RevisionUserTest.php @@ -0,0 +1,170 @@ +<?php + +namespace Drupal\Tests\media\Kernel\Views; + +use Drupal\media\Entity\Media; +use Drupal\Tests\user\Traits\UserCreationTrait; +use Drupal\Tests\views\Kernel\ViewsKernelTestBase; +use Drupal\views\Tests\ViewResultAssertionTrait; +use Drupal\views\Tests\ViewTestData; +use Drupal\views\Views; +use Drupal\Tests\media\Traits\MediaTypeCreationTrait; + +/** + * Tests the media_revision_user field. + * + * @group media + */ +class RevisionUserTest extends ViewsKernelTestBase { + + use UserCreationTrait; + use ViewResultAssertionTrait; + use MediaTypeCreationTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'media', + 'media_test_views', + 'media_test_source', + 'system', + 'user', + 'views', + 'image', + 'field', + 'file', + ]; + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = ['test_media_revision_uid']; + + /** + * The test media type. + * + * @var \Drupal\media\MediaTypeInterface + */ + protected $testMediaType; + + /** + * Map column names. + * + * @var array + */ + public static $columnMap = [ + 'mid' => 'mid', + 'vid' => 'vid', + 'uid' => 'uid', + 'revision_user' => 'revision_user', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp($import_test_views = TRUE): void { + parent::setUp($import_test_views); + + $this->installEntitySchema('media'); + $this->installEntitySchema('file'); + $this->installSchema('file', 'file_usage'); + $this->installEntitySchema('user'); + $this->installConfig(['field', 'system', 'image', 'file', 'media']); + + if ($import_test_views) { + ViewTestData::createTestViews(get_class($this), ['media_test_views']); + } + + $this->testMediaType = $this->createMediaType('test'); + } + + /** + * Tests the media_revision_user relationship. + */ + public function testRevisionUser() { + $primary_author = $this->createUser(); + $secondary_author = $this->createUser(); + + $media = Media::create([ + 'name' => 'Test media', + 'bundle' => $this->testMediaType->id(), + 'uid' => $primary_author->id(), + ]); + $media->setRevisionUserId($primary_author->id()); + $media->save(); + + $view = Views::getView('test_media_revision_uid'); + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'mid' => 1, + 'vid' => 1, + 'uid' => $primary_author->id(), + 'revision_user' => $primary_author->id(), + ], + ], static::$columnMap); + + // Test results shows the original author as well as the revision author. + $media->setRevisionUser($secondary_author); + $media->setNewRevision(); + $media->save(); + + $view = Views::getView('test_media_revision_uid'); + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'mid' => 1, + 'vid' => 2, + 'uid' => $primary_author->id(), + 'revision_user' => $secondary_author->id(), + ], + ], static::$columnMap); + + // Build a larger dataset to allow filtering. + $media2_name = $this->randomString(); + $media2 = Media::create([ + 'name' => $media2_name, + 'bundle' => $this->testMediaType->id(), + 'uid' => $primary_author->id(), + ]); + $media2->save(); + $media2->setRevisionUser($primary_author); + $media2->setNewRevision(); + $media2->save(); + + $view = Views::getView('test_media_revision_uid'); + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'mid' => 1, + 'vid' => 2, + 'uid' => $primary_author->id(), + 'revision_user' => $secondary_author->id(), + ], + [ + 'mid' => 2, + 'vid' => 4, + 'uid' => $primary_author->id(), + 'revision_user' => $primary_author->id(), + ], + ], static::$columnMap); + + // Test filter by revision_user. + $view = Views::getView('test_media_revision_uid'); + $view->initHandlers(); + $view->filter['revision_user']->value = [$secondary_author->id()]; + $this->executeView($view); + $this->assertIdenticalResultset($view, [ + [ + 'mid' => 1, + 'vid' => 2, + 'uid' => $primary_author->id(), + 'revision_user' => $secondary_author->id(), + ], + ], static::$columnMap); + } + +}