diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 3f05ad7a59030..d63b0172335d1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * Add support for assets pre-compression * Rename `TranslationUpdateCommand` to `TranslationExtractCommand` + * Add JsonEncoder services and configuration 7.2 --- diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php index ae2523e515d0c..45d08a975bd83 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php @@ -53,6 +53,9 @@ class UnusedTagsPass implements CompilerPassInterface 'form.type_guesser', 'html_sanitizer', 'http_client.client', + 'json_encoder.denormalizer', + 'json_encoder.encodable', + 'json_encoder.normalizer', 'kernel.cache_clearer', 'kernel.cache_warmer', 'kernel.event_listener', diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 372da4a5ee8e5..99592fe4989c9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -31,6 +31,7 @@ use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\IpUtils; +use Symfony\Component\JsonEncoder\EncoderInterface; use Symfony\Component\Lock\Lock; use Symfony\Component\Lock\Store\SemaphoreStore; use Symfony\Component\Mailer\Mailer; @@ -181,6 +182,7 @@ public function getConfigTreeBuilder(): TreeBuilder $this->addHtmlSanitizerSection($rootNode, $enableIfStandalone); $this->addWebhookSection($rootNode, $enableIfStandalone); $this->addRemoteEventSection($rootNode, $enableIfStandalone); + $this->addJsonEncoderSection($rootNode, $enableIfStandalone); return $treeBuilder; } @@ -2570,4 +2572,26 @@ private function addHtmlSanitizerSection(ArrayNodeDefinition $rootNode, callable ->end() ; } + + private function addJsonEncoderSection(ArrayNodeDefinition $rootNode, callable $enableIfStandalone): void + { + $rootNode + ->children() + ->arrayNode('json_encoder') + ->info('JSON encoder configuration') + ->{$enableIfStandalone('symfony/json-encoder', EncoderInterface::class)}() + ->fixXmlConfig('path') + ->children() + ->arrayNode('paths') + ->info('Namespaces and paths of encodable/decodable classes.') + ->normalizeKeys(false) + ->useAttributeAsKey('namespace') + ->scalarPrototype()->end() + ->defaultValue([]) + ->end() + ->end() + ->end() + ->end() + ; + } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 3f51575820ae2..862abe3ca5942 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -99,6 +99,11 @@ use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\HttpKernel\Log\DebugLoggerConfigurator; +use Symfony\Component\JsonEncoder\Decode\Denormalizer\DenormalizerInterface as JsonEncoderDenormalizerInterface; +use Symfony\Component\JsonEncoder\DecoderInterface as JsonEncoderDecoderInterface; +use Symfony\Component\JsonEncoder\Encode\Normalizer\NormalizerInterface as JsonEncoderNormalizerInterface; +use Symfony\Component\JsonEncoder\EncoderInterface as JsonEncoderEncoderInterface; +use Symfony\Component\JsonEncoder\JsonEncoder; use Symfony\Component\Lock\LockFactory; use Symfony\Component\Lock\LockInterface; use Symfony\Component\Lock\PersistingStoreInterface; @@ -176,6 +181,7 @@ use Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\TypeResolver\PhpDocAwareReflectionTypeResolver; use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver; +use Symfony\Component\TypeInfo\TypeResolver\TypeResolverInterface; use Symfony\Component\Uid\Factory\UuidFactory; use Symfony\Component\Uid\UuidV4; use Symfony\Component\Validator\Constraints\ExpressionLanguageProvider; @@ -414,7 +420,7 @@ public function load(array $configs, ContainerBuilder $container): void $container->removeDefinition('console.command.serializer_debug'); } - if ($this->readConfigEnabled('type_info', $container, $config['type_info'])) { + if ($typeInfoEnabled = $this->readConfigEnabled('type_info', $container, $config['type_info'])) { $this->registerTypeInfoConfiguration($container, $loader); } @@ -422,6 +428,14 @@ public function load(array $configs, ContainerBuilder $container): void $this->registerPropertyInfoConfiguration($container, $loader); } + if ($this->readConfigEnabled('json_encoder', $container, $config['json_encoder'])) { + if (!$typeInfoEnabled) { + throw new LogicException('JsonEncoder support cannot be enabled as the TypeInfo component is not '.(interface_exists(TypeResolverInterface::class) ? 'enabled.' : 'installed. Try running "composer require symfony/type-info".')); + } + + $this->registerJsonEncoderConfiguration($config['json_encoder'], $container, $loader); + } + if ($this->readConfigEnabled('lock', $container, $config['lock'])) { $this->registerLockConfiguration($config['lock'], $container, $loader); } @@ -1990,6 +2004,36 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $container->setParameter('.serializer.named_serializers', $config['named_serializers'] ?? []); } + private function registerJsonEncoderConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader): void + { + if (!class_exists(JsonEncoder::class)) { + throw new LogicException('JsonEncoder support cannot be enabled as the JsonEncoder component is not installed. Try running "composer require symfony/json-encoder".'); + } + + $container->registerForAutoconfiguration(JsonEncoderNormalizerInterface::class) + ->addTag('json_encoder.normalizer'); + $container->registerForAutoconfiguration(JsonEncoderDenormalizerInterface::class) + ->addTag('json_encoder.denormalizer'); + + $loader->load('json_encoder.php'); + + $container->registerAliasForArgument('json_encoder.encoder', JsonEncoderEncoderInterface::class, 'json.encoder'); + $container->registerAliasForArgument('json_encoder.decoder', JsonEncoderDecoderInterface::class, 'json.decoder'); + + $container->setParameter('.json_encoder.encoders_dir', '%kernel.cache_dir%/json_encoder/encoder'); + $container->setParameter('.json_encoder.decoders_dir', '%kernel.cache_dir%/json_encoder/decoder'); + $container->setParameter('.json_encoder.lazy_ghosts_dir', '%kernel.cache_dir%/json_encoder/lazy_ghost'); + + $encodableDefinition = (new Definition()) + ->setAbstract(true) + ->addTag('container.excluded') + ->addTag('json_encoder.encodable'); + + foreach ($config['paths'] as $namespace => $path) { + $loader->registerClasses($encodableDefinition, $namespace, $path); + } + } + private function registerPropertyInfoConfiguration(ContainerBuilder $container, PhpFileLoader $loader): void { if (!interface_exists(PropertyInfoExtractorInterface::class)) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/json_encoder.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/json_encoder.php new file mode 100644 index 0000000000000..b864ed0f9a893 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/json_encoder.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\JsonEncoder\CacheWarmer\EncoderDecoderCacheWarmer; +use Symfony\Component\JsonEncoder\CacheWarmer\LazyGhostCacheWarmer; +use Symfony\Component\JsonEncoder\Decode\Denormalizer\DateTimeDenormalizer; +use Symfony\Component\JsonEncoder\Encode\Normalizer\DateTimeNormalizer; +use Symfony\Component\JsonEncoder\JsonDecoder; +use Symfony\Component\JsonEncoder\JsonEncoder; +use Symfony\Component\JsonEncoder\Mapping\Decode\AttributePropertyMetadataLoader as DecodeAttributePropertyMetadataLoader; +use Symfony\Component\JsonEncoder\Mapping\Decode\DateTimeTypePropertyMetadataLoader as DecodeDateTimeTypePropertyMetadataLoader; +use Symfony\Component\JsonEncoder\Mapping\Encode\AttributePropertyMetadataLoader as EncodeAttributePropertyMetadataLoader; +use Symfony\Component\JsonEncoder\Mapping\Encode\DateTimeTypePropertyMetadataLoader as EncodeDateTimeTypePropertyMetadataLoader; +use Symfony\Component\JsonEncoder\Mapping\GenericTypePropertyMetadataLoader; +use Symfony\Component\JsonEncoder\Mapping\PropertyMetadataLoader; + +return static function (ContainerConfigurator $container) { + $container->services() + // encoder/decoder + ->set('json_encoder.encoder', JsonEncoder::class) + ->args([ + tagged_locator('json_encoder.normalizer'), + service('json_encoder.encode.property_metadata_loader'), + param('.json_encoder.encoders_dir'), + false, + ]) + ->set('json_encoder.decoder', JsonDecoder::class) + ->args([ + tagged_locator('json_encoder.denormalizer'), + service('json_encoder.decode.property_metadata_loader'), + param('.json_encoder.decoders_dir'), + param('.json_encoder.lazy_ghosts_dir'), + ]) + ->alias(JsonEncoder::class, 'json_encoder.encoder') + ->alias(JsonDecoder::class, 'json_encoder.decoder') + + // metadata + ->stack('json_encoder.encode.property_metadata_loader', [ + inline_service(EncodeAttributePropertyMetadataLoader::class) + ->args([ + service('.inner'), + tagged_locator('json_encoder.normalizer'), + service('type_info.resolver'), + ]), + inline_service(EncodeDateTimeTypePropertyMetadataLoader::class) + ->args([ + service('.inner'), + ]), + inline_service(GenericTypePropertyMetadataLoader::class) + ->args([ + service('.inner'), + service('type_info.type_context_factory'), + ]), + inline_service(PropertyMetadataLoader::class) + ->args([ + service('type_info.resolver'), + ]), + ]) + + ->stack('json_encoder.decode.property_metadata_loader', [ + inline_service(DecodeAttributePropertyMetadataLoader::class) + ->args([ + service('.inner'), + tagged_locator('json_encoder.denormalizer'), + service('type_info.resolver'), + ]), + inline_service(DecodeDateTimeTypePropertyMetadataLoader::class) + ->args([ + service('.inner'), + ]), + inline_service(GenericTypePropertyMetadataLoader::class) + ->args([ + service('.inner'), + service('type_info.type_context_factory'), + ]), + inline_service(PropertyMetadataLoader::class) + ->args([ + service('type_info.resolver'), + ]), + ]) + + // normalizers/denormalizers + ->set('json_encoder.normalizer.date_time', DateTimeNormalizer::class) + ->tag('json_encoder.normalizer') + ->set('json_encoder.denormalizer.date_time', DateTimeDenormalizer::class) + ->args([ + false, + ]) + ->tag('json_encoder.denormalizer') + ->set('json_encoder.denormalizer.date_time_immutable', DateTimeDenormalizer::class) + ->args([ + true, + ]) + ->tag('json_encoder.denormalizer') + + // cache + ->set('.json_encoder.cache_warmer.encoder_decoder', EncoderDecoderCacheWarmer::class) + ->args([ + tagged_iterator('json_encoder.encodable'), + service('json_encoder.encode.property_metadata_loader'), + service('json_encoder.decode.property_metadata_loader'), + param('.json_encoder.encoders_dir'), + param('.json_encoder.decoders_dir'), + false, + service('logger')->ignoreOnInvalid(), + ]) + ->tag('kernel.cache_warmer') + + ->set('.json_encoder.cache_warmer.lazy_ghost', LazyGhostCacheWarmer::class) + ->args([ + tagged_iterator('json_encoder.encodable'), + param('.json_encoder.lazy_ghosts_dir'), + ]) + ->tag('kernel.cache_warmer') + ; +}; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 91528b60f3de6..9cb89207ddade 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -46,6 +46,7 @@ + @@ -1003,4 +1004,13 @@ + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index c7113cfb47d45..963cac6386c57 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -970,6 +970,10 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor 'remote-event' => [ 'enabled' => !class_exists(FullStack::class) && class_exists(RemoteEvent::class), ], + 'json_encoder' => [ + 'enabled' => false, + 'paths' => [], + ], ]; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/json_encoder.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/json_encoder.php new file mode 100644 index 0000000000000..42204b2cbb1dd --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/json_encoder.php @@ -0,0 +1,14 @@ +loadFromExtension('framework', [ + 'annotations' => false, + 'http_method_override' => false, + 'handle_all_throwables' => true, + 'php_errors' => ['log' => true], + 'type_info' => [ + 'enabled' => true, + ], + 'json_encoder' => [ + 'enabled' => true, + ], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index c01e857838bc3..a3e5cfd88b5ff 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -46,5 +46,6 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/json_encoder.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/json_encoder.xml new file mode 100644 index 0000000000000..a20f98567581a --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/json_encoder.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index 7550749eb1a1e..8e272d11bfb47 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -70,3 +70,4 @@ framework: formats: csv: ['text/csv', 'text/plain'] pdf: 'application/pdf' + json_encoder: ~ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/json_encoder.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/json_encoder.yml new file mode 100644 index 0000000000000..e09f7c7d368b0 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/json_encoder.yml @@ -0,0 +1,10 @@ +framework: + annotations: false + http_method_override: false + handle_all_throwables: true + php_errors: + log: true + type_info: + enabled: true + json_encoder: + enabled: true diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 798217191e7c0..0446eb5d2e7c6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -2497,6 +2497,12 @@ public function testSemaphoreWithService() self::assertEquals(new Reference('my_service'), $storeDef->getArgument(0)); } + public function testJsonEncoderEnabled() + { + $container = $this->createContainerFromFile('json_encoder'); + $this->assertTrue($container->has('json_encoder.encoder')); + } + protected function createContainer(array $data = []) { return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php new file mode 100644 index 0000000000000..0ab66e6c1830f --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +use Symfony\Bundle\FrameworkBundle\Tests\Functional\app\JsonEncoder\Dto\Dummy; +use Symfony\Component\JsonEncoder\DecoderInterface; +use Symfony\Component\JsonEncoder\EncoderInterface; +use Symfony\Component\TypeInfo\Type; + +/** + * @author Mathias Arlaud + */ +class JsonEncoderTest extends AbstractWebTestCase +{ + public function testEncode() + { + static::bootKernel(['test_case' => 'JsonEncoder']); + + /** @var EncoderInterface $encoder */ + $encoder = static::getContainer()->get('json_encoder.encoder.alias'); + + $this->assertSame('{"@name":"DUMMY","range":"10..20"}', (string) $encoder->encode(new Dummy(), Type::object(Dummy::class))); + } + + public function testDecode() + { + static::bootKernel(['test_case' => 'JsonEncoder']); + + /** @var DecoderInterface $decoder */ + $decoder = static::getContainer()->get('json_encoder.decoder.alias'); + + $expected = new Dummy(); + $expected->name = 'dummy'; + $expected->range = [0, 1]; + + $this->assertEquals($expected, $decoder->decode('{"@name": "DUMMY", "range": "0..1"}', Type::object(Dummy::class))); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/Dto/Dummy.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/Dto/Dummy.php new file mode 100644 index 0000000000000..344b9d11cba03 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/Dto/Dummy.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\app\JsonEncoder\Dto; + +use Symfony\Bundle\FrameworkBundle\Tests\Functional\app\JsonEncoder\RangeNormalizer; +use Symfony\Component\JsonEncoder\Attribute\Denormalizer; +use Symfony\Component\JsonEncoder\Attribute\EncodedName; +use Symfony\Component\JsonEncoder\Attribute\Normalizer; + +/** + * @author Mathias Arlaud + */ +class Dummy +{ + #[EncodedName('@name')] + #[Normalizer('strtoupper')] + #[Denormalizer('strtolower')] + public string $name = 'dummy'; + + #[Normalizer(RangeNormalizer::class)] + #[Denormalizer(RangeNormalizer::class)] + public array $range = [10, 20]; +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/RangeNormalizer.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/RangeNormalizer.php new file mode 100644 index 0000000000000..beb9e81888ce4 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/RangeNormalizer.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\app\JsonEncoder; + +use Symfony\Component\JsonEncoder\Decode\Denormalizer\DenormalizerInterface; +use Symfony\Component\JsonEncoder\Encode\Normalizer\NormalizerInterface; +use Symfony\Component\TypeInfo\Type; +use Symfony\Component\TypeInfo\Type\BuiltinType; + +/** + * @author Mathias Arlaud + */ +class RangeNormalizer implements NormalizerInterface, DenormalizerInterface +{ + public function normalize(mixed $denormalized, array $options = []): string + { + return $denormalized[0].'..'.$denormalized[1]; + } + + public function denormalize(mixed $normalized, array $options = []): array + { + return array_map(static fn (string $v): int => (int) $v, explode('..', $normalized)); + } + + public static function getNormalizedType(): BuiltinType + { + return Type::string(); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/bundles.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/bundles.php new file mode 100644 index 0000000000000..15ff182c6fed5 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/bundles.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; +use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle; + +return [ + new FrameworkBundle(), + new TestBundle(), +]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/config.yml new file mode 100644 index 0000000000000..55fdf53f5c2fd --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/JsonEncoder/config.yml @@ -0,0 +1,24 @@ +imports: + - { resource: ../config/default.yml } + +framework: + http_method_override: false + type_info: ~ + json_encoder: + enabled: true + paths: + Symfony\Bundle\FrameworkBundle\Tests\Functional\app\JsonEncoder\Dto\: '../../Tests/Functional/app/JsonEncoder/Dto/*' + +services: + _defaults: + autoconfigure: true + + json_encoder.encoder.alias: + alias: json_encoder.encoder + public: true + + json_encoder.decoder.alias: + alias: json_encoder.decoder + public: true + + Symfony\Bundle\FrameworkBundle\Tests\Functional\app\JsonEncoder\RangeNormalizer: ~ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy