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

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