Skip to content

Instantly share code, notes, and snippets.

@msaari
Last active June 20, 2023 13:47
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msaari/fe2da6a584f690a213db733d596b0030 to your computer and use it in GitHub Desktop.
Save msaari/fe2da6a584f690a213db733d596b0030 to your computer and use it in GitHub Desktop.
Relevanssi REST API endpoint
<?php
/**
* Plugin Name: Relevanssi REST API Endpoint
* Description: Adds REST API Endpoint for Relevanssi queries
* Author: Aucor Oy
* Author URI: https://www.aucor.fi/
* Version: 1.0
* License: GPL2+
*
* Usage: /wp-json/relevanssi/v1/search?s=query
* /wp-json/relevanssi/v1/search?s=query&posts_per_page=5
**/
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
add_action( 'rest_api_init', 'relevanssi_rest_api_filter_add_filters' );
// Add filter to posts
function relevanssi_rest_api_filter_add_filters() {
// Register new route for search queries
register_rest_route( 'relevanssi/v1', 'search', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'relevanssi_search_route_callback',
'permission_callback' => '__return_true',
) );
}
/**
* Generate results for the /wp-json/relevanssi/v1/search route.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return WP_REST_Response|WP_Error The response for the request.
*/
function relevanssi_search_route_callback( WP_REST_Request $request ) {
$parameters = $request->get_query_params();
// Force the posts_per_page to be no more than 10
if ( isset( $parameters['posts_per_page'] ) && ( (int) $parameters['posts_per_page'] >= 1 && (int) $filter['posts_per_page'] <= 10 ) ) {
$posts_per_page = intval( $parameters['posts_per_page'] );
} else {
$posts_per_page = 10;
}
// default search args
$args = array(
's' => $parameters['s'],
'posts_per_page' => $posts_per_page,
);
// run query
$search_query = new WP_Query();
$search_query->parse_query( $args );
if ( function_exists( 'relevanssi_do_query' ) ) {
relevanssi_do_query( $search_query );
}
$controller = new WP_REST_Posts_Controller('post');
$posts = array();
while ( $search_query->have_posts() ) : $search_query->the_post();
$data = $controller->prepare_item_for_response( $search_query->post, $request );
$posts[] = $controller->prepare_response_for_collection( $data );
endwhile;
// return results
if( ! empty( $posts ) ) {
return new WP_REST_Response( $posts, 200 );
} else {
return new WP_Error( 'No results', 'Nothing found' );
}
}
Copy link

ghost commented Aug 26, 2020

Where should this file be located in the wordpress code structure?

@msaari
Copy link
Author

msaari commented Aug 26, 2020

It's best implemented as a separate plugin, but can also be added to your theme, in the functions.php file for example.

Copy link

ghost commented Aug 26, 2020 via email

@scotth527
Copy link

hey this has been really helpful! just wondering is there a way to get the total page count for the results?

@msaari
Copy link
Author

msaari commented May 10, 2022 via email

@WilhelmHjelm
Copy link

WilhelmHjelm commented May 30, 2022

You just need this to ensure the standard search route uses relevanssi:

 add_filter('rest_post_search_query', function ($args, $request){
    $args['relevanssi'] = true;
    //you can even add this
    $args['relevanssi_log_queries'] = true;

    return $args;
 }, 10, 2);

Then you can do:
.../wp-json/wp/v2/search?search=searchstring

@SourabhChakraborty
Copy link

Do you know how I could add the values from the Advanced Custom Fields associated with each post to the post data?

@msaari
Copy link
Author

msaari commented Jun 16, 2023

I don't know exactly, but there's the loop where $data = $controller->prepare_item_for_response( $search_query->post, $request ); is done for each post; I suppose you can add the ACF values to $data there.

@WilhelmHjelm
Copy link

WilhelmHjelm commented Jun 16, 2023

Do you know how I could add the values from the Advanced Custom Fields associated with each post to the post data?

You can use the register_rest_field to add values to a WordPress endpoint. This needs to be added to the rest_api_init action. To add ACF-fields to a search result:

add_action('rest_api_init', function () {    
   register_rest_field(
        'search-result', 
        'acf', 
        array(
            'get_callback' => function ($data) {
                return get_fields($data['id']);;
            },
            'schema' => array(
                'type' => 'object', // the type of value we expect to be passed back
            )
        )
    );
}

@SourabhChakraborty
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment