751 lines
23 KiB
PHP
751 lines
23 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* Plugin Name: WP GraphQL
|
||
|
|
* Plugin URI: https://github.com/wp-graphql/wp-graphql
|
||
|
|
* Description: GraphQL API for WordPress
|
||
|
|
* Author: WPGraphQL
|
||
|
|
* Author URI: http://www.wpgraphql.com
|
||
|
|
* Version: 0.0.28
|
||
|
|
* Text Domain: wp-graphql
|
||
|
|
* Domain Path: /languages/
|
||
|
|
* Requires at least: 4.7.0
|
||
|
|
* Tested up to: 4.7.1
|
||
|
|
* Requires PHP: 5.5
|
||
|
|
* License: GPL-3
|
||
|
|
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||
|
|
*
|
||
|
|
* @package WPGraphQL
|
||
|
|
* @category Core
|
||
|
|
* @author WPGraphQL
|
||
|
|
* @version 0.0.28
|
||
|
|
*/
|
||
|
|
// Exit if accessed directly.
|
||
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
||
|
|
exit;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This plugin brings the power of GraphQL (http://graphql.org/) to WordPress.
|
||
|
|
*
|
||
|
|
* This plugin is based on the hard work of Jason Bahl, Ryan Kanner, Hughie Devore and Peter Pak of Digital First Media
|
||
|
|
* (https://github.com/dfmedia), and Edwin Cromley of BE-Webdesign (https://github.com/BE-Webdesign).
|
||
|
|
*
|
||
|
|
* The plugin is built on top of the graphql-php library by Webonyx (https://github.com/webonyx/graphql-php) and makes
|
||
|
|
* use of the graphql-relay-php library by Ivome (https://github.com/ivome/graphql-relay-php/)
|
||
|
|
*
|
||
|
|
* Special thanks to Digital First Media (http://digitalfirstmedia.com) for allocating development resources to push
|
||
|
|
* the project forward.
|
||
|
|
*
|
||
|
|
* Some of the concepts and code are based on the WordPress Rest API.
|
||
|
|
* Much love to the folks (https://github.com/orgs/WP-API/people) that put their blood, sweat and tears into the
|
||
|
|
* WP-API project, as it's been huge in moving WordPress forward as a platform and helped inspire and direct the
|
||
|
|
* development of WPGraphQL.
|
||
|
|
*
|
||
|
|
* Much love to Facebook® for open sourcing the GraphQL spec (https://facebook.github.io/graphql/) and maintaining the
|
||
|
|
* JS reference implementation (https://github.com/graphql/graphql-js)
|
||
|
|
*
|
||
|
|
* Much love to Apollo (Meteor Development Group) for their work on driving GraphQL forward and providing a
|
||
|
|
* lot of insight into how to design GraphQL schemas, etc. Check them out: http://www.apollodata.com/
|
||
|
|
*/
|
||
|
|
|
||
|
|
if ( ! class_exists( 'WPGraphQL' ) ) :
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This is the one true WPGraphQL class
|
||
|
|
*/
|
||
|
|
final class WPGraphQL {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Stores the instance of the WPGraphQL class
|
||
|
|
*
|
||
|
|
* @var WPGraphQL The one true WPGraphQL
|
||
|
|
* @since 0.0.1
|
||
|
|
* @access private
|
||
|
|
*/
|
||
|
|
private static $instance;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Holds the Schema def
|
||
|
|
* @var \WPGraphQL\WPSchema
|
||
|
|
*/
|
||
|
|
protected static $schema;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Stores an array of allowed post types
|
||
|
|
*
|
||
|
|
* @var array allowed_post_types
|
||
|
|
* @since 0.0.5
|
||
|
|
* @access public
|
||
|
|
*/
|
||
|
|
public static $allowed_post_types;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Stores an array of allowed taxonomies
|
||
|
|
*
|
||
|
|
* @var array allowed_taxonomies
|
||
|
|
* @since 0.0.5
|
||
|
|
* @access public
|
||
|
|
*/
|
||
|
|
public static $allowed_taxonomies;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The instance of the WPGraphQL object
|
||
|
|
*
|
||
|
|
* @return object|WPGraphQL - The one true WPGraphQL
|
||
|
|
* @since 0.0.1
|
||
|
|
* @access public
|
||
|
|
*/
|
||
|
|
public static function instance() {
|
||
|
|
|
||
|
|
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPGraphQL ) ) {
|
||
|
|
self::$instance = new WPGraphQL;
|
||
|
|
self::$instance->setup_constants();
|
||
|
|
self::$instance->includes();
|
||
|
|
self::$instance->actions();
|
||
|
|
self::$instance->filters();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the WPGraphQL Instance
|
||
|
|
*/
|
||
|
|
return self::$instance;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Throw error on object clone.
|
||
|
|
* The whole idea of the singleton design pattern is that there is a single object
|
||
|
|
* therefore, we don't want the object to be cloned.
|
||
|
|
*
|
||
|
|
* @since 0.0.1
|
||
|
|
* @access public
|
||
|
|
* @return void
|
||
|
|
*/
|
||
|
|
public function __clone() {
|
||
|
|
|
||
|
|
// Cloning instances of the class is forbidden.
|
||
|
|
_doing_it_wrong( __FUNCTION__, esc_html__( 'The WPGraphQL class should not be cloned.', 'wp-graphql' ), '0.0.1' );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Disable unserializing of the class.
|
||
|
|
*
|
||
|
|
* @since 0.0.1
|
||
|
|
* @access protected
|
||
|
|
* @return void
|
||
|
|
*/
|
||
|
|
public function __wakeup() {
|
||
|
|
|
||
|
|
// De-serializing instances of the class is forbidden.
|
||
|
|
_doing_it_wrong( __FUNCTION__, esc_html__( 'De-serializing instances of the WPGraphQL class is not allowed', 'wp-graphql' ), '0.0.1' );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Setup plugin constants.
|
||
|
|
*
|
||
|
|
* @access private
|
||
|
|
* @since 0.0.1
|
||
|
|
* @return void
|
||
|
|
*/
|
||
|
|
private function setup_constants() {
|
||
|
|
|
||
|
|
// Plugin version.
|
||
|
|
if ( ! defined( 'WPGRAPHQL_VERSION' ) ) {
|
||
|
|
define( 'WPGRAPHQL_VERSION', '0.0.28' );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Plugin Folder Path.
|
||
|
|
if ( ! defined( 'WPGRAPHQL_PLUGIN_DIR' ) ) {
|
||
|
|
define( 'WPGRAPHQL_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Plugin Folder URL.
|
||
|
|
if ( ! defined( 'WPGRAPHQL_PLUGIN_URL' ) ) {
|
||
|
|
define( 'WPGRAPHQL_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Plugin Root File.
|
||
|
|
if ( ! defined( 'WPGRAPHQL_PLUGIN_FILE' ) ) {
|
||
|
|
define( 'WPGRAPHQL_PLUGIN_FILE', __FILE__ );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Whether to autoload the files or not
|
||
|
|
if ( ! defined( 'WPGRAPHQL_AUTOLOAD' ) ) {
|
||
|
|
define( 'WPGRAPHQL_AUTOLOAD', true );
|
||
|
|
}
|
||
|
|
|
||
|
|
// Whether to run the plugin in debug mode. Default is false.
|
||
|
|
if ( ! defined( 'GRAPHQL_DEBUG' ) ) {
|
||
|
|
define( 'GRAPHQL_DEBUG', false );
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Include required files.
|
||
|
|
* Uses composer's autoload
|
||
|
|
*
|
||
|
|
* @access private
|
||
|
|
* @since 0.0.1
|
||
|
|
* @return void
|
||
|
|
*/
|
||
|
|
private function includes() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* WPGRAPHQL_AUTOLOAD can be set to "false" to prevent the autoloader from running.
|
||
|
|
* In most cases, this is not something that should be disabled, but some environments
|
||
|
|
* may bootstrap their dependencies in a global autoloader that will autoload files
|
||
|
|
* before we get to this point, and requiring the autoloader again can trigger fatal errors.
|
||
|
|
*
|
||
|
|
* The codeception tests are an example of an environment where adding the autoloader again causes issues
|
||
|
|
* so this is set to false for tests.
|
||
|
|
*/
|
||
|
|
if ( defined( 'WPGRAPHQL_AUTOLOAD' ) && true === WPGRAPHQL_AUTOLOAD ) {
|
||
|
|
// Autoload Required Classes
|
||
|
|
require_once( WPGRAPHQL_PLUGIN_DIR . 'vendor/autoload.php' );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// Required non-autoloaded classes
|
||
|
|
require_once( WPGRAPHQL_PLUGIN_DIR . 'access-functions.php' );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets up actions to run at certain spots throughout WordPress and the WPGraphQL execution cycle
|
||
|
|
*/
|
||
|
|
private function actions() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Init WPGraphQL after themes have been setup,
|
||
|
|
* allowing for both plugins and themes to register
|
||
|
|
* things before graphql_init
|
||
|
|
*/
|
||
|
|
add_action( 'after_setup_theme', function() {
|
||
|
|
|
||
|
|
new \WPGraphQL\Data\Config();
|
||
|
|
new \WPGraphQL\Router();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Fire off init action
|
||
|
|
*
|
||
|
|
* @param WPGraphQL $instance The instance of the WPGraphQL class
|
||
|
|
*/
|
||
|
|
do_action( 'graphql_init', self::$instance );
|
||
|
|
|
||
|
|
} );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Flush permalinks if the registered GraphQL endpoint has not yet been registered.
|
||
|
|
*/
|
||
|
|
add_action( 'wp_loaded', [ $this, 'maybe_flush_permalinks' ] );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Register default settings available in WordPress so we can use
|
||
|
|
* the get_registered_settings method
|
||
|
|
*
|
||
|
|
* @source https://github.com/WordPress/WordPress/blob/master/wp-includes/default-filters.php#L393
|
||
|
|
*/
|
||
|
|
add_action( 'do_graphql_request', 'register_initial_settings', 10 );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Hook in before fields resolve to check field permissions
|
||
|
|
*/
|
||
|
|
add_action( 'graphql_before_resolve_field', [ '\WPGraphQL\Utils\InstrumentSchema', 'check_field_permissions' ], 10, 8 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Flush permalinks if the GraphQL Endpoint route isn't yet registered
|
||
|
|
*/
|
||
|
|
public function maybe_flush_permalinks() {
|
||
|
|
$rules = get_option( 'rewrite_rules' );
|
||
|
|
if ( ! isset( $rules[ \WPGraphQL\Router::$route . '/?$' ] ) ) {
|
||
|
|
flush_rewrite_rules();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Setup filters
|
||
|
|
*/
|
||
|
|
private function filters() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* mediaItems are the attachment postObject, but they have a different schema shape
|
||
|
|
* than postObjects out of the box, so this filter adjusts the core mediaItem
|
||
|
|
* shape of data
|
||
|
|
*/
|
||
|
|
add_filter( 'graphql_mediaItem_fields', [ '\WPGraphQL\Type\MediaItem\MediaItemType', 'fields' ], 10, 1 );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Instrument the Schema to provide Resolve Hooks and sanitize Schema output
|
||
|
|
*/
|
||
|
|
add_filter( 'graphql_schema', [ '\WPGraphQL\Utils\InstrumentSchema', 'instrument_schema' ], 10, 1 );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Function to execute when the user activates the plugin.
|
||
|
|
*
|
||
|
|
* @since 0.0.17
|
||
|
|
*/
|
||
|
|
public function activate() {
|
||
|
|
flush_rewrite_rules();
|
||
|
|
// Save the version of the plugin as an option in order to force actions
|
||
|
|
// on upgrade.
|
||
|
|
update_option( 'wp_graphql_version', WPGRAPHQL_VERSION, 'no' );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Function to execute when the user deactivates the plugin.
|
||
|
|
*
|
||
|
|
* @since 0.0.17
|
||
|
|
*/
|
||
|
|
public function deactivate() {
|
||
|
|
flush_rewrite_rules();
|
||
|
|
delete_option( 'wp_graphql_version' );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This sets up built-in post_types and taxonomies to show in the GraphQL Schema
|
||
|
|
*
|
||
|
|
* @since 0.0.2
|
||
|
|
* @access public
|
||
|
|
* @return void
|
||
|
|
*/
|
||
|
|
public static function show_in_graphql() {
|
||
|
|
|
||
|
|
global $wp_post_types, $wp_taxonomies;
|
||
|
|
|
||
|
|
// Adds GraphQL support for attachments
|
||
|
|
if ( isset( $wp_post_types['attachment'] ) ) {
|
||
|
|
$wp_post_types['attachment']->show_in_graphql = true;
|
||
|
|
$wp_post_types['attachment']->graphql_single_name = 'mediaItem';
|
||
|
|
$wp_post_types['attachment']->graphql_plural_name = 'mediaItems';
|
||
|
|
}
|
||
|
|
|
||
|
|
// Adds GraphQL support for pages
|
||
|
|
if ( isset( $wp_post_types['page'] ) ) {
|
||
|
|
$wp_post_types['page']->show_in_graphql = true;
|
||
|
|
$wp_post_types['page']->graphql_single_name = 'page';
|
||
|
|
$wp_post_types['page']->graphql_plural_name = 'pages';
|
||
|
|
}
|
||
|
|
|
||
|
|
// Adds GraphQL support for posts
|
||
|
|
if ( isset( $wp_post_types['post'] ) ) {
|
||
|
|
$wp_post_types['post']->show_in_graphql = true;
|
||
|
|
$wp_post_types['post']->graphql_single_name = 'post';
|
||
|
|
$wp_post_types['post']->graphql_plural_name = 'posts';
|
||
|
|
}
|
||
|
|
|
||
|
|
// Adds GraphQL support for categories
|
||
|
|
if ( isset( $wp_taxonomies['category'] ) ) {
|
||
|
|
$wp_taxonomies['category']->show_in_graphql = true;
|
||
|
|
$wp_taxonomies['category']->graphql_single_name = 'category';
|
||
|
|
$wp_taxonomies['category']->graphql_plural_name = 'categories';
|
||
|
|
}
|
||
|
|
|
||
|
|
// Adds GraphQL support for tags
|
||
|
|
if ( isset( $wp_taxonomies['post_tag'] ) ) {
|
||
|
|
$wp_taxonomies['post_tag']->show_in_graphql = true;
|
||
|
|
$wp_taxonomies['post_tag']->graphql_single_name = 'tag';
|
||
|
|
$wp_taxonomies['post_tag']->graphql_plural_name = 'tags';
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the post types that are allowed to be used in GraphQL. This gets all post_types that
|
||
|
|
* are set to show_in_graphql, but allows for external code (plugins/theme) to filter the
|
||
|
|
* list of allowed_post_types to add/remove additional post_types
|
||
|
|
*
|
||
|
|
* @return array
|
||
|
|
* @since 0.0.4
|
||
|
|
* @access public
|
||
|
|
*/
|
||
|
|
public static function get_allowed_post_types() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all post_types
|
||
|
|
*/
|
||
|
|
$post_types = get_post_types([
|
||
|
|
'show_in_graphql' => true,
|
||
|
|
]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate that the post_types have a graphql_single_name and graphql_plural_name
|
||
|
|
*/
|
||
|
|
array_map( function( $post_type ) {
|
||
|
|
$post_type_object = get_post_type_object( $post_type );
|
||
|
|
if ( empty( $post_type_object->graphql_single_name ) || empty( $post_type_object->graphql_plural_name ) ) {
|
||
|
|
throw new \GraphQL\Error\UserError( sprintf( __( 'The %s post_type isn\'t configured properly to show in GraphQL. It needs a "graphql_single_name" and a "graphql_plural_name"', 'wp-graphql' ), $post_type_object->name ) );
|
||
|
|
}
|
||
|
|
}, $post_types );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Define the $allowed_post_types to be exposed by GraphQL Queries Pass through a filter
|
||
|
|
* to allow the post_types to be modified (for example if a certain post_type should
|
||
|
|
* not be exposed to the GraphQL API)
|
||
|
|
*
|
||
|
|
* @since 0.0.2
|
||
|
|
*
|
||
|
|
* @param array $post_types Array of post types
|
||
|
|
*
|
||
|
|
* @return array
|
||
|
|
*/
|
||
|
|
self::$allowed_post_types = apply_filters( 'graphql_post_entities_allowed_post_types', $post_types );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the array of allowed_post_types
|
||
|
|
*/
|
||
|
|
return self::$allowed_post_types;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the taxonomies that are allowed to be used in GraphQL/This gets all taxonomies that
|
||
|
|
* are set to "show_in_graphql" but allows for external code (plugins/themes) to filter
|
||
|
|
* the list of allowed_taxonomies to add/remove additional taxonomies
|
||
|
|
*
|
||
|
|
* @since 0.0.4
|
||
|
|
* @access public
|
||
|
|
* @return array
|
||
|
|
*/
|
||
|
|
public static function get_allowed_taxonomies() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all taxonomies
|
||
|
|
*/
|
||
|
|
$taxonomies = get_taxonomies([
|
||
|
|
'show_in_graphql' => true,
|
||
|
|
]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate that the taxonomies have a graphql_single_name and graphql_plural_name
|
||
|
|
*/
|
||
|
|
array_map( function( $taxonomy ) {
|
||
|
|
$tax_object = get_taxonomy( $taxonomy );
|
||
|
|
if ( empty( $tax_object->graphql_single_name ) || empty( $tax_object->graphql_plural_name ) ) {
|
||
|
|
throw new \GraphQL\Error\UserError( sprintf( __( 'The %s taxonomy isn\'t configured properly to show in GraphQL. It needs a "graphql_single_name" and a "graphql_plural_name"', 'wp-graphql' ), $tax_object->name ) );
|
||
|
|
}
|
||
|
|
}, $taxonomies );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Define the $allowed_taxonomies to be exposed by GraphQL Queries Pass through a filter
|
||
|
|
* to allow the taxonomies to be modified (for example if a certain taxonomy should not
|
||
|
|
* be exposed to the GraphQL API)
|
||
|
|
*
|
||
|
|
* @since 0.0.2
|
||
|
|
* @return array
|
||
|
|
*
|
||
|
|
* @param array $taxonomies Array of taxonomy objects
|
||
|
|
*/
|
||
|
|
self::$allowed_taxonomies = apply_filters( 'graphql_term_entities_allowed_taxonomies', $taxonomies );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the array of $allowed_taxonomies
|
||
|
|
*/
|
||
|
|
return self::$allowed_taxonomies;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the Schema as defined by static registrations throughout
|
||
|
|
* the WP Load.
|
||
|
|
*
|
||
|
|
* @access protected
|
||
|
|
* @return \WPGraphQL\WPSchema
|
||
|
|
*/
|
||
|
|
public static function get_schema() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Fire an action when the Schema is returned
|
||
|
|
*/
|
||
|
|
do_action( 'graphql_get_schema', self::$schema );
|
||
|
|
|
||
|
|
if ( null === self::$schema ) {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create an executable Schema from the registered
|
||
|
|
* root_Query and root_mutation
|
||
|
|
*/
|
||
|
|
$executable_schema = [
|
||
|
|
'query' => \WPGraphQL\Types::root_query(),
|
||
|
|
'mutation' => \WPGraphQL\Types::root_mutation(),
|
||
|
|
];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generate the Schema
|
||
|
|
*/
|
||
|
|
$schema = new \WPGraphQL\WPSchema( $executable_schema );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generate & Filter the schema.
|
||
|
|
*
|
||
|
|
* @since 0.0.5
|
||
|
|
*
|
||
|
|
* @param array $schema The executable Schema that GraphQL executes against
|
||
|
|
* @param \WPGraphQL\AppContext $app_context Object The AppContext object containing all of the
|
||
|
|
* information about the context we know at this point
|
||
|
|
*/
|
||
|
|
self::$schema = apply_filters( 'graphql_schema', $schema, self::get_app_context() );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the Schema after applying filters
|
||
|
|
*/
|
||
|
|
return ! empty( self::$schema ) ? self::$schema : null;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the static schema if there is one
|
||
|
|
*
|
||
|
|
* @return null|string
|
||
|
|
* @access public
|
||
|
|
*/
|
||
|
|
public static function get_static_schema() {
|
||
|
|
$schema = null;
|
||
|
|
if ( file_exists( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ) && ! empty( file_get_contents( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ) ) ) {
|
||
|
|
$schema = file_get_contents( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' );
|
||
|
|
}
|
||
|
|
|
||
|
|
return $schema;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the AppContext for use in passing down the Resolve Tree
|
||
|
|
* @return \WPGraphQL\AppContext
|
||
|
|
* @access public
|
||
|
|
*/
|
||
|
|
public static function get_app_context() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Configure the app_context which gets passed down to all the resolvers.
|
||
|
|
*
|
||
|
|
* @since 0.0.4
|
||
|
|
*/
|
||
|
|
$app_context = new \WPGraphQL\AppContext();
|
||
|
|
$app_context->viewer = wp_get_current_user();
|
||
|
|
$app_context->root_url = get_bloginfo( 'url' );
|
||
|
|
$app_context->request = ! empty( $_REQUEST ) ? $_REQUEST : null;
|
||
|
|
|
||
|
|
return $app_context;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This processes a GraphQL request, given a $request and optional $variables
|
||
|
|
*
|
||
|
|
* This function is used to resolve the HTTP requests for the GraphQL API, but can also be
|
||
|
|
* used internally to run GraphQL queries inside WordPress via PHP.
|
||
|
|
*
|
||
|
|
* @since 0.0.5
|
||
|
|
*
|
||
|
|
* @param string $request The GraphQL request to be run
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param string $variables Variables to be passed to your GraphQL request
|
||
|
|
*
|
||
|
|
* @return array $result The results of your request
|
||
|
|
*/
|
||
|
|
public static function do_graphql_request( $request, $operation_name = '', $variables = '' ) {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Whether it's a GraphQL Request (http or internal)
|
||
|
|
*
|
||
|
|
* @since 0.0.5
|
||
|
|
*/
|
||
|
|
if ( ! defined( 'GRAPHQL_REQUEST' ) ) {
|
||
|
|
define( 'GRAPHQL_REQUEST', true );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Setup the post_types and taxonomies to show_in_graphql
|
||
|
|
*/
|
||
|
|
\WPGraphQL::show_in_graphql();
|
||
|
|
\WPGraphQL::get_allowed_post_types();
|
||
|
|
\WPGraphQL::get_allowed_taxonomies();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Store the global post so it can be reset after GraphQL execution
|
||
|
|
*
|
||
|
|
* This allows for a GraphQL query to be used in the middle of post content, such as in a Shortcode
|
||
|
|
* without disrupting the flow of the post as the global POST before and after GraphQL execution will be
|
||
|
|
* the same.
|
||
|
|
*/
|
||
|
|
$global_post = ! empty( $GLOBALS['post'] ) ? $GLOBALS['post'] : null;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Run an action as soon when do_graphql_request begins.
|
||
|
|
*
|
||
|
|
* @param string $request The GraphQL request to be run
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param string $variables Variables to be passed to your GraphQL request
|
||
|
|
*/
|
||
|
|
do_action( 'do_graphql_request', $request, $operation_name, $variables );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Run an action before generating the schema
|
||
|
|
* This is a great spot for plugins/themes to hook in to customize the schema.
|
||
|
|
*
|
||
|
|
* @since 0.0.5
|
||
|
|
*
|
||
|
|
* @param string $request The request to be executed by GraphQL
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param array $variables Variables to be passed to your GraphQL request
|
||
|
|
* @param AppContext object The AppContext object containing all of the
|
||
|
|
* information about the context we know at this point
|
||
|
|
*/
|
||
|
|
if ( ! is_array( $variables ) ) {
|
||
|
|
$variables = (string) $variables;
|
||
|
|
$variables = (array) json_decode( $variables );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Executes the request and captures the result
|
||
|
|
*/
|
||
|
|
$result = \GraphQL\GraphQL::executeAndReturnResult(
|
||
|
|
self::get_schema(),
|
||
|
|
$request,
|
||
|
|
null,
|
||
|
|
self::get_app_context(),
|
||
|
|
$variables,
|
||
|
|
$operation_name
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Run an action. This is a good place for debug tools to hook in to log things, etc.
|
||
|
|
*
|
||
|
|
* @since 0.0.4
|
||
|
|
*
|
||
|
|
* @param array $result The result of your GraphQL request
|
||
|
|
* @param Schema object $schema The schema object for the root request
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param string $request The request that GraphQL executed
|
||
|
|
* @param array|null $variables Variables to passed to your GraphQL query
|
||
|
|
*/
|
||
|
|
do_action( 'graphql_execute', $result, self::get_schema(), $operation_name, $request, $variables );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Filter the $result of the GraphQL execution. This allows for the response to be filtered before
|
||
|
|
* it's returned, allowing granular control over the response at the latest point.
|
||
|
|
*
|
||
|
|
* POSSIBLE USAGE EXAMPLES:
|
||
|
|
* This could be used to ensure that certain fields never make it to the response if they match
|
||
|
|
* certain criteria, etc. For example, this filter could be used to check if a current user is
|
||
|
|
* allowed to see certain things, and if they are not, the $result could be filtered to remove
|
||
|
|
* the data they should not be allowed to see.
|
||
|
|
*
|
||
|
|
* Or, perhaps some systems want the result to always include some additional piece of data in
|
||
|
|
* every response, regardless of the request that was sent to it, this could allow for that
|
||
|
|
* to be hooked in and included in the $result
|
||
|
|
*
|
||
|
|
* @since 0.0.5
|
||
|
|
*
|
||
|
|
* @param array $result The result of your GraphQL query
|
||
|
|
* @param Schema object $schema The schema object for the root query
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param string $request The request that GraphQL executed
|
||
|
|
* @param array|null $variables Variables to passed to your GraphQL request
|
||
|
|
*/
|
||
|
|
$filtered_result = apply_filters( 'graphql_request_results', $result, self::get_schema(), $operation_name, $request, $variables );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Run an action after the result has been filtered, as the response is being returned.
|
||
|
|
* This is a good place for debug tools to hook in to log things, etc.
|
||
|
|
*
|
||
|
|
* @param array $filtered_result The filtered_result of the GraphQL request
|
||
|
|
* @param array $result The result of your GraphQL request
|
||
|
|
* @param Schema object $schema The schema object for the root request
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param string $request The request that GraphQL executed
|
||
|
|
* @param array|null $variables Variables to passed to your GraphQL query
|
||
|
|
*/
|
||
|
|
do_action( 'graphql_return_response', $filtered_result, $result, self::get_schema(), $operation_name, $request, $variables );
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reset the global post after execution
|
||
|
|
*
|
||
|
|
* This allows for a GraphQL query to be used in the middle of post content, such as in a Shortcode
|
||
|
|
* without disrupting the flow of the post as the global POST before and after GraphQL execution will be
|
||
|
|
* the same.
|
||
|
|
*/
|
||
|
|
if ( ! empty( $global_post ) ) {
|
||
|
|
$GLOBALS['post'] = $global_post;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the result of the request
|
||
|
|
*/
|
||
|
|
return $result->toArray( GRAPHQL_DEBUG );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function server( $request = null ) {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Whether it's a GraphQL Request (http or internal)
|
||
|
|
*
|
||
|
|
* @since 0.0.5
|
||
|
|
*/
|
||
|
|
if ( ! defined( 'GRAPHQL_REQUEST' ) ) {
|
||
|
|
define( 'GRAPHQL_REQUEST', true );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Setup the post_types and taxonomies to show_in_graphql
|
||
|
|
*/
|
||
|
|
\WPGraphQL::show_in_graphql();
|
||
|
|
\WPGraphQL::get_allowed_post_types();
|
||
|
|
\WPGraphQL::get_allowed_taxonomies();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Run an action as soon when do_graphql_request begins.
|
||
|
|
*/
|
||
|
|
$helper = new \GraphQL\Server\Helper();
|
||
|
|
$query = $helper->parseHttpRequest()->query;
|
||
|
|
$operation = $helper->parseHttpRequest()->operation;
|
||
|
|
$variables = $helper->parseHttpRequest()->variables;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Run an action as soon when do_graphql_request begins.
|
||
|
|
*
|
||
|
|
* @param string $request The GraphQL request to be run
|
||
|
|
* @param string $operation_name The name of the operation
|
||
|
|
* @param string $variables Variables to be passed to your GraphQL request
|
||
|
|
*/
|
||
|
|
do_action( 'do_graphql_request', $query, $operation, $variables );
|
||
|
|
|
||
|
|
$config = new \GraphQL\Server\ServerConfig();
|
||
|
|
$config
|
||
|
|
->setDebug( GRAPHQL_DEBUG )
|
||
|
|
->setSchema( self::get_schema() )
|
||
|
|
->setContext( self::get_app_context() )
|
||
|
|
->setQueryBatching(true);
|
||
|
|
|
||
|
|
$server = new \GraphQL\Server\StandardServer( $config );
|
||
|
|
|
||
|
|
return $server;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
endif;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Function that instantiates the plugins main class
|
||
|
|
*
|
||
|
|
* @since 0.0.1
|
||
|
|
*/
|
||
|
|
function graphql_init() {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return an instance of the action
|
||
|
|
*/
|
||
|
|
return \WPGraphQL::instance();
|
||
|
|
}
|
||
|
|
graphql_init();
|
||
|
|
|
||
|
|
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||
|
|
require_once( 'cli/wp-cli.php' );
|
||
|
|
}
|