diff --git a/core/modules/media_library/src/Form/AddFormBase.php b/core/modules/media_library/src/Form/AddFormBase.php index 4b87718853bddc34639d0b8c431030fd42dd830b..9a1b2a15441d1b6bd12039a3e5a0f5aac43c49fc 100644 --- a/core/modules/media_library/src/Form/AddFormBase.php +++ b/core/modules/media_library/src/Form/AddFormBase.php @@ -510,7 +510,12 @@ protected function processInputValues(array $source_field_values, array $form, F $form_state->set('media', array_values($media)); // Save the selected items in the form state so they are remembered when an // item is removed. - $form_state->set('current_selection', array_filter(explode(',', $form_state->getValue('current_selection')))); + $media = $this->entityTypeManager->getStorage('media') + ->loadMultiple(explode(',', $form_state->getValue('current_selection'))); + // Any ID can be passed to the form, so we have to check access. + $form_state->set('current_selection', array_filter($media, function ($media_item) { + return $media_item->access('view'); + })); $form_state->setRebuild(); } @@ -806,13 +811,9 @@ protected function getSourceFieldName(MediaTypeInterface $media_type) { * An array containing the pre-selected media items keyed by ID. */ protected function getPreSelectedMediaItems(FormStateInterface $form_state) { - // Get the current selection from the form state. + // Get the pre-selected media items from the form state. // @see ::processInputValues() - $media_ids = $form_state->get('current_selection'); - if (!$media_ids) { - return []; - } - return $this->entityTypeManager->getStorage('media')->loadMultiple($media_ids); + return $form_state->get('current_selection') ?: []; } /** @@ -823,7 +824,7 @@ protected function getPreSelectedMediaItems(FormStateInterface $form_state) { * * @return \Drupal\media\MediaInterface[] * An array containing the added media items keyed by delta. The media items - * won't have an ID untill they are saved in ::submitForm(). + * won't have an ID until they are saved in ::submitForm(). */ protected function getAddedMediaItems(FormStateInterface $form_state) { return $form_state->get('media') ?: []; diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/WidgetAccessTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/WidgetAccessTest.php index d62b84b8c3f807c1664b9bc4438ddd25e7a79f24..0abb57271d6dafb32b0fcb39b92e772e0f36e67b 100644 --- a/core/modules/media_library/tests/src/FunctionalJavascript/WidgetAccessTest.php +++ b/core/modules/media_library/tests/src/FunctionalJavascript/WidgetAccessTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\media_library\FunctionalJavascript; +use Drupal\media\Entity\Media; use Drupal\media_library\MediaLibraryState; use Drupal\user\Entity\Role; use Drupal\user\RoleInterface; @@ -18,6 +19,35 @@ class WidgetAccessTest extends MediaLibraryTestBase { */ public function testWidgetAccess() { $assert_session = $this->assertSession(); + $session = $this->getSession(); + + $this->createMediaItems([ + 'type_one' => ['Horse', 'Bear'], + ]); + $account = $this->drupalCreateUser(['create basic_page content']); + $this->drupalLogin($account); + + // Assert users can not select media items they do not have access to. + $unpublished_media = Media::create([ + 'name' => 'Mosquito', + 'bundle' => 'type_one', + 'field_media_test' => 'Mosquito', + 'status' => FALSE, + ]); + $unpublished_media->save(); + // Visit a node create page. + $this->drupalGet('node/add/basic_page'); + // Set the hidden value and trigger the mousedown event on the button via + // JavaScript since the field and button are hidden. + $session->executeScript("jQuery('[data-media-library-widget-value=\"field_unlimited_media\"]').val('1,2,{$unpublished_media->id()}')"); + $session->executeScript("jQuery('[data-media-library-widget-update=\"field_unlimited_media\"]').trigger('mousedown')"); + $this->assertElementExistsAfterWait('css', '.js-media-library-item'); + // Assert the published items are selected and the unpublished item is not + // selected. + $assert_session->pageTextContains('Horse'); + $assert_session->pageTextContains('Bear'); + $assert_session->pageTextNotContains('Mosquito'); + $this->drupalLogout(); $role = Role::load(RoleInterface::ANONYMOUS_ID); $role->revokePermission('view media'); diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/WidgetUploadTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/WidgetUploadTest.php index b90fecb0818d84426f14d5aec0df2c862a4841e1..353629fc1499b82fc7999a286a8f40042d779afe 100644 --- a/core/modules/media_library/tests/src/FunctionalJavascript/WidgetUploadTest.php +++ b/core/modules/media_library/tests/src/FunctionalJavascript/WidgetUploadTest.php @@ -568,6 +568,29 @@ public function testWidgetUploadAdvancedUi() { $this->pressInsertSelected('Added one media item.'); $assert_session->pageTextContains($file_system->basename($jpg_uri_2)); + // Assert users can not select media items they do not have access to. + $unpublished_media = Media::create([ + 'name' => 'Mosquito', + 'bundle' => 'type_one', + 'field_media_test' => 'Mosquito', + 'status' => FALSE, + ]); + $unpublished_media->save(); + $this->openMediaLibraryForField('field_unlimited_media'); + $this->switchToMediaType('Three'); + // Set the hidden field with the current selection via JavaScript and upload + // a file. + $this->getSession()->executeScript("jQuery('.js-media-library-add-form-current-selection').val('1,2,{$unpublished_media->id()}')"); + $this->addMediaFileToField('Add files', $this->container->get('file_system')->realpath($png_uri_3)); + // Assert the pre-selected items are shown. + $this->getSelectionArea(); + // Assert the published items are selected and the unpublished item is not + // selected. + $this->waitForText(Media::load(1)->label()); + $this->waitForText(Media::load(2)->label()); + $assert_session->pageTextNotContains('Mosquito'); + $page->find('css', '.ui-dialog-titlebar-close')->click(); + // Assert we can also remove selected items from the selection area in the // upload form. $this->openMediaLibraryForField('field_unlimited_media');