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

587 lines 14.9 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/(?P<item_id>\d+)',
36 [
37 [
38 'methods' => \WP_REST_Server::CREATABLE,
39 'callback' => [ $this, 'preview_library_post' ],
40 'args' => [
41 'item_id' => [
42 'required' => true,
43 'type' => 'number',
44 ],
45 ],
46 'permission_callback' => function () {
47 return current_user_can( 'edit_others_posts' );
48 },
49 ],
50 ]
51 );
52
53 $this->route(
54 '/posts/(?P<id>\d+)/library/(?P<library_id>\d+)',
55 [
56 [
57 'methods' => \WP_REST_Server::CREATABLE,
58 'callback' => [ $this, 'save_to_library' ],
59 'args' => [
60 'id' => [
61 'required' => true,
62 'type' => 'number',
63 ],
64 'library_id' => [
65 'required' => true,
66 'type' => 'number',
67 ],
68 ],
69 'permission_callback' => function () {
70 return current_user_can( 'edit_others_posts' );
71 },
72 ],
73 ]
74 );
75
76 $this->route(
77 '/posts/(?P<id>\d+)/sync_to_library/(?P<item_id>\d+)',
78 [
79 [
80 'methods' => \WP_REST_Server::CREATABLE,
81 'callback' => [ $this, 'sync_to_library' ],
82 'args' => [
83 'id' => [
84 'required' => true,
85 'type' => 'number',
86 ],
87 'item_id' => [
88 'required' => true,
89 'type' => 'number',
90 ],
91 ],
92 'permission_callback' => function () {
93 return current_user_can( 'edit_others_posts' );
94 },
95 ],
96 ]
97 );
98
99 $this->route(
100 '/posts/import_from_library/(?P<item_id>\d+)',
101 [
102 [
103 'methods' => \WP_REST_Server::CREATABLE,
104 'callback' => [ $this, 'import_from_library' ],
105 'args' => [
106 'item_id' => [
107 'required' => true,
108 'type' => 'number',
109 ],
110 'import_media' => [
111 'type' => 'number',
112 'default' => 1,
113 ],
114 ],
115 'permission_callback' => function () {
116 return current_user_can( 'edit_others_posts' );
117 },
118 ],
119 ]
120 );
121
122 $this->route(
123 '/posts/(?P<id>\d+)/sync_from_library/(?P<item_id>\d+)',
124 [
125 [
126 'methods' => \WP_REST_Server::CREATABLE,
127 'callback' => [ $this, 'sync_from_library' ],
128 'args' => [
129 'id' => [
130 'required' => true,
131 'type' => 'number',
132 ],
133 'item_id' => [
134 'required' => true,
135 'type' => 'number',
136 ],
137 'import_media' => [
138 'type' => 'number',
139 'default' => 1,
140 ],
141 ],
142 'permission_callback' => function () {
143 return current_user_can( 'edit_others_posts' );
144 },
145 ],
146 ]
147 );
148 }
149
150 /**
151 * Handles previewing a post from a cloud library.
152 *
153 * @param object $request
154 * @return array
155 */
156 public function preview_library_post( $request ) {
157 global $wpdb;
158
159 $item_id = $request->get_param( 'item_id' );
160
161 $meta = $wpdb->get_row(
162 $wpdb->prepare(
163 "SELECT * FROM $wpdb->postmeta
164 WHERE meta_key = '_fl_asst_preview_library_item_id'
165 AND meta_value = %s",
166 $item_id
167 )
168 );
169
170 if ( $meta ) {
171 $request->set_param( 'id', $meta->post_id );
172 $response = $this->sync_from_library( $request );
173 } else {
174 $response = $this->import_from_library( $request );
175 }
176
177 if ( isset( $response->data['error'] ) ) {
178 return $response;
179 }
180
181 $post_id = $response->data['id'];
182
183 wp_update_post(
184 [
185 'ID' => $post_id,
186 'post_status' => 'auto-draft',
187 ]
188 );
189
190 update_post_meta( $post_id, '_fl_asst_preview_library_item_id', $item_id );
191
192 return rest_ensure_response(
193 [
194 'url' => PreviewHelper::get_post_preview_url( $post_id ),
195 ]
196 );
197 }
198
199 /**
200 * Gets the data for saving to a library or updating a library item.
201 *
202 * @param object $request
203 * @param object $post
204 * @return array
205 */
206 public function get_save_data( $request, $post ) {
207 return [
208 'name' => $post->post_title,
209 'type' => 'post',
210 'data' => [
211 'post' => [
212 'comment_status' => $post->comment_status,
213 'menu_order' => $post->menu_order,
214 'ping_status' => $post->ping_status,
215 'post_content' => $post->post_content,
216 'post_excerpt' => $post->post_excerpt,
217 'post_mime_type' => $post->post_mime_type,
218 'post_name' => $post->post_name,
219 'post_title' => $post->post_title,
220 'post_type' => $post->post_type,
221 ],
222 'meta' => get_post_meta( $post->ID ),
223 'terms' => $this->get_post_terms( $post ),
224
225 ],
226 'media' => [
227 'thumb' => get_attached_file( get_post_thumbnail_id( $post ) ),
228 'attachments' => $this->get_post_image_paths( $post ),
229 ],
230 'screenshot' => $this->get_post_screenshot( $request, $post ),
231 ];
232 }
233
234 /**
235 * Saves a post to a cloud library.
236 *
237 * @param object $request
238 * @return array
239 */
240 public function save_to_library( $request ) {
241 $id = $request->get_param( 'id' );
242 $library_id = $request->get_param( 'library_id' );
243 $post = get_post( $id );
244 $client = new CloudClient;
245
246 return $client->libraries->create_item(
247 $library_id,
248 $this->get_save_data( $request, $post )
249 );
250 }
251
252 /**
253 * Replaces a library post with a post on this site.
254 *
255 * @param object $request
256 * @return array
257 */
258 public function sync_to_library( $request ) {
259 $id = $request->get_param( 'id' );
260 $item_id = $request->get_param( 'item_id' );
261 $post = get_post( $id );
262 $client = new CloudClient;
263
264 return $client->libraries->update_item(
265 $item_id,
266 $this->get_save_data( $request, $post )
267 );
268 }
269
270 /**
271 * Imports a post from a library to the site.
272 *
273 * @param object $request
274 * @return array
275 */
276 public function import_from_library( $request ) {
277 $item_id = $request->get_param( 'item_id' );
278 $import_media = ! ! $request->get_param( 'import_media' );
279 $client = new CloudClient;
280 $response = $client->libraries->get_item( $item_id );
281 $post_data = $response->data->post;
282
283 $new_post_id = wp_insert_post(
284 [
285 'comment_status' => $post_data->comment_status,
286 'menu_order' => $post_data->menu_order,
287 'ping_status' => $post_data->ping_status,
288 'post_author' => wp_get_current_user()->ID,
289 'post_content' => $post_data->post_content ? $post_data->post_content : '',
290 'post_excerpt' => $post_data->post_excerpt ? $post_data->post_excerpt : '',
291 'post_mime_type' => $post_data->post_mime_type,
292 'post_name' => $post_data->post_name,
293 'post_status' => 'draft',
294 'post_title' => $post_data->post_title,
295 'post_type' => $post_data->post_type,
296 ]
297 );
298
299 if ( is_wp_error( $new_post_id ) ) {
300 return rest_ensure_response(
301 [
302 'error' => true,
303 ]
304 );
305 }
306
307 $this->import_post_meta_from_library( $new_post_id, $response->data->meta );
308 $this->import_post_terms_from_library( $new_post_id, $response->data->terms );
309 $this->import_post_media_from_library( $new_post_id, $response->media, $import_media );
310 $this->regenerate_builder_cache( $response );
311
312 return rest_ensure_response(
313 $this->posts->transform(
314 get_post( $new_post_id )
315 )
316 );
317 }
318
319 /**
320 * Replaces a post on this site with a post from a library.
321 *
322 * @param object $request
323 * @return array
324 */
325 public function sync_from_library( $request ) {
326 $post_id = $request->get_param( 'id' );
327 $item_id = $request->get_param( 'item_id' );
328 $import_media = ! ! $request->get_param( 'import_media' );
329 $client = new CloudClient;
330 $response = $client->libraries->get_item( $item_id );
331
332 $updated = wp_update_post(
333 [
334 'ID' => $post_id,
335 'post_content' => $response->data->post->post_content,
336 ]
337 );
338
339 if ( is_wp_error( $updated ) ) {
340 return rest_ensure_response(
341 [
342 'error' => true,
343 ]
344 );
345 }
346
347 $this->import_post_meta_from_library( $post_id, $response->data->meta );
348 $this->import_post_terms_from_library( $post_id, $response->data->terms );
349 $this->import_post_media_from_library( $post_id, $response->media, $import_media );
350 $this->regenerate_builder_cache( $response );
351
352 return rest_ensure_response(
353 $this->posts->transform(
354 get_post( $post_id )
355 )
356 );
357 }
358
359 /**
360 * Imports meta for a library post to the site.
361 *
362 * @param int $post_id
363 * @param object $meta
364 * @return void
365 */
366 public function import_post_meta_from_library( $post_id, $meta ) {
367 global $wpdb;
368
369 if ( ! $meta || ! is_object( $meta ) ) {
370 return;
371 }
372
373 foreach ( $meta as $meta_key => $meta_value ) {
374 if ( metadata_exists( 'post', $post_id, $meta_key ) ) {
375 delete_metadata( 'post', $post_id, $meta_key );
376 }
377
378 foreach ( $meta_value as $value ) {
379 $value = addslashes( $value );
380 // @codingStandardsIgnoreStart
381 $wpdb->query( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) values ({$post_id}, '{$meta_key}', '{$value}')" );
382 // @codingStandardsIgnoreEnd
383 }
384 }
385 }
386
387 /**
388 * Imports terms for a library post to the site.
389 *
390 * @param int $post_id
391 * @param array $terms
392 * @return void
393 */
394 public function import_post_terms_from_library( $post_id, $terms ) {
395 if ( ! $terms || ! is_array( $terms ) || 0 === count( $terms ) ) {
396 return;
397 }
398
399 $taxonomies = get_taxonomies( '', 'objects' );
400 $taxonomy_terms = [];
401
402 foreach ( $terms as $term ) {
403 if ( ! isset( $term->name ) || ! isset( $term->taxonomy ) ) {
404 continue;
405 } else if ( ! taxonomy_exists( $term->taxonomy ) ) {
406 continue;
407 } elseif ( ! isset( $taxonomy_terms ) ) {
408 $taxonomy_terms[ $term->taxonomy ] = [];
409 }
410
411 $existing_term = term_exists( $term->slug, $term->taxonomy );
412 $is_hierarchical = ! ! $taxonomies[ $term->taxonomy ]->hierarchical;
413
414 if ( is_array( $existing_term ) ) {
415 $term_id = $is_hierarchical ? $existing_term['term_taxonomy_id'] : $term->name;
416 } else {
417 $new_term = wp_insert_term(
418 $term->name,
419 $term->taxonomy,
420 [
421 'description' => $term->description,
422 'slug' => $term->slug,
423 ]
424 );
425 $term_id = $is_hierarchical ? $new_term['term_taxonomy_id'] : $term->name;
426 }
427
428 $taxonomy_terms[ $term->taxonomy ] = $term_id;
429 }
430
431 foreach ( $taxonomy_terms as $taxonomy => $terms ) {
432 wp_delete_object_term_relationships( $post_id, $taxonomy );
433 wp_set_post_terms( $post_id, $terms, $taxonomy, true );
434 }
435 }
436
437 /**
438 * Returns an array of all terms for a post.
439 *
440 * @param object $post
441 * @return array
442 */
443 public function get_post_terms( $post ) {
444 $taxonomies = get_taxonomies( '', 'names' );
445 $object_terms = wp_get_object_terms( $post->ID, $taxonomies );
446 $terms = [];
447
448 foreach ( $object_terms as $term ) {
449 $terms[] = [
450 'description' => $term->description,
451 'name' => $term->name,
452 'slug' => $term->slug,
453 'taxonomy' => $term->taxonomy,
454 ];
455 }
456
457 return $terms;
458 }
459
460 /**
461 * Returns the screenshot data for a post.
462 *
463 * @param object $request
464 * @param object $post
465 * @return array
466 */
467 public function get_post_screenshot( $request, $post ) {
468 $url = PreviewHelper::get_post_preview_url( $post );
469 $url = add_query_arg( 'fl_asst_screenshot', '1', $url );
470 return ScreenshotHelper::get_for_request( $request, $url );
471 }
472
473 /**
474 * Imports the media for a post.
475 *
476 * @param int $post_id
477 * @param object $media
478 * @param bool $import
479 * @return void
480 */
481 public function import_post_media_from_library( $post_id, $media, $import = true ) {
482 $service = new MediaLibraryService();
483
484 // Import post thumbnail
485 if ( $import && isset( $media->thumb ) && 'screenshot.png' !== $media->thumb->file_name ) {
486 $response = $service->import_cloud_media( $media->thumb, $post_id );
487 set_post_thumbnail( $post_id, $response['id'] );
488 }
489
490 // Import post attachments
491 if ( isset( $media->attachments ) ) {
492 $imported = [];
493
494 foreach ( $media->attachments as $attachment ) {
495 if ( $import ) {
496 $response = $service->import_cloud_media( $attachment, $post_id );
497 $imported[ $attachment->file_name ] = wp_get_attachment_metadata( $response['id'] );
498 $imported[ $attachment->file_name ]['id'] = $response['id'];
499 } else {
500 $imported[ $attachment->file_name ] = $attachment;
501 }
502 }
503
504 $this->replace_imported_attachment_urls_in_content( $post_id, $imported );
505 $this->replace_imported_attachment_urls_in_meta( $post_id, $imported );
506 }
507 }
508
509 /**
510 * Replaces the imported attachment urls in post content.
511 *
512 * @param int $post_id
513 * @param array $imported
514 * @return void
515 */
516 public function replace_imported_attachment_urls_in_content( $post_id, $imported ) {
517 $content = get_post_field( 'post_content', $post_id );
518 $content = MediaPathHelper::replace_imported_attachment_urls_in_string( $content, $imported );
519
520 wp_update_post(
521 [
522 'ID' => $post_id,
523 'post_content' => $content,
524 ]
525 );
526 }
527
528 /**
529 * Replaces the imported attachment urls in post meta.
530 *
531 * @param int $post_id
532 * @param array $imported
533 * @return void
534 */
535 public function replace_imported_attachment_urls_in_meta( $post_id, $imported ) {
536 $meta = get_post_meta( $post_id );
537
538 foreach ( $meta as $key => $val ) {
539 $val = maybe_unserialize( $val[0] );
540
541 if ( is_object( $val ) || is_array( $val ) ) {
542 $val = MediaPathHelper::replace_imported_attachment_urls_in_data( $val, $imported );
543 } elseif ( JsonHelper::is_string_json( $val ) ) {
544 $val = json_decode( $val );
545 $val = MediaPathHelper::replace_imported_attachment_urls_in_data( $val, $imported );
546 $val = wp_slash( json_encode( $val ) );
547 } else {
548 $val = MediaPathHelper::replace_imported_attachment_urls_in_string( $val, $imported );
549 }
550
551 update_post_meta( $post_id, $key, $val );
552 }
553 }
554
555 /**
556 * Get the server paths to all images associated with a post.
557 *
558 * @param object $post
559 * @return array
560 */
561 public function get_post_image_paths( $post ) {
562 $content_paths = MediaPathHelper::get_image_paths_from_string( $post->post_content );
563 $meta = get_post_meta( $post->ID );
564 $meta_paths = [];
565
566 if ( $meta && count( $meta ) > 0 ) {
567 $meta_paths = MediaPathHelper::get_image_paths_from_data( $meta );
568 }
569
570 return array_unique( array_merge( $content_paths, $meta_paths ) );
571 }
572
573 /**
574 * Regenerate the asset cache for posts created with a builder.
575 *
576 * @param object $item
577 * @return void
578 */
579 public function regenerate_builder_cache( $item ) {
580 $meta = (array) $item->data->meta;
581
582 if ( isset( $meta['_elementor_data'] ) && class_exists( 'Elementor\Plugin' ) ) {
583 \Elementor\Plugin::$instance->files_manager->clear_cache();
584 }
585 }
586 }
587