Skip to content

Instantly share code, notes, and snippets.

@lstellway
Last active July 14, 2020 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lstellway/175bbce8657734f23a1a86c724076d74 to your computer and use it in GitHub Desktop.
Save lstellway/175bbce8657734f23a1a86c724076d74 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: GraphQL Meta Queries
Plugin URI: https://loganstellway.com
Description: Extends WPGraphQL to allow meta queries on post connections
Version: 0.0.1
Author: Logan Stellway
Author URI: https://loganstellway.com
*/
namespace LoganStellway\WPGraphQL;
if (!defined('ABSPATH') || !is_blog_installed()) {
return;
}
class MetaQueries
{
/**
* Register meta query relation enum
*/
protected function registerMetaQueryRelationEnum()
{
register_graphql_enum_type(
'MetaQueryRelationEnum',
[
'description' => __('The condition used for meta query filters', 'loganstellway'),
'values' => [
'AND' => [
'value' => 'AND',
],
'OR' => [
'value' => 'OR',
],
],
'defaultValue' => 'AND',
]
);
}
/**
* Register meta query relation enum
*/
protected function registerMetaDataCompareEnum()
{
register_graphql_enum_type(
'MetaDataCompareEnum',
[
'description' => __('The method used for matching meta data values', 'loganstellway'),
'values' => [
'EQUAL' => [
'value' => '=',
],
'NOT_EQUAL' => [
'value' => '!=',
],
'GREATER_THAN' => [
'value' => '>',
],
'GREATER_THAN_OR_EQUAL' => [
'value' => '>=',
],
'LESS_THAN' => [
'value' => '<',
],
'LESS_THAN_OR_EQUAL' => [
'value' => '<=',
],
'LIKE' => [
'value' => 'LIKE',
],
'NOT_LIKE' => [
'value' => 'NOT LIKE',
],
'IN' => [
'value' => 'IN',
],
'NOT_IN' => [
'value' => 'NOT IN',
],
'BETWEEN' => [
'value' => 'BETWEEN',
],
'NOT_BETWEEN' => [
'value' => 'NOT BETWEEN',
],
'EXISTS' => [
'value' => 'EXISTS',
],
'NOT_EXISTS' => [
'value' => 'NOT EXISTS',
],
'REGEXP' => [
'value' => 'REGEXP',
],
'NOT_REGEXP' => [
'value' => 'NOT REGEXP',
],
'RLIKE' => [
'value' => 'RLIKE',
],
],
'defaultValue' => '=',
]
);
}
/**
* Register meta data input
*/
protected function registerMetaDataInput()
{
register_graphql_input_type(
'MetaDataInputArgs',
array(
'description' => __('Meta data.', 'loganstellway'),
'fields' => array(
'key' => array(
'type' => array('non_null' => 'String'),
'description' => __('Meta key.', 'loganstellway'),
'resolve' => function ($source) {
return !empty($source->key) ? $source->key : null;
},
),
'value' => array(
'type' => 'String',
'description' => __('Meta value.', 'wp-graphql-woocommerce'),
'resolve' => function ($source) {
return !empty($source->value) ? $source->value : null;
},
),
'compare' => array(
'type' => array('non_null' => 'MetaDataCompareEnum'),
'description' => __('Comparison operator', 'loganstellway'),
'resolve' => function ($source) {
return !empty($source->compare) ? $source->compare : null;
},
),
),
)
);
}
/**
* Register meta query input type
*/
protected function registerMetaDataQueryInput()
{
register_graphql_input_type(
'MetaDataQueryInput',
[
'description' => __('Meta data query.', 'loganstellway'),
'fields' => [
'relation' => [
'type' => 'MetaQueryRelationEnum',
'description' => __('Relation type', 'loganstellway'),
],
'metaData' => [
'type' => ['list_of' => 'MetaDataInputArgs'],
'description' => __('Meta data.', 'loganstellway'),
],
],
]
);
}
/**
* Register meta query field
*/
protected function registerMetaQueryField()
{
$graphql_post_types = get_post_types(['show_in_graphql' => true]);
if (is_array($graphql_post_types)) {
foreach ($graphql_post_types as $post_type) {
$post_type_object = get_post_type_object($post_type);
register_graphql_field('RootQueryTo' . ucfirst($post_type_object->graphql_single_name) . 'ConnectionWhereArgs', 'metaQuery', [
'type' => 'MetaDataQueryInput',
'description' => __('Arguments for a meta query', 'loganstellway'),
]);
}
}
}
/**
* Initialize connection query args
*/
protected function initializeConnectionQueryArgs()
{
$connections = [
'graphql_wc_posts_connection_query_args',
'graphql_post_object_connection_query_args',
'graphql_product_connection_query_args',
];
foreach ($connections as $connection) {
add_filter($connection, function ($query_args, $source, $args, $context, $info) {
$where = $args['where'] ?? [];
$metaQuery = $where['metaQuery'] ?? [];
if ($metaQuery && isset($metaQuery['metaData']) && is_array($metaQuery['metaData'])) {
if (!isset($query_args['meta_query']) || !is_array($query_args['meta_query'])) {
$query_args['meta_query'] = [];
}
// Add the meta query
$query_args['meta_query'][] = [
'relation' => $metaQuery['relation'] ?? 'AND',
$metaQuery['metaData']
];
}
return $query_args;
}, 10, 5);
}
}
/**
* Initialize
*/
public function initialize()
{
/**
* Register types
*/
add_action('graphql_register_types', function () {
$this->registerMetaQueryRelationEnum();
$this->registerMetaDataCompareEnum();
$this->registerMetaDataInput();
$this->registerMetaDataQueryInput();
$this->registerMetaQueryField();
$this->initializeConnectionQueryArgs();
});
}
}
$registration = new MetaQueries();
$registration->initialize();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment