Loading core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php +20 −7 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Drupal\media_library\Plugin\Field\FieldWidget; use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\SortArray; use Drupal\Core\Ajax\AjaxResponse; Loading Loading @@ -393,6 +394,20 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen ]; foreach ($referenced_entities as $delta => $media_item) { if ($media_item->access('view')) { // @todo Make the view mode configurable in https://www.drupal.org/project/drupal/issues/2971209 $preview = $view_builder->view($media_item, 'media_library'); } else { $item_label = $media_item->access('view label') ? $media_item->label() : new FormattableMarkup('@label @id', [ '@label' => $media_item->getEntityType()->getSingularLabel(), '@id' => $media_item->id(), ]); $preview = [ '#theme' => 'media_embed_error', '#message' => $this->t('You do not have permission to view @item_label.', ['@item_label' => $item_label]), ]; } $element['selection'][$delta] = [ '#theme' => 'media_library_item__widget', '#attributes' => [ Loading @@ -416,22 +431,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#value' => $this->t('Remove'), '#media_id' => $media_item->id(), '#attributes' => [ 'aria-label' => $this->t('Remove @label', ['@label' => $media_item->label()]), 'aria-label' => $media_item->access('view label') ? $this->t('Remove @label', ['@label' => $media_item->label()]) : $this->t('Remove media'), ], '#ajax' => [ 'callback' => [static::class, 'updateWidget'], 'wrapper' => $wrapper_id, 'progress' => [ 'type' => 'throbber', 'message' => $this->t('Removing @label.', ['@label' => $media_item->label()]), 'message' => $media_item->access('view label') ? $this->t('Removing @label.', ['@label' => $media_item->label()]) : $this->t('Removing media.'), ], ], '#submit' => [[static::class, 'removeItem']], // Prevent errors in other widgets from preventing removal. '#limit_validation_errors' => $limit_validation_errors, ], // @todo Make the view mode configurable in https://www.drupal.org/project/drupal/issues/2971209 'rendered_entity' => $view_builder->view($media_item, 'media_library'), 'rendered_entity' => $preview, 'target_id' => [ '#type' => 'hidden', '#value' => $media_item->id(), Loading Loading @@ -700,9 +714,8 @@ public static function updateWidget(array $form, FormStateInterface $form_state) // Announce the updated content to screen readers. if ($is_remove_button) { $announcement = new TranslatableMarkup('@label has been removed.', [ '@label' => Media::load($field_state['removed_item_id'])->label(), ]); $media_item = Media::load($field_state['removed_item_id']); $announcement = $media_item->access('view label') ? new TranslatableMarkup('@label has been removed.', ['@label' => $media_item->label()]) : new TranslatableMarkup('Media has been removed.'); } else { $new_items = count(static::getNewMediaItems($element, $form_state)); Loading core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php +56 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,8 @@ use Drupal\field\Entity\FieldConfig; use Drupal\FunctionalJavascriptTests\SortableTestTrait; use Drupal\user\Entity\Role; use Drupal\user\RoleInterface; /** * Tests the Media library entity reference widget. Loading Loading @@ -579,4 +581,58 @@ protected function sortableUpdate($item, $from, $to = NULL) { $this->getSession()->executeScript($script); } /** * Tests the preview displayed by the field widget. */ public function testWidgetPreview() { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); $node = $this->drupalCreateNode([ 'type' => 'basic_page', 'field_unlimited_media' => [ $this->mediaItems['Horse'], ], ]); $media_id = $this->mediaItems['Horse']->id(); // Assert that preview is present for current user, who can view media. $this->drupalGet($node->toUrl('edit-form')); $assert_session->elementTextContains('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0"]', 'Horse'); $remove_button = $page->find('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0-remove-button"]'); $this->assertSame('Remove Horse', $remove_button->getAttribute('aria-label')); $assert_session->pageTextNotContains('You do not have permission to view media item'); $remove_button->press(); $this->waitForText("Removing Horse."); $this->waitForText("Horse has been removed."); // Logout without saving. $this->drupalLogout(); // Create a user who can edit content but not view media. // Must remove permission from authenticated role first, otherwise the new // user will inherit that permission. $role = Role::load(RoleInterface::AUTHENTICATED_ID); $role->revokePermission('view media'); $role->save(); $non_media_editor = $this->drupalCreateUser([ 'access content', 'create basic_page content', 'edit any basic_page content', ]); $this->drupalLogin($non_media_editor); // Assert that preview does not reveal media name. $this->drupalGet($node->toUrl('edit-form')); // There should be no preview name. $assert_session->elementTextNotContains('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0"]', 'Horse'); // The remove button should have a generic message. $remove_button = $page->find('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0-remove-button"]'); $this->assertSame('Remove media', $remove_button->getAttribute('aria-label')); $assert_session->pageTextContains("You do not have permission to view media item $media_id."); // Confirm ajax text does not reveal media name. $remove_button->press(); $this->waitForText("Removing media."); $this->waitForText("Media has been removed."); } } Loading
core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php +20 −7 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Drupal\media_library\Plugin\Field\FieldWidget; use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\SortArray; use Drupal\Core\Ajax\AjaxResponse; Loading Loading @@ -393,6 +394,20 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen ]; foreach ($referenced_entities as $delta => $media_item) { if ($media_item->access('view')) { // @todo Make the view mode configurable in https://www.drupal.org/project/drupal/issues/2971209 $preview = $view_builder->view($media_item, 'media_library'); } else { $item_label = $media_item->access('view label') ? $media_item->label() : new FormattableMarkup('@label @id', [ '@label' => $media_item->getEntityType()->getSingularLabel(), '@id' => $media_item->id(), ]); $preview = [ '#theme' => 'media_embed_error', '#message' => $this->t('You do not have permission to view @item_label.', ['@item_label' => $item_label]), ]; } $element['selection'][$delta] = [ '#theme' => 'media_library_item__widget', '#attributes' => [ Loading @@ -416,22 +431,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#value' => $this->t('Remove'), '#media_id' => $media_item->id(), '#attributes' => [ 'aria-label' => $this->t('Remove @label', ['@label' => $media_item->label()]), 'aria-label' => $media_item->access('view label') ? $this->t('Remove @label', ['@label' => $media_item->label()]) : $this->t('Remove media'), ], '#ajax' => [ 'callback' => [static::class, 'updateWidget'], 'wrapper' => $wrapper_id, 'progress' => [ 'type' => 'throbber', 'message' => $this->t('Removing @label.', ['@label' => $media_item->label()]), 'message' => $media_item->access('view label') ? $this->t('Removing @label.', ['@label' => $media_item->label()]) : $this->t('Removing media.'), ], ], '#submit' => [[static::class, 'removeItem']], // Prevent errors in other widgets from preventing removal. '#limit_validation_errors' => $limit_validation_errors, ], // @todo Make the view mode configurable in https://www.drupal.org/project/drupal/issues/2971209 'rendered_entity' => $view_builder->view($media_item, 'media_library'), 'rendered_entity' => $preview, 'target_id' => [ '#type' => 'hidden', '#value' => $media_item->id(), Loading Loading @@ -700,9 +714,8 @@ public static function updateWidget(array $form, FormStateInterface $form_state) // Announce the updated content to screen readers. if ($is_remove_button) { $announcement = new TranslatableMarkup('@label has been removed.', [ '@label' => Media::load($field_state['removed_item_id'])->label(), ]); $media_item = Media::load($field_state['removed_item_id']); $announcement = $media_item->access('view label') ? new TranslatableMarkup('@label has been removed.', ['@label' => $media_item->label()]) : new TranslatableMarkup('Media has been removed.'); } else { $new_items = count(static::getNewMediaItems($element, $form_state)); Loading
core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php +56 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,8 @@ use Drupal\field\Entity\FieldConfig; use Drupal\FunctionalJavascriptTests\SortableTestTrait; use Drupal\user\Entity\Role; use Drupal\user\RoleInterface; /** * Tests the Media library entity reference widget. Loading Loading @@ -579,4 +581,58 @@ protected function sortableUpdate($item, $from, $to = NULL) { $this->getSession()->executeScript($script); } /** * Tests the preview displayed by the field widget. */ public function testWidgetPreview() { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); $node = $this->drupalCreateNode([ 'type' => 'basic_page', 'field_unlimited_media' => [ $this->mediaItems['Horse'], ], ]); $media_id = $this->mediaItems['Horse']->id(); // Assert that preview is present for current user, who can view media. $this->drupalGet($node->toUrl('edit-form')); $assert_session->elementTextContains('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0"]', 'Horse'); $remove_button = $page->find('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0-remove-button"]'); $this->assertSame('Remove Horse', $remove_button->getAttribute('aria-label')); $assert_session->pageTextNotContains('You do not have permission to view media item'); $remove_button->press(); $this->waitForText("Removing Horse."); $this->waitForText("Horse has been removed."); // Logout without saving. $this->drupalLogout(); // Create a user who can edit content but not view media. // Must remove permission from authenticated role first, otherwise the new // user will inherit that permission. $role = Role::load(RoleInterface::AUTHENTICATED_ID); $role->revokePermission('view media'); $role->save(); $non_media_editor = $this->drupalCreateUser([ 'access content', 'create basic_page content', 'edit any basic_page content', ]); $this->drupalLogin($non_media_editor); // Assert that preview does not reveal media name. $this->drupalGet($node->toUrl('edit-form')); // There should be no preview name. $assert_session->elementTextNotContains('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0"]', 'Horse'); // The remove button should have a generic message. $remove_button = $page->find('css', '[data-drupal-selector="edit-field-unlimited-media-selection-0-remove-button"]'); $this->assertSame('Remove media', $remove_button->getAttribute('aria-label')); $assert_session->pageTextContains("You do not have permission to view media item $media_id."); // Confirm ajax text does not reveal media name. $remove_button->press(); $this->waitForText("Removing media."); $this->waitForText("Media has been removed."); } }