PluginProbe
Meow Gallery / 5.5.2
Meow Gallery v5.5.2
5.5.4 5.5.3 5.5.2 5.5.1 5.5.0 5.4.9 5.4.8 5.4.7 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 All 156 releases
meow-gallery / classes / rest.php

rest.php in Meow Gallery 5.5.2, at classes/rest.php

681 lines 21.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Meow_MGL_Rest
4 {
5 private $core;
6 private $namespace = 'meow-gallery/v1';
7
8 public function __construct( $core ) {
9 $this->core = $core;
10
11 // FOR DEBUG
12 // For experiencing the UI behavior on a slower install.
13 // sleep( 1 );
14 // For experiencing the UI behavior on a buggy install.
15 // trigger_error( "Error", E_USER_ERROR );
16 // trigger_error( "Warning", E_USER_WARNING );
17 // trigger_error( "Notice", E_USER_NOTICE );
18 // trigger_error( "Deprecated", E_USER_DEPRECATED );
19
20 add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
21 }
22
23
24 function rest_api_init( ) {
25
26 // Settings
27 register_rest_route( $this->namespace, '/update_option/', array(
28 'methods' => 'POST',
29 'permission_callback' => array( $this->core, 'can_access_settings' ),
30 'callback' => array( $this, 'rest_update_option' )
31 ) );
32 register_rest_route( $this->namespace, '/all_settings/', array(
33 'methods' => 'GET',
34 'permission_callback' => array( $this->core, 'can_access_settings' ),
35 'callback' => array( $this, 'rest_all_settings' )
36 ) );
37 register_rest_route( $this->namespace, '/reset_options', array(
38 'methods' => 'POST',
39 'permission_callback' => array( $this->core, 'can_access_settings' ),
40 'callback' => array( $this, 'rest_reset_options' )
41 ) );
42
43
44 // Gallery Manager
45 register_rest_route( $this->namespace, '/latest_photos', array(
46 'methods' => 'GET',
47 'permission_callback' => array( $this->core, 'can_access_settings' ),
48 'callback' => array( $this, 'rest_latest_photos' ),
49 'args' => array(
50 'search' => array( 'required' => false ),
51 'offset' => array( 'required' => false, 'default' => 0 ),
52 'except' => array( 'required' => false ),
53 )
54 ) );
55 register_rest_route( $this->namespace, '/save_shortcode', array(
56 'methods' => 'POST',
57 'permission_callback' => array( $this->core, 'can_access_settings' ),
58 'callback' => array( $this, 'rest_save_shortcode' ),
59 ) );
60 register_rest_route( $this->namespace, '/remove_shortcode', array(
61 'methods' => 'POST',
62 'permission_callback' => array( $this->core, 'can_access_settings' ),
63 'callback' => array( $this, 'rest_remove_shortcode' ),
64 ) );
65 register_rest_route( $this->namespace, '/update_gallery_rank', array(
66 'methods' => 'POST',
67 'permission_callback' => array( $this->core, 'can_access_settings' ),
68 'callback' => array( $this, 'rest_update_gallery_rank' ),
69 ) );
70 register_rest_route( $this->namespace, '/rml_folders', array(
71 'methods' => 'GET',
72 'permission_callback' => array( $this->core, 'can_access_settings' ),
73 'callback' => array( $this, 'rest_rml_folders' ),
74 ) );
75
76
77 register_rest_route( $this->namespace, '/fetch_shortcodes', array(
78 'methods' => 'POST',
79 'permission_callback' => array( $this->core, 'can_access_features' ),
80 'callback' => array( $this, 'rest_fetch_shortcodes' ),
81 ) );
82 register_rest_route( $this->namespace, '/fetch_gallery_items', array(
83 'methods' => 'POST',
84 'permission_callback' => array( $this->core, 'can_access_features' ),
85 'callback' => array( $this, 'rest_fetch_gallery_items' ),
86 ) );
87
88
89
90 //Collection Manager
91 register_rest_route( $this->namespace, '/save_collection', array(
92 'methods' => 'POST',
93 'permission_callback' => array( $this->core, 'can_access_settings' ),
94 'callback' => array( $this, 'rest_save_collection' ),
95 ) );
96 register_rest_route( $this->namespace, '/remove_collection', array(
97 'methods' => 'POST',
98 'permission_callback' => array( $this->core, 'can_access_settings' ),
99 'callback' => array( $this, 'rest_remove_collection' ),
100 ) );
101
102 register_rest_route( $this->namespace, '/fetch_collections', array(
103 'methods' => 'POST',
104 'permission_callback' => array( $this->core, 'can_access_features' ),
105 'callback' => array( $this, 'rest_fetch_collections' ),
106 ) );
107
108 register_rest_route( $this->namespace, '/load_gallery_collection', array(
109 'methods' => 'POST',
110 'permission_callback' => '__return_true',
111 'callback' => array( $this, 'rest_load_gallery_collection' ),
112 ) );
113
114 // Gutenberg Block
115 register_rest_route( $this->namespace, '/preview', array(
116 'methods' => 'POST',
117 'permission_callback' => array( $this->core, 'can_access_features' ),
118 'callback' => array( $this, 'preview' ),
119 ) );
120
121 // Gallery
122 register_rest_route( $this->namespace, '/images/', array(
123 'methods' => 'POST',
124 'permission_callback' => '__return_true',
125 'callback' => array( $this, 'rest_images' )
126 ) );
127
128 register_rest_route( $this->namespace, '/fetch_posts', array(
129 'methods' => 'POST',
130 'permission_callback' => array( $this->core, 'can_access_features' ),
131 'callback' => array( $this, 'rest_fetch_posts' ),
132 'args' => array(
133 'search' => array( 'required' => false ),
134 'offset' => array( 'required' => false, 'default' => 0 ),
135 'limit' => array( 'required' => false, 'default' => 10 ),
136 )
137 ) );
138 }
139
140 function preview( WP_REST_Request $request ) {
141 $params = $request->get_body( );
142 $params = json_decode( $params );
143 $params->ids = implode( ',', $params->ids );
144 $atts = ( array ) $params;
145
146 $is_collection = isset( $atts['collection'] ) && !empty( $atts['collection'] );
147 if ( $is_collection ) {
148 $html = do_shortcode( '[meow-collection id="' . $atts['collection'] . '"]' );
149 } else {
150 $html = $this->core->gallery( $atts, [ 'isPreview' => true ] );
151 }
152
153
154 return new WP_REST_Response( [ 'success' => true, 'data' => $html ], 200 );
155 }
156
157 function rest_load_gallery_collection( $request ) {
158 try {
159 $params = $request->get_json_params( );
160 $gallery_id = $params['id'];
161 $search_slug = $params['search_slug'];
162 $gallery_atts = $params['gallery_atts'];
163
164 $key = [
165 'gallery_id' => 'id',
166 'wplr_collection_id' => 'wplr-collection',
167 'rml' => 'rml',
168 ];
169
170 $shortcode_atts = array();
171 $shortcode_atts[ $key[$search_slug] ] = $gallery_id;
172 $shortcode_atts = [...$shortcode_atts, ...$gallery_atts];
173
174 $html = $this->core->gallery( $shortcode_atts, [ 'isPreview' => false, 'isRest' => true ] );
175 $mwlData = json_encode( $this->core->get_rewritten_mwl_data( ) );
176 return new WP_REST_Response( [ 'success' => true, 'data' => $html, 'mwl_data' => $mwlData ], 200 );
177 }
178 catch ( Exception $e ) {
179 return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage( ) ], 500 );
180 }
181 }
182
183 function rest_all_settings( ) {
184 return new WP_REST_Response( [ 'success' => true, 'data' => $this->core->get_all_options( ) ], 200 );
185 }
186
187 function rest_rml_folders( ) {
188 if ( ! Meow_MGL_RML::is_available() ) {
189 return new WP_REST_Response( [ 'success' => true, 'available' => false, 'data' => [] ], 200 );
190 }
191 return new WP_REST_Response( [ 'success' => true, 'available' => true, 'data' => Meow_MGL_RML::get_all_folders() ], 200 );
192 }
193
194 function rest_reset_options( ) {
195 $this->core->reset_options( );
196 return new WP_REST_Response( [ 'success' => true, 'options' => $this->core->get_all_options( ) ], 200 );
197 }
198
199 function rest_save_shortcode( $request ) {
200 try {
201 global $wpdb;
202 $params = $request->get_json_params( );
203
204 $id = $params['id'];
205 $medias = $params['medias'];
206 $name = $params['name'];
207 $layout = $params['layout'];
208 $description = $params['description'];
209 $posts = $params['posts'];
210 $latest_posts = $params['latest_posts'];
211 $tags = $params['tags'];
212 $dynamic_source = $params['dynamic_source'];
213 $lead_image_id = $params['lead_image_id'];
214 $order_by = $params['order_by'];
215 $is_post_mode = $params['is_post_mode'];
216 $is_hero_mode = $params['is_hero_mode'];
217 $rml = $params['rml'] ?? null;
218
219 if ( !$name ) {
220 throw new Exception( __( 'Please enter a name for your shortcode.', MGL_DOMAIN ));
221 }
222
223 if ( !$is_post_mode && ( !$medias || !count( $medias['thumbnail_ids'] )) ) {
224 throw new Exception( __( 'Please select at least one image.', MGL_DOMAIN ));
225 }
226
227 if ( $is_post_mode && $dynamic_source === 'posts' && ( !$posts && !$latest_posts )) {
228 throw new Exception( __( 'Please select at least one post.', MGL_DOMAIN ));
229 }
230
231 if ( $is_post_mode && $dynamic_source === 'tags' && !$tags ) {
232 throw new Exception( __( 'Please enter at least one tag.', MGL_DOMAIN ));
233 }
234
235 if ( $is_post_mode && $dynamic_source === 'rml' && empty( $rml ) ) {
236 throw new Exception( __( 'Please select a Real Media Library folder.', MGL_DOMAIN ));
237 }
238
239 if ( $is_hero_mode && !$is_post_mode ) {
240 throw new Exception( __( 'Hero mode is only available for post mode.', MGL_DOMAIN ));
241 }
242
243 if ( !$id || $id == '' ) {
244 $id = $this->core->generate_uniqid( 10 );
245 }
246
247 $shortcodes_table = $wpdb->prefix . 'mgl_gallery_shortcodes';
248 Meow_MGL_Migrations::check_db();
249
250 // Check if the record exists
251 $exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( * ) FROM $shortcodes_table WHERE id = %s", $id ));
252
253 $data = [
254 'name' => $name,
255 'description' => $description,
256 'layout' => $layout,
257 'medias' => serialize( $medias ),
258 'lead_image_id' => $lead_image_id,
259 'order_by' => $order_by,
260 'is_post_mode' => $is_post_mode ? 1 : 0,
261 'is_hero_mode' => $is_hero_mode ? 1 : 0,
262 'posts' => $posts ? serialize( $posts ) : null,
263 'latest_posts' => $latest_posts,
264 'tags' => serialize( $tags ),
265 'dynamic_source' => $dynamic_source,
266 'rml' => $rml
267 ];
268
269 if ( $exists ) {
270 // Update existing record
271 $wpdb->update(
272 $shortcodes_table,
273 $data,
274 ['id' => $id]
275 );
276 } else {
277 // Insert new record
278 $data['id'] = $id;
279 $wpdb->insert( $shortcodes_table, $data );
280 }
281
282
283 return new WP_REST_Response( ['success' => true, 'message' => 'Shortcode created.'], 200 );
284 } catch ( Exception $e ) {
285 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
286 }
287 }
288
289 function rest_remove_collection( $request ) {
290 try {
291 global $wpdb;
292 $params = $request->get_json_params( );
293 $id = $params['id'];
294
295 $collections_table = $wpdb->prefix . 'mgl_collections';
296 Meow_MGL_Migrations::check_db();
297
298 $wpdb->delete( $collections_table, ['id' => $id] );
299
300
301 return new WP_REST_Response( ['success' => true, 'message' => 'Collection removed.'], 200 );
302 } catch ( Exception $e ) {
303 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
304 }
305 }
306
307 function rest_save_collection( $request ) {
308 try {
309 global $wpdb;
310 $params = $request->get_json_params( );
311
312 $id = $params['id'];
313 $name = $params['name'];
314 $layout = $params['layout'];
315 $galleries_ids = $params['galleries_ids'];
316 $description = $params['description'];
317
318 if ( !$name ) {
319 throw new Exception( __( 'Please enter a name for your collection.', MGL_DOMAIN ));
320 }
321
322 if ( !$galleries_ids || !count( $galleries_ids )) {
323 throw new Exception( __( 'Please select at least one gallery.', MGL_DOMAIN ));
324 }
325
326 if ( !$id || $id == '' ) {
327 $id = $this->core->generate_uniqid( 10 );
328 }
329
330 $collections_table = $wpdb->prefix . 'mgl_collections';
331 Meow_MGL_Migrations::check_db();
332
333 // Check if the record exists
334 $exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( * ) FROM $collections_table WHERE id = %s", $id ));
335
336 $data = [
337 'name' => $name,
338 'description' => $description,
339 'layout' => $layout,
340 'galleries_ids' => serialize( $galleries_ids )
341 ];
342
343 if ( $exists ) {
344 // Update existing record
345 $wpdb->update(
346 $collections_table,
347 $data,
348 ['id' => $id]
349 );
350 } else {
351 // Insert new record
352 $data['id'] = $id;
353 $wpdb->insert( $collections_table, $data );
354 }
355
356
357 return new WP_REST_Response( ['success' => true, 'message' => 'Collection created.'], 200 );
358 } catch ( Exception $e ) {
359 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
360 }
361 }
362
363
364 function rest_fetch_collections( $request ) {
365 try {
366 $params = $request->get_json_params( );
367
368 $offset = isset( $params['offset'] ) ? $params['offset'] : 0;
369 $limit = isset( $params['limit'] ) ? $params['limit'] : 10;
370 $sort_updated = $params['sort']['by']; // desc, asc
371 $page = isset( $params['page'] ) ? $params['page'] : 1;
372 $order = $sort_updated === 'desc' ? 'DESC' : 'ASC';
373 $search = isset( $params['search'] ) ? $params['search'] : '';
374
375 $res = $this->core->get_collections( $offset, $limit, $order, $page, $search );
376 $collections = $res['collections'];
377 $total = $res['total'];
378
379 return new WP_REST_Response( ['success' => true, 'data' => $collections, 'total' => $total], 200 );
380 }
381 catch ( Exception $e ) {
382 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
383 }
384 }
385
386 function rest_fetch_gallery_items( $request ) {
387 try {
388 global $wpdb;
389 $params = $request->get_json_params( );
390 $galleryIds = $params['galleryIds'];
391
392 $shortcodes_table = $wpdb->prefix . 'mgl_gallery_shortcodes';
393 Meow_MGL_Migrations::check_db();
394
395 $galleries = [];
396 if ( !empty( $galleryIds )) {
397 $ids_str = "'" . implode( "','", array_map( 'esc_sql', $galleryIds )) . "'";
398 $query = "SELECT * FROM $shortcodes_table WHERE id IN ( $ids_str )";
399 $results = $wpdb->get_results( $query, ARRAY_A );
400
401 foreach ( $results as $gallery ) {
402 // Transform database format to match expected format
403 $galleries[$gallery['id']] = [
404 'name' => $gallery['name'],
405 'description' => $gallery['description'],
406 'layout' => $gallery['layout'],
407 'medias' => unserialize( $gallery['medias'] ),
408 'is_post_mode' => ( bool )$gallery['is_post_mode'],
409 'hero' => ( bool )$gallery['is_hero_mode'],
410 'posts' => $gallery['posts'] ? unserialize( $gallery['posts'] ) : null,
411 'latest_posts' => $gallery['latest_posts'],
412 'tags' => unserialize( $gallery['tags'] ),
413 'dynamic_source' => $gallery['dynamic_source'],
414 'updated' => strtotime( $gallery['updated_at'] )
415 ];
416 }
417 }
418
419 return new WP_REST_Response( ['success' => true, 'data' => $galleries], 200 );
420 } catch ( Exception $e ) {
421 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
422 }
423 }
424
425 function rest_fetch_shortcodes( $request ) {
426 try {
427 $params = $request->get_json_params( );
428
429 $offset = isset( $params['offset'] ) ? $params['offset'] : 0;
430 $limit = isset( $params['limit'] ) ? $params['limit'] : 10;
431 $page = isset( $params['page'] ) ? $params['page'] : 1;
432
433 $search = isset( $params['search'] ) ? $params['search'] : '';
434
435 $sort_by = $params['sort']['accessor'] ?? null;
436 $order_by = strtoupper( $params['sort']['by'] ); // desc, asc
437
438 $res = $this->core->get_galleries( $offset, $limit, $order_by, $sort_by, $page, $search );
439 $shortcodes = $res['galleries'];
440 $total = $res['total'];
441
442 return new WP_REST_Response( ['success' => true, 'data' => $shortcodes, 'total' => $total], 200 );
443 }
444 catch ( Exception $e ) {
445 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
446 }
447 }
448
449 function rest_remove_shortcode( $request ) {
450 try {
451 global $wpdb;
452 $params = $request->get_json_params( );
453 $id = $params['id'];
454
455 $shortcodes_table = $wpdb->prefix . 'mgl_gallery_shortcodes';
456 Meow_MGL_Migrations::check_db();
457
458 $wpdb->delete( $shortcodes_table, ['id' => $id] );
459
460
461 return new WP_REST_Response( ['success' => true, 'message' => 'Shortcode removed.'], 200 );
462 } catch ( Exception $e ) {
463 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage( )], 500 );
464 }
465 }
466
467 function rest_update_gallery_rank( $request ) {
468 try {
469 global $wpdb;
470 $params = $request->get_json_params();
471 $id = $params['id'];
472 $direction = $params['direction']; // 'up' or 'down'
473
474 $shortcodes_table = $wpdb->prefix . 'mgl_gallery_shortcodes';
475 Meow_MGL_Migrations::check_db();
476
477 // Get current rank
478 $current_rank = $wpdb->get_var( $wpdb->prepare( "SELECT pref_rank FROM $shortcodes_table WHERE id = %s", $id ) );
479 $current_rank = intval( $current_rank );
480
481 // Calculate new rank (up = higher priority = higher number, down = lower priority = lower number)
482 $new_rank = $direction === 'up' ? $current_rank + 1 : $current_rank - 1;
483
484 // Update the rank
485 $wpdb->update(
486 $shortcodes_table,
487 ['pref_rank' => $new_rank],
488 ['id' => $id]
489 );
490
491 return new WP_REST_Response( ['success' => true, 'message' => 'Gallery rank updated.', 'new_rank' => $new_rank], 200 );
492 } catch ( Exception $e ) {
493 return new WP_REST_Response( ['success' => false, 'message' => $e->getMessage()], 500 );
494 }
495 }
496
497 function rest_latest_photos( $request ) {
498
499 $search = trim( $request->get_param( 'search' ) );
500 $offset = trim( $request->get_param( 'offset' ) );
501 $limit = trim( $request->get_param( 'limit' ) );
502
503 $except = json_decode( trim( $request->get_param( 'except' ) ), true );
504 $unusedImages = trim( $request->get_param( 'unusedImages' ) );
505
506 global $wpdb;
507 $searchPlaceholder = $search ? '%' . $search . '%' : '';
508 $where_search_clause = $search ? $wpdb->prepare(
509 "AND ( p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_name LIKE %s ) ",
510 $searchPlaceholder,
511 $searchPlaceholder,
512 $searchPlaceholder
513 ) : '';
514 $where_search_clause .= $except && count( $except ) ? $wpdb->prepare(
515 "AND p.ID NOT IN ( " . implode( ', ', array_fill( 0, count( $except ), '%s' )) . " )", $except
516 ) : '';
517 $join_clause = '';
518 if ( $unusedImages ) {
519 // Retrieve the serialized option from the database
520 $meow_gallery_shortcodes = get_option( 'mgl_shortcodes' );
521
522 // Deserialize the option to get the array
523 $shortcodes_array = maybe_unserialize( $meow_gallery_shortcodes );
524
525 // Extract all thumbnail IDs from the array
526 $used_thumbnail_ids = [];
527 foreach ( $shortcodes_array as $shortcode ) {
528 if ( isset( $shortcode['medias']['thumbnail_ids'] ) && is_array( $shortcode['medias']['thumbnail_ids'] ) ) {
529 $used_thumbnail_ids = array_merge( $used_thumbnail_ids, $shortcode['medias']['thumbnail_ids'] );
530 }
531 }
532
533 // Make sure the IDs are integers
534 $used_thumbnail_ids = array_map( 'intval', $used_thumbnail_ids );
535
536 // Include the NOT IN clause to exclude used thumbnail IDs
537 if ( !empty( $used_thumbnail_ids ) ) {
538 $placeholders = implode( ',', array_fill( 0, count( $used_thumbnail_ids ), '%d' ) );
539 $where_search_clause .= $wpdb->prepare( " AND p.ID NOT IN ( $placeholders ) ", $used_thumbnail_ids );
540 }
541 }
542 $posts = $wpdb->get_results(
543 $wpdb->prepare(
544 "SELECT p.ID, p.post_title, p.post_mime_type
545 FROM $wpdb->posts p
546 $join_clause
547 WHERE p.post_type='attachment'
548 AND p.post_status='inherit'
549 $where_search_clause
550 ORDER BY p.post_modified DESC
551 LIMIT %d, $limit", $offset
552 ), OBJECT
553 );
554 $posts_count = ( int )$wpdb->get_var(
555 "SELECT COUNT( * )
556 FROM $wpdb->posts p
557 $join_clause
558 WHERE p.post_type='attachment'
559 AND p.post_status='inherit'
560 $where_search_clause"
561 );
562
563 $data = [];
564 foreach ( $posts as $post ) {
565 $file_url = get_attached_file( $post->ID );
566
567 $mime = $post->post_mime_type;
568 $is_video = ( strpos( $mime, 'video' ) !== false );
569
570 $thumbnail_url = $is_video ? wp_get_attachment_url( $post->ID ) : wp_get_attachment_image_url( $post->ID, 'thumbnail' );
571
572 if ( file_exists( $file_url ) ) {
573 $data[] = [
574 'id' => $post->ID,
575 'thumbnail_url' => $thumbnail_url,
576 'zoom_url' => wp_get_attachment_image_url( $post->ID, 'large' ),
577 'title' => $post->post_title,
578 'filename' => basename( $file_url ),
579 'size' => size_format( filesize( $file_url ) ),
580 'mime' => $mime,
581 ];
582 }
583 }
584 return new WP_REST_Response( [
585 'success' => true,
586 'data' => $data,
587 'total' => $posts_count
588 ], 200 );
589 }
590
591 function rest_update_option( $request ) {
592 try {
593 $params = $request->get_json_params( );
594 $value = $params['options'];
595 $options = $this->core->update_options( $value );
596 $success = !!$options;
597 $message = __( $success ? 'OK' : "Could not update options.", MGL_DOMAIN );
598 return new WP_REST_Response( [ 'success' => $success, 'message' => $message, 'options' => $success ? $options : null ], 200 );
599 }
600 catch ( Exception $e ) {
601 return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage( ) ], 500 );
602 }
603 }
604
605 function rest_images( $request ) {
606 $params = $request->get_json_params( );
607
608 $image_ids = $params['imageIds'];
609 $atts = $params['atts'];
610 $layout = trim( $params['layout'] );
611 $size = trim( $params['size'] );
612
613 return new WP_REST_Response( [
614 'success' => true,
615 'data' => $this->core->get_gallery_images( $image_ids, $atts, $layout, $size )
616 ], 200 );
617 }
618
619 function rest_fetch_posts( $request ) {
620 try {
621 $params = $request->get_json_params();
622 $search = isset($params['search']) ? $params['search'] : '';
623 $offset = isset($params['offset']) ? intval($params['offset']) : 0;
624 $limit = isset($params['limit']) ? intval($params['limit']) : 10;
625
626 global $wpdb;
627 $searchPlaceholder = $search ? '%' . $search . '%' : '';
628 $where_search_clause = $search ? $wpdb->prepare(
629 "AND ( p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_name LIKE %s ) ",
630 $searchPlaceholder,
631 $searchPlaceholder,
632 $searchPlaceholder
633 ) : '';
634
635 $posts = $wpdb->get_results(
636 $wpdb->prepare(
637 "SELECT p.ID, p.post_title, p.post_date, p.post_status, u.display_name as author
638 FROM $wpdb->posts p
639 LEFT JOIN $wpdb->users u ON p.post_author = u.ID
640 WHERE p.post_type = 'post'
641 AND p.post_status IN ('publish', 'draft', 'private')
642 $where_search_clause
643 ORDER BY p.post_date DESC
644 LIMIT %d, %d",
645 $offset,
646 $limit
647 ),
648 OBJECT
649 );
650
651 $posts_count = (int)$wpdb->get_var(
652 "SELECT COUNT(*)
653 FROM $wpdb->posts p
654 WHERE p.post_type = 'post'
655 AND p.post_status IN ('publish', 'draft', 'private')
656 $where_search_clause"
657 );
658
659 $data = array_map(function($post) {
660 return [
661 'id' => $post->ID,
662 'title' => $post->post_title,
663 'date' => $post->post_date,
664 'author' => $post->author,
665 'status' => $post->post_status
666 ];
667 }, $posts);
668
669 return new WP_REST_Response([
670 'success' => true,
671 'data' => $data,
672 'total' => $posts_count
673 ], 200);
674 } catch (Exception $e) {
675 return new WP_REST_Response(['success' => false, 'message' => $e->getMessage()], 500);
676 }
677 }
678
679 }
680
681 ?>