"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 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; }