Unverified Commit 057b54e0 authored by alexpott's avatar alexpott

Issue #2988617 by samuel.mortenson, bkosborne, alexpott, phenaproxima,...

Issue #2988617 by samuel.mortenson, bkosborne, alexpott, phenaproxima, marcoscano, amateescu, chr.fritsch: Creating media with the media library upload is broken for unlimited cardinality
parent 1c7ca421
......@@ -8,6 +8,7 @@
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
......@@ -358,7 +359,7 @@ public function validateUploadElement(array $element, FormStateInterface $form_s
$element['#value'] = [];
}
$values = $form_state->getValue('upload', []);
if (count($values['fids']) > $element['#cardinality']) {
if (count($values['fids']) > $element['#cardinality'] && $element['#cardinality'] !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$form_state->setError($element, $this->t('A maximum of @count files can be uploaded.', [
'@count' => $element['#cardinality'],
]));
......@@ -444,26 +445,36 @@ public function updateFormCallback(array &$form, FormStateInterface $form_state)
/**
* Access callback to check that the user can create file based media.
*
* @param array $allowed_types
* (optional) The contextually allowed types.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*
* @todo Remove $allowed_types param in https://www.drupal.org/node/2956747
*/
public function access() {
return AccessResultAllowed::allowedIf(count($this->getTypes()))->mergeCacheMaxAge(0);
public function access(array $allowed_types = NULL) {
return AccessResultAllowed::allowedIf(count($this->getTypes($allowed_types)))->mergeCacheMaxAge(0);
}
/**
* Returns media types which use files that the current user can create.
*
* @param array $allowed_types
* (optional) The contextually allowed types.
*
* @todo Move in https://www.drupal.org/node/2987924
*
* @return \Drupal\media\MediaTypeInterface[]
* A list of media types that are valid for this form.
*/
protected function getTypes() {
protected function getTypes(array $allowed_types = NULL) {
// Cache results if possible.
if (!isset($this->types)) {
$media_type_storage = $this->entityTypeManager->getStorage('media_type');
$allowed_types = _media_library_get_allowed_types() ?: NULL;
if (!$allowed_types) {
$allowed_types = _media_library_get_allowed_types() ?: NULL;
}
$types = $media_type_storage->loadMultiple($allowed_types);
$types = $this->filterTypesWithFileSource($types);
$types = $this->filterTypesWithCreateAccess($types);
......
......@@ -14,6 +14,7 @@
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\media\Entity\Media;
use Drupal\media_library\Form\MediaLibraryUploadForm;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
......@@ -41,6 +42,13 @@ class MediaLibraryWidget extends WidgetBase implements ContainerFactoryPluginInt
*/
protected $entityTypeManager;
/**
* Indicates whether or not the add button should be shown.
*
* @var bool
*/
protected $addAccess = FALSE;
/**
* Constructs a MediaLibraryWidget widget.
*
......@@ -56,23 +64,30 @@ class MediaLibraryWidget extends WidgetBase implements ContainerFactoryPluginInt
* Any third party settings.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager service.
* @param bool $add_access
* Indicates whether or not the add button should be shown.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager) {
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, $add_access) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
$this->entityTypeManager = $entity_type_manager;
$this->addAccess = $add_access;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$settings = $configuration['field_definition']->getSettings()['handler_settings'];
$target_bundles = isset($settings['target_bundles']) ? $settings['target_bundles'] : NULL;
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['third_party_settings'],
$container->get('entity_type.manager')
$container->get('entity_type.manager'),
// @todo Use URL access in https://www.drupal.org/node/2956747
MediaLibraryUploadForm::create($container)->access($target_bundles)->isAllowed()
);
}
......@@ -248,14 +263,13 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
'#access' => $cardinality_unlimited || $remaining > 0,
];
$add_url = Url::fromRoute('media_library.upload', [], [
'query' => $query,
]);
$element['media_library_add_button'] = [
'#type' => 'link',
'#title' => $this->t('Add media'),
'#name' => $field_name . '-media-library-add-button' . $id_suffix,
'#url' => $add_url,
'#url' => Url::fromRoute('media_library.upload', [], [
'query' => $query,
]),
'#attributes' => [
'class' => ['button', 'use-ajax', 'media-library-add-button'],
'data-dialog-type' => 'modal',
......@@ -263,7 +277,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
],
// Prevent errors in other widgets from preventing addition.
'#limit_validation_errors' => $limit_validation_errors,
'#access' => $add_url->access() && ($cardinality_unlimited || $remaining > 0),
'#access' => $this->addAccess && ($cardinality_unlimited || $remaining > 0),
];
// This hidden field and button are used to add new items to the widget.
......
......@@ -4,6 +4,7 @@ dependencies:
config:
- field.field.node.basic_page.field_twin_media
- field.field.node.basic_page.field_unlimited_media
- field.field.node.basic_page.field_noadd_media
- node.type.basic_page
module:
- media_library
......@@ -30,6 +31,12 @@ content:
settings: { }
third_party_settings: { }
region: content
field_noadd_media:
type: media_library_widget
weight: 123
settings: { }
third_party_settings: { }
region: content
promote:
type: boolean_checkbox
settings:
......
......@@ -4,6 +4,7 @@ dependencies:
config:
- field.field.node.basic_page.field_twin_media
- field.field.node.basic_page.field_unlimited_media
- field.field.node.basic_page.field_noadd_media
- node.type.basic_page
module:
- user
......@@ -30,6 +31,15 @@ content:
link: false
third_party_settings: { }
region: content
field_noadd_media:
type: entity_reference_entity_view
weight: 103
label: above
settings:
view_mode: default
link: false
third_party_settings: { }
region: content
links:
weight: 100
settings: { }
......
langcode: en
status: true
dependencies:
config:
- field.storage.node.field_noadd_media
- media.type.type_one
- media.type.type_two
- node.type.basic_page
id: node.basic_page.field_noadd_media
field_name: field_noadd_media
entity_type: node
bundle: basic_page
label: 'No add media'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:media'
handler_settings:
target_bundles:
type_one: type_one
type_two: type_two
sort:
field: _none
auto_create: false
auto_create_bundle: file
field_type: entity_reference
......@@ -20,6 +20,7 @@ settings:
handler_settings:
target_bundles:
type_one: type_one
type_three: type_three
sort:
field: _none
auto_create: false
......
langcode: en
status: true
dependencies:
module:
- media
- node
id: node.field_noadd_media
field_name: field_noadd_media
entity_type: node
type: entity_reference
settings:
target_type: media
module: core
locked: false
cardinality: -1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
......@@ -317,9 +317,12 @@ public function testWidgetUpload() {
/** @var \Drupal\Core\File\FileSystemInterface $file_system */
$file_system = $this->container->get('file_system');
// Ensure that the add button is not present if no media can be created.
$assert_session->elementNotExists('css', '.media-library-add-button[href*="field_noadd_media"]');
// Add to the twin media field using the add button directly on the widget.
$unlimited_button = $assert_session->elementExists('css', '.media-library-add-button[href*="field_twin_media"]');
$unlimited_button->click();
$twin_button = $assert_session->elementExists('css', '.media-library-add-button[href*="field_twin_media"]');
$twin_button->click();
$assert_session->assertWaitOnAjaxRequest();
$page->attachFileToField('Upload', $this->container->get('file_system')->realpath($png_image->uri));
......@@ -348,10 +351,26 @@ public function testWidgetUpload() {
$assert_session->pageTextNotContains('Media library');
$assert_session->pageTextContains($png_image->filename);
// Open the browser again to test type resolution.
$unlimited_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]');
// Also make sure that we can upload to the unlimited cardinality field.
$unlimited_button = $assert_session->elementExists('css', '.media-library-add-button[href*="field_unlimited_media"]');
$unlimited_button->click();
$assert_session->assertWaitOnAjaxRequest();
$page->attachFileToField('Upload', $this->container->get('file_system')->realpath($png_image->uri));
$assert_session->assertWaitOnAjaxRequest();
$page->fillField('Name', 'Unlimited Cardinality Image');
$page->fillField('Alternative text', $this->randomString());
$assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Save');
$assert_session->assertWaitOnAjaxRequest();
// Ensure the media item was added.
$assert_session->pageTextNotContains('Media library');
$assert_session->pageTextContains('Unlimited Cardinality Image');
// Open the browser again to test type resolution.
$twin_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]');
$twin_button->click();
$assert_session->assertWaitOnAjaxRequest();
$assert_session->pageTextContains('Media library');
$assert_session->elementExists('css', '#drupal-modal')->clickLink('Add media');
$assert_session->assertWaitOnAjaxRequest();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment