3838use TheCodingMachine \GraphQLite \Middlewares \FieldMiddlewareInterface ;
3939use TheCodingMachine \GraphQLite \Middlewares \InputFieldHandlerInterface ;
4040use TheCodingMachine \GraphQLite \Middlewares \InputFieldMiddlewareInterface ;
41+ use TheCodingMachine \GraphQLite \Middlewares \MagicPropertyResolver ;
4142use TheCodingMachine \GraphQLite \Middlewares \MissingMagicGetException ;
43+ use TheCodingMachine \GraphQLite \Middlewares \ServiceResolver ;
44+ use TheCodingMachine \GraphQLite \Middlewares \SourceConstructorParameterResolver ;
45+ use TheCodingMachine \GraphQLite \Middlewares \SourceInputPropertyResolver ;
46+ use TheCodingMachine \GraphQLite \Middlewares \SourceMethodResolver ;
47+ use TheCodingMachine \GraphQLite \Middlewares \SourcePropertyResolver ;
4248use TheCodingMachine \GraphQLite \Parameters \InputTypeParameterInterface ;
4349use TheCodingMachine \GraphQLite \Parameters \ParameterInterface ;
4450use TheCodingMachine \GraphQLite \Parameters \PrefetchDataParameter ;
@@ -370,14 +376,6 @@ private function getFieldsByMethodAnnotations(string|object $controller, Reflect
370376 $ type = $ this ->typeMapper ->mapReturnType ($ refMethod , $ docBlockObj );
371377 }
372378
373- $ fieldDescriptor = new QueryFieldDescriptor (
374- name: $ name ,
375- type: $ type ,
376- comment: trim ($ description ),
377- deprecationReason: $ this ->getDeprecationReason ($ docBlockObj ),
378- refMethod: $ refMethod ,
379- );
380-
381379 $ parameters = $ refMethod ->getParameters ();
382380 if ($ injectSource === true ) {
383381 $ firstParameter = array_shift ($ parameters );
@@ -398,19 +396,21 @@ private function getFieldsByMethodAnnotations(string|object $controller, Reflect
398396 $ args = ['__graphqlite_prefectData ' => $ prefetchDataParameter , ...$ args ];
399397 }
400398
401- $ fieldDescriptor = $ fieldDescriptor ->withParameters ($ args );
399+ $ resolver = is_string ($ controller ) ?
400+ new SourceMethodResolver ($ refMethod ) :
401+ new ServiceResolver ([$ controller , $ methodName ]);
402402
403- if ( is_string ( $ controller )) {
404- $ fieldDescriptor = $ fieldDescriptor -> withTargetMethodOnSource ( $ refMethod -> getDeclaringClass ()-> getName (), $ methodName );
405- } else {
406- $ callable = [ $ controller , $ methodName ];
407- assert ( is_callable ( $ callable ));
408- $ fieldDescriptor = $ fieldDescriptor -> withCallable ( $ callable );
409- }
410-
411- $ fieldDescriptor = $ fieldDescriptor
412- -> withInjectSource ( $ injectSource )
413- -> withMiddlewareAnnotations ( $ this -> annotationReader -> getMiddlewareAnnotations ( $ refMethod ) );
403+ $ fieldDescriptor = new QueryFieldDescriptor (
404+ name: $ name ,
405+ type: $ type ,
406+ resolver: $ resolver ,
407+ originalResolver: $ resolver ,
408+ parameters: $ args ,
409+ injectSource: $ injectSource ,
410+ comment: trim ( $ description ),
411+ deprecationReason: $ this -> getDeprecationReason ( $ docBlockObj ),
412+ middlewareAnnotations: $ this -> annotationReader -> getMiddlewareAnnotations ( $ refMethod ),
413+ );
414414
415415 $ field = $ this ->fieldMiddleware ->process ($ fieldDescriptor , new class implements FieldHandlerInterface {
416416 public function handle (QueryFieldDescriptor $ fieldDescriptor ): FieldDefinition |null
@@ -480,26 +480,22 @@ private function getFieldsByPropertyAnnotations(string|object $controller, Refle
480480 assert ($ type instanceof OutputType);
481481 }
482482
483+ $ originalResolver = new SourcePropertyResolver ($ refProperty );
484+ $ resolver = is_string ($ controller ) ?
485+ $ originalResolver :
486+ fn () => PropertyAccessor::getValue ($ controller , $ refProperty ->getName ());
487+
483488 $ fieldDescriptor = new QueryFieldDescriptor (
484489 name: $ name ,
485490 type: $ type ,
491+ resolver: $ resolver ,
492+ originalResolver: $ originalResolver ,
493+ injectSource: false ,
486494 comment: trim ($ description ),
487495 deprecationReason: $ this ->getDeprecationReason ($ docBlock ),
488- refProperty : $ refProperty ,
496+ middlewareAnnotations : $ this -> annotationReader -> getMiddlewareAnnotations ( $ refProperty) ,
489497 );
490498
491- if (is_string ($ controller )) {
492- $ fieldDescriptor = $ fieldDescriptor ->withTargetPropertyOnSource ($ refProperty ->getDeclaringClass ()->getName (), $ refProperty ->getName ());
493- } else {
494- $ fieldDescriptor = $ fieldDescriptor ->withCallable (static function () use ($ controller , $ refProperty ) {
495- return PropertyAccessor::getValue ($ controller , $ refProperty ->getName ());
496- });
497- }
498-
499- $ fieldDescriptor = $ fieldDescriptor
500- ->withInjectSource (false )
501- ->withMiddlewareAnnotations ($ this ->annotationReader ->getMiddlewareAnnotations ($ refProperty ));
502-
503499 $ field = $ this ->fieldMiddleware ->process ($ fieldDescriptor , new class implements FieldHandlerInterface {
504500 public function handle (QueryFieldDescriptor $ fieldDescriptor ): FieldDefinition |null
505501 {
@@ -597,15 +593,16 @@ private function getQueryFieldsFromSourceFields(array $sourceFields, ReflectionC
597593 $ type = $ this ->typeMapper ->mapReturnType ($ refMethod , $ docBlockObj );
598594 }
599595
596+ $ resolver = new SourceMethodResolver ($ refMethod );
597+
600598 $ fieldDescriptor = new QueryFieldDescriptor (
601599 name: $ sourceField ->getName (),
602600 type: $ type ,
601+ resolver: $ resolver ,
602+ originalResolver: $ resolver ,
603603 parameters: $ args ,
604- targetClass: $ refMethod ->getDeclaringClass ()->getName (),
605- targetMethodOnSource: $ methodName ,
606604 comment: $ description ,
607605 deprecationReason: $ deprecationReason ?? null ,
608- refMethod: $ refMethod ,
609606 );
610607 } else {
611608 $ outputType = $ sourceField ->getOutputType ();
@@ -619,11 +616,13 @@ private function getQueryFieldsFromSourceFields(array $sourceFields, ReflectionC
619616 $ type = $ this ->resolvePhpType ($ phpTypeStr , $ refClass , $ magicGefRefMethod );
620617 }
621618
619+ $ resolver = new MagicPropertyResolver ($ refClass ->getName (), $ sourceField ->getSourceName () ?? $ sourceField ->getName ());
620+
622621 $ fieldDescriptor = new QueryFieldDescriptor (
623622 name: $ sourceField ->getName (),
624623 type: $ type ,
625- targetClass : $ refClass -> getName () ,
626- magicProperty : $ sourceField -> getSourceName () ?? $ sourceField -> getName () ,
624+ resolver : $ resolver ,
625+ originalResolver : $ resolver ,
627626 comment: $ sourceField ->getDescription (),
628627 );
629628 }
@@ -889,27 +888,22 @@ private function getInputFieldsByMethodAnnotations(string|object $controller, Re
889888
890889 assert ($ type instanceof InputType);
891890
891+ $ resolver = new SourceMethodResolver ($ refMethod );
892+
892893 $ inputFieldDescriptor = new InputFieldDescriptor (
893894 name: $ name ,
894895 type: $ type ,
896+ resolver: $ resolver ,
897+ originalResolver: $ resolver ,
895898 parameters: $ args ,
899+ injectSource: $ injectSource ,
896900 comment: trim ($ description ),
897- refMethod : $ refMethod ,
901+ middlewareAnnotations : $ this -> annotationReader -> getMiddlewareAnnotations ( $ refMethod) ,
898902 isUpdate: $ isUpdate ,
903+ hasDefaultValue: $ isUpdate ,
904+ defaultValue: $ args [$ name ]->getDefaultValue ()
899905 );
900906
901- $ inputFieldDescriptor = $ inputFieldDescriptor
902- ->withHasDefaultValue ($ isUpdate )
903- ->withDefaultValue ($ args [$ name ]->getDefaultValue ());
904- $ constructerParameters = $ this ->getClassConstructParameterNames ($ refClass );
905- if (!in_array ($ name , $ constructerParameters )) {
906- $ inputFieldDescriptor = $ inputFieldDescriptor ->withTargetMethodOnSource ($ refMethod ->getDeclaringClass ()->getName (), $ methodName );
907- }
908-
909- $ inputFieldDescriptor = $ inputFieldDescriptor
910- ->withInjectSource ($ injectSource )
911- ->withMiddlewareAnnotations ($ this ->annotationReader ->getMiddlewareAnnotations ($ refMethod ));
912-
913907 $ field = $ this ->inputFieldMiddleware ->process ($ inputFieldDescriptor , new class implements InputFieldHandlerInterface {
914908 public function handle (InputFieldDescriptor $ inputFieldDescriptor ): InputField |null
915909 {
@@ -965,53 +959,38 @@ private function getInputFieldsByPropertyAnnotations(string|object $controller,
965959 $ description = $ inputProperty ->getDescription ();
966960 }
967961
968- if (in_array ($ name , $ constructerParameters )) {
969- $ middlewareAnnotations = $ this ->annotationReader ->getPropertyAnnotations ($ refProperty , MiddlewareAnnotationInterface::class);
970- if ($ middlewareAnnotations !== []) {
971- throw IncompatibleAnnotationsException::middlewareAnnotationsUnsupported ();
972- }
973- // constructor hydrated
974- $ field = new InputField (
975- $ name ,
976- $ inputProperty ->getType (),
977- [$ inputProperty ->getName () => $ inputProperty ],
978- null ,
979- null ,
980- trim ($ description ),
981- $ isUpdate ,
982- $ inputProperty ->hasDefaultValue (),
983- $ inputProperty ->getDefaultValue (),
984- );
985- } else {
986- $ type = $ inputProperty ->getType ();
987- if (!$ inputType && $ isUpdate && $ type instanceof NonNull) {
988- $ type = $ type ->getWrappedType ();
989- }
990- assert ($ type instanceof InputType);
962+ $ type = $ inputProperty ->getType ();
963+ if (!$ inputType && $ isUpdate && $ type instanceof NonNull) {
964+ $ type = $ type ->getWrappedType ();
965+ }
966+ assert ($ type instanceof InputType);
967+ $ forConstructorHydration = in_array ($ name , $ constructerParameters );
968+ $ resolver = $ forConstructorHydration ?
969+ new SourceConstructorParameterResolver ($ refProperty ->getDeclaringClass ()->getName (), $ refProperty ->getName ()) :
970+ new SourceInputPropertyResolver ($ refProperty );
991971
992- // setters and properties
993- $ inputFieldDescriptor = new InputFieldDescriptor (
994- name: $ inputProperty ->getName (),
995- type: $ type ,
996- parameters: [ $ inputProperty -> getName () => $ inputProperty ] ,
997- targetClass : $ refProperty -> getDeclaringClass ()-> getName () ,
998- targetPropertyOnSource: $ refProperty ->getName (),
999- injectSource: false ,
1000- comment: trim ( $ description ) ,
1001- middlewareAnnotations: $ this -> annotationReader -> getMiddlewareAnnotations ( $ refProperty ),
1002- refProperty : $ refProperty ,
1003- isUpdate: $ isUpdate ,
1004- hasDefaultValue: $ inputProperty ->hasDefaultValue (),
1005- defaultValue: $ inputProperty ->getDefaultValue (),
1006- );
972+ // setters and properties
973+ $ inputFieldDescriptor = new InputFieldDescriptor (
974+ name: $ inputProperty ->getName (),
975+ type: $ type ,
976+ resolver: $ resolver ,
977+ originalResolver : $ resolver ,
978+ parameters: [ $ inputProperty ->getName () => $ inputProperty ] ,
979+ injectSource: false ,
980+ forConstructorHydration: $ forConstructorHydration ,
981+ comment: trim ( $ description ),
982+ middlewareAnnotations : $ this -> annotationReader -> getMiddlewareAnnotations ( $ refProperty) ,
983+ isUpdate: $ isUpdate ,
984+ hasDefaultValue: $ inputProperty ->hasDefaultValue (),
985+ defaultValue: $ inputProperty ->getDefaultValue (),
986+ );
1007987
1008- $ field = $ this ->inputFieldMiddleware ->process ($ inputFieldDescriptor , new class implements InputFieldHandlerInterface {
1009- public function handle (InputFieldDescriptor $ inputFieldDescriptor ): InputField |null
1010- {
1011- return InputField::fromFieldDescriptor ($ inputFieldDescriptor );
1012- }
1013- });
1014- }
988+ $ field = $ this ->inputFieldMiddleware ->process ($ inputFieldDescriptor , new class implements InputFieldHandlerInterface {
989+ public function handle (InputFieldDescriptor $ inputFieldDescriptor ): InputField |null
990+ {
991+ return InputField::fromFieldDescriptor ($ inputFieldDescriptor );
992+ }
993+ });
1015994
1016995 if ($ field === null ) {
1017996 continue ;
0 commit comments