diff -u b/core/modules/media/media.module b/core/modules/media/media.module --- b/core/modules/media/media.module +++ b/core/modules/media/media.module @@ -52,7 +52,7 @@ * * Fix broken operations array in field UI for entities with restricted access. * - * @todo: This hook can be removed when issue 2836384 is fixed. + * @todo This hook can be removed when issue #2836384 is done. * @see https://www.drupal.org/node/2836384 */ function media_entity_operation_alter(array &$operations, EntityInterface $entity) { diff -u b/core/modules/media/src/Entity/Media.php b/core/modules/media/src/Entity/Media.php --- b/core/modules/media/src/Entity/Media.php +++ b/core/modules/media/src/Entity/Media.php @@ -2,10 +2,10 @@ namespace Drupal\media\Entity; -use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityPublishedTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\RevisionableContentEntityBase; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\media\MediaInterface; @@ -17,7 +17,7 @@ /** * Defines the media entity class. * - * @todo Remove default/fallback entity form operation when #2006348 lands. + * @todo Remove default/fallback entity form operation when #2006348 is done. * @see https://www.drupal.org/node/2006348. * * @ContentEntityType( @@ -77,7 +77,7 @@ * } * ) */ -class Media extends ContentEntityBase implements MediaInterface { +class Media extends RevisionableContentEntityBase implements MediaInterface { use EntityChangedTrait; use EntityPublishedTrait; @@ -299,17 +299,17 @@ parent::preSaveRevision($storage, $record); $is_new_revision = $this->isNewRevision(); - if (!$is_new_revision && isset($this->original) && empty($record->revision_log)) { + if (!$is_new_revision && isset($this->original) && empty($record->revision_log_message)) { // If we are updating an existing media item without adding a - // new revision, we need to make sure $entity->revision_log is reset - // whenever it is empty. + // new revision, we need to make sure $entity->revision_log_message is + // reset whenever it is empty. // Therefore, this code allows us to avoid clobbering an existing log // entry with an empty one. - $record->revision_log = $this->original->revision_log->value; + $record->revision_log_message = $this->original->revision_log_message->value; } if ($is_new_revision) { - $record->revision_timestamp = self::getRequestTime(); + $record->revision_created = self::getRequestTime(); } } @@ -422,34 +422,6 @@ ->setTranslatable(TRUE) ->setRevisionable(TRUE); - $fields['revision_timestamp'] = BaseFieldDefinition::create('created') - ->setLabel(t('Revision timestamp')) - ->setDescription(t('The time the current revision was created.')) - ->setQueryable(FALSE) - ->setRevisionable(TRUE); - - $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Revision authored by')) - ->setDescription(t('The user ID of the author of the current revision.')) - ->setDefaultValueCallback(static::class . '::getCurrentUserId') - ->setSetting('target_type', 'user') - ->setQueryable(FALSE) - ->setRevisionable(TRUE); - - $fields['revision_log'] = BaseFieldDefinition::create('string_long') - ->setLabel(t('Revision Log')) - ->setDescription(t('The log entry explaining the changes in this revision.')) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE) - ->setDefaultValue('') - ->setDisplayOptions('form', [ - 'type' => 'string_textarea', - 'weight' => 25, - 'settings' => [ - 'rows' => 4, - ], - ]); - return $fields; } @@ -474,62 +446,2 @@ - /** - * {@inheritdoc} - */ - public function getRevisionCreationTime() { - return $this->revision_timestamp->value; - } - - /** - * {@inheritdoc} - */ - public function setRevisionCreationTime($timestamp) { - $this->revision_timestamp->value = $timestamp; - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRevisionUser() { - return $this->revision_uid->entity; - } - - /** - * {@inheritdoc} - */ - public function setRevisionUser(UserInterface $account) { - $this->revision_uid->entity = $account; - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRevisionUserId() { - return $this->revision_uid->target_id; - } - - /** - * {@inheritdoc} - */ - public function setRevisionUserId($user_id) { - $this->revision_uid->target_id = $user_id; - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRevisionLogMessage() { - return $this->revision_log->value; - } - - /** - * {@inheritdoc} - */ - public function setRevisionLogMessage($revision_log_message) { - $this->revision_log->value = $revision_log_message; - return $this; - } - } diff -u b/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php b/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php --- b/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php +++ b/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php @@ -16,9 +16,9 @@ class MediaDeleteMultipleConfirmForm extends ConfirmFormBase { /** - * The array of media items to delete. + * The array of media items to delete, indexed by ID and language. * - * @var array + * @var string[][] */ protected $mediaItems = []; @@ -92,7 +92,7 @@ /** * {@inheritdoc} * - * @todo: Change to trait or base class when #2843395 is done. + * @todo Change to trait or base class when #2843395 is done. * @see https://www.drupal.org/node/2843395 */ public function buildForm(array $form, FormStateInterface $form_state) { @@ -145,7 +145,7 @@ /** * {@inheritdoc} * - * @todo: Change to trait or base class when #2843395 is done. + * @todo Change to trait or base class when #2843395 is done. * @see https://www.drupal.org/node/2843395 */ public function submitForm(array &$form, FormStateInterface $form_state) { diff -u b/core/modules/media/src/MediaForm.php b/core/modules/media/src/MediaForm.php --- b/core/modules/media/src/MediaForm.php +++ b/core/modules/media/src/MediaForm.php @@ -91,11 +91,11 @@ // If already published, the 'publish' button is primary. if ($media->isPublished()) { - unset($element['unpublish']['#button_type']); + $element['publish']['#button_type'] = 'primary'; } // Otherwise, the 'unpublish' button is primary and should come first. else { - unset($element['publish']['#button_type']); + $element['unpublish']['#button_type'] = 'primary'; $element['unpublish']['#weight'] = -10; } diff -u b/core/modules/media/src/MediaInterface.php b/core/modules/media/src/MediaInterface.php --- b/core/modules/media/src/MediaInterface.php +++ b/core/modules/media/src/MediaInterface.php @@ -16,6 +16,9 @@ /** * Returns the media item creation timestamp. * + * @todo Remove and use the new interface when #2833378 is done. + * @see https://www.drupal.org/node/2833378 + * * @return int * Creation timestamp of the media item. */ @@ -24,6 +27,9 @@ /** * Sets the media item creation timestamp. * + * @todo Remove and use the new interface when #2833378 is done. + * @see https://www.drupal.org/node/2833378 + * * @param int $timestamp * The media creation timestamp. * diff -u b/core/modules/media/src/MediaSourceBase.php b/core/modules/media/src/MediaSourceBase.php --- b/core/modules/media/src/MediaSourceBase.php +++ b/core/modules/media/src/MediaSourceBase.php @@ -76,6 +76,8 @@ $this->entityFieldManager = $entity_field_manager; $this->fieldTypeManager = $field_type_manager; $this->configFactory = $config_factory; + + // Add the default configuration of the media source to the plugin. $this->setConfiguration($configuration); } diff -u b/core/modules/media/src/MediaSourceInterface.php b/core/modules/media/src/MediaSourceInterface.php --- b/core/modules/media/src/MediaSourceInterface.php +++ b/core/modules/media/src/MediaSourceInterface.php @@ -44,8 +44,8 @@ * URL or other identifier, while sources that represent local files might * check the MIME type of the file. * - Providing a default name for a media item. This will save users from - * manually entering the name when it can be reliably set automatically. Media - * sources for local files will generally use the filename, while media + * manually entering the name when it can be reliably set automatically. + * Media sources for local files will generally use the filename, while media * sources for remote resources might obtain a title attribute through a * third-party API. The name can always be overridden by the user. * - Providing metadata specific to the given media type. For example, remote @@ -67,6 +67,11 @@ interface MediaSourceInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface { /** + * Default empty value for metadata fields. + */ + const METADATA_FIELD_EMPTY = '_none'; + + /** * Gets a list of metadata attributes provided by this plugin. * * Most media sources have associated metadata, describing attributes diff -u b/core/modules/media/src/MediaTypeForm.php b/core/modules/media/src/MediaTypeForm.php --- b/core/modules/media/src/MediaTypeForm.php +++ b/core/modules/media/src/MediaTypeForm.php @@ -60,7 +60,7 @@ */ public function ajaxHandlerData(array $form, FormStateInterface $form_state) { $response = new AjaxResponse(); - $response->addCommand(new ReplaceCommand('#source-dependent', $form['source_dependent('])); + $response->addCommand(new ReplaceCommand('#source-dependent', $form['source_dependent'])); return $response; } @@ -111,12 +111,12 @@ $options[$plugin_id] = $definition['label']; } - $form['source_dependent('] = [ + $form['source_dependent'] = [ '#type' => 'container', '#attributes' => ['id' => 'source-dependent'], ]; - $form['source_dependent(']['source'] = [ + $form['source_dependent']['source'] = [ '#type' => 'select', '#title' => $this->t('Media source'), '#default_value' => $source ? $source->getPluginId() : NULL, @@ -132,17 +132,17 @@ if ($source) { // Media source plugin configuration. - $form['source_dependent(']['source_configuration'] = [ + $form['source_dependent']['source_configuration'] = [ '#type' => 'fieldset', '#title' => $this->t('Media source configuration'), '#tree' => TRUE, ]; - $form['source_dependent(']['source_configuration'] = $source->buildConfigurationForm($form['source_dependent(']['source_configuration'], $this->getSourceSubFormState($form, $form_state)); + $form['source_dependent']['source_configuration'] = $source->buildConfigurationForm($form['source_dependent']['source_configuration'], $this->getSourceSubFormState($form, $form_state)); } // Field mapping configuration. - $form['source_dependent(']['field_map'] = [ + $form['source_dependent']['field_map'] = [ '#type' => 'fieldset', '#title' => $this->t('Field mapping'), '#tree' => TRUE, @@ -152,10 +152,10 @@ ]; if (empty($source) || empty($source->getMetadataAttributes())) { - $form['source_dependent(']['field_map']['#access'] = FALSE; + $form['source_dependent']['field_map']['#access'] = FALSE; } else { - $options = ['_none' => $this->t('- Skip field -')]; + $options = [MediaSourceInterface::METADATA_FIELD_EMPTY => $this->t('- Skip field -')]; foreach ($this->entityFieldManager->getFieldDefinitions('media', $this->entity->id()) as $field_name => $field) { if (!($field instanceof BaseFieldDefinition) || $field_name === 'name') { $options[$field_name] = $field->getLabel(); @@ -164,11 +164,11 @@ $field_map = $this->entity->getFieldMap(); foreach ($source->getMetadataAttributes() as $metadata_attribute_name => $metadata_attribute_label) { - $form['source_dependent(']['field_map'][$metadata_attribute_name] = [ + $form['source_dependent']['field_map'][$metadata_attribute_name] = [ '#type' => 'select', '#title' => $metadata_attribute_label, '#options' => $options, - '#default_value' => isset($field_map[$metadata_attribute_name]) ? $field_map[$metadata_attribute_name] : '_none', + '#default_value' => isset($field_map[$metadata_attribute_name]) ? $field_map[$metadata_attribute_name] : MediaSourceInterface::METADATA_FIELD_EMPTY, ]; } } @@ -247,11 +247,11 @@ * @param \Drupal\Core\Form\FormStateInterface $form_state * Parent form state. * - * @return \Drupal\Core\Form\SubFormStateInterface + * @return \Drupal\Core\Form\SubformStateInterface * Sub-form state for the media source configuration form. */ protected function getSourceSubFormState(array $form, FormStateInterface $form_state) { - return SubformState::createForSubform($form['source_dependent(']['source_configuration'], $form, $form_state) + return SubformState::createForSubform($form['source_dependent']['source_configuration'], $form, $form_state) ->set('operation', $this->operation) ->set('type', $this->entity); } @@ -262,9 +262,9 @@ public function validateForm(array &$form, FormStateInterface $form_state) { parent::validateForm($form, $form_state); - if ($form['source_dependent(']['source_configuration']) { + if ($form['source_dependent']['source_configuration']) { // Let the selected plugin validate its settings. - $this->entity->getSource()->validateConfigurationForm($form['source_dependent(']['source_configuration'], $this->getSourceSubFormState($form, $form_state)); + $this->entity->getSource()->validateConfigurationForm($form['source_dependent']['source_configuration'], $this->getSourceSubFormState($form, $form_state)); } } @@ -275,7 +275,7 @@ $form_state->setValue('field_map', array_filter( $form_state->getValue('field_map', []), function ($item) { - return $item != '_none'; + return $item != MediaSourceInterface::METADATA_FIELD_EMPTY; } )); @@ -285,9 +285,9 @@ ->setStatus((bool) $form_state->getValue(['options', 'status'])) ->setNewRevision((bool) $form_state->getValue(['options', 'new_revision'])); - if ($form['source_dependent(']['source_configuration']) { + if ($form['source_dependent']['source_configuration']) { // Let the selected plugin save its settings. - $this->entity->getSource()->submitConfigurationForm($form['source_dependent(']['source_configuration'], $this->getSourceSubFormState($form, $form_state)); + $this->entity->getSource()->submitConfigurationForm($form['source_dependent']['source_configuration'], $this->getSourceSubFormState($form, $form_state)); } } @@ -316,7 +316,6 @@ $source_field = $source->getSourceFieldDefinition($media_type); if (!$source_field) { $source_field = $source->createSourceField($media_type); - /** @var \Drupal\field\FieldStorageConfigInterface $storage */ $storage = $source_field->getFieldStorageDefinition(); if ($storage->isNew() || !$storage->isLocked()) { diff -u b/core/modules/media/src/MediaTypeInterface.php b/core/modules/media/src/MediaTypeInterface.php --- b/core/modules/media/src/MediaTypeInterface.php +++ b/core/modules/media/src/MediaTypeInterface.php @@ -78,8 +78,8 @@ * copied to the corresponding entity fields. * * @return array - * Field mapping array with fields provided by the type plugin as keys and - * Drupal Entity fields as values. + * Field mapping array provided by media source with metadata attribute + * names as keys and entity field names as values. */ public function getFieldMap(); @@ -87,8 +87,8 @@ * Sets the metadata field map. * * @param array $map - * Field mapping with metadata attribute names as keys and entity field - * names as values. + * Field mapping array with metadata attribute names as keys and entity + * field names as values. * * @return $this */ diff -u b/core/modules/media/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php b/core/modules/media/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php --- b/core/modules/media/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php +++ b/core/modules/media/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php @@ -2,6 +2,7 @@ namespace Drupal\media\Plugin\Field\FieldFormatter; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; @@ -9,6 +10,7 @@ use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\Core\Render\RendererInterface; +use Drupal\media\MediaInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Field\FieldDefinitionInterface; @@ -129,48 +131,31 @@ */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = []; - $media = $this->getEntitiesToView($items, $langcode); + $media_items = $this->getEntitiesToView($items, $langcode); // Early opt-out if the field is empty. - if (empty($media)) { + if (empty($media_items)) { return $elements; } - $url = NULL; - $image_link_setting = $this->getSetting('image_link'); - // Check if the formatter involves a link. - if ($image_link_setting == 'content') { - $entity = $items->getEntity(); - if (!$entity->isNew()) { - $url = $entity->toUrl(); - } - } - elseif ($image_link_setting === 'media') { - $link_media = TRUE; - } - $image_style_setting = $this->getSetting('image_style'); - /** @var \Drupal\media\MediaInterface[] $media */ - foreach ($media as $delta => $media_item) { - if (isset($link_media)) { - $url = $media_item->toUrl(); - } - + /** @var \Drupal\media\MediaInterface[] $media_items */ + foreach ($media_items as $delta => $media) { $elements[$delta] = [ '#theme' => 'image_formatter', - '#item' => $media_item->get('thumbnail'), + '#item' => $media->get('thumbnail')->first(), '#item_attributes' => [], - '#image_style' => $image_style_setting, - '#url' => $url, + '#image_style' => $this->getSetting('image_style'), + '#url' => $this->getMediaUrl($media, $items->getEntity()), ]; // Add cacheability of each item in the field. - $this->renderer->addCacheableDependency($elements[$delta], $media_item); + $this->renderer->addCacheableDependency($elements[$delta], $media); } // Add cacheability of the image style setting. - if ($image_link_setting && ($image_style = $this->imageStyleStorage->load($image_style_setting))) { + if ($this->getSetting('image_link') && ($image_style = $this->imageStyleStorage->load($image_style_setting))) { $this->renderer->addCacheableDependency($elements, $image_style); } @@ -188,2 +173,29 @@ + /** + * Get the URL for the media thumbnail. + * + * @param \Drupal\media\MediaInterface $media + * The media item. + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity that the field belongs to. + * + * @return \Drupal\Core\Url|null + * The URL object for the media item or null if we don't want to add + * a link. + */ + protected function getMediaUrl(MediaInterface $media, EntityInterface $entity) { + $url = NULL; + $image_link_setting = $this->getSetting('image_link'); + // Check if the formatter involves a link. + if ($image_link_setting == 'content') { + if (!$entity->isNew()) { + $url = $entity->toUrl(); + } + } + elseif ($image_link_setting === 'media') { + $url = $media->toUrl(); + } + return $url; + } + } diff -u b/core/modules/media/src/Plugin/QueueWorker/ThumbnailDownloader.php b/core/modules/media/src/Plugin/QueueWorker/ThumbnailDownloader.php --- b/core/modules/media/src/Plugin/QueueWorker/ThumbnailDownloader.php +++ b/core/modules/media/src/Plugin/QueueWorker/ThumbnailDownloader.php @@ -2,6 +2,7 @@ namespace Drupal\media\Plugin\QueueWorker; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\media\Entity\Media; use Drupal\Core\Queue\QueueWorkerBase; @@ -19,10 +20,27 @@ class ThumbnailDownloader extends QueueWorkerBase implements ContainerFactoryPluginInterface { /** - * {@inheritdoc} + * The entity type manager service. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * Constructs a new class instance. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * Entity type manager service. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->entityTypeManager = $entity_type_manager; } /** @@ -32,7 +50,8 @@ return new static( $configuration, $plugin_id, - $plugin_definition + $plugin_definition, + $container->get('entity_type.manager') ); } @@ -40,7 +59,8 @@ * {@inheritdoc} */ public function processItem($data) { - if ($media = Media::load($data['id'])) { + /** @var \Drupal\media\Entity\Media $media */ + if ($media = $this->entityTypeManager->getStorage('media')->load($data['id'])) { $media->updateQueuedThumbnail(); $media->save(); } diff -u b/core/modules/media/src/Plugin/views/wizard/Media.php b/core/modules/media/src/Plugin/views/wizard/Media.php --- b/core/modules/media/src/Plugin/views/wizard/Media.php +++ b/core/modules/media/src/Plugin/views/wizard/Media.php @@ -29,7 +29,7 @@ */ protected $filters = [ 'status' => [ - 'value' => TRUE, + 'value' => '1', 'table' => 'media_field_data', 'field' => 'status', 'plugin_id' => 'boolean', diff -u b/core/modules/media/src/Plugin/views/wizard/MediaRevision.php b/core/modules/media/src/Plugin/views/wizard/MediaRevision.php --- b/core/modules/media/src/Plugin/views/wizard/MediaRevision.php +++ b/core/modules/media/src/Plugin/views/wizard/MediaRevision.php @@ -20,7 +20,7 @@ * * @var string */ - protected $createdColumn = 'created'; + protected $createdColumn = 'media_field_revision-created'; /** * Set default values for the filters. diff -u b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php --- b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php @@ -8,7 +8,7 @@ use Drupal\media\MediaSourceBase; /** - * Provides test media type. + * Provides test media source. * * @MediaSource( * id = "test", @@ -23,6 +23,9 @@ * {@inheritdoc} */ public function getMetadataAttributes() { + // The metadata attributes are kept in state storage. This allows tests to + // change the metadata attributes and makes it easier to test different + // variations. $attributes = \Drupal::state()->get('media_source_test_attributes', [ 'attribute_1' => ['label' => $this->t('Attribute 1'), 'value' => 'Value 1'], 'attribute_2' => ['label' => $this->t('Attribute 2'), 'value' => 'Value 1'], diff -u b/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml b/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml --- b/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml +++ b/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml @@ -10 +10,2 @@ -field_map: { } +field_map: + metadata_attribute: 'field_attribute_config_test' diff -u b/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php b/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php --- b/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php +++ b/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php @@ -15,7 +15,7 @@ */ class MediaCacheTagsTest extends EntityWithUriCacheTagsTestBase { - use MediaFunctionalTestTrait; + use MediaFunctionalTestCreateMediaTypeTrait; /** * {@inheritdoc} diff -u b/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php b/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php --- b/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php +++ b/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php @@ -10,6 +10,7 @@ abstract class MediaFunctionalTestBase extends BrowserTestBase { use MediaFunctionalTestTrait; + use MediaFunctionalTestCreateMediaTypeTrait; /** * Modules to enable. @@ -27,66 +28,2 @@ - /** - * Permissions for the admin user that will be logged in for test. - * - * @var array - */ - protected static $adminUserPermissions = [ - // Media entity permissions. - 'administer media', - 'administer media fields', - 'administer media form display', - 'administer media display', - 'administer media types', - 'view media', - 'create media', - 'update media', - 'update any media', - 'delete media', - 'delete any media', - // Other permissions. - 'administer views', - 'access content overview', - 'view all revisions', - 'administer content types', - 'administer node fields', - 'administer node form display', - 'bypass node access', - ]; - - /** - * An admin test user account. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $adminUser; - - /** - * A non-admin test user account. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $nonAdminUser; - - /** - * The storage handler. - * - * @var \Drupal\Core\Entity\EntityStorageInterface - */ - protected $storage; - - /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - - // Have two users ready to be used in tests. - $this->adminUser = $this->drupalCreateUser(static::$adminUserPermissions); - $this->nonAdminUser = $this->drupalCreateUser([]); - // Start off logged in as admin. - $this->drupalLogin($this->adminUser); - - $this->storage = $this->container->get('entity_type.manager')->getStorage('media'); - } - } diff -u b/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php b/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php --- b/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php +++ b/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php @@ -2,64 +2,73 @@ namespace Drupal\Tests\media\Functional; -use Drupal\media\Entity\MediaType; - /** * Trait with helpers for Media functional tests. */ trait MediaFunctionalTestTrait { /** - * Creates a media type. + * Permissions for the admin user that will be logged-in for test. + * + * @var array + */ + protected static $adminUserPermissions = [ + // Media entity permissions. + 'administer media', + 'administer media fields', + 'administer media form display', + 'administer media display', + 'administer media types', + 'view media', + 'create media', + 'update media', + 'update any media', + 'delete media', + 'delete any media', + // Other permissions. + 'administer views', + 'access content overview', + 'view all revisions', + 'administer content types', + 'administer node fields', + 'administer node form display', + 'bypass node access', + ]; + + /** + * An admin test user account. + * + * @var \Drupal\Core\Session\AccountInterface + */ + protected $adminUser; + + /** + * A non-admin test user account. * - * @param array $values - * The media type values. - * @param string $source - * (optional) The media source plugin that is responsible for additional - * logic related to this media type. Defaults to 'test'. + * @var \Drupal\Core\Session\AccountInterface + */ + protected $nonAdminUser; + + /** + * The storage service. * - * @return \Drupal\media\MediaTypeInterface - * A newly created media type. + * @var \Drupal\Core\Entity\EntityStorageInterface */ - protected function createMediaType(array $values = [], $source = 'test') { - if (empty($values['bundle'])) { - $id = strtolower($this->randomMachineName()); - } - else { - $id = $values['bundle']; - } - $values += [ - 'id' => $id, - 'label' => $id, - 'source' => $source, - 'source_configuration' => [], - 'field_map' => [], - 'new_revision' => FALSE, - ]; - - $media_type = MediaType::create($values); - $status = $media_type->save(); - - $this->assertSame(SAVED_NEW, $status, 'Media type was created successfully.'); - - // Ensure that the source field exists. - $source = $media_type->getSource(); - $source_field = $source->getSourceFieldDefinition($media_type); - if (!$source_field) { - $source_field = $source->createSourceField($media_type); - /** @var \Drupal\field\FieldStorageConfigInterface $storage */ - $storage = $source_field->getFieldStorageDefinition(); - $storage->setLocked(TRUE)->save(); - $source_field->save(); - - $media_type - ->set('source_configuration', [ - 'source_field' => $source_field->getName(), - ]) - ->save(); - } + protected $storage; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + // Have two users ready to be used in tests. + $this->adminUser = $this->drupalCreateUser(static::$adminUserPermissions); + $this->nonAdminUser = $this->drupalCreateUser([]); + // Start off logged in as admin. + $this->drupalLogin($this->adminUser); - return $media_type; + $this->storage = $this->container->get('entity_type.manager')->getStorage('media'); } } diff -u b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php --- b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php +++ b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php @@ -52,7 +52,7 @@ $media_name = $this->randomMachineName(); $page->fillField('name[0][value]', $media_name); $revision_log_message = $this->randomString(); - $page->fillField('revision_log[0][value]', $revision_log_message); + $page->fillField('revision_log_message[0][value]', $revision_log_message); $page->pressButton('Save and publish'); $media_id = $this->container->get('entity.query')->get('media')->execute(); $media_id = reset($media_id); @@ -61,7 +61,8 @@ ->getStorage('media') ->loadUnchanged($media_id); $this->assertEquals($media->getRevisionLogMessage(), $revision_log_message); - $assert_session->titleEquals($media->label() . ' | Drupal'); + $this->assertEquals($media->label(), $media_name); + $assert_session->titleEquals($media_name . ' | Drupal'); // Tests media edit form. $media_type->setNewRevision(FALSE); @@ -72,6 +73,11 @@ $media_name = $this->randomMachineName(); $page->fillField('name[0][value]', $media_name2); $page->pressButton('Save and keep published'); + /** @var \Drupal\media\MediaInterface $media */ + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged($media_id); + $this->assertEquals($media->label(), $media_name2); $assert_session->titleEquals($media_name2 . ' | Drupal'); // Test that there is no empty vertical tabs element, if the container is @@ -90,13 +96,13 @@ $this->drupalLogin($this->adminUser); // Enable revisions by default. - $previoius_revision_id = $media->getRevisionId(); + $previous_revision_id = $media->getRevisionId(); $media_type->setNewRevision(TRUE); $media_type->save(); $this->drupalGet('media/' . $media_id . '/edit'); $assert_session->checkboxChecked('edit-revision'); $page->fillField('name[0][value]', $media_name); - $page->fillField('revision_log[0][value]', $revision_log_message); + $page->fillField('revision_log_message[0][value]', $revision_log_message); $page->pressButton('Save and keep published'); $assert_session->titleEquals($media_name . ' | Drupal'); /** @var \Drupal\media\MediaInterface $media */ @@ -104,7 +110,7 @@ ->getStorage('media') ->loadUnchanged($media_id); $this->assertEquals($media->getRevisionLogMessage(), $revision_log_message); - $this->assertNotEquals($previoius_revision_id, $media->getRevisionId()); + $this->assertNotEquals($previous_revision_id, $media->getRevisionId()); // Tests media delete form. $this->drupalGet('media/' . $media_id . '/edit'); diff -u b/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php b/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php --- b/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\media\FunctionalJavascript; use Drupal\FunctionalJavascriptTests\JavascriptTestBase; +use Drupal\Tests\media\Functional\MediaFunctionalTestCreateMediaTypeTrait; use Drupal\Tests\media\Functional\MediaFunctionalTestTrait; /** @@ -11,6 +12,7 @@ abstract class MediaJavascriptTestBase extends JavascriptTestBase { use MediaFunctionalTestTrait; + use MediaFunctionalTestCreateMediaTypeTrait; /** * Modules to enable. @@ -27,70 +29,6 @@ ]; /** - * Permissions for the admin user that will be logged-in for test. - * - * @var array - */ - protected static $adminUserPermissions = [ - // Media entity permissions. - 'administer media', - 'administer media fields', - 'administer media form display', - 'administer media display', - 'administer media types', - 'view media', - 'create media', - 'update media', - 'update any media', - 'delete media', - 'delete any media', - // Other permissions. - 'administer views', - 'access content overview', - 'view all revisions', - 'administer content types', - 'administer node fields', - 'administer node form display', - 'bypass node access', - ]; - - /** - * An admin test user account. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $adminUser; - - /** - * A non-admin test user account. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $nonAdminUser; - - /** - * The storage service. - * - * @var \Drupal\Core\Entity\EntityStorageInterface - */ - protected $storage; - - /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - - // Have two users ready to be used in tests. - $this->adminUser = $this->drupalCreateUser(static::$adminUserPermissions); - $this->nonAdminUser = $this->drupalCreateUser([]); - // Start off logged in as admin. - $this->drupalLogin($this->adminUser); - - $this->storage = $this->container->get('entity_type.manager')->getStorage('media'); - } - - /** * Waits and asserts that a given element is visible. * * @param string $selector diff -u b/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php --- b/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php @@ -5,6 +5,7 @@ use Drupal\field\FieldConfigInterface; use Drupal\media\Entity\Media; use Drupal\media\Entity\MediaType; +use Drupal\media\MediaSourceInterface; /** * Ensures that media UI works correctly. @@ -147,7 +148,7 @@ $assert_session->checkboxChecked('options[queue_thumbnail_downloads]'); $assert_session->fieldValueEquals('Test config value', 'This is new config value.'); $assert_session->fieldValueEquals('Attribute 1', 'name'); - $assert_session->fieldValueEquals('Attribute 2', '_none'); + $assert_session->fieldValueEquals('Attribute 2', MediaSourceInterface::METADATA_FIELD_EMPTY); /** @var \Drupal\media\MediaTypeInterface $loaded_media_type */ $loaded_media_type = $this->container->get('entity_type.manager') diff -u b/core/modules/media/tests/src/Kernel/BasicCreationTest.php b/core/modules/media/tests/src/Kernel/BasicCreationTest.php --- b/core/modules/media/tests/src/Kernel/BasicCreationTest.php +++ b/core/modules/media/tests/src/Kernel/BasicCreationTest.php @@ -32,7 +32,7 @@ // Source field is not set on the media source, but it should never // be created automatically when a config is being imported. $this->assertEquals(['source_field' => '', 'test_config_value' => 'Kakec'], $test_media_type->get('source_configuration'), 'Could not assure the correct media source configuration.'); - $this->assertEquals([], $test_media_type->get('field_map'), 'Could not assure the correct field map.'); + $this->assertEquals(['metadata_attribute' => 'field_attribute_config_test'], $test_media_type->get('field_map'), 'Could not assure the correct field map.'); } /** diff -u b/core/modules/media/tests/src/Kernel/MediaSourceTest.php b/core/modules/media/tests/src/Kernel/MediaSourceTest.php --- b/core/modules/media/tests/src/Kernel/MediaSourceTest.php +++ b/core/modules/media/tests/src/Kernel/MediaSourceTest.php @@ -290,6 +290,7 @@ $this->fail('Save was allowed without validation.'); } catch (EntityStorageException $exception) { + $this->assertEquals('Entity validation was skipped.', $exception->getMessage(), 'Incorrect validation message.'); $this->assertTrue(TRUE, 'Validation was enforced before save.'); } @@ -328,6 +329,7 @@ $this->fail('Save was allowed without validation.'); } catch (EntityStorageException $exception) { + $this->assertEquals('Entity validation was skipped.', $exception->getMessage(), 'Incorrect validation message.'); $this->assertTrue(TRUE, 'Validation was enforced before save.'); } only in patch2: unchanged: --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaFunctionalTestCreateMediaTypeTrait.php @@ -0,0 +1,67 @@ +randomMachineName()); + } + else { + $id = $values['bundle']; + } + $values += [ + 'id' => $id, + 'label' => $id, + 'source' => $source, + 'source_configuration' => [], + 'field_map' => [], + 'new_revision' => FALSE, + ]; + + $media_type = MediaType::create($values); + $status = $media_type->save(); + + // @todo Rename to assertSame() when #1945040 is done. + // @see https://www.drupal.org/node/1945040 + $this->assertIdentical(SAVED_NEW, $status, 'Media type was created successfully.'); + + // Ensure that the source field exists. + $source = $media_type->getSource(); + $source_field = $source->getSourceFieldDefinition($media_type); + if (!$source_field) { + $source_field = $source->createSourceField($media_type); + /** @var \Drupal\field\FieldStorageConfigInterface $storage */ + $storage = $source_field->getFieldStorageDefinition(); + $storage->setLocked(TRUE)->save(); + $source_field->save(); + + $media_type + ->set('source_configuration', [ + 'source_field' => $source_field->getName(), + ]) + ->save(); + } + + return $media_type; + } + +}