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

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