Last active
June 8, 2023 21:46
-
-
Save drewbaker/600ed8cf0054d98ff70e54ecaa384c5c to your computer and use it in GitHub Desktop.
A custom WP JSON API SearchWP endpoint
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 | |
/* | |
* 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