Skip to content

Commit

Permalink
Merge pull request #152 from alleyinteractive/150-add-support-for-gra…
Browse files Browse the repository at this point in the history
…phql-via-wpgraphql-hooks

Add support for GraphQL via WPGraphQL hooks
  • Loading branch information
ellm authored Mar 25, 2024
2 parents 62b2681 + 60ce76d commit 736351a
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `WP Curate` will be documented in this file.

## 1.8.0 - 2024-03-19

- Enhancement: Integration with [WPGraphQL plugin](https://wordpress.org/plugins/wp-graphql/) to support custom GraphQL interface type and connection.

## 1.7.1 - 2024-03-13

- Bug Fix: Query block does not update with posts from custom post types when selected in Query Paramaters block settings.
Expand Down
141 changes: 141 additions & 0 deletions src/features/class-graphql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php
/**
* GraphQL class file
*
* @package wp-curate
*/

namespace Alley\WP\WP_Curate\Features;

use Alley\WP\Types\Feature;
use WPGraphQL\AppContext;
use GraphQL\Type\Definition\ResolveInfo;
use WPGraphQL\Data\Connection\PostObjectConnectionResolver;

/**
* Add support for GraphQL, if WPGraphQL plugin exists.
*/
final class GraphQL implements Feature {
/**
* Post types allowed in GraphQL.
*
* @var string[]
*/
private $allowed_post_types;

/**
* Get the GraphQL Type by Post Type.
*
* @param string $post_type_string Name of the post type. Ex: 'post'.
*
* @return string GraphQL Type name. Ex: 'Post'.
*/
private function get_graphql_type_by_post_type( string $post_type_string ): string {
$post_type_object = get_post_type_object( $post_type_string );

// Only return a GraphQL type for allowed post types in WP Curate.
if ( ! in_array( $post_type_string, $this->allowed_post_types, true ) ) {
return '';
}

if ( empty( $post_type_object ) ) {
return '';
}

// @phpstan-ignore-next-line
return ucfirst( $post_type_object->graphql_single_name );
}

/**
* Get GraphQL Types from allowed post types.
*
* @return array<string>
*/
private function get_types_from_allowed_post_types(): array {
$interface_to_types = [];

foreach ( $this->allowed_post_types as $post_type ) {
$interface_to_types[] = $this->get_graphql_type_by_post_type( $post_type );
}

return $interface_to_types;
}

/**
* Set up.
*/
public function __construct() {
$this->allowed_post_types = apply_filters( 'wp_curate_allowed_post_types', [ 'post' ] );
}

/**
* Boot the feature.
*/
public function boot(): void {
add_action( 'graphql_register_types', [ $this, 'graphql_register_types' ] );
}

/**
* Register types in WPGraphQL
*
* @return void
*/
public function graphql_register_types(): void {

/**
* Add an Interface Type for WP Curate to the registry.
*
* @see https://www.wpgraphql.com/functions/register_graphql_interface_type
*/
register_graphql_interface_type( // @phpstan-ignore-line
'WPCurateInterface',
[
'description' => __( 'Represents the interface type a WP Curate post', 'wp-curate' ),
'interfaces' => [ 'ContentNode', 'NodeWithTitle', 'NodeWithFeaturedImage' ],
'fields' => [],
'resolveType' => function ( $node ) {
return $this->get_graphql_type_by_post_type( $node->post_type );
},
]
);


/**
* Apply the WP Curate interface to registered GraphQL Types.
* Types can be filtered to include project specific custom post types.
*
* @see https://www.wpgraphql.com/functions/register_graphql_interfaces_to_types
*/
register_graphql_interfaces_to_types( [ 'WPCurateInterface' ], $this->get_types_from_allowed_post_types() ); // @phpstan-ignore-line

/**
* Register a new connection field named 'wpCuratePosts' on `RootQuery`
* to access WP Curate posts. Supports Inline Fragments when constructing
* your GraphQL query.
*
* @see https://www.wpgraphql.com/functions/register_graphql_connection
*/
register_graphql_connection( // @phpstan-ignore-line
[
'fromType' => 'RootQuery',
'toType' => 'WPCurateInterface',
'fromFieldName' => 'wpCuratePosts',
'connectionArgs' => [
'in' => [
'type' => [ 'list_of' => 'ID' ],
'description' => __( 'Array of IDs for the objects to retrieve', 'wp-curate' ),
],
],
// @phpstan-ignore-next-line
'resolve' => function ( $source, $args, AppContext $context, ResolveInfo $info ) {
$resolver = new PostObjectConnectionResolver( $source, $args, $context, $info ); // @phpstan-ignore-line

$resolver->set_query_arg( 'post__in', $args['where']['in'] ); // @phpstan-ignore-line
$resolver->set_query_arg( 'post_type', $this->allowed_post_types ); // @phpstan-ignore-line

return $resolver->get_connection(); // @phpstan-ignore-line
},
],
);
}
}
1 change: 1 addition & 0 deletions src/main.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function main(): void {
$features[] = new Features\Parsely_Support();

$features[] = new Features\Rest_Api();
$features[] = new Features\GraphQL();

foreach ( $features as $feature ) {
$feature->boot();
Expand Down
2 changes: 1 addition & 1 deletion wp-curate.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: WP Curate
* Plugin URI: https://github.com/alleyinteractive/wp-curate
* Description: Plugin to curate homepages and other landing pages
* Version: 1.7.1
* Version: 1.8.0
* Author: Alley Interactive
* Author URI: https://github.com/alleyinteractive/wp-curate
* Requires at least: 6.4
Expand Down

0 comments on commit 736351a

Please sign in to comment.