Skip to content

Instantly share code, notes, and snippets.

@drewbaker
Last active June 8, 2023 21:46
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 drewbaker/600ed8cf0054d98ff70e54ecaa384c5c to your computer and use it in GitHub Desktop.
Save drewbaker/600ed8cf0054d98ff70e54ecaa384c5c to your computer and use it in GitHub Desktop.
A custom WP JSON API SearchWP endpoint
<?php
/*
* Register custom API endpoints
*
* NOTE: Will be accessable at: https://example.com/wp-json/fuxt/v1/search?term=Netflix&engine=work
*/
function add_fuxt_api_routes()
{
// Sitemap
register_rest_route("fuxt/v1", "/search", [
[
"methods" => "GET",
"callback" => "fuxt_search_get",
"args" => ["term", "engine", "page", "per_page"],
"permission_callback" => "__return_true",
],
]);
}
add_action("rest_api_init", "add_fuxt_api_routes");
/**
* GET an array of posts that match the search term
*
* @return array of Post objects
*/
function fuxt_search_get($request)
{
// Setup inputs
$term = $request->get_param("term") ?? "";
$engine = $request->get_param("engine") ?? "default";
$page = $request->get_param("page") ?? 1;
$per_page = $request->get_param("per_page") ?? -1;
// Our default SearchWP args
$search_args = [
"s" => $term,
"engine" => $engine,
"posts_per_page" => $per_page,
"page" => $page,
"fields" => "all",
];
// Example: Limit an engine to specific sub-pages of a page
/*
if ($engine == "our_work") {
$args = [
'post_type' => ['page'],
'post_parent__in' => [32], // Our Work
'fields' => 'ids',
'posts_per_page' => -1,
];
$page_ids = get_posts($args);
$search_args['post__in'] = $page_ids;
}
*/
// Do a new WP Search.
// SEE: https://searchwp.com/documentation/classes/swp_query/
$search = new SWP_Query($search_args);
$results = $search->get_posts();
// Build out post objects with any extra data needed
$posts = array_map(function ($post_obj) {
// Convert object to array for manipulation
$array = (array) $post_obj;
// Add data to reponse
$array["meta"] = get_fields($post_obj->ID);
$array["featured_image"] = custom_build_repsponsive_image(
get_post_thumbnail_id($post_obj->ID)
);
// Add data to mimic WP-GQL
$array["ID"] = "post-" . $post_obj->ID;
$array["database_id"] = $post_obj->ID;
$array["uri"] = wp_make_link_relative(get_permalink($post_obj->ID));
return camelCaseKeys($array);
}, $results);
return new WP_REST_Response($posts, 200);
}
/**
* Utility function to build an image in the same format <wp-image> expects it from WP-GQL
*
* @param int $attachment_id The WordPress attachment ID
* @param string $size The WordPress image size keyword
*/
function custom_build_repsponsive_image(
$attachment_id,
$size = "fullscreen-xlarge"
) {
$attachment = get_post($attachment_id);
$attachment_data = wp_get_attachment_image_src($attachment_id, $size);
$attachment_data_small = wp_get_attachment_image_src(
$attachment_id,
"fullscreen-small"
);
// Build image details array
$media_details = [
"height" => $attachment_data[2],
"width" => $attachment_data[1],
];
// Add ACF image meta data
$acf_image_meta = [
"videoUrl" => $attachment->videoUrl,
"primaryColor" => $attachment->primaryColor,
"focalPointY" => $attachment->focal_point_x,
"focalPointX" => $attachment->focal_point_y,
"blurhash" => $attachment->blurhash,
];
// Build base image data
$image = [
"sourceUrl" => $attachment_data[0],
"sizes" => wp_calculate_image_sizes(
$size,
$attachment_data[0],
null,
$attachment->ID
),
"srcSet" => wp_get_attachment_image_srcset($attachment->ID, $size),
"src" => $attachment_data_small[0],
"id" => "attachment-" . $attachment->ID,
"databaseId" => $attachment->ID,
"title" => $attachment->post_title,
"altText" => $attachment->_wp_attachment_image_alt,
"caption" => $attachment->post_excerpt,
"mediaDetails" => $media_details,
"imageMeta" => $acf_image_meta,
];
return $image;
}
/**
* Utility function to recursively camelCase all keys in an array
*/
function camelCaseKeys($array)
{
$finalArray = [];
foreach ($array as $key => $value):
// If key is all uppercase, make all lower case. ID => id
if ($key == strtoupper($key)) {
$key = strtolower($key);
}
// Remove post_ from all keys to match WP_GQL
$key = str_replace("post_", "", $key);
// Let's convert key into camelCase
if (strpos($key, "_")) {
$key = lcfirst(str_replace("_", "", ucwords($key, "_")));
}
// Recursive if key's value contains another array
if (is_array($value)) {
$finalArray[$key] = camelCaseKeys($value);
} else {
$finalArray[$key] = $value;
}
endforeach;
return $finalArray;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment