Last active
July 14, 2020 17:26
-
-
Save lstellway/175bbce8657734f23a1a86c724076d74 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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