Issue #3160238 by JeroenT, phenaproxima, vsujeetkumar, ravi.shankar, snehalgaikwad, dishabhadra, vakulrai, gmercer, mitthukumawat, RoshaniBhangale, thalles, Abhijith S, chandu7929, janmejaig, tanubansal, manojithape, quietone: Media Library widget produces "This value should not be null" error when field is required

(cherry picked from commit b6efcaf636)
merge-requests/961/head
catch 2021-07-16 12:04:46 +01:00
parent 4d7c3c7079
commit d890c95f4e
2 changed files with 62 additions and 1 deletions

View File

@ -21,8 +21,8 @@ use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\field_ui\FieldUI;
use Drupal\media\Entity\Media;
use Drupal\media_library\MediaLibraryUiBuilder;
use Drupal\media_library\MediaLibraryState;
use Drupal\media_library\MediaLibraryUiBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
@ -321,6 +321,10 @@ class MediaLibraryWidget extends WidgetBase implements TrustedCallbackInterface
],
];
if ($this->fieldDefinition->isRequired()) {
$element['#element_validate'][] = [static::class, 'validateRequired'];
}
// When the list of allowed types in the field configuration is null,
// ::getAllowedMediaTypeIdsSorted() returns all existing media types. When
// the list of allowed types is an empty array, we show a message to users
@ -940,4 +944,29 @@ class MediaLibraryWidget extends WidgetBase implements TrustedCallbackInterface
static::setWidgetState($element['#field_parents'], $element['#field_name'], $form_state, $field_state);
}
/**
* Validates whether the widget is required and contains values.
*
* @param array $element
* The form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
* @param array $form
* The form array.
*/
public static function validateRequired(array $element, FormStateInterface $form_state, array $form) {
// If a remove button triggered submit, this validation isn't needed.
if (in_array([static::class, 'removeItem'], $form_state->getSubmitHandlers(), TRUE)) {
return;
}
$field_state = static::getFieldState($element, $form_state);
// Trigger error if the field is required and no media is present. Although
// the Form API's default validation would also catch this, the validation
// error message is too vague, so a more precise one is provided here.
if (count($field_state['items']) === 0) {
$form_state->setError($element, t('@name field is required.', ['@name' => $element['#title']]));
}
}
}

View File

@ -2,6 +2,8 @@
namespace Drupal\Tests\media_library\FunctionalJavascript;
use Drupal\field\Entity\FieldConfig;
/**
* Tests the Media library entity reference widget.
*
@ -448,4 +450,34 @@ class EntityReferenceWidgetTest extends MediaLibraryTestBase {
$assert_session->pageTextNotContains('Snake');
}
/**
* Tests saving a required media library field.
*/
public function testRequiredMediaField() {
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
// Make field_unlimited_media required.
$field_config = FieldConfig::loadByName('node', 'basic_page', 'field_unlimited_media');
$field_config->setRequired(TRUE)->save();
$this->drupalGet('node/add/basic_page');
$page->fillField('Title', 'My page');
$page->pressButton('Save');
// Check that a clear error message is shown.
$assert_session->pageTextNotContains('This value should not be null.');
$assert_session->pageTextContains(sprintf('%s field is required.', $field_config->label()));
// Open the media library, select an item and save the node.
$this->openMediaLibraryForField('field_unlimited_media');
$this->selectMediaItem(0);
$this->pressInsertSelected('Added one media item.');
$page->pressButton('Save');
// Confirm that the node was created.
$this->assertSession()->pageTextContains('Basic page My page has been created.');
}
}