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

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