Problem/Motivation

Story: A sitebuilder can configure the (gorgeous!) media reference widget so, that the user can
a) only add media items
b) only choose existing media items
c) both

Proposed resolution

Add widget settings.

Remaining tasks

Codeit.

User interface changes

Added widget settings.

API changes

None.

Data model changes

None.

Issue fork drupal-2993187

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

axel.rutz created an issue. See original summary.

stefan.korn’s picture

Version: 8.6.x-dev » 8.7.x-dev
StatusFileSize
new5.24 KB

How about this patch

stefan.korn’s picture

Status: Active » Needs review
geek-merlin’s picture

Hey, nice work! I did not test this, but code looks straightforward.

For the constants and UI texts though, i'd suggest using positive wording like "Allow adding new and using existing media" / ALLOW_NEW_AND_EXISTING.

dww’s picture

Status: Needs review » Needs work

Nice to see this feature, and a patch to get it close. Thanks!

+1 to the suggestions in #4. The patch and UI is a bit hard to make sense of as-is.

+++ b/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php
@@ -536,4 +560,59 @@ protected static function setFieldState(array $element, FormStateInterface $form
+      $summary[] = $this->t('Add and attach button settings: @setting_label', ['@setting_label' => $setting_label]);

This also seems clumsy. Not entirely sure the best solution, but maybe we don't need the 'Add and attach button settings: " part of this at all. Just have the summary include the (positively worded) version of which button(s) are visible?

Cheers,
-Derek

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

taivu’s picture

this patch could not be applied after 8.7.1 update.

chr.fritsch’s picture

Assigned: Unassigned » chr.fritsch

I am working on this

chr.fritsch’s picture

Title: Add a media widget setting to only add or only choose existing media » Add a media library widget setting to only choose existing media
Issue tags: +media library

After talking to @phenaproxima on slack, we agreed that this issue is quite outdated because it is based on the media library design of D8.6.
Since then the library evolved a lot. So we have to re-think this issue.

We agreed that "only use existing" is still valid. But "only upload" is against how the library is designed nowadays.

So we want to add a field widget config setting to choose the "only use existing" behavior.

chr.fritsch’s picture

Assigned: chr.fritsch » Unassigned
Status: Needs work » Needs review
StatusFileSize
new8 KB

Here is a patch that implements #9

phenaproxima’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Thanks, @chr.fritsch! However...

I don't think the setting is something we should be propagating in the MediaLibraryState object. It's a field-level setting, and it's not going to change while a user interacts with the library. A preferable approach, I think, would be for MediaLibraryWidget to deny access to the add form returned from the UI builder, based on the setting. Something like this:

$build = $this->uiBuilder->build();
$build['content']['add_form']['#access'] = !$this->getSetting('only_use_existing');

Also tagging for tests.

chr.fritsch’s picture

Status: Needs work » Needs review
StatusFileSize
new2.56 KB
new7.91 KB

Thanks for the quick response. Media Library is still new for me.

So here is the next approach 😁

I will look into the tests next week.

The last submitted patch, 10: 2993187-10.patch, failed testing. View results

wim leers’s picture

Status: Needs review » Needs work

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

phenaproxima’s picture

andreyjan’s picture

The last patch is not applying to 8.9. Rerolled the patch and also updated settings summary with the new setting.

Working on the tests.

andreyjan’s picture

Here's the patch with tests for this functionality.

Status: Needs review » Needs work
andreyjan’s picture

andreyjan’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
seanb’s picture

+++ b/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php
@@ -749,6 +761,7 @@ public static function removeItem(array $form, FormStateInterface $form_state) {
+    $library_ui['content']['form']['#access'] = !$triggering_element['#only_use_existing'];

I think we should try to pass this to the UI builder via the library state (maybe through the opener parameters) and solve this in the UI builder.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

sakthivel m’s picture

Issue tags: +Needs reroll
sakthivel m’s picture

Status: Needs work » Needs review
StatusFileSize
new8.08 KB

#30 Please review the Patch

Status: Needs review » Needs work
vsujeetkumar’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new8.08 KB
new2.79 KB

@Sakthivel M if #30 is the reroll then changes has been done in the wrong file(core.entity_view_display.node.basic_page.default.yml).
Re-roll patch given, Please have a look.

Status: Needs review » Needs work

The last submitted patch, 32: 2993187-32.patch, failed testing. View results

phenaproxima’s picture

I think I see another way to accomplish this. It would be more complex, but also more robust, and would not require us to add a setting.

Right now, the media library asks the entity system if the user can create media of the current type, and that's how it determines whether the "add new media" form should be shown. This happens in \Drupal\media_library\MediaLibraryUiBuilder::buildMediaTypeAddForm():

if (!$this->entityTypeManager->getAccessControlHandler('media')->createAccess($selected_type_id)) {
      return [];
    }

As it turns out, entity access control handlers support passing an arbitrary $context array to createAccess(), as per https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21....

I propose that we simply pass the media library state object to the access control handler, and let the other modules in the system figure out access. This provides a great deal of flexibility to implement this sort of behavior using hooks like hook_ENTITY_TYPE_create_access(), whilst keeping Media Library's functionality small and well-scoped.

I'm going to implement this in another branch of the issue fork, so that we have a proof of concept. But to me, this approach would be very much in keeping with Media Library's philosophy of keeping things as simple as possible out-of-the-box.

alexpott’s picture

I think that the current implementation in HEAD is correct. If the user has the ability to create media items we should allow that. I think most use-cases can be achieved with roles and permissions already. If we want to add additional context for very use-case specific cases to the create access method then @phenaproxima's MR makes sense.

If someone wants a special widget with additional settings or that leverage the new context information then that can go in contrib.

phenaproxima’s picture

Opened #3224530: Pass the media library state object to createAccess() to make the $context change in core, so that we can close this issue in favor of a contrib/custom solution.

seanb’s picture

+1 for passing the media library state to createAccess() so we could use proper access to show/hide the form. This should allow enough flexibility for contrib to add a third party setting and an access hook to implement this.

Maybe this could be added to something like https://www.drupal.org/project/media_library_extras for now?

phenaproxima’s picture

Status: Needs work » Closed (works as designed)
Issue tags: -media library, -Needs tests

Yes, once this is in core that's exactly where I think it would make sense to put it.

Since I've opened #3224530: Pass the media library state object to createAccess(), I think we have discussed this issue enough. I'm closing this out as "works as designed". For reference, once that other issue lands (probably in 9.3.x and up only, for the record), this is what you could put into your module to cut off access to the "add new media" part of the media library:

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;

/**
  * Implements hook_ENTITY_TYPE_create_access().
  */
function mymodule_media_create_access(AccountInterface $account, array $context, $entity_bundle) {
  // Don't allow the creation of media items in the media library (hide the form).
  if (isset($context['media_library_state'])) {
    return AccessResult::forbidden();
  }
  // No opinion otherwise.
  return AccessResult::neutral();
}

Obviously you could also implement more complicated logic for more exotic use cases, too.