From 424002b7c0ebe909924597a29b505d4b5e104da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 10 Jul 2016 11:41:46 +0200 Subject: [PATCH 1/5] [Serializer] Add a YAML encoder --- .../Serializer/Encoder/YamlEncoder.php | 73 +++++++++++++++++++ .../Tests/Encoder/YamlEncoderTest.php | 68 +++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/Symfony/Component/Serializer/Encoder/YamlEncoder.php create mode 100644 src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php diff --git a/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php b/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php new file mode 100644 index 0000000000000..a1a8d18fb1624 --- /dev/null +++ b/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Encoder; + +use Symfony\Component\Yaml\Dumper; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Yaml; + +/** + * Encodes YAML data. + * + * @author Kévin Dunglas + */ +class YamlEncoder implements EncoderInterface, DecoderInterface +{ + const FORMAT = 'yaml'; + + private $dumper; + private $parser; + private $defaultContext; + + public function __construct(Dumper $dumper = null, Parser $parser = null, $defaultContext = array('yaml_inline' => 0, 'yaml_indent' => 0, 'yaml_flags' => 0)) + { + $this->dumper = $dumper ?: new Dumper(); + $this->parser = $parser ?: new Parser(); + $this->defaultContext = $defaultContext; + } + + /** + * {@inheritdoc} + */ + public function encode($data, $format, array $context = array()) + { + $context = array_merge($this->defaultContext, $context); + + return $this->dumper->dump($data, $context['yaml_inline'], $context['yaml_indent'], $context['yaml_flags']); + } + + /** + * {@inheritdoc} + */ + public function supportsEncoding($format) + { + return self::FORMAT === $format; + } + + /** + * {@inheritdoc} + */ + public function decode($data, $format, array $context = array()) + { + $context = array_merge($this->defaultContext, $context); + + return Yaml::parse($data, $context['yaml_flags']); + } + + /** + * {@inheritdoc} + */ + public function supportsDecoding($format) + { + return self::FORMAT === $format; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php new file mode 100644 index 0000000000000..8627460a974f0 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Encoder; + +use Symfony\Component\Serializer\Encoder\YamlEncoder; +use Symfony\Component\Yaml\Dumper; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Yaml; + +/** + * @author Kévin Dunglas + */ +class YamlEncoderTest extends \PHPUnit_Framework_TestCase +{ + public function testEncode() + { + $encoder = new YamlEncoder(); + + $this->assertEquals('foo', $encoder->encode('foo', 'yaml')); + $this->assertEquals('{ foo: 1 }', $encoder->encode(array('foo' => 1), 'yaml')); + } + + public function testSupportsEncoding() + { + $encoder = new YamlEncoder(); + + $this->assertTrue($encoder->supportsEncoding('yaml')); + $this->assertFalse($encoder->supportsEncoding('json')); + } + + public function testDecode() + { + $encoder = new YamlEncoder(); + + $this->assertEquals('foo', $encoder->decode('foo', 'yaml')); + $this->assertEquals(array('foo' => 1), $encoder->decode('{ foo: 1 }', 'yaml')); + } + + public function testSupportsDecoding() + { + $encoder = new YamlEncoder(); + + $this->assertTrue($encoder->supportsDecoding('yaml')); + $this->assertFalse($encoder->supportsDecoding('json')); + } + + public function testContext() + { + $encoder = new YamlEncoder(new Dumper(), new Parser(), array('yaml_inline' => 1, 'yaml_indent' => 4, 'yaml_flags' => Yaml::DUMP_OBJECT | Yaml::PARSE_OBJECT)); + + $obj = new \stdClass(); + $obj->bar = 2; + + $this->assertEquals(" foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n", $encoder->encode(array('foo' => $obj), 'yaml')); + $this->assertEquals(' { foo: null }', $encoder->encode(array('foo' => $obj), 'yaml', array('yaml_inline' => 0, 'yaml_indent' => 2, 'yaml_flags' => 0))); + $this->assertEquals(array('foo' => $obj), $encoder->decode('foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml')); + $this->assertEquals(array('foo' => null), $encoder->decode('foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml', array('yaml_flags' => 0))); + } +} From 2ecebeaa6dd902745be2150a8212623cac22821a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 10 Jul 2016 11:44:00 +0200 Subject: [PATCH 2/5] [FrameworkBundle] Register the YAML encoder in FrameworkBundle --- .../DependencyInjection/FrameworkExtension.php | 7 +++++++ src/Symfony/Component/Serializer/Encoder/YamlEncoder.php | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 8cd1fea64a0fa..0aa0c618012a9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -26,6 +26,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\Config\FileLocator; use Symfony\Component\PropertyAccess\PropertyAccessor; +use Symfony\Component\Serializer\Encoder\YamlEncoder; use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory; use Symfony\Component\Serializer\Normalizer\DataUriNormalizer; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; @@ -977,6 +978,12 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $definition->addTag('serializer.normalizer', array('priority' => -900)); } + if (class_exists(YamlEncoder::class)) { + $definition = $container->register('serializer.encoder.yaml', YamlEncoder::class); + $definition->setPublic(false); + $definition->addTag('serializer.encoder'); + } + $loader->load('serializer.xml'); $chainLoader = $container->getDefinition('serializer.mapping.chain_loader'); diff --git a/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php b/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php index a1a8d18fb1624..e83a618b99b54 100644 --- a/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php @@ -26,13 +26,13 @@ class YamlEncoder implements EncoderInterface, DecoderInterface private $dumper; private $parser; - private $defaultContext; + private $defaultContext = array('yaml_inline' => 0, 'yaml_indent' => 0, 'yaml_flags' => 0); - public function __construct(Dumper $dumper = null, Parser $parser = null, $defaultContext = array('yaml_inline' => 0, 'yaml_indent' => 0, 'yaml_flags' => 0)) + public function __construct(Dumper $dumper = null, Parser $parser = null, $defaultContext = array()) { $this->dumper = $dumper ?: new Dumper(); $this->parser = $parser ?: new Parser(); - $this->defaultContext = $defaultContext; + $this->defaultContext = array_merge($this->defaultContext, $defaultContext); } /** From f46a4985e8404bd5e9bbe26467c9c1151ec3448d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 17 Jul 2016 11:57:44 +0200 Subject: [PATCH 3/5] Require YAML >=3.1 --- src/Symfony/Component/Serializer/composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index 13d60e1a9e602..91fe7bcf12da3 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -19,7 +19,7 @@ "php": ">=5.5.9" }, "require-dev": { - "symfony/yaml": "~2.8|~3.0", + "symfony/yaml": "~3.1", "symfony/config": "~2.8|~3.0", "symfony/property-access": "~2.8|~3.0", "symfony/http-foundation": "~2.8|~3.0", @@ -29,7 +29,8 @@ "doctrine/cache": "~1.0" }, "conflict": { - "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4" + "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", + "symfony/yaml": "<3.1" }, "suggest": { "psr/cache-implementation": "For using the metadata cache.", From 8032750de783f9f183812f0fb1a69c7610ccfd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 16 Aug 2016 11:33:43 +0200 Subject: [PATCH 4/5] Check that the YAML component is installed --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 0aa0c618012a9..fcbda5951ed8e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -33,6 +33,7 @@ use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer; use Symfony\Component\Validator\Validation; use Symfony\Component\Workflow; +use Symfony\Component\Yaml\Yaml; /** * FrameworkExtension. @@ -978,7 +979,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $definition->addTag('serializer.normalizer', array('priority' => -900)); } - if (class_exists(YamlEncoder::class)) { + if (class_exists(YamlEncoder::class) && defined('Symfony\Component\Yaml\Yaml::DUMP_OBJECT')) { $definition = $container->register('serializer.encoder.yaml', YamlEncoder::class); $definition->setPublic(false); $definition->addTag('serializer.encoder'); From 4cecb3567099b8df5825043bc5dac341fd77f882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 16 Aug 2016 11:34:55 +0200 Subject: [PATCH 5/5] Add missing typehint --- src/Symfony/Component/Serializer/Encoder/YamlEncoder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php b/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php index e83a618b99b54..48eff39611095 100644 --- a/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/YamlEncoder.php @@ -28,7 +28,7 @@ class YamlEncoder implements EncoderInterface, DecoderInterface private $parser; private $defaultContext = array('yaml_inline' => 0, 'yaml_indent' => 0, 'yaml_flags' => 0); - public function __construct(Dumper $dumper = null, Parser $parser = null, $defaultContext = array()) + public function __construct(Dumper $dumper = null, Parser $parser = null, array $defaultContext = array()) { $this->dumper = $dumper ?: new Dumper(); $this->parser = $parser ?: new Parser();