core/modules/media/media.module | 16 ++++ core/modules/media/media.services.yml | 6 ++ .../src/Normalizer/MediaEntitiesNormalizer.php | 37 +++++++++ .../src/Kernel/MediaEntitiesNormalizerTest.php | 95 ++++++++++++++++++++++ .../media/tests/src/Kernel/MediaResourceTest.php | 47 +++++++++++ 5 files changed, 201 insertions(+) diff --git a/core/modules/media/media.module b/core/modules/media/media.module index eeb2ac1..ea6bc01 100644 --- a/core/modules/media/media.module +++ b/core/modules/media/media.module @@ -114,3 +114,19 @@ function template_preprocess_media(array &$variables) { $variables['content'][$key] = $variables['elements'][$key]; } } + +/** + * Implements hook_rest_resource_alter(). + * + * The normalization of Media and Media Type entities was never considered + * during their development. Rather than allowing them to fall back to defaults + * for their normalizations (and hence serializations), this excludes them from + * being exposed as REST resources. This is done to ensure we don't let clients + * be developed against the default normalizations, which are known to contain + * gaps especially for file handling, and hence are guaranteed to break BC. + * + * @todo Remove this in https://www.drupal.org/node/2895573 + */ +function media_rest_resource_alter(&$definitions) { + unset($definitions['entity:media'], $definitions['entity:media_type']); +} diff --git a/core/modules/media/media.services.yml b/core/modules/media/media.services.yml index f22f90a..b61f7d2 100644 --- a/core/modules/media/media.services.yml +++ b/core/modules/media/media.services.yml @@ -8,3 +8,9 @@ services: arguments: ['@entity_type.manager'] tags: - { name: access_check, applies_to: _access_media_revision } + + # @todo Remove this in https://www.drupal.org/node/2895573 + serializer.normalizer.media: + class: Drupal\media\Normalizer\MediaEntitiesNormalizer + tags: + - { name: normalizer, priority: 1000 } diff --git a/core/modules/media/src/Normalizer/MediaEntitiesNormalizer.php b/core/modules/media/src/Normalizer/MediaEntitiesNormalizer.php new file mode 100644 index 0000000..3fe903f --- /dev/null +++ b/core/modules/media/src/Normalizer/MediaEntitiesNormalizer.php @@ -0,0 +1,37 @@ +setExpectedException(UnsupportedException::class, "Normalizing $entity_type_id entities is not yet supported."); + + $media_type = $this->createMediaType(); + if ($entity_type_id === 'media') { + $media = Media::create([ + 'bundle' => $media_type->id(), + 'name' => 'Unnamed', + ]); + } + $entity_under_test = $entity_type_id === 'media' ? $media : $media_type; + + $this->container->get('serializer')->$operation($entity_under_test, 'json'); + } + + public function providerTestNormalize() { + return [ + 'normalize Media' => ['media', 'normalize'], + 'serialize Media' => ['media', 'serialize'], + 'normalize Media Type' => ['media_type', 'normalize'], + 'serialize Media Type' => ['media_type', 'serialize'], + ]; + } + + /** + * @covers ::denormalize + * @dataProvider providerTestDenormalize + */ + public function testDenormalize($entity_type_id, $operation) { + $this->setExpectedException(UnsupportedException::class, "Denormalizing $entity_type_id entities is not yet supported."); + + $data = []; + $class = MediaType::class; + if ($entity_type_id === 'media') { + $media_type = $this->createMediaType(); + $data = ['bundle' => $media_type->id()]; + $class = Media::class; + } + + if ($operation === 'deserialize') { + $data = Json::encode($data); + } + + $this->container->get('serializer')->$operation($data, $class, 'json'); + } + + public function providerTestDenormalize() { + return [ + 'denormalize Media' => ['media', 'denormalize'], + 'deserialize Media' => ['media', 'deserialize'], + 'denormalize Media Type' => ['media_type', 'denormalize'], + 'deserialize Media Type' => ['media_type', 'deserialize'], + ]; + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaResourceTest.php b/core/modules/media/tests/src/Kernel/MediaResourceTest.php new file mode 100644 index 0000000..0623257 --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaResourceTest.php @@ -0,0 +1,47 @@ +setExpectedException(PluginNotFoundException::class, 'The "entity:' . $entity_type_id . '" plugin does not exist.'); + RestResourceConfig::create([ + 'id' => 'entity.' . $entity_type_id, + 'granularity' => RestResourceConfigInterface::RESOURCE_GRANULARITY, + 'configuration' => [ + 'methods' => ['GET'], + 'formats' => ['json'], + 'authentication' => ['cookie'], + ], + ]) + ->enable() + ->save(); + } + + public function providerTestEnableMediaEntityType() { + return [ + ['media'], + ['media_type'], + ]; + } + +}