My First WPGraphQL Extension
Last updated
Was this helpful?
Last updated
Was this helpful?
wp-content\plugins\my-first-wpgraphql-extension\my-first-wpgraphql-extension.php
<?php
/**
* Plugin Name: My First WPGraphQL Extension
* Plugin URI: https://github.com/wp-graphql/wp-graphql
* GitHub Plugin URI: https://github.com/wp-graphql/wp-graphql
* Description: A tutorial plugin demonstrating WPGraphQL extension development
* Author: WPGraphQL
* Author URI: http://www.wpgraphql.com
* Version: 1.31.1
* Text Domain: wp-graphql
* Domain Path: /languages/
* Requires at least: 5.9
* Tested up to: 6.7.1
* Requires PHP: 7.1
* License: GPL-3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*
* @package WPGraphQL
* @category Core
* @author WPGraphQL
* @version 1.31.1
*/
// Prevent direct access to this file
if (! defined('ABSPATH')) {
die('Unauthorized access!');
}
add_action('graphql_register_types', function () {
// Register a custom type
register_graphql_object_type('CustomType', [
'description' => __('An example custom type demonstrating schema extension', 'my-graphql-extension'),
'fields' => [
'message' => [
'type' => 'String',
'description' => __('A simple message field', 'my-graphql-extension'),
],
'number' => [
'type' => 'Int',
'description' => __('A simple number field', 'my-graphql-extension'),
],
],
]);
// Register a field that returns our custom type
register_graphql_field('RootQuery', 'example', [
'type' => 'CustomType',
'description' => __('An example field returning our custom type', 'my-graphql-extension'),
'resolve' => function () {
return [
'message' => 'Hello from your first WPGraphQL extension!',
'number' => 42,
];
}
]);
});
<?php
/**
* Plugin Name: My First WPGraphQL Extension
* Plugin URI: https://github.com/wp-graphql/wp-graphql
* GitHub Plugin URI: https://github.com/wp-graphql/wp-graphql
* Description: A tutorial plugin demonstrating WPGraphQL extension development
* Author: WPGraphQL
* Author URI: http://www.wpgraphql.com
* Version: 1.31.1
* Text Domain: wp-graphql
* Domain Path: /languages/
* Requires at least: 5.9
* Tested up to: 6.7.1
* Requires PHP: 7.1
* License: GPL-3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*
* @package WPGraphQL
* @category Core
* @author WPGraphQL
* @version 1.31.1
*/
// Prevent direct access to this file
if (! defined('ABSPATH')) {
die('Unauthorized access!');
}
add_action('graphql_register_types', function () {
// Register a custom type
register_graphql_object_type('CustomType', [
'description' => __('An example custom type demonstrating schema extension', 'my-graphql-extension'),
'fields' => [
'message' => [
'type' => 'String',
'description' => __('A simple message field', 'my-graphql-extension'),
],
'number' => [
'type' => 'Int',
'description' => __('A simple number field', 'my-graphql-extension'),
],
],
]);
// Register a field that returns our custom type
register_graphql_field('RootQuery', 'example', [
'type' => 'CustomType',
'description' => __('An example field returning our custom type', 'my-graphql-extension'),
'resolve' => function () {
return [
'message' => 'Hello from your first WPGraphQL extension!',
'number' => 42,
];
}
]);
});
add_action( 'graphql_register_types', function() {
register_graphql_field( 'RootQuery', 'siteCustomSetting', [
'type' => 'String',
'description' => __( 'A custom site setting', 'my-graphql-extension' ),
'resolve' => function() {
// Basic capability check
if ( ! current_user_can( 'read' ) ) {
throw new \GraphQL\Error\UserError( 'You do not have permission to access this setting' );
}
return get_option( 'my_custom_setting', 'default value' );
}
]);
});
wp-content\plugins\my-first-wpgraphql-extension\my-first-wpgraphql-extension.php
<?php
/**
* Plugin Name: My First WPGraphQL Extension
* Plugin URI: https://github.com/wp-graphql/wp-graphql
* GitHub Plugin URI: https://github.com/wp-graphql/wp-graphql
* Description: A tutorial plugin demonstrating WPGraphQL extension development
* Author: WPGraphQL
* Author URI: http://www.wpgraphql.com
* Version: 1.31.1
* Text Domain: wp-graphql
* Domain Path: /languages/
* Requires at least: 5.9
* Tested up to: 6.7.1
* Requires PHP: 7.1
* License: GPL-3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*
* @package WPGraphQL
* @category Core
* @author WPGraphQL
* @version 1.31.1
*/
// Prevent direct access to this file
if (! defined('ABSPATH')) {
die('Unauthorized access!');
}
add_action('graphql_register_types', function () {
// Register a custom type
register_graphql_object_type('CustomType', [
'description' => __('An example custom type demonstrating schema extension', 'my-graphql-extension'),
'fields' => [
'message' => [
'type' => 'String',
'description' => __('A simple message field', 'my-graphql-extension'),
],
'number' => [
'type' => 'Int',
'description' => __('A simple number field', 'my-graphql-extension'),
],
],
]);
// Register a field that returns our custom type
register_graphql_field('RootQuery', 'example', [
'type' => 'CustomType',
'description' => __('An example field returning our custom type', 'my-graphql-extension'),
'resolve' => function () {
return [
'message' => 'Hello from your first WPGraphQL extension!',
'number' => 42,
];
}
]);
});
add_action('graphql_register_types', function () {
register_graphql_field('RootQuery', 'siteCustomSetting', [
'type' => 'String',
'description' => __('A custom site setting', 'my-graphql-extension'),
'resolve' => function () {
// Basic capability check
if (! current_user_can('read')) {
throw new \GraphQL\Error\UserError('You do not have permission to access this setting');
}
return get_option('my_custom_setting', 'default value');
}
]);
});
add_action('graphql_register_types', function () {
// Register a custom settings type
register_graphql_object_type('CustomSiteSettings', [
'description' => __('Custom site settings', 'my-graphql-extension'),
'fields' => [
'mainColor' => [
'type' => 'String',
'description' => __('The main color theme setting', 'my-graphql-extension'),
],
'featuredCategories' => [
'type' => ['list_of' => 'String'],
'description' => __('List of featured category slugs', 'my-graphql-extension'),
],
'lastUpdated' => [
'type' => 'String',
'description' => __('When the settings were last updated', 'my-graphql-extension'),
],
],
]);
// Register a field that returns our settings type
register_graphql_field('RootQuery', 'customSiteSettings', [
'type' => 'CustomSiteSettings',
'description' => __('Custom site settings configuration', 'my-graphql-extension'),
'resolve' => function () {
// Check permissions
if (! current_user_can('manage_options')) {
throw new \GraphQL\Error\UserError(__('You do not have permission to access site settings', 'my-graphql-extension'));
}
try {
return [
'mainColor' => get_option('site_main_color', '#ffffff'),
'featuredCategories' => get_option('featured_categories', [1,2,3]),
'lastUpdated' => get_option('settings_updated_at','18-05-2025'),
];
} catch (\Exception $e) {
throw new \GraphQL\Error\UserError(__('Error fetching site settings', 'my-graphql-extension'));
}
}
]);
});
register_graphql_field('RootQuery', 'sensitiveData', [
'type' => 'String',
'resolve' => function () {
// Always check capabilities
if (! current_user_can('manage_options')) {
throw new \GraphQL\Error\UserError('Unauthorized access');
}
return get_option('sensitive_data');
}
]);
'resolve' => function( $source, array $args ) {
// Always sanitize input
$safe_input = sanitize_text_field( $args['input'] );
return wp_kses_post( $safe_input );
}
'resolve' => function() {
try {
// Your resolution logic
return get_option( 'some_option' );
} catch ( \Exception $e ) {
throw new \GraphQL\Error\UserError(
__( 'Failed to retrieve data', 'my-textdomain' )
);
}
}
wp-content\plugins\wp-graphql-cpt.php
<?php
/**
* Plugin Name: WP GraphQL Custom Post Types and Custom Taxonomies
* Description: Exposes all registered Custom Post Types and Custom Taxonomies to the WPGraphQL EndPoint.
* Author: Niklas Dahlqvist
* Author URI: https://www.niklasdahlqvist.com
* Version: 0.7
* License: GPL2+
*/
namespace WPGraphQL\Extensions;
if (!defined('ABSPATH')) {
exit;
}
if (!class_exists('\WPGraphQL\Extensions\CPT')) {
class CPT
{
public function __construct()
{
// Actions
// Filters
add_filter('register_post_type_args', [$this, 'filterPostTypes'], 10, 2);
add_filter('register_taxonomy_args', [$this, 'filterTaxonomies'], 10, 2);
}
public function filterPostTypes($args, $post_type)
{
$graphQLArgs = [];
$wp_default_post_types = [
'post',
'page',
'attachment',
'revision',
'nav_menu_item',
'custom_css',
'customize_changeset',
'oembed_cache',
'user_request',
'wp_block',
'wp_template',
'wp_template_part',
'wp_global_styles',
'wp_navigation',
// Exclude ACF Field Groups
'acf-field-group',
// Exclude WooCommerce products
'product',
'product_variation',
'shop_coupon',
'shop_order',
'shop_order_refund',
'shop_order_placehold'
];
$wp_default_post_types = apply_filters('graphql_cpt_excluded_post_types', $wp_default_post_types);
// Filter Out Truly Custom Post Types, we don't want to mess around with the others
if (!in_array($post_type, $wp_default_post_types) && !$this->graphQLKeysExists($args)) {
if (isset($args['labels']) && isset($args['public']) && $args['public'] == true) {
$graphQLArgs = apply_filters('graphql_cpt_post_type_graphql_args', [
'show_in_graphql' => true,
'graphql_single_name' => $this->cleanStrings($args['labels']['singular_name']),
'graphql_plural_name' => $this->cleanStrings($args['labels']['name'])
], $post_type);
$graphQLArgs = apply_filters("graphql_cpt_{$post_type}_graphql_args", $graphQLArgs);
// Merge args together.
return apply_filters("graphql_cpt_{$post_type}_merged_args", array_merge($args, $graphQLArgs));
}
}
return $args;
}
public function filterTaxonomies($args, $taxonomy)
{
$wp_default_taxonomies = [
'category',
'post_tag',
'nav_menu',
'link_category',
'nav_menu_item',
'post_format',
'wp_theme',
'wp_template_part_area',
'product_type',
'product_visibility',
'product_cat',
'product_tag',
'product_shipping_class',
];
$wp_default_taxonomies = apply_filters('graphql_cpt_excluded_taxonomies', $wp_default_taxonomies);
// Filter Out Truly Custom Taxonomies, we don't want to mess around with the others
if (!in_array($taxonomy, $wp_default_taxonomies) && !$this->graphQLKeysExists($args)) {
if (isset($args['labels'])) {
$graphQLArgs = apply_filters('graphql_cpt_taxonomy_graphql_args', [
'show_in_graphql' => true,
'graphql_single_name' => $this->cleanStrings($args['labels']['singular_name']),
'graphql_plural_name' => $this->cleanStrings($args['labels']['name'])
], $taxonomy);
$graphQLArgs = apply_filters("graphql_cpt_{$taxonomy}_graphql_args", $graphQLArgs);
// Merge args together.
return apply_filters("graphql_cpt_{$taxonomy}_merged_args", array_merge($args, $graphQLArgs));
}
}
return $args;
}
public function graphQLKeysExists($args)
{
$graphQLKeys = apply_filters('graphql_cpt_existing_keys_to_check_against', [
'show_in_graphql',
'graphql_single_name',
'graphql_plural_name'
]);
return !array_diff_key(array_flip($graphQLKeys), $args);
}
public function cleanStrings($string)
{
return preg_replace('/[^a-zA-Z0-9_]+/', '', lcfirst(ucwords($string)));
}
}
}
// Boot Plugin
add_action('plugins_loaded', function () {
new CPT();
});