Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 106
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
MultiSearchController
0.00% covered (danger)
0.00%
0 / 106
0.00% covered (danger)
0.00%
0 / 5
132
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
2
 get_multi_search_result
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
12
 get_tooltip_search_result
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
20
 check_permission
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace NewfoldLabs\WP\Module\HelpCenter;
4
5/**
6 * APIs for getting the result from the Type Sense (Multi Site search)
7 */
8class MultiSearchController extends \WP_REST_Controller {
9
10    /**
11     * The namespace of this controller's route.
12     *
13     * @var string
14     */
15    protected $namespace = 'newfold-multi-search/v1';
16
17    /**
18     * The base of this controller's route
19     *
20     * @var string
21     */
22    protected $rest_base = 'multi_search';
23
24    /**
25     * The API key for the multi-search service
26     *
27     * @var string
28     */
29    protected $api_key;
30
31    /**
32     * The endpoint for the multi-search service
33     *
34     * @var string
35     */
36    protected $endpoint;
37
38    /**
39     * Constructor to initialize the API key and endpoint
40     */
41    public function __construct() {
42        $this->api_key  = 'B9wvYIokTPPgXEM3isTqsxbDOva21igT';
43        $this->endpoint = 'https://search.hiive.cloud/multi_search?x-typesense-api-key=' . $this->api_key;
44    }
45
46    /**
47     * Register the routes for this objects of the controller
48     */
49    public function register_routes() {
50        register_rest_route(
51            $this->namespace,
52            '/' . $this->rest_base,
53            array(
54                array(
55                    'methods'             => \WP_REST_Server::CREATABLE,
56                    'callback'            => array( $this, 'get_multi_search_result' ),
57                    'args'                => array(
58                        'query' => array(
59                            'required' => true,
60                            'type'     => 'string',
61                        ),
62                    ),
63                    'permission_callback' => array( $this, 'check_permission' ),
64                ),
65            )
66        );
67
68        /**
69         * Register the routes for this objects of the controller
70         */
71        register_rest_route(
72            $this->namespace,
73            '/tooltip_search',
74            array(
75                array(
76                    'methods'             => \WP_REST_Server::CREATABLE,
77                    'callback'            => array( $this, 'get_tooltip_search_result' ),
78                    'args'                => array(
79                        'postId' => array(
80                            'required' => true,
81                            'type'     => 'string',
82                        ),
83                        'locale' => array(
84                            'required' => false,
85                            'type'     => 'string',
86                        ),
87                    ),
88                    'permission_callback' => array( $this, 'check_permission' ),
89                ),
90            )
91        );
92    }
93
94    /**
95     * Fetch the result from typesense
96     *
97     * @param \WP_REST_Request $request the REST request object
98     */
99    public function get_multi_search_result( \WP_REST_Request $request ) {
100        $brand = sanitize_text_field( $request->get_param( 'brand' ) );
101        $query = sanitize_text_field( $request->get_param( 'query' ) );
102
103        $params = array(
104            'searches' => array(
105                array(
106                    'q'                         => $query,
107                    'query_by'                  => 'post_title,post_content',
108                    'group_by'                  => 'post_title',
109                    'group_limit'               => 1,
110                    'sort_by'                   => '_text_match:desc,post_likes:desc',
111                    'filter_by'                 => 'post_category:=' . $brand,
112                    'prioritize_token_position' => true,
113                    'limit_hits'                => 3,
114                    'per_page'                  => 3,
115                    'highlight_full_fields'     => 'post_title,post_content',
116                    'collection'                => 'nfd_help_articles',
117                    'page'                      => 1,
118                ),
119            ),
120        );
121
122        $args = array(
123            'body'    => wp_json_encode( $params ),
124            'headers' => array(
125                'Content-Type'        => 'application/json',
126                'X-TYPESENSE-API-KEY' => $this->api_key,
127            ),
128        );
129
130        $response = wp_remote_post( $this->endpoint, $args );
131        if ( is_wp_error( $response ) ) {
132            return new \WP_Error( 'request_failed', __( 'The request failed', 'wp-module-help-center' ), array( 'status' => 500 ) );
133        }
134
135        $body = wp_remote_retrieve_body( $response );
136        $data = json_decode( $body, true );
137        if ( empty( $data ) ) {
138            return new \WP_Error( 'no_data', __( 'No data found', 'wp-module-help-center' ), array( 'status' => 404 ) );
139        }
140
141        return rest_ensure_response( $data );
142    }
143
144    /**
145     * Fetch the result from typesense
146     *
147     * @param \WP_REST_Request $request the REST request object
148     */
149    public function get_tooltip_search_result( \WP_REST_Request $request ) {
150        $postId = sanitize_text_field( $request->get_param( 'postId' ) );
151        $locale = get_user_locale();
152
153        $url = USER_INTERACTION_SERVICE_BASE . 'postContent/';
154
155        $args = array(
156            'method'  => 'POST',
157            'headers' => array(
158                'Content-Type' => 'application/json',
159            ),
160            'timeout' => 60,
161            'body'    => wp_json_encode(
162                array(
163                    'postId' => $postId,
164                    'locale' => $locale,
165                )
166            ),
167        );
168
169        $response = wp_remote_post( $url, $args );
170        if ( is_wp_error( $response ) ) {
171            return new \WP_Error( 'request_failed', __( 'The request failed', 'wp-module-help-center' ), array( 'status' => 500 ) );
172        }
173
174        $body = wp_remote_retrieve_body( $response );
175        $data = json_decode( $body, true );
176        if ( isset( $data['data']['status'] ) && 404 === $data['data']['status'] ) {
177            return new \WP_Error( 'no_data', __( 'No data found', 'wp-module-help-center' ), array( 'status' => 404 ) );
178        }
179
180        return rest_ensure_response( $data );
181    }
182
183    /**
184     * Check permissions for routes.
185     *
186     * @return \WP_Error|boolean
187     */
188    public function check_permission() {
189        if ( ! current_user_can( 'manage_options' ) ) {
190            return new \WP_Error(
191                'rest_forbidden',
192                __( 'You must be authenticated to make this call', 'wp-module-help-center' ),
193                array( 'status' => 401 )
194            );
195        }
196        return true;
197    }
198}