PluginProbe
Assistant – Every Day Productivity Apps / 1.3.7
Assistant – Every Day Productivity Apps v1.3.7
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.3.7, at backend/src/Controllers/Cloud/Libraries/LibraryItemPostController.php

677 lines 16.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 $post_data = $item->data->post;
324 $meta_data = $item->data->meta;
325 $term_data = $item->data->terms;
326
327 $new_post_id = wp_insert_post(
328 [
329 'comment_status' => $post_data->comment_status,
330 'menu_order' => $post_data->menu_order,
331 'ping_status' => $post_data->ping_status,
332 'post_author' => wp_get_current_user()->ID,
333 'post_content' => $post_data->post_content ? $post_data->post_content : '',
334 'post_excerpt' => $post_data->post_excerpt ? $post_data->post_excerpt : '',
335 'post_mime_type' => $post_data->post_mime_type,
336 'post_name' => $post_data->post_name,
337 'post_status' => 'publish',
338 'post_title' => $post_data->post_title,
339 'post_type' => $post_data->post_type,
340 ]
341 );
342
343 if ( is_wp_error( $new_post_id ) ) {
344 return rest_ensure_response(
345 [
346 'error' => true,
347 ]
348 );
349 }
350
351 $this->import_post_meta_from_library( $new_post_id, $meta_data );
352 $this->import_post_terms_from_library( $new_post_id, $term_data );
353 $this->regenerate_builder_cache( $new_post_id, $item );
354
355 return rest_ensure_response(
356 $this->posts->transform(
357 get_post( $new_post_id )
358 )
359 );
360 }
361
362 /**
363 * Replaces a post on this site with a post from a library.
364 *
365 * @param object $request
366 * @return array
367 */
368 public function sync_from_library( $request ) {
369 $post_id = $request->get_param( 'id' );
370 $data = $request->get_param( 'item' );
371 $item = $data ? json_decode( $data ) : null;
372
373 if ( ! $item ) {
374 return rest_ensure_response(
375 [
376 'error' => true,
377 ]
378 );
379 }
380
381 $client = new CloudClient;
382 $item = $client->libraries->get_item( $item->id );
383 $post_data = $item->data->post;
384 $meta_data = $item->data->meta;
385 $term_data = $item->data->terms;
386
387 $updated = wp_update_post(
388 [
389 'ID' => $post_id,
390 'post_content' => $post_data->post_content,
391 ]
392 );
393
394 if ( is_wp_error( $updated ) ) {
395 return rest_ensure_response(
396 [
397 'error' => true,
398 ]
399 );
400 }
401
402 $this->import_post_meta_from_library( $post_id, $meta_data );
403 $this->import_post_terms_from_library( $post_id, $term_data );
404 $this->regenerate_builder_cache( $post_id, $item );
405
406 return rest_ensure_response(
407 $this->posts->transform(
408 get_post( $post_id )
409 )
410 );
411 }
412
413 /**
414 * Imports meta for a library post to the site.
415 *
416 * @param int $post_id
417 * @param object $meta
418 * @return void
419 */
420 public function import_post_meta_from_library( $post_id, $meta ) {
421 global $wpdb;
422
423 if ( ! $meta || ! is_object( $meta ) ) {
424 return;
425 }
426
427 if ( isset( $meta->_fl_builder_data ) ) {
428 $meta->_fl_builder_draft = $meta->_fl_builder_data;
429 $meta->_fl_builder_draft_settings = $meta->_fl_builder_data_settings;
430 }
431
432 foreach ( $meta as $meta_key => $meta_value ) {
433 if ( metadata_exists( 'post', $post_id, $meta_key ) ) {
434 delete_metadata( 'post', $post_id, $meta_key );
435 }
436 if ( is_array( $meta_value ) && count( $meta_value ) !== 0 ) {
437 foreach ( $meta_value as $value ) {
438 $value = addslashes( $value );
439 // @codingStandardsIgnoreStart
440 $wpdb->query( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) values ({$post_id}, '{$meta_key}', '{$value}')" );
441 // @codingStandardsIgnoreEnd
442 }
443 }
444 }
445 }
446
447 /**
448 * Imports terms for a library post to the site.
449 *
450 * @param int $post_id
451 * @param array $terms
452 * @return void
453 */
454 public function import_post_terms_from_library( $post_id, $terms ) {
455 $terms = is_object( $terms ) ? [ $terms ] : $terms;
456
457 if ( ! $terms || ! is_array( $terms ) || 0 === count( $terms ) ) {
458 return;
459 }
460
461 $taxonomies = get_taxonomies( '', 'objects' );
462 $taxonomy_terms = [];
463
464 foreach ( $terms as $term ) {
465 if ( ! isset( $term->name ) || ! isset( $term->taxonomy ) ) {
466 continue;
467 } elseif ( ! taxonomy_exists( $term->taxonomy ) ) {
468 continue;
469 } elseif ( ! isset( $taxonomy_terms ) ) {
470 $taxonomy_terms[ $term->taxonomy ] = [];
471 }
472
473 $existing_term = term_exists( $term->slug, $term->taxonomy );
474 $is_hierarchical = ! ! $taxonomies[ $term->taxonomy ]->hierarchical;
475
476 if ( is_array( $existing_term ) ) {
477 $term_id = $is_hierarchical ? $existing_term['term_taxonomy_id'] : $term->name;
478 } else {
479 $new_term = wp_insert_term(
480 $term->name,
481 $term->taxonomy,
482 [
483 'description' => $term->description,
484 'slug' => $term->slug,
485 ]
486 );
487 $term_id = $is_hierarchical ? $new_term['term_taxonomy_id'] : $term->name;
488 }
489
490 $taxonomy_terms[ $term->taxonomy ][] = $term_id;
491 }
492
493 foreach ( $taxonomy_terms as $taxonomy => $terms ) {
494 wp_delete_object_term_relationships( $post_id, $taxonomy );
495 wp_set_post_terms( $post_id, $terms, $taxonomy, true );
496 }
497 }
498
499 /**
500 * Returns an array of all terms for a post.
501 *
502 * @param object $post
503 * @return array
504 */
505 public function get_post_terms( $post ) {
506 $taxonomies = get_taxonomies( '', 'names' );
507 $object_terms = wp_get_object_terms( $post->ID, $taxonomies );
508 $terms = [];
509
510 foreach ( $object_terms as $term ) {
511 $terms[] = [
512 'description' => $term->description,
513 'name' => $term->name,
514 'slug' => $term->slug,
515 'taxonomy' => $term->taxonomy,
516 ];
517 }
518
519 return $terms;
520 }
521
522 /**
523 * Returns the screenshot data for a post.
524 *
525 * @param object $request
526 * @param object $post
527 * @return array
528 */
529 public function get_post_screenshot( $request, $post ) {
530 $url = PreviewHelper::get_post_preview_url( $post );
531 $url = add_query_arg( 'fl_asst_screenshot', '1', $url );
532 return ScreenshotHelper::get_for_rest_request( $request, $url );
533 }
534
535 /**
536 * Imports the featured image for a post.
537 *
538 * @param object $request
539 * @return array
540 */
541 public function import_post_thumb_from_library( $request ) {
542 $post_id = $request->get_param( 'post_id' );
543 $thumb = $request->get_param( 'thumb' );
544 $service = new MediaLibraryService();
545
546 if ( ! preg_match( '/screenshot\.(png|jpg|gif)/', $thumb['file_name'] ) ) {
547 $response = $service->import_cloud_media( $thumb, $post_id );
548 set_post_thumbnail( $post_id, $response['id'] );
549 }
550
551 return [ 'success' => true ];
552 }
553
554 /**
555 * Imports a media item for a post.
556 *
557 * @param object $request
558 * @return array
559 */
560 public function import_post_media_from_library( $request ) {
561 $post_id = $request->get_param( 'post_id' );
562 $media = $request->get_param( 'media' );
563 $service = new MediaLibraryService();
564
565 $imported = [];
566 $response = $service->import_cloud_media( $media, $post_id );
567 $imported[ $media['file_name'] ] = wp_get_attachment_metadata( $response['id'] );
568 $imported[ $media['file_name'] ]['id'] = $response['id'];
569
570 $this->replace_imported_attachment_urls_in_content( $post_id, $imported );
571 $this->replace_imported_attachment_urls_in_meta( $post_id, $imported );
572
573 return [ 'success' => true ];
574 }
575
576 /**
577 * Replace attachment urls with urls from the cloud.
578 *
579 * @param object $item
580 * @param int $post_id
581 * @return void
582 */
583 public function replace_attachment_urls_with_cloud_urls( $item, $post_id ) {
584 if ( isset( $item->media->attachments ) ) {
585 $imported = [];
586
587 foreach ( $item->media->attachments as $attachment ) {
588 $imported[ $attachment->file_name ] = $attachment;
589 }
590
591 $this->replace_imported_attachment_urls_in_content( $post_id, $imported );
592 $this->replace_imported_attachment_urls_in_meta( $post_id, $imported );
593 }
594 }
595
596 /**
597 * Replaces the imported attachment urls in post content.
598 *
599 * @param int $post_id
600 * @param array $imported
601 * @return void
602 */
603 public function replace_imported_attachment_urls_in_content( $post_id, $imported ) {
604 $content = get_post_field( 'post_content', $post_id );
605 $content = MediaPathHelper::replace_imported_attachment_urls_in_string( $content, $imported );
606
607 wp_update_post(
608 [
609 'ID' => $post_id,
610 'post_content' => $content,
611 ]
612 );
613 }
614
615 /**
616 * Replaces the imported attachment urls in post meta.
617 *
618 * @param int $post_id
619 * @param array $imported
620 * @return void
621 */
622 public function replace_imported_attachment_urls_in_meta( $post_id, $imported ) {
623 $meta = get_post_meta( $post_id );
624
625 foreach ( $meta as $key => $val ) {
626 $val = maybe_unserialize( $val[0] );
627
628 if ( is_object( $val ) || is_array( $val ) ) {
629 $val = MediaPathHelper::replace_imported_attachment_urls_in_data( $val, $imported );
630 } elseif ( JsonHelper::is_string_json( $val ) ) {
631 $val = json_decode( $val );
632 $val = MediaPathHelper::replace_imported_attachment_urls_in_data( $val, $imported );
633 $val = wp_slash( json_encode( $val ) );
634 } else {
635 $val = MediaPathHelper::replace_imported_attachment_urls_in_string( $val, $imported );
636 }
637
638 update_post_meta( $post_id, $key, $val );
639 }
640 }
641
642 /**
643 * Get the server paths to all images associated with a post.
644 *
645 * @param object $post
646 * @return array
647 */
648 public function get_post_image_paths( $post ) {
649 $content_paths = MediaPathHelper::get_image_paths_from_string( $post->post_content );
650 $meta = get_post_meta( $post->ID );
651 $meta_paths = [];
652
653 if ( $meta && count( $meta ) > 0 ) {
654 $meta_paths = MediaPathHelper::get_image_paths_from_data( $meta );
655 }
656
657 return array_unique( array_merge( $content_paths, $meta_paths ) );
658 }
659
660 /**
661 * Regenerate the asset cache for posts created with a builder.
662 *
663 * @param object $item
664 * @return void
665 */
666 public function regenerate_builder_cache( $post_id, $item ) {
667 $meta = (array) $item->data->meta;
668
669 if ( isset( $meta['_fl_builder_data'] ) && class_exists( 'FLBuilderModel' ) ) {
670 \FLBuilderModel::delete_all_asset_cache( $post_id );
671 }
672 if ( isset( $meta['_elementor_data'] ) && class_exists( 'Elementor\Plugin' ) ) {
673 \Elementor\Plugin::$instance->files_manager->clear_cache();
674 }
675 }
676 }
677