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 // TODO: remove following if-block in 1.0
@@ -61,6 +64,84 @@ public function process(ContainerBuilder $container): void
6164 ['container ' , 'service_container ' ]
6265 );
6366
64- $ container ->findDefinition (GraphQLServices::class)->addArgument ($ locateableServices );
67+ $ container ->findDefinition (GraphQLServices::class)->addArgument (array_unique ($ locateableServices ));
68+ }
69+
70+ private function tagAllNotTaggedGraphQLServices (ContainerBuilder $ container ): void
71+ {
72+ if (!$ container ->hasParameter ('overblog_graphql_types.config ' )) {
73+ return ;
74+ }
75+ /** @var array $configs */
76+ $ configs = $ container ->getParameter ('overblog_graphql_types.config ' );
77+ foreach ($ configs as &$ typeConfig ) {
78+ switch ($ typeConfig ['type ' ]) {
79+ case 'object ' :
80+ if (isset ($ typeConfig ['config ' ]['fieldResolver ' ])) {
81+ $ this ->resolveServiceIdAndMethod ($ container , $ typeConfig ['config ' ]['fieldResolver ' ]);
82+ }
83+
84+ foreach ($ typeConfig ['config ' ]['fields ' ] as &$ field ) {
85+ if (isset ($ field ['resolver ' ])) {
86+ $ this ->resolveServiceIdAndMethod ($ container , $ field ['resolver ' ]);
87+ }
88+ }
89+ break ;
90+
91+ case 'interface ' :
92+ case 'union ' :
93+ if (isset ($ typeConfig ['config ' ]['typeResolver ' ])) {
94+ $ this ->resolveServiceIdAndMethod ($ container , $ typeConfig ['config ' ]['typeResolver ' ]);
95+ }
96+ break ;
97+ }
98+ }
99+ $ container ->setParameter ('overblog_graphql_types.config ' , $ configs );
100+ }
101+
102+ private function resolveServiceIdAndMethod (ContainerBuilder $ container , ?array &$ resolver ): void
103+ {
104+ if (!isset ($ resolver ['id ' ]) && !isset ($ resolver ['method ' ])) {
105+ return ;
106+ }
107+ $ originalId = $ resolver ['id ' ] ?? null ;
108+ $ originalMethod = $ resolver ['method ' ] ?? null ;
109+
110+ if (null === $ originalId ) {
111+ [$ id , $ method ] = explode (':: ' , $ originalMethod , 2 ) + [null , null ];
112+ $ throw = false ;
113+ } else {
114+ $ id = $ originalId ;
115+ $ method = $ originalMethod ;
116+ $ throw = true ;
117+ }
118+
119+ try {
120+ $ definition = $ container ->getDefinition ($ id );
121+ } catch (ServiceNotFoundException $ e ) {
122+ // get Alias real service ID
123+ try {
124+ $ alias = $ container ->getAlias ($ id );
125+ $ id = (string ) $ alias ;
126+ $ definition = $ container ->getDefinition ($ id );
127+ } catch (ServiceNotFoundException | InvalidArgumentException $ e ) {
128+ if ($ throw ) {
129+ throw $ e ;
130+ }
131+ $ resolver ['id ' ] = null ;
132+ $ resolver ['method ' ] = $ originalMethod ;
133+
134+ return ;
135+ }
136+ }
137+ if (
138+ !$ definition ->hasTag ('overblog_graphql.service ' )
139+ && !$ definition ->hasTag ('overblog_graphql.global_variable ' )
140+ ) {
141+ $ definition ->addTag ('overblog_graphql.service ' );
142+ }
143+
144+ $ resolver ['id ' ] = $ id ;
145+ $ resolver ['method ' ] = $ method ;
65146 }
66147}
0 commit comments