@@ -68,10 +68,19 @@ abstract class AbstractConnectionResolver {
6868 */
6969 protected $ should_execute = true ;
7070
71+ /**
72+ * The loader name.
73+ *
74+ * Defaults to `loader_name()` and filterable by `graphql_connection_loader_name`.
75+ *
76+ * @var ?string
77+ */
78+ protected $ loader_name ;
79+
7180 /**
7281 * The loader the resolver is configured to use.
7382 *
74- * @var \WPGraphQL\Data\Loader\AbstractDataLoader
83+ * @var ? \WPGraphQL\Data\Loader\AbstractDataLoader
7584 */
7685 protected $ loader ;
7786
@@ -169,7 +178,7 @@ public function __construct( $source, array $args, AppContext $context, ResolveI
169178 }
170179
171180 // Get the loader for the Connection.
172- $ this ->loader = $ this ->getLoader ();
181+ $ this ->loader = $ this ->get_loader ();
173182
174183 /**
175184 *
@@ -200,12 +209,14 @@ public function __construct( $source, array $args, AppContext $context, ResolveI
200209 }
201210
202211 /**
203- * Returns the source of the connection
212+ * The name of the loader to use for this connection.
204213 *
205- * @return mixed
214+ * Filterable by `graphql_connection_loader_name`.
215+ *
216+ * @todo This is protected for backwards compatibility, but should be abstract and implemented by the child classes.
206217 */
207- public function getSource () {
208- return $ this -> source ;
218+ protected function loader_name (): string {
219+ return '' ;
209220 }
210221
211222 /**
@@ -219,36 +230,6 @@ public function get_args(): array {
219230 return $ this ->args ;
220231 }
221232
222- /**
223- * Returns the AppContext of the connection
224- */
225- public function getContext (): AppContext {
226- return $ this ->context ;
227- }
228-
229- /**
230- * Returns the ResolveInfo of the connection
231- */
232- public function getInfo (): ResolveInfo {
233- return $ this ->info ;
234- }
235-
236- /**
237- * Returns whether the connection should execute
238- */
239- public function getShouldExecute (): bool {
240- return $ this ->should_execute ;
241- }
242-
243- /**
244- * Get_loader_name
245- *
246- * Return the name of the loader to be used with the connection resolver
247- *
248- * @return string
249- */
250- abstract public function get_loader_name ();
251-
252233 /**
253234 * Get_query_args
254235 *
@@ -365,7 +346,6 @@ public function get_offset_for_cursor( string $cursor = null ) { // phpcs:ignore
365346 return is_numeric ( $ offset ) ? absint ( $ offset ) : $ offset ;
366347 }
367348
368-
369349 /**
370350 * Validates Model.
371351 *
@@ -380,6 +360,81 @@ protected function is_valid_model( $model ) {
380360 return isset ( $ model ->fields ) && ! empty ( $ model ->fields );
381361 }
382362
363+ /**
364+ * Returns the source of the connection
365+ *
366+ * @return mixed
367+ */
368+ public function get_source () {
369+ return $ this ->source ;
370+ }
371+
372+ /**
373+ * Returns the AppContext of the connection.
374+ */
375+ public function get_context (): AppContext {
376+ return $ this ->context ;
377+ }
378+
379+ /**
380+ * Returns the ResolveInfo of the connection.
381+ */
382+ public function get_info (): ResolveInfo {
383+ return $ this ->info ;
384+ }
385+
386+ /**
387+ * Returns the loader name.
388+ *
389+ * If $loader_name is not initialized, this plugin will initialize it.
390+ *
391+ * @return string
392+ *
393+ * @throws \Exception
394+ */
395+ public function get_loader_name () {
396+ // Only initialize the loader_name property once.
397+ if ( ! isset ( $ this ->loader_name ) ) {
398+ $ name = $ this ->loader_name ();
399+
400+ // This is a b/c check because `loader_name()` is not abstract.
401+ if ( empty ( $ name ) ) {
402+ throw new \Exception (
403+ sprintf (
404+ // translators: %s is the name of the connection resolver class.
405+ esc_html__ ( 'Class %s does not implement a valid method `loader_name()`. ' , 'wp-graphql ' ),
406+ esc_html ( static ::class )
407+ )
408+ );
409+ }
410+
411+ /**
412+ * Filters the loader name.
413+ * This is the name of the registered DataLoader that will be used to load the data for the connection.
414+ *
415+ * @param string $loader_name The name of the loader.
416+ * @param self $resolver The AbstractConnectionResolver instance.
417+ */
418+ $ name = apply_filters ( 'graphql_connection_loader_name ' , $ name , $ this );
419+
420+ // Bail if the loader name is invalid.
421+ if ( empty ( $ name ) || ! is_string ( $ name ) ) {
422+ throw new \Exception ( esc_html__ ( 'The Connection Resolver needs to define a loader name ' , 'wp-graphql ' ) );
423+ }
424+
425+ $ this ->loader_name = $ name ;
426+ }
427+
428+ return $ this ->loader_name ;
429+ }
430+
431+ /**
432+ * Returns whether the connection should execute.
433+ */
434+ public function get_should_execute (): bool {
435+ return $ this ->should_execute ;
436+ }
437+
383438 /**
384439 * Returns the $args passed to the connection, before any modifications.
385440 *
@@ -596,16 +651,19 @@ public function one_to_one() {
596651 /**
597652 * Returns the loader.
598653 *
654+ * If $loader is not initialized, this method will initialize it.
655+ *
599656 * @return \WPGraphQL\Data\Loader\AbstractDataLoader
600- * @throws \Exception
601657 */
602- protected function getLoader () {
603- $ name = $ this ->get_loader_name ();
604- if ( empty ( $ name ) || ! is_string ( $ name ) ) {
605- throw new Exception ( esc_html__ ( 'The Connection Resolver needs to define a loader name ' , 'wp-graphql ' ) );
658+ protected function get_loader () {
659+ // If the loader isn't set, set it.
660+ if ( ! isset ( $ this ->loader ) ) {
661+ $ name = $ this ->get_loader_name ();
662+
663+ $ this ->loader = $ this ->context ->get_loader ( $ name );
606664 }
607665
608- return $ this ->context -> get_loader ( $ name ) ;
666+ return $ this ->loader ;
609667 }
610668
611669 /**
@@ -678,7 +736,7 @@ public function get_connection() {
678736 return new Deferred (
679737 function () {
680738 if ( ! empty ( $ this ->ids ) ) {
681- $ this ->loader ->load_many ( $ this ->ids );
739+ $ this ->get_loader () ->load_many ( $ this ->ids );
682740 }
683741
684742 /**
@@ -792,7 +850,7 @@ public function execute_and_get_ids() {
792850 /**
793851 * Buffer the IDs for deferred resolution
794852 */
795- $ this ->loader ->buffer ( $ this ->ids );
853+ $ this ->get_loader () ->buffer ( $ this ->ids );
796854
797855 return $ this ->ids ;
798856 }
@@ -890,7 +948,7 @@ public function get_ids_for_nodes() {
890948 * @throws \Exception
891949 */
892950 public function get_node_by_id ( $ id ) {
893- return $ this ->loader ->load ( $ id );
951+ return $ this ->get_loader () ->load ( $ id );
894952 }
895953
896954 /**
@@ -1068,4 +1126,64 @@ public function get_offset() {
10681126
10691127 return $ this ->get_offset_for_cursor ( $ cursor );
10701128 }
1129+
1130+ /**
1131+ * Returns the source of the connection.
1132+ *
1133+ * @deprecated @todo in favor of $this->get_source().
1134+ *
1135+ * @return mixed
1136+ */
1137+ public function getSource () {
1138+ _deprecated_function ( __METHOD__ , '@todo ' , static ::class . '::get_source() ' );
1139+
1140+ return $ this ->get_source ();
1141+ }
1142+
1143+ /**
1144+ * Returns the AppContext of the connection.
1145+ *
1146+ * @deprecated @todo in favor of $this->get_context().
1147+ */
1148+ public function getContext (): AppContext {
1149+ _deprecated_function ( __METHOD__ , '@todo ' , static ::class . '::get_context() ' );
1150+
1151+ return $ this ->get_context ();
1152+ }
1153+
1154+ /**
1155+ * Returns the ResolveInfo of the connection.
1156+ *
1157+ * @deprecated @todo in favor of $this->get_info().
1158+ */
1159+ public function getInfo (): ResolveInfo {
1160+ _deprecated_function ( __METHOD__ , '@todo ' , static ::class . '::get_info() ' );
1161+
1162+ return $ this ->get_info ();
1163+ }
1164+
1165+ /**
1166+ * Returns whether the connection should execute.
1167+ *
1168+ * @deprecated @todo in favor of $this->get_should_execute().
1169+ */
1170+ public function getShouldExecute (): bool {
1171+ _deprecated_function ( __METHOD__ , '@todo ' , static ::class . '::should_execute() ' );
1172+
1173+ return $ this ->get_should_execute ();
1174+ }
1175+
1176+ /**
1177+ * Returns the loader.
1178+ *
1179+ * @deprecated @todo in favor of $this->get_loader().
1180+ *
1181+ * @return \WPGraphQL\Data\Loader\AbstractDataLoader
1182+ * @throws \Exception
1183+ */
1184+ protected function getLoader () {
1185+ _deprecated_function ( __METHOD__ , '@todo ' , static ::class . '::get_loader() ' );
1186+
1187+ return $ this ->get_loader ();
1188+ }
10711189}
0 commit comments