PluginProbe
Assistant – Every Day Productivity Apps / 1.5.1
Assistant – Every Day Productivity Apps v1.5.1
1.5.5 trunk 0.1.0 0.2.0 0.2.1 0.2.2 0.3.0 0.3.1 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.6.0 0.7.0 0.7.0.2 0.7.0.3 0.7.0.4 0.7.0.5 0.7.0.6 0.7.0.7 0.7.0.8 0.7.0.9 0.7.1 1.0 All 71 releases
assistant / backend / src / Controllers / Cloud / Libraries / LibraryItemPostController.php

LibraryItemPostController.php in Assistant – Every Day Productivity Apps 1.5.1, at backend/src/Controllers/Cloud/Libraries/LibraryItemPostController.php

692 lines 17.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FL\Assistant\Controllers\Cloud\Libraries;
4
5 use FL\Assistant\System\Contracts\ControllerAbstract;
6 use FL\Assistant\Data\Transformers\PostTransformer;
7 use FL\Assistant\Helpers\PreviewHelper;
8 use FL\Assistant\Helpers\JsonHelper;
9 use FL\Assistant\Helpers\MediaPathHelper;
10 use FL\Assistant\Helpers\ScreenshotHelper;
11 use FL\Assistant\Services\MediaLibraryService;
12 use FL\Assistant\Clients\Cloud\CloudClient;
13
14 class LibraryItemPostController extends ControllerAbstract {
15
16 protected $posts;
17
18 /**
19 * Controller constructor.
20 *
21 * @return void
22 */
23 public function __construct( PostTransformer $posts ) {
24 $this->posts = $posts;
25 }
26
27 /**
28 * Register routes.
29 *
30 * @return void
31 */
32 public function register_routes() {
33
34 $this->route(
35 '/posts/preview_library_post/',
36 [
37 [
38 'methods' => \WP_REST_Server::CREATABLE,
39 'callback' => [ $this, 'preview_library_post' ],
40 'permission_callback' => function () {
41 return current_user_can( 'edit_others_posts' );
42 },
43 ],
44 ]
45 );
46
47 $this->route(
48 '/posts/(?P<id>\d+)/library/(?P<library_id>\d+)',
49 [
50 [
51 'methods' => \WP_REST_Server::CREATABLE,
52 'callback' => [ $this, 'save_to_library' ],
53 'args' => [
54 'id' => [
55 'required' => true,
56 'type' => 'number',
57 ],
58 'library_id' => [
59 'required' => true,
60 'type' => 'number',
61 ],
62 ],
63 'permission_callback' => function () {
64 return current_user_can( 'edit_others_posts' );
65 },
66 ],
67 ]
68 );
69
70 $this->route(
71 '/posts/(?P<id>\d+)/sync_to_library/(?P<item_id>\d+)',
72 [
73 [
74 'methods' => \WP_REST_Server::CREATABLE,
75 'callback' => [ $this, 'sync_to_library' ],
76 'args' => [
77 'id' => [
78 'required' => true,
79 'type' => 'number',
80 ],
81 'item_id' => [
82 'required' => true,
83 'type' => 'number',
84 ],
85 ],
86 'permission_callback' => function () {
87 return current_user_can( 'edit_others_posts' );
88 },
89 ],
90 ]
91 );
92
93 $this->route(
94 '/posts/import_from_library/',
95 [
96 [
97 'methods' => \WP_REST_Server::CREATABLE,
98 'callback' => [ $this, 'import_from_library' ],
99 'permission_callback' => function () {
100 return current_user_can( 'edit_others_posts' );
101 },
102 ],
103 ]
104 );
105
106 $this->route(
107 '/posts/import_post_thumb_from_library/(?P<post_id>\d+)',
108 [
109 [
110 'methods' => \WP_REST_Server::CREATABLE,
111 'callback' => [ $this, 'import_post_thumb_from_library' ],
112 'args' => [
113 'post_id' => [
114 'required' => true,
115 'type' => 'number',
116 ],
117 ],
118 'permission_callback' => function () {
119 return current_user_can( 'edit_others_posts' );
120 },
121 ],
122 ]
123 );
124
125 $this->route(
126 '/posts/import_post_media_from_library/(?P<post_id>\d+)',
127 [
128 [
129 'methods' => \WP_REST_Server::CREATABLE,
130 'callback' => [ $this, 'import_post_media_from_library' ],
131 'args' => [
132 'post_id' => [
133 'required' => true,
134 'type' => 'number',
135 ],
136 ],
137 'permission_callback' => function () {
138 return current_user_can( 'edit_others_posts' );
139 },
140 ],
141 ]
142 );
143
144 $this->route(
145 '/posts/(?P<id>\d+)/sync_from_library/',
146 [
147 [
148 'methods' => \WP_REST_Server::CREATABLE,
149 'callback' => [ $this, 'sync_from_library' ],
150 'args' => [
151 'id' => [
152 'required' => true,
153 'type' => 'number',
154 ],
155 ],
156 'permission_callback' => function () {
157 return current_user_can( 'edit_others_posts' );
158 },
159 ],
160 ]
161 );
162 }
163
164 /**
165 * Handles previewing a post from a cloud library.
166 *
167 * @param object $request
168 * @return array
169 */
170 public function preview_library_post( $request ) {
171 global $wpdb;
172
173 $data = $request->get_param( 'item' );
174 $item = $data ? json_decode( $data ) : null;
175
176 if ( ! $item ) {
177 return rest_ensure_response(
178 [
179 'error' => true,
180 ]
181 );
182 }
183
184 $meta = $wpdb->get_row(
185 $wpdb->prepare(
186 "SELECT * FROM $wpdb->postmeta
187 WHERE meta_key = '_fl_asst_preview_library_item_id'
188 AND meta_value = %s",
189 $item->id
190 )
191 );
192
193 if ( $meta ) {
194 $request->set_param( 'id', $meta->post_id );
195 $response = $this->sync_from_library( $request );
196 } else {
197 $response = $this->import_from_library( $request );
198 }
199
200 if ( isset( $response->data['error'] ) ) {
201 return $response;
202 }
203
204 $post_id = $response->data['id'];
205
206 wp_update_post(
207 [
208 'ID' => $post_id,
209 'post_status' => 'auto-draft',
210 ]
211 );
212
213 update_post_meta( $post_id, '_fl_asst_preview_library_item_id', $item->id );
214
215 $this->replace_attachment_urls_with_cloud_urls( $item, $post_id );
216
217 return rest_ensure_response(
218 [
219 'url' => PreviewHelper::get_post_preview_url( $post_id ),
220 ]
221 );
222 }
223
224 /**
225 * Gets the data for saving to a library or updating a library item.
226 *
227 * @param object $request
228 * @param object $post
229 * @return array
230 */
231 public function get_save_data( $request, $post ) {
232 $data = [
233 'name' => $post->post_title,
234 'type' => 'post',
235 'post_data' => [
236 'post' => [
237 'comment_status' => $post->comment_status,
238 'menu_order' => $post->menu_order,
239 'ping_status' => $post->ping_status,
240 'post_content' => $post->post_content,
241 'post_excerpt' => $post->post_excerpt,
242 'post_mime_type' => $post->post_mime_type,
243 'post_name' => $post->post_name,
244 'post_title' => $post->post_title,
245 'post_type' => $post->post_type,
246 ],
247 'meta' => get_post_meta( $post->ID ),
248 'terms' => $this->get_post_terms( $post ),
249
250 ],
251 'media' => [
252 'attachments' => $this->get_post_image_paths( $post ),
253 ],
254 'screenshot' => $this->get_post_screenshot( $request, $post ),
255 ];
256
257 $thumbnail = get_attached_file( get_post_thumbnail_id( $post ) );
258
259 if ($thumbnail) {
260 $data['media']['thumb'] = $thumbnail;
261 }
262
263 return $data;
264 }
265
266 /**
267 * Saves a post to a cloud library.
268 *
269 * @param object $request
270 * @return array
271 */
272 public function save_to_library( $request ) {
273 $id = $request->get_param( 'id' );
274 $library_id = $request->get_param( 'library_id' );
275 $post = get_post( $id );
276 $client = new CloudClient;
277
278 return $client->libraries->create_item(
279 $library_id,
280 $this->get_save_data( $request, $post )
281 );
282 }
283
284 /**
285 * Replaces a library post with a post on this site.
286 *
287 * @param object $request
288 * @return array
289 */
290 public function sync_to_library( $request ) {
291 $id = $request->get_param( 'id' );
292 $item_id = $request->get_param( 'item_id' );
293 $post = get_post( $id );
294 $client = new CloudClient;
295 $data = $this->get_save_data( $request, $post );
296
297 return $client->libraries->update_item(
298 $item_id,
299 $data
300 );
301 }
302
303 /**
304 * Imports a post from a library to the site.
305 *
306 * @param object $request
307 * @return array
308 */
309 public function import_from_library( $request ) {
310 $data = $request->get_param( 'item' );
311 $item = $data ? json_decode( $data ) : null;
312
313 if ( ! $item ) {
314 return rest_ensure_response(
315 [
316 'error' => true,
317 ]
318 );
319 }
320
321 $client = new CloudClient;
322 $item = $client->libraries->get_item( $item->id );
323
324 $registered_post_types = get_post_types();
325
326 if ( ! in_array( $item->data->post->post_type, $registered_post_types ) ) {
327 return rest_ensure_response(
328 [
329 'error' => true,
330 'error_code' => 'post_type_not_registered',
331 'post_type' => $item->data->post->post_type,
332 ]
333 );
334 }
335
336 $post_data = $item->data->post;
337 $meta_data = $item->data->meta;
338 $term_data = $item->data->terms;
339
340 $new_post_id = wp_insert_post(
341 [
342 'comment_status' => $post_data->comment_status,
343 'menu_order' => $post_data->menu_order,
344 'ping_status' => $post_data->ping_status,
345 'post_author' => wp_get_current_user()->ID,
346 'post_content' => $post_data->post_content ? $post_data->post_content : '',
347 'post_excerpt' => $post_data->post_excerpt ? $post_data->post_excerpt : '',
348 'post_mime_type' => $post_data->post_mime_type ? $post_data->post_mime_type : '',
349 'post_name' => $post_data->post_name,
350 'post_status' => 'publish',
351 'post_title' => $post_data->post_title,
352 'post_type' => $post_data->post_type,
353 ]
354 );
355
356 if ( is_wp_error( $new_post_id ) ) {
357 return rest_ensure_response(
358 [
359 'error' => true,
360 ]
361 );
362 }
363
364 $this->import_post_meta_from_library( $new_post_id, $meta_data );
365 $this->import_post_terms_from_library( $new_post_id, $term_data );
366 $this->regenerate_builder_cache( $new_post_id, $item );
367
368 return rest_ensure_response(
369 $this->posts->transform(
370 get_post( $new_post_id )
371 )
372 );
373 }
374
375 /**
376 * Replaces a post on this site with a post from a library.
377 *
378 * @param object $request
379 * @return array
380 */
381 public function sync_from_library( $request ) {
382 $post_id = $request->get_param( 'id' );
383 $data = $request->get_param( 'item' );
384 $item = $data ? json_decode( $data ) : null;
385
386 if ( ! $item ) {
387 return rest_ensure_response(
388 [
389 'error' => true,
390 ]
391 );
392 }
393
394 $client = new CloudClient;
395 $item = $client->libraries->get_item( $item->id );
396 $post_data = $item->data->post;
397 $meta_data = $item->data->meta;
398 $term_data = $item->data->terms;
399
400 $updated = wp_update_post(
401 [
402 'ID' => $post_id,
403 'post_content' => $post_data->post_content,
404 ]
405 );
406
407 if ( is_wp_error( $updated ) ) {
408 return rest_ensure_response(
409 [
410 'error' => true,
411 ]
412 );
413 }
414
415 $this->import_post_meta_from_library( $post_id, $meta_data );
416 $this->import_post_terms_from_library( $post_id, $term_data );
417 $this->regenerate_builder_cache( $post_id, $item );
418
419 return rest_ensure_response(
420 $this->posts->transform(
421 get_post( $post_id )
422 )
423 );
424 }
425
426 /**
427 * Imports meta for a library post to the site.
428 *
429 * @param int $post_id
430 * @param object $meta
431 * @return void
432 */
433 public function import_post_meta_from_library( $post_id, $meta ) {
434 global $wpdb;
435
436 if ( ! $meta || ! is_object( $meta ) ) {
437 return;
438 }
439
440 if ( isset( $meta->_fl_builder_data ) ) {
441 $meta->_fl_builder_draft = $meta->_fl_builder_data;
442 $meta->_fl_builder_draft_settings = $meta->_fl_builder_data_settings;
443 }
444
445 foreach ( $meta as $meta_key => $meta_value ) {
446 if ( metadata_exists( 'post', $post_id, $meta_key ) ) {
447 delete_metadata( 'post', $post_id, $meta_key );
448 }
449 if ( is_array( $meta_value ) && count( $meta_value ) !== 0 ) {
450 foreach ( $meta_value as $value ) {
451 if ( $value !== null ) {
452 $value = addslashes( $value );
453 }
454 // @codingStandardsIgnoreStart
455 $wpdb->query( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) values ({$post_id}, '{$meta_key}', '{$value}')" );
456 // @codingStandardsIgnoreEnd
457 }
458 }
459 }
460 }
461
462 /**
463 * Imports terms for a library post to the site.
464 *
465 * @param int $post_id
466 * @param array $terms
467 * @return void
468 */
469 public function import_post_terms_from_library( $post_id, $terms ) {
470 $terms = is_object( $terms ) ? [ $terms ] : $terms;
471
472 if ( ! $terms || ! is_array( $terms ) || 0 === count( $terms ) ) {
473 return;
474 }
475
476 $taxonomies = get_taxonomies( '', 'objects' );
477 $taxonomy_terms = [];
478
479 foreach ( $terms as $term ) {
480 if ( ! isset( $term->name ) || ! isset( $term->taxonomy ) ) {
481 continue;
482 } elseif ( ! taxonomy_exists( $term->taxonomy ) ) {
483 continue;
484 } elseif ( ! isset( $taxonomy_terms ) ) {
485 $taxonomy_terms[ $term->taxonomy ] = [];
486 }
487
488 $existing_term = term_exists( $term->slug, $term->taxonomy );
489 $is_hierarchical = ! ! $taxonomies[ $term->taxonomy ]->hierarchical;
490
491 if ( is_array( $existing_term ) ) {
492 $term_id = $is_hierarchical ? $existing_term['term_taxonomy_id'] : $term->name;
493 } else {
494 $new_term = wp_insert_term(
495 $term->name,
496 $term->taxonomy,
497 [
498 'description' => $term->description,
499 'slug' => $term->slug,
500 ]
501 );
502 $term_id = $is_hierarchical ? $new_term['term_taxonomy_id'] : $term->name;
503 }
504
505 $taxonomy_terms[ $term->taxonomy ][] = $term_id;
506 }
507
508 foreach ( $taxonomy_terms as $taxonomy => $terms ) {
509 wp_delete_object_term_relationships( $post_id, $taxonomy );
510 wp_set_post_terms( $post_id, $terms, $taxonomy, true );
511 }
512 }
513
514 /**
515 * Returns an array of all terms for a post.
516 *
517 * @param object $post
518 * @return array
519 */
520 public function get_post_terms( $post ) {
521 $taxonomies = get_taxonomies( '', 'names' );
522 $object_terms = wp_get_object_terms( $post->ID, $taxonomies );
523 $terms = [];
524
525 foreach ( $object_terms as $term ) {
526 $terms[] = [
527 'description' => $term->description,
528 'name' => $term->name,
529 'slug' => $term->slug,
530 'taxonomy' => $term->taxonomy,
531 ];
532 }
533
534 return $terms;
535 }
536
537 /**
538 * Returns the screenshot data for a post.
539 *
540 * @param object $request
541 * @param object $post
542 * @return array
543 */
544 public function get_post_screenshot( $request, $post ) {
545 $url = PreviewHelper::get_post_preview_url( $post );
546 $url = add_query_arg( 'fl_asst_screenshot', '1', $url );
547 return ScreenshotHelper::get_for_rest_request( $request, $url );
548 }
549
550 /**
551 * Imports the featured image for a post.
552 *
553 * @param object $request
554 * @return array
555 */
556 public function import_post_thumb_from_library( $request ) {
557 $post_id = $request->get_param( 'post_id' );
558 $thumb = $request->get_param( 'thumb' );
559 $service = new MediaLibraryService();
560
561 if ( ! preg_match( '/screenshot\.(png|jpg|gif)/', $thumb['file_name'] ) ) {
562 $response = $service->import_cloud_media( $thumb, $post_id );
563 set_post_thumbnail( $post_id, $response['id'] );
564 }
565
566 return [ 'success' => true ];
567 }
568
569 /**
570 * Imports a media item for a post.
571 *
572 * @param object $request
573 * @return array
574 */
575 public function import_post_media_from_library( $request ) {
576 $post_id = $request->get_param( 'post_id' );
577 $media = $request->get_param( 'media' );
578 $service = new MediaLibraryService();
579
580 $imported = [];
581 $response = $service->import_cloud_media( $media, $post_id );
582 $imported[ $media['file_name'] ] = wp_get_attachment_metadata( $response['id'] );
583 $imported[ $media['file_name'] ]['id'] = $response['id'];
584
585 $this->replace_imported_attachment_urls_in_content( $post_id, $imported );
586 $this->replace_imported_attachment_urls_in_meta( $post_id, $imported );
587
588 return [ 'success' => true ];
589 }
590
591 /**
592 * Replace attachment urls with urls from the cloud.
593 *
594 * @param object $item
595 * @param int $post_id
596 * @return void
597 */
598 public function replace_attachment_urls_with_cloud_urls( $item, $post_id ) {
599 if ( isset( $item->media->attachments ) ) {
600 $imported = [];
601
602 foreach ( $item->media->attachments as $attachment ) {
603 $imported[ $attachment->file_name ] = $attachment;
604 }
605
606 $this->replace_imported_attachment_urls_in_content( $post_id, $imported );
607 $this->replace_imported_attachment_urls_in_meta( $post_id, $imported );
608 }
609 }
610
611 /**
612 * Replaces the imported attachment urls in post content.
613 *
614 * @param int $post_id
615 * @param array $imported
616 * @return void
617 */
618 public function replace_imported_attachment_urls_in_content( $post_id, $imported ) {
619 $content = get_post_field( 'post_content', $post_id );
620 $content = MediaPathHelper::replace_imported_attachment_urls_in_string( $content, $imported );
621
622 wp_update_post(
623 [
624 'ID' => $post_id,
625 'post_content' => $content,
626 ]
627 );
628 }
629
630 /**
631 * Replaces the imported attachment urls in post meta.
632 *
633 * @param int $post_id
634 * @param array $imported
635 * @return void
636 */
637 public function replace_imported_attachment_urls_in_meta( $post_id, $imported ) {
638 $meta = get_post_meta( $post_id );
639
640 foreach ( $meta as $key => $val ) {
641 $val = maybe_unserialize( $val[0] );
642
643 if ( is_object( $val ) || is_array( $val ) ) {
644 $val = MediaPathHelper::replace_imported_attachment_urls_in_data( $val, $imported );
645 } elseif ( JsonHelper::is_string_json( $val ) ) {
646 $val = json_decode( $val );
647 $val = MediaPathHelper::replace_imported_attachment_urls_in_data( $val, $imported );
648 $val = wp_slash( json_encode( $val ) );
649 } else {
650 $val = MediaPathHelper::replace_imported_attachment_urls_in_string( $val, $imported );
651 }
652
653 update_post_meta( $post_id, $key, $val );
654 }
655 }
656
657 /**
658 * Get the server paths to all images associated with a post.
659 *
660 * @param object $post
661 * @return array
662 */
663 public function get_post_image_paths( $post ) {
664 $content_paths = MediaPathHelper::get_image_paths_from_string( $post->post_content );
665 $meta = get_post_meta( $post->ID );
666 $meta_paths = [];
667
668 if ( $meta && count( $meta ) > 0 ) {
669 $meta_paths = MediaPathHelper::get_image_paths_from_data( $meta );
670 }
671
672 return array_unique( array_merge( $content_paths, $meta_paths ) );
673 }
674
675 /**
676 * Regenerate the asset cache for posts created with a builder.
677 *
678 * @param object $item
679 * @return void
680 */
681 public function regenerate_builder_cache( $post_id, $item ) {
682 $meta = (array) $item->data->meta;
683
684 if ( isset( $meta['_fl_builder_data'] ) && class_exists( 'FLBuilderModel' ) ) {
685 \FLBuilderModel::delete_all_asset_cache( $post_id );
686 }
687 if ( isset( $meta['_elementor_data'] ) && class_exists( 'Elementor\Plugin' ) ) {
688 \Elementor\Plugin::$instance->files_manager->clear_cache();
689 }
690 }
691 }
692