11<?php
22namespace Yoanm \SymfonyJsonRpcHttpServer \Infra \Symfony \DependencyInjection ;
33
4+ use Symfony \Component \Config \Definition \Processor ; // <= Must stay optional !
45use Symfony \Component \DependencyInjection \Compiler \CompilerPassInterface ;
56use Symfony \Component \DependencyInjection \ContainerBuilder ;
67use Symfony \Component \DependencyInjection \Definition ;
@@ -30,16 +31,21 @@ class JsonRpcHttpServerExtension implements ExtensionInterface, CompilerPassInte
3031{
3132 // Use this service to inject string request
3233 const ENDPOINT_SERVICE_NAME = 'yoanm.jsonrpc_http_server.endpoint ' ;
34+
3335 // Use this tag to inject your own resolver
3436 const METHOD_RESOLVER_TAG = 'yoanm.jsonrpc_http_server.method_resolver ' ;
37+
3538 // Use this tag to inject your JSON-RPC methods into the default method resolver
3639 const JSONRPC_METHOD_TAG = 'yoanm.jsonrpc_http_server.jsonrpc_method ' ;
40+
3741 // In case you want to add mapping for a method, use the following service
3842 const SERVICE_NAME_RESOLVER_SERVICE_NAME = 'yoanm.jsonrpc_http_server.resolver.service_name ' ;
39-
40-
43+ // And add an attribute with following key
4144 const JSONRPC_METHOD_TAG_METHOD_NAME_KEY = 'method ' ;
4245
46+ // Extension identifier (used in configuration for instance)
47+ const EXTENSION_IDENTIFIER = 'json_rpc_http_server ' ;
48+
4349
4450 private $ sdkAppResponseCreatorServiceId = 'sdk.app.creator.response ' ;
4551 private $ sdkAppCustomExceptionCreatorServiceId = 'sdk.app.creator.custom_exception ' ;
@@ -55,12 +61,26 @@ class JsonRpcHttpServerExtension implements ExtensionInterface, CompilerPassInte
5561 private $ psr11InfraMethodResolverServiceId = 'psr11.infra.resolver.method ' ;
5662
5763 private $ methodResolverStubServiceId = 'infra.resolver.method ' ;
64+ private $ customResolverContainerParameter = self ::EXTENSION_IDENTIFIER .'.custom_method_resolver ' ;
65+
66+ /** @var bool */
67+ private $ parseConfig = false ;
68+
69+ /**
70+ * @param bool|false $parseConfig If true, Config component is required
71+ */
72+ public function __construct (bool $ parseConfig = false )
73+ {
74+ $ this ->parseConfig = $ parseConfig ;
75+ }
5876
5977 /**
6078 * {@inheritdoc}
6179 */
6280 public function load (array $ configs , ContainerBuilder $ container )
6381 {
82+ $ this ->compileAndProcessConfigurations ($ configs , $ container );
83+
6484 // Use only references to avoid class instantiation
6585 // And don't use file configuration in order to not add Symfony\Component\Config as dependency
6686 $ this ->createPublicServiceDefinitions ($ container );
@@ -89,7 +109,7 @@ public function getXsdValidationBasePath()
89109 */
90110 public function getAlias ()
91111 {
92- return ' json_rpc_http_server ' ;
112+ return self :: EXTENSION_IDENTIFIER ;
93113 }
94114
95115 /**
@@ -235,23 +255,27 @@ protected function createPublicServiceDefinitions(ContainerBuilder $container)
235255 private function aliasMethodResolver (ContainerBuilder $ container )
236256 {
237257 $ isContainerResolver = false ;
238- $ serviceIdList = array_keys ($ container ->findTaggedServiceIds (self ::METHOD_RESOLVER_TAG ));
239- $ serviceCount = count ($ serviceIdList );
240- if ($ serviceCount > 0 ) {
241- if ($ serviceCount > 1 ) {
242- throw new LogicException (
243- sprintf (
244- 'Only one method resolver could be defined, found following services : %s ' ,
245- implode (', ' , $ serviceIdList )
246- )
247- );
248- }
249- // Use the first result
250- $ resolverServiceId = array_shift ($ serviceIdList );
258+ if ($ container ->hasParameter ($ this ->customResolverContainerParameter )) {
259+ $ resolverServiceId = $ container ->getParameter ($ this ->customResolverContainerParameter );
251260 } else {
252- // Use ArrayMethodResolver as default resolver
253- $ resolverServiceId = $ this ->prependServiceName ($ this ->psr11InfraMethodResolverServiceId );
254- $ isContainerResolver = true ;
261+ $ serviceIdList = array_keys ($ container ->findTaggedServiceIds (self ::METHOD_RESOLVER_TAG ));
262+ $ serviceCount = count ($ serviceIdList );
263+ if ($ serviceCount > 0 ) {
264+ if ($ serviceCount > 1 ) {
265+ throw new LogicException (
266+ sprintf (
267+ 'Only one method resolver could be defined, found following services : %s ' ,
268+ implode (', ' , $ serviceIdList )
269+ )
270+ );
271+ }
272+ // Use the first result
273+ $ resolverServiceId = array_shift ($ serviceIdList );
274+ } else {
275+ // Use ArrayMethodResolver as default resolver
276+ $ resolverServiceId = $ this ->prependServiceName ($ this ->psr11InfraMethodResolverServiceId );
277+ $ isContainerResolver = true ;
278+ }
255279 }
256280
257281 $ container ->setAlias ($ this ->prependServiceName ($ this ->methodResolverStubServiceId ), $ resolverServiceId );
@@ -324,4 +348,20 @@ private function checkJsonRpcMethodService(ContainerBuilder $container, string $
324348 ));
325349 }
326350 }
351+
352+ /**
353+ * @param array $configs
354+ * @param ContainerBuilder $container
355+ */
356+ private function compileAndProcessConfigurations (array $ configs , ContainerBuilder $ container )
357+ {
358+ if (true === $ this ->parseConfig ) {
359+ $ configuration = new Configuration ();
360+ $ config = (new Processor ())->processConfiguration ($ configuration , $ configs );
361+
362+ if (array_key_exists ('method_resolver ' , $ config ) && $ config ['method_resolver ' ]) {
363+ $ container ->setParameter ($ this ->customResolverContainerParameter , $ config ['method_resolver ' ]);
364+ }
365+ }
366+ }
327367}
0 commit comments