PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.0.0
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.0.0
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 47 releases
content-control / classes / RestAPI / ObjectSearch.php

ObjectSearch.php in Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More 2.0.0, at classes/RestAPI/ObjectSearch.php

428 lines 10.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * RestAPI Global Settings Endpoint.
4 *
5 * @copyright (c) 2021, Code Atlantic LLC.
6 * @package ContentControl
7 */
8
9 namespace ContentControl\RestAPI;
10
11 use WP_User_Query, WP_Rest_Controller, WP_REST_Response, WP_REST_Server, WP_Error;
12
13 defined( 'ABSPATH' ) || exit;
14
15 /**
16 * Rest API Object Search Controller Class.
17 */
18 class ObjectSearch extends WP_REST_Controller {
19
20 /**
21 * Endpoint namespace.
22 *
23 * @var string
24 */
25 protected $namespace = 'content-control/v2';
26
27 /**
28 * Route base.
29 *
30 * @var string
31 */
32 protected $base = 'objectSearch';
33
34 /**
35 * Register API endpoint routes.
36 */
37 public function register_routes() {
38 register_rest_route(
39 $this->namespace,
40 '/' . $this->base,
41 [
42 [
43 'methods' => WP_REST_Server::READABLE,
44 'callback' => [ $this, 'object_search' ],
45 'permission_callback' => '__return_true', // Read only, so anyone can view.
46 'args' => [
47 'nonce' => [
48 'description' => __( 'Nonce', 'content-control' ),
49 'type' => 'string',
50 'required' => true,
51 ],
52 'hash' => [
53 'description' => __( 'Hash', 'content-control' ),
54 'type' => 'string',
55 'required' => true,
56 ],
57 'entityKind' => [
58 'description' => __( 'Object kind, (postType, taxonomy)', 'content-control' ),
59 'type' => 'string',
60 'required' => true,
61 ],
62 'entityType' => [
63 'description' => __( 'Object type (post, category)', 'content-control' ),
64 'type' => 'string',
65 'required' => true,
66 ],
67 'paged' => [
68 'description' => __( 'Page number', 'content-control' ),
69 'type' => 'integer',
70 'required' => false,
71 ],
72 's' => [
73 'description' => __( 'Search term', 'content-control' ),
74 'type' => 'string',
75 'required' => false,
76 ],
77 'include' => [
78 'description' => __( 'Include IDs', 'content-control' ),
79 'type' => 'string',
80 'required' => false,
81 ],
82 'exclude' => [
83 'description' => __( 'Exclude IDs', 'content-control' ),
84 'type' => 'string',
85 'required' => false,
86 ],
87 ],
88 ],
89 ]
90 );
91 }
92
93 /**
94 * Get block type list.
95 *
96 * @param \WP_REST_Request $request Request object.
97 *
98 * @return WP_Error|WP_REST_Response
99 */
100 public function object_search( $request ) {
101 $nonce = $request->get_param( 'nonce' );
102 $params = $request->get_params();
103
104 if ( ! isset( $nonce ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $nonce ) ), 'content_control_object_search_nonce' ) ) {
105 wp_send_json_error();
106 }
107
108 $results = [
109 'hash' => $request->get_param( 'hash' ),
110 'items' => [],
111 'totalCount' => 0,
112 ];
113
114 $object_kind = isset( $params['entityKind'] ) ? sanitize_text_field( wp_unslash( $params['entityKind'] ) ) : '';
115 $object_type = isset( $params['entityType'] ) ? sanitize_text_field( wp_unslash( $params['entityType'] ) ) : '';
116 $include = ! empty( $params['include'] ) ? wp_parse_id_list( wp_unslash( $params['include'] ) ) : [];
117 $exclude = ! empty( $params['exclude'] ) ? wp_parse_id_list( wp_unslash( $params['exclude'] ) ) : [];
118
119 if ( ! empty( $include ) ) {
120 $exclude = array_merge( $include, $exclude );
121 }
122
123 switch ( $object_kind ) {
124 case 'post_type':
125 $post_type = ! empty( $object_type ) ? $object_type : 'post';
126
127 if ( ! empty( $include ) ) {
128 $include_query = $this->post_type_selectlist_query(
129 $post_type,
130 [
131 'post__in' => $include,
132 'posts_per_page' => - 1,
133 ],
134 true
135 );
136
137 foreach ( $include_query['items'] as $id => $name ) {
138 $results['items'][] = [
139 'id' => $id,
140 'text' => "$name (ID: $id)",
141 ];
142 }
143
144 $results['totalCount'] += (int) $include_query['totalCount'];
145 }
146
147 $query = $this->post_type_selectlist_query(
148 $post_type,
149 [
150 's' => ! empty( $params['s'] ) ? sanitize_text_field( wp_unslash( $params['s'] ) ) : null,
151 'paged' => ! empty( $params['paged'] ) ? absint( $params['paged'] ) : null,
152 'post__not_in' => $exclude,
153 'posts_per_page' => 10,
154 ],
155 true
156 );
157
158 foreach ( $query['items'] as $id => $name ) {
159 $results['items'][] = [
160 'id' => $id,
161 'text' => "$name (ID: $id)",
162 ];
163 }
164
165 $results['totalCount'] += (int) $query['totalCount'];
166 break;
167
168 case 'taxonomy':
169 $taxonomy = ! empty( $params['object_key'] ) ? sanitize_text_field( wp_unslash( $params['object_key'] ) ) : 'category';
170
171 if ( ! empty( $include ) ) {
172 $include_query = $this->taxonomy_selectlist_query(
173 $taxonomy,
174 [
175 'include' => $include,
176 'number' => 0,
177 ],
178 true
179 );
180
181 foreach ( $include_query['items'] as $id => $name ) {
182 $results['items'][] = [
183 'id' => $id,
184 'text' => "$name (ID: $id)",
185 ];
186 }
187
188 $results['totalCount'] += (int) $include_query['totalCount'];
189 }
190
191 $query = $this->taxonomy_selectlist_query(
192 $taxonomy,
193 [
194 'search' => ! empty( $params['s'] ) ? sanitize_text_field( wp_unslash( $params['s'] ) ) : null,
195 'paged' => ! empty( $params['paged'] ) ? absint( $params['paged'] ) : null,
196 'exclude' => $exclude,
197 'number' => 10,
198 ],
199 true
200 );
201
202 foreach ( $query['items'] as $id => $name ) {
203 $results['items'][] = [
204 'id' => $id,
205 'text' => "$name (ID: $id)",
206 ];
207 }
208
209 $results['totalCount'] += (int) $query['totalCount'];
210 break;
211 case 'user':
212 if ( ! current_user_can( 'list_users' ) ) {
213 wp_send_json_error();
214 }
215
216 $user_role = ! empty( $params['object_key'] ) ? sanitize_text_field( wp_unslash( $params['object_key'] ) ) : null;
217
218 if ( ! empty( $include ) ) {
219 $include_query = $this->user_selectlist_query(
220 [
221 'role' => $user_role,
222 'include' => $include,
223 'number' => - 1,
224 ],
225 true
226 );
227
228 foreach ( $include_query['items'] as $id => $name ) {
229 $results['items'][] = [
230 'id' => $id,
231 'text' => "$name (ID: $id)",
232 ];
233 }
234
235 $results['totalCount'] += (int) $include_query['totalCount'];
236 }
237
238 $query = $this->user_selectlist_query(
239 [
240 'role' => $user_role,
241 'search' => ! empty( $params['s'] ) ? '*' . sanitize_text_field( wp_unslash( $params['s'] ) ) . '*' : null,
242 'paged' => ! empty( $params['paged'] ) ? absint( $params['paged'] ) : null,
243 'exclude' => $exclude,
244 'number' => 10,
245 ],
246 true
247 );
248
249 foreach ( $query['items'] as $id => $name ) {
250 $results['items'][] = [
251 'id' => $id,
252 'text' => "$name (ID: $id)",
253 ];
254 }
255
256 $results['totalCount'] += (int) $query['totalCount'];
257 break;
258 }
259
260 // Take out keys which were only used to deduplicate.
261 $results['items'] = array_values( $results['items'] );
262
263 if ( $results ) {
264 return new WP_REST_Response( $results, 200 );
265 } else {
266 return new WP_Error( '404', __( 'Something went wrong, the results could not be returned.', 'content-control' ), [ 'status' => 404 ] );
267 }
268 }
269
270
271 /**
272 * Get a list of posts for a select list.
273 *
274 * @param array $post_type Post type(s) to query.
275 * @param array $args Query arguments.
276 * @param boolean $include_total Whether to include the total count in the response.
277 * @return array
278 */
279 public function post_type_selectlist_query( $post_type = [], $args = [], $include_total = false ) {
280 if ( empty( $post_type ) ) {
281 $post_type = [ 'any' ];
282 }
283
284 $args = wp_parse_args( $args, [
285 'posts_per_page' => 10,
286 'post_type' => $post_type,
287 'post__in' => null,
288 'post__not_in' => null,
289 'post_status' => null,
290 'page' => 1,
291 // Performance Optimization.
292 'no_found_rows' => ! $include_total ? true : false,
293 'update_post_term_cache' => false,
294 'update_post_meta_cache' => false,
295 ] );
296
297 if ( 'attachment' === $post_type ) {
298 $args['post_status'] = 'inherit';
299 }
300
301 // Query Caching.
302 static $queries = [];
303
304 $key = md5( maybe_serialize( $args ) );
305
306 if ( ! isset( $queries[ $key ] ) ) {
307 $query = new \WP_Query( $args );
308
309 $posts = [];
310 foreach ( $query->posts as $post ) {
311 $posts[ $post->ID ] = $post->post_title;
312 }
313
314 $results = [
315 'items' => $posts,
316 'totalCount' => $query->found_posts,
317 ];
318
319 $queries[ $key ] = $results;
320 } else {
321 $results = $queries[ $key ];
322 }
323
324 return ! $include_total ? $results['items'] : $results;
325 }
326
327 /**
328 * Get a list of terms for a select list.
329 *
330 * @param array $taxonomies Taxonomy(s) to query.
331 * @param array $args Query arguments.
332 * @param boolean $include_total Whether to include the total count in the response.
333 * @return array
334 */
335 public function taxonomy_selectlist_query( $taxonomies = [], $args = [], $include_total = false ) {
336 if ( empty( $taxonomies ) ) {
337 $taxonomies = [ 'category' ];
338 }
339
340 $args = wp_parse_args( $args, [
341 'hide_empty' => false,
342 'number' => 10,
343 'search' => '',
344 'include' => null,
345 'exclude' => null,
346 'offset' => 0,
347 'page' => null,
348 'taxonomy' => $taxonomies,
349 ] );
350
351 if ( $args['page'] ) {
352 $args['offset'] = ( $args['page'] - 1 ) * $args['number'];
353 }
354
355 // Query Caching.
356 static $queries = [];
357
358 $key = md5( maybe_serialize( $args ) );
359
360 if ( ! isset( $queries[ $key ] ) ) {
361 $terms = [];
362
363 foreach ( get_terms( $args ) as $term ) {
364 $terms[ $term->term_id ] = $term->name;
365 }
366
367 $total_args = $args;
368 $total_args['fields'] = 'count';
369 unset( $total_args['number'] );
370 unset( $total_args['offset'] );
371
372 $results = [
373 'items' => $terms,
374 'totalCount' => $include_total ? get_terms( $total_args ) : null,
375 ];
376
377 $queries[ $key ] = $results;
378 } else {
379 $results = $queries[ $key ];
380 }
381
382 return ! $include_total ? $results['items'] : $results;
383 }
384
385 /**
386 * Get a list of users for a select list.
387 *
388 * @param array $args Query arguments.
389 * @param bool $include_total Whether to include the total count in the response.
390 *
391 * @return array|mixed
392 */
393 public function user_selectlist_query( $args = [], $include_total = false ) {
394 $args = wp_parse_args(
395 $args,
396 [
397 'role' => null,
398 'count_total' => ! $include_total ? true : false,
399 ]
400 );
401
402 // Query Caching.
403 static $queries = [];
404
405 $key = md5( maybe_serialize( $args ) );
406
407 if ( ! isset( $queries[ $key ] ) ) {
408 $query = new WP_User_Query( $args );
409
410 $users = [];
411 foreach ( $query->get_results() as $user ) {
412 $users[ $user->ID ] = $user->display_name;
413 }
414
415 $results = [
416 'items' => $users,
417 'totalCount' => $query->get_total(),
418 ];
419
420 $queries[ $key ] = $results;
421 } else {
422 $results = $queries[ $key ];
423 }
424
425 return ! $include_total ? $results['items'] : $results;
426 }
427 }
428