Issue #1814864 by linclark, effulgentsia: Added Provide way to register serialization classes.
parent
876bcaeb5d
commit
99bef1de6c
|
@ -10,6 +10,7 @@ namespace Drupal\Core;
|
|||
use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
|
||||
use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
|
||||
use Drupal\Core\DependencyInjection\Compiler\RegisterNestedMatchersPass;
|
||||
use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
@ -126,10 +127,17 @@ class CoreBundle extends Bundle
|
|||
->setFactoryClass('Drupal\Core\ExceptionController')
|
||||
->setFactoryMethod('getExceptionListener');
|
||||
|
||||
// Add Serializer with arguments to be replaced in the compiler pass.
|
||||
$container->register('serializer', 'Symfony\Component\Serializer\Serializer')
|
||||
->addArgument(array())
|
||||
->addArgument(array());
|
||||
|
||||
$container->addCompilerPass(new RegisterMatchersPass());
|
||||
$container->addCompilerPass(new RegisterNestedMatchersPass());
|
||||
// Add a compiler pass for registering event subscribers.
|
||||
$container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
// Add a compiler pass for adding Normalizers and Encoders to Serializer.
|
||||
$container->addCompilerPass(new RegisterSerializationClassesPass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\serialization\RegisterSerializationClassesPass.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
|
||||
/**
|
||||
* Adds services tagged 'normalizer' and 'encoder' to the Serializer.
|
||||
*/
|
||||
class RegisterSerializationClassesPass implements CompilerPassInterface {
|
||||
|
||||
/**
|
||||
* Adds services to the Serializer.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
|
||||
* The container to process.
|
||||
*/
|
||||
public function process(ContainerBuilder $container) {
|
||||
$definition = $container->getDefinition('serializer');
|
||||
|
||||
// Retrieve registered Normalizers and Encoders from the container.
|
||||
foreach ($container->findTaggedServiceIds('normalizer') as $id => $attributes) {
|
||||
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
|
||||
$normalizers[$priority][] = new Reference($id);
|
||||
}
|
||||
foreach ($container->findTaggedServiceIds('encoder') as $id => $attributes) {
|
||||
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
|
||||
$encoders[$priority][] = new Reference($id);
|
||||
}
|
||||
|
||||
// Add the registered Normalizers and Encoders to the Serializer.
|
||||
if (!empty($normalizers)) {
|
||||
$definition->replaceArgument(0, $this->sort($normalizers));
|
||||
}
|
||||
if (!empty($encoders)) {
|
||||
$definition->replaceArgument(1, $this->sort($encoders));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts by priority.
|
||||
*
|
||||
* Order services from highest priority number to lowest (reverse sorting).
|
||||
*
|
||||
* @param array $services
|
||||
* A nested array keyed on priority number. For each priority number, the
|
||||
* value is an array of Symfony\Component\DependencyInjection\Reference
|
||||
* objects, each a reference to a normalizer or encoder service.
|
||||
*
|
||||
* @return array
|
||||
* A flattened array of Reference objects from $services, ordered from high
|
||||
* to low priority.
|
||||
*/
|
||||
protected function sort($services) {
|
||||
$sorted = array();
|
||||
krsort($services);
|
||||
|
||||
// Flatten the array.
|
||||
foreach ($services as $a) {
|
||||
$sorted = array_merge($sorted, $a);
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\jsonld\Tests\SerializationTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Tests\Serialization;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
|
||||
class SerializationTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('serialization_test');
|
||||
|
||||
/**
|
||||
* The serializer service to test.
|
||||
*
|
||||
* @var Symfony\Component\Serializer\SerializerInterface
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Serialization tests',
|
||||
'description' => 'Funtional tests for serialization system.',
|
||||
'group' => 'Serialization',
|
||||
);
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->serializer = drupal_container()->get('serializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that modules can register normalizers and encoders.
|
||||
*/
|
||||
public function testSerializerComponentRegistration() {
|
||||
$object = new \stdClass();
|
||||
$format = 'serialization_test';
|
||||
$expected = 'Normalized by SerializationTestNormalizer, Encoded by SerializationTestEncoder';
|
||||
|
||||
// Ensure the serialization invokes the expected normalizer and encoder.
|
||||
$this->assertIdentical($this->serializer->serialize($object, $format), $expected);
|
||||
|
||||
// Ensure the serialization fails for an unsupported format.
|
||||
try {
|
||||
$this->serializer->serialize($object, 'unsupported_format');
|
||||
$this->fail('The serializer was expected to throw an exception for an unsupported format, but did not.');
|
||||
}
|
||||
catch (UnexpectedValueException $e) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\serialization_test\SerializationTestBundle.
|
||||
*/
|
||||
|
||||
namespace Drupal\serialization_test;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
|
||||
/**
|
||||
* SerializationTest dependency injection container.
|
||||
*/
|
||||
class SerializationTestBundle extends Bundle {
|
||||
|
||||
/**
|
||||
* Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
|
||||
*/
|
||||
public function build(ContainerBuilder $container) {
|
||||
$container->register('serializer.normalizer.serialization_test', 'Drupal\serialization_test\SerializationTestNormalizer')->addTag('normalizer');
|
||||
$container->register('serializer.encoder.serialization_test', 'Drupal\serialization_test\SerializationTestEncoder')->addTag('encoder');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\serialization_test\SerializationTestEncoder.
|
||||
*/
|
||||
|
||||
namespace Drupal\serialization_test;
|
||||
|
||||
use Symfony\Component\Serializer\Encoder\EncoderInterface;
|
||||
|
||||
class SerializationTestEncoder implements EncoderInterface {
|
||||
|
||||
/**
|
||||
* The format that this Encoder supports.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static protected $format = 'serialization_test';
|
||||
|
||||
/**
|
||||
* Encodes data into the requested format.
|
||||
*
|
||||
* @param mixed $data
|
||||
* Data to encode.
|
||||
* @param string $format
|
||||
* Format name.
|
||||
*
|
||||
* @return string
|
||||
* A string representation of $data in the requested format.
|
||||
*/
|
||||
public function encode($data, $format) {
|
||||
// @see Drupal\serialization_test\SerializationTestNormalizer::normalize().
|
||||
return 'Normalized by ' . $data['normalized_by'] . ', Encoded by SerializationTestEncoder';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this encoder can encode to the requested format.
|
||||
*
|
||||
* @param string $format
|
||||
* The short name of the format.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if this encoder can encode to the requested format.
|
||||
*/
|
||||
public function supportsEncoding($format) {
|
||||
return static::$format === $format;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\serialization_test\SerializationTestNormalizer.
|
||||
*/
|
||||
|
||||
namespace Drupal\serialization_test;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class SerializationTestNormalizer implements NormalizerInterface {
|
||||
|
||||
/**
|
||||
* The format that this Normalizer supports.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static protected $format = 'serialization_test';
|
||||
|
||||
/**
|
||||
* Normalizes an object into a set of arrays/scalars.
|
||||
*
|
||||
* @param object $object
|
||||
* Object to normalize.
|
||||
* @param string $format
|
||||
* Format the normalization result will be encoded as.
|
||||
*
|
||||
* @return array
|
||||
* An array containing a normalized representation of $object, appropriate
|
||||
* for encoding to the requested format.
|
||||
*/
|
||||
public function normalize($object, $format = NULL) {
|
||||
$normalized = (array) $object;
|
||||
// Add identifying value that can be used to verify that the expected
|
||||
// normalizer was invoked.
|
||||
$normalized['normalized_by'] = 'SerializationTestNormalizer';
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether format is supported by this normalizer.
|
||||
*
|
||||
* @param mixed $data
|
||||
* Data to normalize.
|
||||
* @param string $format
|
||||
* Format the normalization result will be encoded as.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the normalizer can handle the request.
|
||||
*/
|
||||
public function supportsNormalization($data, $format = NULL) {
|
||||
return static::$format === $format;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
name = Serialization test module
|
||||
description = "Support module for serialization tests."
|
||||
package = Testing
|
||||
core = 8.x
|
||||
hidden = TRUE
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper module for serialization tests. This file is empty, because all
|
||||
* implementation is in autoloaded classes.
|
||||
*/
|
Loading…
Reference in New Issue