1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
class Jetpack_Search_Local_Endpoint { |
4
|
|
View Code Duplication |
public function register_routes() { |
5
|
|
|
register_rest_route( |
6
|
|
|
'jetpack/v4', |
7
|
|
|
'/search-local', |
8
|
|
|
array( |
9
|
|
|
array( |
10
|
|
|
'methods' => WP_REST_Server::READABLE, |
11
|
|
|
'callback' => array( $this, 'get_items' ), |
12
|
|
|
'permission_callback' => array( $this, 'get_items_permissions_check' ), |
13
|
|
|
'args' => $this->get_request_args(), |
14
|
|
|
), |
15
|
|
|
'schema' => array( $this, 'get_schema' ), |
16
|
|
|
) |
17
|
|
|
); |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
public function get_request_args() { |
21
|
|
|
return array( |
22
|
|
|
'context' => 'view', |
23
|
|
|
'size' => array( |
24
|
|
|
'type' => 'integer', |
25
|
|
|
'minimum' => 1, |
26
|
|
|
'maximum' => 20, |
27
|
|
|
'default' => 10, |
28
|
|
|
), |
29
|
|
|
'from' => array( |
30
|
|
|
'type' => 'integer', |
31
|
|
|
'minimum' => 0, |
32
|
|
|
'maximum' => 200, |
33
|
|
|
'default' => 0, |
34
|
|
|
), |
35
|
|
|
'fields' => array( |
36
|
|
|
'type' => 'array', |
37
|
|
|
'items' => array( |
38
|
|
|
'type' => 'string', |
39
|
|
|
), |
40
|
|
|
'default' => array( 'blog_id', 'post_id' ), |
41
|
|
|
), |
42
|
|
|
'highlight_fields' => array( |
43
|
|
|
'items' => array( |
44
|
|
|
'type' => 'string', |
45
|
|
|
), |
46
|
|
|
), |
47
|
|
|
'query' => array( |
48
|
|
|
'type' => 'string', |
49
|
|
|
'required' => true, |
50
|
|
|
), |
51
|
|
|
'sort' => array( |
52
|
|
|
'type' => 'string', |
53
|
|
|
'default' => 'score_default', |
54
|
|
|
'enum' => array( |
55
|
|
|
'score_default', |
56
|
|
|
'date_desc', |
57
|
|
|
'date_asc', |
58
|
|
|
), |
59
|
|
|
), |
60
|
|
|
'page_handle' => array( |
61
|
|
|
'type' => 'string', |
62
|
|
|
), |
63
|
|
|
); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
public function get_schema() { |
67
|
|
|
return array( |
68
|
|
|
'$schema' => 'http://json-schema.org/draft-04/schema#', |
69
|
|
|
'title' => 'search-local-result', |
70
|
|
|
'type' => 'object', |
71
|
|
|
'properties' => array( |
72
|
|
|
'aggregations' => array( |
73
|
|
|
'type' => 'array', |
74
|
|
|
'context' => array( 'view', 'edit' ), |
75
|
|
|
), |
76
|
|
|
'corrected_query' => array( |
77
|
|
|
'type' => array( 'string', 'boolean' ), |
78
|
|
|
'context' => array( 'view', 'edit' ), |
79
|
|
|
), |
80
|
|
|
'page_handle' => array( |
81
|
|
|
'type' => array( 'string', 'boolean' ), |
82
|
|
|
'context' => array( 'view', 'edit' ), |
83
|
|
|
), |
84
|
|
|
'results' => array( |
85
|
|
|
'type' => 'array', |
86
|
|
|
'items' => array( |
87
|
|
|
'type' => 'object', |
88
|
|
|
'properties' => array( |
89
|
|
|
'fields' => array( |
90
|
|
|
'type' => 'object', |
91
|
|
|
'properties' => array( |
92
|
|
|
'blog_id' => array( |
93
|
|
|
'type' => 'integer', |
94
|
|
|
), |
95
|
|
|
'post_id' => array( |
96
|
|
|
'type' => 'integer', |
97
|
|
|
), |
98
|
|
|
'date' => array( |
99
|
|
|
'type' => 'string', |
100
|
|
|
'format' => 'date-time', |
101
|
|
|
), |
102
|
|
|
'post_type' => array( |
103
|
|
|
'type' => 'string', |
104
|
|
|
), |
105
|
|
|
'permalink.url.raw' => array( |
106
|
|
|
'type' => 'string', |
107
|
|
|
), |
108
|
|
|
'has.image' => array( |
109
|
|
|
'type' => 'integer', |
110
|
|
|
), |
111
|
|
|
'category.name.default' => array( |
112
|
|
|
'type' => 'string', |
113
|
|
|
), |
114
|
|
|
), |
115
|
|
|
), |
116
|
|
|
'highlight' => array( |
117
|
|
|
'type' => 'object', |
118
|
|
|
'properties' => array( |
119
|
|
|
'content' => array( |
120
|
|
|
'type' => array( |
121
|
|
|
'items' => array( |
122
|
|
|
'type' => 'string', |
123
|
|
|
), |
124
|
|
|
), |
125
|
|
|
), |
126
|
|
|
'title' => array( |
127
|
|
|
'type' => array( |
128
|
|
|
'items' => array( |
129
|
|
|
'type' => 'string', |
130
|
|
|
), |
131
|
|
|
), |
132
|
|
|
), |
133
|
|
|
), |
134
|
|
|
), |
135
|
|
|
'railcar' => array( |
136
|
|
|
'type' => 'object', |
137
|
|
|
), |
138
|
|
|
'result_type' => array( |
139
|
|
|
'type' => 'string', |
140
|
|
|
), |
141
|
|
|
), |
142
|
|
|
), |
143
|
|
|
), |
144
|
|
|
'suggestions' => array( |
145
|
|
|
'type' => 'array', |
146
|
|
|
), |
147
|
|
|
'total' => array( |
148
|
|
|
'type' => 'integer', |
149
|
|
|
), |
150
|
|
|
), |
151
|
|
|
); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
public function get_items_permissions_check() { |
155
|
|
|
return Jetpack::is_development_mode() |
156
|
|
|
? true |
157
|
|
|
: new WP_Error( |
158
|
|
|
'development_mode_only', |
|
|
|
|
159
|
|
|
__( "This endpoint is meant only for local testing and is only available in Jetpack's Development Mode." ), |
160
|
|
|
array( |
161
|
|
|
'status' => 400, |
162
|
|
|
) |
163
|
|
|
); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
// @todo - page_handle |
167
|
|
|
// @todo - search comments |
168
|
|
|
public function get_items( $request ) { |
169
|
|
|
if ( 'score_default' === $request['sort'] ) { |
170
|
|
|
$orderby = 'relevance'; |
171
|
|
|
$order = 'DESC'; |
172
|
|
|
} else { |
173
|
|
|
$orderby = 'date'; |
174
|
|
|
$order = 'date_desc' === $request['sort'] ? 'DESC' : 'ASC'; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
$post_query = new WP_Query( array( |
178
|
|
|
'posts_per_page' => $request['size'], |
179
|
|
|
'offset' => $request['from'], |
180
|
|
|
'orderby' => $orderby, |
181
|
|
|
'order' => $order, |
182
|
|
|
's' => $request['query'], |
183
|
|
|
|
184
|
|
|
'fields' => 'ids', |
185
|
|
|
) ); |
186
|
|
|
|
187
|
|
|
$terms = preg_split( '/\\s+/', wp_kses( $request['query'], 'strip' ) ); |
188
|
|
|
|
189
|
|
|
$term_regex = '/(' . join( '|', array_map( function( $term ) { |
190
|
|
|
return preg_quote( $term, '/' ); |
191
|
|
|
}, $terms ) ) . ')/i'; |
192
|
|
|
|
193
|
|
|
$fields = $request['fields']; |
194
|
|
|
|
195
|
|
|
$results = array(); |
196
|
|
|
foreach ( $post_query->posts as $post_id ) { |
197
|
|
|
$result = $this->get_post_result( $post_id, $fields ); |
198
|
|
|
foreach ( $result['highlight'] as &$highlight ) { |
199
|
|
|
foreach ( $highlight as &$text ) { |
200
|
|
|
$text = preg_replace( $term_regex, '<mark>\\1</mark>', $text ); |
201
|
|
|
} |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
$results[] = $result; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
return array( |
208
|
|
|
'results' => $results, |
209
|
|
|
'total' => (int) $post_query->found_posts, |
210
|
|
|
|
211
|
|
|
// Unsupported |
212
|
|
|
'aggregations' => array(), |
213
|
|
|
'corrected_query' => false, |
214
|
|
|
'page_handle' => false, |
215
|
|
|
'suggestions' => array(), |
216
|
|
|
); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
// @todo has.image |
220
|
|
|
// @todo _score |
221
|
|
|
private function get_post_result( $post_id, $fields ) { |
222
|
|
|
$post = get_post( $post_id ); |
223
|
|
|
$blog_id = get_current_blog_id(); |
224
|
|
|
|
225
|
|
|
$return = array( |
226
|
|
|
'fields' => array(), |
227
|
|
|
'highlight' => array( |
228
|
|
|
'title' => array( |
229
|
|
|
// strip_tags() to remove HTML comments. |
230
|
|
|
strip_tags( wp_kses( $post->post_title, 'strip' ) ), |
231
|
|
|
), |
232
|
|
|
'content' => array( |
233
|
|
|
strip_tags( wp_kses( $post->post_content, 'strip' ) ), |
234
|
|
|
), |
235
|
|
|
), |
236
|
|
|
'railcar' => array(), |
237
|
|
|
'result_type' => 'post', |
238
|
|
|
'_score' => 1, |
239
|
|
|
); |
240
|
|
|
|
241
|
|
|
foreach ( $fields as $field ) { |
242
|
|
|
switch ( $field ) { |
243
|
|
|
case 'blog_id' : |
244
|
|
|
$return['fields'][ $field ] = (int) $blog_id; |
245
|
|
|
break; |
246
|
|
|
case 'post_id' : |
247
|
|
|
$return['fields'][ $field ] = (int) $post_id; |
248
|
|
|
break; |
249
|
|
|
case 'date' : |
250
|
|
|
$return['fields'][ $field ] = (string) $post->post_date; |
251
|
|
|
break; |
252
|
|
|
case 'post_type' : |
253
|
|
|
$return['fields'][ $field ] = (string) $post->post_type; |
254
|
|
|
break; |
255
|
|
|
case 'permalink.url.raw' : |
256
|
|
|
$return['fields'][ $field ] = (string) get_permalink( $post ); |
257
|
|
|
break; |
258
|
|
|
case 'has.image' : |
259
|
|
|
$return['fields'][ $field ] = (int) 0; |
260
|
|
|
break; |
261
|
|
|
case 'category.name.default' : |
262
|
|
|
$return['fields'][ $field ] = (string) get_the_category( $post )[0]->name; |
263
|
|
|
break; |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
return $return; |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.