From accfe351a1a5fd217bc4cd024fe9b3b61b637033 Mon Sep 17 00:00:00 2001 From: hsimah Date: Sun, 3 May 2020 08:23:18 -0700 Subject: [PATCH] unidirectional relationships and custom resolvers (#17) --- README.md | 4 +- class-config.php | 67 ++++++++++++++++++++++++ class-mb-relationships.php | 93 +++++++++++++++++---------------- wp-graphql-mb-relationships.php | 4 +- 4 files changed, 118 insertions(+), 50 deletions(-) create mode 100644 class-config.php diff --git a/README.md b/README.md index 9fa0bf7..0051756 100755 --- a/README.md +++ b/README.md @@ -3,12 +3,12 @@ WPGraphQL Provider for MB Relationships This is a simple WPGraphQL integration plugin for Meta Box Relationships. **It only supports post types at the moment.** -You will need to get the latest `master` branch from [MB Relationships](https://github.com/wpmetabox/mb-relationships) as there is a new hook to use. - There are three new fields to add to the API configuration: - `show_in_graphql` - a boolean to show the connection in the schema - `graphql_name` - the name of the connection field in the schema - `graphql_args` - the connection args (optional) + - `resolve` - the resolve handler (see WPGraphQL documentation) (experimental) + - `resolve_node` - the node resolve handler (see WPGraphQL documentaiton) (experimental) ``` MB_Relationships_API::register( [ diff --git a/class-config.php b/class-config.php new file mode 100644 index 0000000..d94bcf8 --- /dev/null +++ b/class-config.php @@ -0,0 +1,67 @@ +type_name = $settings['field']['post_type']; + $this->connection_name = $settings['graphql_name']; + $this->connection_args = $settings['graphql_args']; + $this->type_object = get_post_type_object($this->type_name); + $this->graphql_type_name = $this->type_object->graphql_single_name; + if (array_key_exists('resolve', $settings)) { + $this->resolve = $settings['resolve']; + } + if (array_key_exists('resolve_node', $settings)) { + $this->resolve_node = $settings['resolve_node']; + } + } + + /** + * Register WPGraphQL MB Relationships config. + * + * @access public + * @since 0.3.0 + * @return void + */ + public function should_register() + { + return $this->type_object !== null && + $this->type_object->show_in_graphql; + } +} diff --git a/class-mb-relationships.php b/class-mb-relationships.php index b4ff5fe..d4a03a2 100755 --- a/class-mb-relationships.php +++ b/class-mb-relationships.php @@ -3,6 +3,8 @@ use WPGraphQL\Data\DataSource; use WPGraphQL\Data\Connection\PostObjectConnectionResolver; +require_once __DIR__ . '/class-config.php'; + final class WPGraphQL_MB_Relationships { @@ -64,57 +66,61 @@ public function __wakeup() } /** - * Register WPGraphQL MB Relationships config. + * Register single direction * * @access public - * @since 0.0.1 + * @since 0.3.0 * @return void */ - public static function register_connection($settings) + public static function register_connection($id, $to, $from, $direction) { - add_action('graphql_register_types', function () use ($settings) { - $resolver = WPGraphQL_MB_Relationships::instance(); - - $show_to = $settings['to']['show_in_graphql']; - $show_from = $settings['from']['show_in_graphql']; - - $from_post_type = $settings['from']['field']['post_type']; - $from_post_object = get_post_type_object($from_post_type); - $from_connection_name = $settings['from']['graphql_name']; - $from_connection_args = $settings['from']['graphql_args']; - $to_post_type = $settings['to']['field']['post_type']; - $to_post_object = get_post_type_object($to_post_type); - $to_connection_name = $settings['to']['graphql_name']; - $to_connection_args = $settings['to']['graphql_args']; - - if ($show_to && $from_post_object !== null && $from_post_object->show_in_graphql) { - register_graphql_connection( - [ - 'fromType' => $from_post_object->graphql_single_name, - 'toType' => $to_post_object->graphql_single_name, - 'fromFieldName' => $from_connection_name, - 'connectionArgs' => isset($from_connection_args) ? $from_connection_args : [], - 'resolveNode' => $resolver->get_node_resolver(), - 'resolve' => $resolver->get_resolver($to_post_type, $settings['id'], 'from'), - ] - ); - } + add_action('graphql_register_types', function () use ($to, $from, $id, $direction) { + $to_config = new WPGraphQL_MB_Relationships_Config($to); + $from_config = new WPGraphQL_MB_Relationships_Config($from); + + if ($to_config->should_register() && $from_config->should_register()) { + + $resolver = WPGraphQL_MB_Relationships::instance(); - if ($show_from && $to_post_object !== null && $to_post_object->show_in_graphql) { register_graphql_connection( [ - 'fromType' => $to_post_object->graphql_single_name, - 'toType' => $from_post_object->graphql_single_name, - 'fromFieldName' => $to_connection_name, - 'connectionArgs' => isset($to_connection_args) ? $to_connection_args : [], - 'resolveNode' => $resolver->get_node_resolver(), - 'resolve' => $resolver->get_resolver($from_post_type, $settings['id'], 'to'), + 'fromType' => $from_config->graphql_type_name, + 'toType' => $to_config->graphql_type_name, + 'fromFieldName' => $from_config->connection_name, + 'connectionArgs' => isset($from_config->connection_args) ? $from_config->connection_args : [], + 'resolveNode' => $to_config->resolve !== null ? $to_config->resolve : $resolver->get_node_resolver(), + 'resolve' => $to_config->resolve_node !== null ? $to_config->resolve_node : $resolver->get_resolver($to_config->type_name, $id, $direction), ] ); } }); } + /** + * Register WPGraphQL MB Relationships config. + * + * @access public + * @since 0.0.1 + * @return void + */ + public static function register_connections($settings) + { + $to = $settings['to']; + $from = $settings['from']; + + if ( + (array_key_exists('show_in_graphql', $to) && + $to['show_in_graphql'] === true) + ) { + WPGraphQL_MB_Relationships::register_connection($settings['id'], $from, $to, 'to'); + } + + if ((array_key_exists('show_in_graphql', $from) && + $from['show_in_graphql'] === true)) { + WPGraphQL_MB_Relationships::register_connection($settings['id'], $to, $from, 'from'); + } + } + /** * Get resolve node callback * @@ -122,7 +128,7 @@ public static function register_connection($settings) * @since 0.1.0 * @return function */ - private function get_node_resolver() + protected function get_node_resolver() { return function ($node, $args, $context, $info) { return !empty($node) ? DataSource::resolve_post_object($node->ID, $context) : null; @@ -136,7 +142,7 @@ private function get_node_resolver() * @since 0.1.0 * @return function */ - private function get_resolver($post_type_name, $id, $relationship) + protected function get_resolver($post_type_name, $id, $relationship) { return function ($root, $args, $context, $info) use ($post_type_name, $id, $relationship) { $resolver = new PostObjectConnectionResolver($root, $args, $context, $info, $post_type_name); @@ -158,15 +164,10 @@ private function get_resolver($post_type_name, $id, $relationship) * @since 0.0.1 * @return void */ - private function init() + protected function init() { add_action('mb_relationships_registered', function ($settings) { - $to = $settings['to']; - $from = $settings['from']; - - if ($to['show_in_graphql'] === true || $from['show_in_graphql'] === true) { - WPGraphQL_MB_Relationships::register_connection($settings); - } + WPGraphQL_MB_Relationships::register_connections($settings); }, 10, 1); } } diff --git a/wp-graphql-mb-relationships.php b/wp-graphql-mb-relationships.php index 7d5e046..11e5667 100755 --- a/wp-graphql-mb-relationships.php +++ b/wp-graphql-mb-relationships.php @@ -6,14 +6,14 @@ * Description: WP GraphQL provider for MB Relationships * Author: hsimah * Author URI: http://www.hsimah.com - * Version: 0.2.0 + * Version: 0.3.0 * Text Domain: wpgraphql-mb-relationships * License: GPL-3 * License URI: https://www.gnu.org/licenses/gpl-3.0.html * * @package WPGraphQL_MB_Relationships * @author hsimah - * @version 0.2.0 + * @version 0.3.0 */ // Exit if accessed directly.