Skip to content

Instantly share code, notes, and snippets.

@lightningspirit
Last active June 22, 2022 18:50
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 lightningspirit/45b63ab7baa5bf076f2f2be5da400431 to your computer and use it in GitHub Desktop.
Save lightningspirit/45b63ab7baa5bf076f2f2be5da400431 to your computer and use it in GitHub Desktop.
WPGraphQL search by field with regular expressions support

WPGraphQL search by field with regular expressions support

Adds a where field to WPGraphQL content nodes (post, page and custom post types) to search by field using regexp or like. Supported fields are name, title, author, excerpt, status and mime_type.

Usage

  1. Install WPGraphQL
  2. Download or copy the wpgraphql-search-field.php file
  3. Place it under wp-content/mu-plugins
  4. Done
<?php
/**
* Plugin Name: WPGraphQL Search by Field
* Plugin URI: https://gist.github.com/lightningspirit/45b63ab7baa5bf076f2f2be5da400431
* Author: Move Your Digital, Inc.
* Author URI: https://moveyourdigital.com
* Version: 0.1.0
*
* @package WPGraphQL_Search_By_Field
*/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
use WPGraphQL\Registry\TypeRegistry;
/**
*
*/
add_action('graphql_register_types', function (TypeRegistry $registry) {
register_graphql_enum_type('SearchFieldFieldsEnum', [
'description' => __('Search field available fields', 'wp-graphql'),
'values' => [
'NAME' => [
'value' => 'name',
],
'TITLE' => [
'value' => 'title',
],
'AUTHOR' => [
'value' => 'author',
],
'EXCERPT' => [
'value' => 'excerpt',
],
'STATUS' => [
'value' => 'status',
],
'MIME_TYPE' => [
'value' => 'mime_type',
],
]
]);
register_graphql_enum_type('SearchFieldOperatorEnum', [
'description' => __('Search field available operators', 'wp-graphql'),
'values' => [
'LIKE' => [
'value' => 'like',
],
'REGEXP' => [
'description' => __('Only available for MySQL 5.6+', 'wp-graphql'),
'value' => 'regexp',
],
]
]);
register_graphql_input_type('SearchFieldInput', [
'description' => __('Search field input options', 'wp-graphql'),
'fields' => [
'field' => [
'description' => __('The field to search in', 'wp-graphql'),
'type' => [
'non_null' => 'SearchFieldFieldsEnum',
]
],
'operator' => [
'description' => __('The search operator', 'wp-graphql'),
'type' => 'SearchFieldOperatorEnum'
],
'search' => [
'description' => __('The search term', 'wp-graphql'),
'type' => 'String',
]
]
]);
$args = [
'searchField' => [
'description' => __('Filter by search of one field', 'wp-graphql'),
'type' => 'SearchFieldInput',
],
];
register_graphql_fields(
"RootQueryToContentNodeConnectionWhereArgs",
$args
);
foreach (\WPGraphQL::get_allowed_post_types() as $post_type) {
$post_type = get_post_type_object($post_type);
$type = ucfirst($post_type->graphql_single_name);
register_graphql_fields(
"RootQueryTo${type}ConnectionWhereArgs",
$args
);
}
});
/**
*
*/
add_filter('graphql_post_object_connection_query_args', function (
$query_args, $_, $args
) {
$isset_search_field = isset($args['where']['searchField']);
if ($isset_search_field) {
$query_args['search_field'] = $args['where']['searchField'];
}
return $query_args;
}, 10, 3);
/**
* Since core query cannot search in one field,
* we need to hack the posts_where filter and
* generate our own SQL
*/
add_filter('posts_where', function ($where, $query) {
global $wpdb;
$search_field = $query->get('search_field');
if ($search_field) {
$field = esc_sql($search_field['field']);
$search = esc_sql($search_field['search']);
switch ($search_field['operator']) {
case 'regexp':
$operator = 'REGEXP';
break;
case 'like':
default:
$operator = 'LIKE';
if (empty($search)) {
$search = '%';
}
}
$where .= " AND $wpdb->posts.post_$field $operator '$search'";
}
return $where;
}, 10, 2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment