44
55namespace Overblog \GraphQLBundle \DependencyInjection \Compiler ;
66
7- use InvalidArgumentException ;
87use Overblog \GraphQLBundle \Definition \GraphQLServices ;
98use Symfony \Component \DependencyInjection \Compiler \CompilerPassInterface ;
109use Symfony \Component \DependencyInjection \ContainerBuilder ;
10+ use Symfony \Component \DependencyInjection \Exception \InvalidArgumentException ;
11+ use Symfony \Component \DependencyInjection \Exception \ServiceNotFoundException ;
1112use Symfony \Component \DependencyInjection \Reference ;
1213use function is_string ;
1314use function sprintf ;
@@ -19,6 +20,8 @@ final class GraphQLServicesPass implements CompilerPassInterface
1920 */
2021 public function process (ContainerBuilder $ container ): void
2122 {
23+ $ this ->tagAllNotTaggedGraphQLServices ($ container );
24+
2225 $ taggedServices = $ container ->findTaggedServiceIds ('overblog_graphql.service ' , true );
2326
2427 $ locateableServices = [];
@@ -51,6 +54,84 @@ public function process(ContainerBuilder $container): void
5154 ['container ' , 'service_container ' ]
5255 );
5356
54- $ container ->findDefinition (GraphQLServices::class)->addArgument ($ locateableServices );
57+ $ container ->findDefinition (GraphQLServices::class)->addArgument (array_unique ($ locateableServices ));
58+ }
59+
60+ private function tagAllNotTaggedGraphQLServices (ContainerBuilder $ container ): void
61+ {
62+ if (!$ container ->hasParameter ('overblog_graphql_types.config ' )) {
63+ return ;
64+ }
65+ /** @var array $configs */
66+ $ configs = $ container ->getParameter ('overblog_graphql_types.config ' );
67+ foreach ($ configs as &$ typeConfig ) {
68+ switch ($ typeConfig ['type ' ]) {
69+ case 'object ' :
70+ if (isset ($ typeConfig ['config ' ]['fieldResolver ' ])) {
71+ $ this ->resolveServiceIdAndMethod ($ container , $ typeConfig ['config ' ]['fieldResolver ' ]);
72+ }
73+
74+ foreach ($ typeConfig ['config ' ]['fields ' ] as &$ field ) {
75+ if (isset ($ field ['resolver ' ])) {
76+ $ this ->resolveServiceIdAndMethod ($ container , $ field ['resolver ' ]);
77+ }
78+ }
79+ break ;
80+
81+ case 'interface ' :
82+ case 'union ' :
83+ if (isset ($ typeConfig ['config ' ]['typeResolver ' ])) {
84+ $ this ->resolveServiceIdAndMethod ($ container , $ typeConfig ['config ' ]['typeResolver ' ]);
85+ }
86+ break ;
87+ }
88+ }
89+ $ container ->setParameter ('overblog_graphql_types.config ' , $ configs );
90+ }
91+
92+ private function resolveServiceIdAndMethod (ContainerBuilder $ container , ?array &$ resolver ): void
93+ {
94+ if (!isset ($ resolver ['id ' ]) && !isset ($ resolver ['method ' ])) {
95+ return ;
96+ }
97+ $ originalId = $ resolver ['id ' ] ?? null ;
98+ $ originalMethod = $ resolver ['method ' ] ?? null ;
99+
100+ if (null === $ originalId ) {
101+ [$ id , $ method ] = explode (':: ' , $ originalMethod , 2 ) + [null , null ];
102+ $ throw = false ;
103+ } else {
104+ $ id = $ originalId ;
105+ $ method = $ originalMethod ;
106+ $ throw = true ;
107+ }
108+
109+ try {
110+ $ definition = $ container ->getDefinition ($ id );
111+ } catch (ServiceNotFoundException $ e ) {
112+ // get Alias real service ID
113+ try {
114+ $ alias = $ container ->getAlias ($ id );
115+ $ id = (string ) $ alias ;
116+ $ definition = $ container ->getDefinition ($ id );
117+ } catch (ServiceNotFoundException | InvalidArgumentException $ e ) {
118+ if ($ throw ) {
119+ throw $ e ;
120+ }
121+ $ resolver ['id ' ] = null ;
122+ $ resolver ['method ' ] = $ originalMethod ;
123+
124+ return ;
125+ }
126+ }
127+ if (
128+ !$ definition ->hasTag ('overblog_graphql.service ' )
129+ && !$ definition ->hasTag ('overblog_graphql.global_variable ' )
130+ ) {
131+ $ definition ->addTag ('overblog_graphql.service ' );
132+ }
133+
134+ $ resolver ['id ' ] = $ id ;
135+ $ resolver ['method ' ] = $ method ;
55136 }
56137}
0 commit comments