Skip to content

Commit

Permalink
unidirectional relationships and custom resolvers (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
hsimah committed May 3, 2020
1 parent 07135b9 commit accfe35
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 50 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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( [
Expand Down
67 changes: 67 additions & 0 deletions class-config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

final class WPGraphQL_MB_Relationships_Config
{
/**
* Type name
*/
public $type_name;

/**
* Type object
*/
public $type_object;

/**
* GraphQL type name
*/
public $graphql_type_name;

/**
* GraphQL connection name
*/
public $connection_name;

/**
* GraphQL connection arguments
*/
public $connection_args;

/**
* GraphQL connection resolve function
*/
public $resolve = null;

/**
* GraphQL connection resolve node function
*/
public $resolve_node = null;

function __construct($settings)
{
$this->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;
}
}
93 changes: 47 additions & 46 deletions class-mb-relationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use WPGraphQL\Data\DataSource;
use WPGraphQL\Data\Connection\PostObjectConnectionResolver;

require_once __DIR__ . '/class-config.php';

final class WPGraphQL_MB_Relationships
{

Expand Down Expand Up @@ -64,65 +66,69 @@ 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
*
* @access private
* @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;
Expand All @@ -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);
Expand All @@ -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);
}
}
4 changes: 2 additions & 2 deletions wp-graphql-mb-relationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit accfe35

Please sign in to comment.