PluginProbe
Meow Gallery / 5.5.0
Meow Gallery v5.5.0
5.5.5 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 All 157 releases
meow-gallery / classes / rest.php

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

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