PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 All 34 releases
media-cloud-sync / includes / integrations / media-library.php

media-library.php in Media Cloud Sync 1.2.13, at includes/integrations/media-library.php

1,012 lines 35.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Dudlewebs\WPMCS;
3
4 defined('ABSPATH') || exit;
5
6 class MediaLibrary {
7 private static $instance = null;
8 private $assets_url;
9 private $version;
10 private $token;
11
12 protected $settings;
13 private $deleting_attachment = false;
14
15
16 public static $source_type_prefix = "media";
17 public static $label = 'Media Library';
18
19 // Map which meta to be updated
20 public static $source_types = [
21 "media_library" => [
22 'table' => 'posts',
23 'class' => 'MediaLibrary'
24 ]
25 ];
26
27 /**
28 * Admin constructor.
29 * @since 1.0.0
30 */
31 public function __construct() {
32 $this->assets_url = WPMCS_ASSETS_URL;
33 $this->version = WPMCS_VERSION;
34 $this->token = WPMCS_TOKEN;
35 $this->settings = Utils::get_settings();
36
37 // Initialize setup
38 $this->registerActions();
39 }
40
41 /**
42 * Register integration access
43 */
44 public function registerActions() {
45 /** IMAGE EDITOR COMPATIBILITY */
46 add_action( 'attachment_submitbox_misc_actions', array( $this, 'attachment_submitbox_metadata'),99 );
47 //Media Modal Ajax
48 add_action( 'wp_ajax_wpmcs_get_attachment_details', array( $this, 'ajax_get_attachment_details' ) );
49
50 /** URL RE-WRITING HOOKS */
51 add_filter( 'wp_get_attachment_url', [ $this, 'wp_get_attachment_url' ], 99, 2 );
52 add_filter( 'wp_get_attachment_image_attributes', [ $this, 'wp_get_attachment_image_attributes' ], 99, 3 );
53 add_filter( 'wp_calculate_image_srcset', [ $this, 'wp_calculate_image_srcset' ], 99, 5 );
54 add_filter( 'get_attached_file', [ $this, 'get_attached_file' ], 10, 2 );
55 add_filter( 'wp_get_original_image_path', [ $this, 'get_attached_file' ], 10, 2 );
56 add_filter( 'wp_video_shortcode', [ $this, 'wp_media_shortcode' ], 100, 5 );
57 add_filter( 'wp_audio_shortcode', [ $this, 'wp_media_shortcode' ], 100, 5 );
58
59 /** FILE MANAGEMENT HOOKS */
60 add_filter( 'wp_unique_filename', [ $this, 'wp_unique_filename' ], 10, 3 );
61 add_filter( 'wp_update_attachment_metadata', [ $this, 'update_attachment_metadata' ], 110, 2 );
62 add_filter( 'pre_delete_attachment', [ $this, 'pre_delete_attachment' ], 20 );
63 add_filter( 'delete_attachment', [ $this, 'delete_attachment' ], 20 );
64 add_action( 'delete_post', [$this, 'delete_post'] );
65 add_filter( 'update_attached_file', [ $this, 'update_attached_file' ], 100, 2 );
66 add_filter( 'load_image_to_edit_path', [ $this, 'load_image_to_edit_path' ], 10, 3 );
67 }
68
69
70 /**
71 * Function to execute on load_image_to_edit_path
72 * @since 1.0.0
73 * @return string
74 *
75 */
76 public function load_image_to_edit_path($path, $attachment_id, $size) {
77 $wpmcsItem = Item::instance();
78 if (!Utils::is_ok_to_serve($attachment_id) && !$wpmcsItem->is_available_from_provider($attachment, true, 'media_library') ) {
79 return $path;
80 }
81
82
83 $server_file = false;
84 //If operation is Image editor Image Save
85 if(
86 isset($_REQUEST['do']) &&
87 isset($_REQUEST['action']) &&
88 $_REQUEST['action'] === 'image-editor' &&
89 $_REQUEST['do']==='save'
90 ) {
91 $server_file = $wpmcsItem->moveToServer($attachment_id, $size, false, 'media_library');
92 }
93
94 return $server_file ? $server_file : $path;
95 }
96
97
98 /**
99 * Allow processes to update the file on provider via update_attached_file()
100 * @since 1.0.0
101 * @param string $file
102 * @param int $attachment_id
103 *
104 * @return string
105 */
106 public function update_attached_file($file, $attachment_id) {
107 if( !Utils::is_ok_to_upload($attachment_id) ) {
108 return $file;
109 }
110
111 $item = Item::instance()->get($attachment_id, 'media_library');
112
113 if (Utils::is_empty($item)) {
114 return $file;
115 }
116
117 $file = apply_filters('wpmcs_update_attached_file', $file, $attachment_id, $item);
118
119 return $file;
120 }
121
122
123 /**
124 * Function to remove data from provider by attachment ID
125 * @since 1.0.0
126 *
127 */
128 public function delete_attachment($attachment_id){
129 if (!Utils::is_service_enabled()) {
130 return $attachment_id;
131 }
132
133 $wpmcsItem = Item::instance();
134 $item = $wpmcsItem->get($attachment_id, 'media_library');
135
136 if (Utils::is_empty($item)) {
137 return $attachment_id;
138 }
139
140 $wpmcsItem->delete_attachments_by_item($item);
141
142 $wpmcsItem->delete($attachment_id, 'media_library');
143
144 return $attachment_id;
145 }
146
147 /**
148 * Function to execute on wp_update_attachment_metadata
149 * @since 1.0.0
150 * @param array $attachment_meta
151 * @param int $attachment_id
152 * @return array|WP_Error
153 */
154 public function update_attachment_metadata($attachment_meta, $attachment_id) {
155 if (!Utils::is_ok_to_upload($attachment_id) || is_wp_error($attachment_meta)) {
156 return $attachment_meta;
157 }
158
159 $attachment_id = (int) $attachment_id;
160 $is_image = wp_attachment_is_image($attachment_id);
161
162 if ($is_image && $this->should_wait_for_subsizes($attachment_meta, $attachment_id)) {
163 return $attachment_meta;
164 }
165
166 $attachment_meta = $attachment_meta ?: wp_get_attachment_metadata($attachment_id);
167
168 $file = $this->get_attachment_file($attachment_meta, $attachment_id);
169 $source_path = Utils::get_attachment_source_path($file);
170
171 if (empty($source_path) || !is_string($source_path)) {
172 return $attachment_meta;
173 }
174
175 $existing = Item::instance()->get($attachment_id, 'media_library');
176 $backup = Item::instance()->get_backup($attachment_id, 'media_library');
177
178 if (Utils::is_empty($existing)) {
179 $this->handle_media_first_upload($attachment_meta, $attachment_id, $source_path);
180 } elseif (Utils::is_empty($backup)) {
181 $this->handle_media_with_no_backup($attachment_meta, $attachment_id, $source_path, $existing);
182 } else {
183 $this->handle_media_with_backup($attachment_meta, $attachment_id, $source_path, $existing, $backup);
184 }
185
186 return $attachment_meta;
187 }
188
189 /**
190 * Checks if we should wait for WordPress to generate subsizes.
191 */
192 private function should_wait_for_subsizes($attachment_meta, $attachment_id) {
193 if (empty($attachment_meta) || !function_exists('wp_get_registered_image_subsizes')) {
194 return false;
195 }
196
197 // Wait for generate_attachment_metadata if the filter is set to true.
198 if (apply_filters('wpmcs_wait_for_generate_attachment_metadata', false)) {
199 return true;
200 }
201
202 // Check if there are any missing image subsizes.
203 $image_sizes = apply_filters(
204 'intermediate_image_sizes_advanced',
205 wp_get_registered_image_subsizes(),
206 $attachment_meta,
207 $attachment_id
208 );
209
210 // If an image has been rotated, remove original image from metadata so that
211 // `wp_get_missing_image_subsizes()` doesn't use non-rotated image for
212 // generating missing thumbnail sizes.
213 // Also, some images, particularly SVGs, don't create thumbnails but do have
214 // metadata for them. At the time `wp_get_missing_image_subsizes()` checks
215 // the saved metadata, it isn't there, but we already have it.
216 $handle_post_meta = function ($value, $object_id, $meta_key, $single, $meta_type) use ($attachment_id, $attachment_meta) {
217 if (
218 !empty($value['image_meta']['orientation']) ||
219 !empty($attachment_meta['image_meta']['orientation'])
220 ) {
221 if (!empty($value['image_meta']['orientation'])) {
222 unset($value['image_meta']['orientation']);
223 }
224 if (!empty($attachment_meta['image_meta']['orientation'])) {
225 unset($attachment_meta['image_meta']['orientation']);
226 }
227 unset($value['original_image'], $attachment_meta['original_image']);
228 }
229 if (
230 is_null($value) &&
231 $object_id === $attachment_id &&
232 '_wp_attachment_metadata' === $meta_key &&
233 $single && $meta_type === 'post'
234 ) {
235 return [$attachment_meta];
236 }
237 return $value;
238 };
239
240 add_filter('get_post_metadata', $handle_post_meta, 10, 5);
241 $missing_sizes = wp_get_missing_image_subsizes($attachment_id);
242 remove_filter('get_post_metadata', $handle_post_meta);
243
244 return !empty(array_intersect_key($missing_sizes, $image_sizes));
245 }
246
247 /**
248 * Gets the attachment file path.
249 */
250 private function get_attachment_file($attachment_meta, $attachment_id) {
251 $file = $attachment_meta['file'] ?? Utils::get_post_meta($attachment_id, '_wp_attached_file', true);
252 if ($file === basename($file)) {
253 $file = Utils::get_post_meta($attachment_id, '_wp_attached_file', true);
254 }
255 return $file;
256 }
257
258 /**
259 * Handles first upload.
260 * @since 1.2.13
261 * @param array $attachment_meta
262 * @param int $attachment_id
263 * @param string $source_path
264 */
265 private function handle_media_first_upload($attachment_meta, $attachment_id, $source_path) {
266 $uploaded_data = $this->uploadMedia($attachment_meta, $attachment_id, $source_path);
267 if ( $uploaded_data && isset($uploaded_data['file']) && !empty($uploaded_data['file'])) {
268 Item::instance()->add(
269 $attachment_id,
270 $uploaded_data['file']['url'],
271 $uploaded_data['file']['key'],
272 $uploaded_data['file']['source_path'],
273 $uploaded_data['extra'],
274 'media_library'
275 );
276 }
277 }
278
279 /**
280 * Handles upload when no backup exists.
281 * @since 1.2.13
282 * @param array $attachment_meta
283 * @param int $attachment_id
284 * @param string $source_path
285 * @param array $existing
286 */
287 private function handle_media_with_no_backup($attachment_meta, $attachment_id, $source_path, $existing) {
288 $uploaded_data = $this->uploadMedia($attachment_meta, $attachment_id, $source_path);
289
290 if ($existing['source_path'] != $source_path) {
291 $uploaded_data['extra']['backup'] = serialize($existing);
292 }
293
294 $this->update_item_if_uploaded($attachment_id, $uploaded_data);
295 }
296
297 /**
298 * Handles upload when backup exists.
299 * @since 1.2.13
300 * @param array $attachment_meta
301 * @param int $attachment_id
302 * @param string $source_path
303 * @param array $existing
304 * @param array $backup
305 */
306 private function handle_media_with_backup($attachment_meta, $attachment_id, $source_path, $existing, $backup) {
307 $delete_existing = false;
308
309 if ($backup['source_path'] != $source_path) {
310 $uploaded_data = $this->uploadMedia($attachment_meta, $attachment_id, $source_path);
311 $uploaded_data['extra']['backup'] = maybe_serialize($backup);
312
313 if ($existing['source_path'] != $source_path) {
314 $delete_existing = true;
315 }
316 } else {
317 $delete_existing = true;
318
319 // construct upload data from backup
320 $uploaded_data = [
321 'file' => [
322 'source_path' => $backup['source_path'],
323 'url' => $backup['url'],
324 'key' => $backup['key'],
325 ],
326 'extra' => maybe_unserialize($backup['extra']),
327 ];
328 }
329
330 if ($delete_existing) {
331 Item::instance()->delete_attachments_by_item($existing, false);
332 Item::instance()->may_be_delete_server_files_by_item($existing, true);
333 }
334
335 $this->update_item_if_uploaded($attachment_id, $uploaded_data);
336 }
337
338 /**
339 * Updates item if upload was successful.
340 * @since 1.2.13
341 * @param int $attachment_id
342 * @param array $uploaded_data
343 * @return void
344 */
345 private function update_item_if_uploaded($attachment_id, $uploaded_data) {
346 if (!empty($uploaded_data['file'])) {
347 Item::instance()->update(
348 $attachment_id,
349 [
350 'source_path' => $uploaded_data['file']['source_path'],
351 'url' => $uploaded_data['file']['url'],
352 'key' => $uploaded_data['file']['key'],
353 'extra' => maybe_serialize($uploaded_data['extra']),
354 ],
355 'media_library'
356 );
357 }
358 }
359
360
361 /**
362 * Create unique names for files effects mainly on delete files from server settings
363 * @since 1.0.0
364 * @return string
365 */
366 public function wp_unique_filename($filename, $ext, $dir) {
367 // Get Post ID if uploaded in post screen.
368 $post_id = Utils::filter_input( 'post_id', INPUT_POST, FILTER_VALIDATE_INT );
369
370 $filename = $this->filter_unique_filename($filename, $ext, $dir, $post_id);
371
372 return $filename;
373 }
374
375 /**
376 * filter unique file names
377 * @since 1.0.0
378 * @return string
379 */
380 private function filter_unique_filename($filename, $ext, $dir, $post_id = null) {
381 if (!Utils::is_service_enabled()) {
382 return $filename;
383 }
384
385 // sanitize the file name before we begin processing
386 $filename = sanitize_file_name($filename);
387 $ext = strtolower($ext);
388 $name = wp_basename($filename, $ext);
389
390 // Edge case: if file is named '.ext', treat as an empty name.
391 if ($name === $ext) {
392 $name = '';
393 }
394
395 // Rebuild filename with lowercase extension as provider will have converted extension on upload.
396 $filename = $name . $ext;
397
398 return $this->generate_unique_filename($name, $ext, $dir);
399 }
400
401
402 /**
403 * Generate unique filename
404 * @since 1.0.0
405 * @param string $name
406 * @param string $ext
407 * @param string $time
408 *
409 * @return string
410 */
411 private function generate_unique_filename($name, $ext, $dir) {
412 $upload_dir = wp_get_upload_dir();
413 $filename = $name . $ext;
414 $no_ext_path = $dir . '/' . $name;
415 $rel_no_ext_path = substr($no_ext_path, strlen(trailingslashit($upload_dir['basedir'])),strlen($no_ext_path));
416 $path = $dir . '/' . $name . $ext;
417 $source_path = substr($path, strlen(trailingslashit($upload_dir['basedir'])),strlen($path));
418
419
420 $uploaded_files = Item::instance()->get_similar_files_by_path($rel_no_ext_path);
421
422 if ($uploaded_files !== false) {
423 if (Utils::check_existing_file_names($source_path, $uploaded_files) || file_exists($path)) {
424 $count = 1;
425 $new_file_name = '';
426 $found = true;
427 while ($found) {
428 $tmp_path = $dir . '/' . $name . '-' . $count . $ext;
429 $rel_temp_path = substr($tmp_path, strlen(trailingslashit($upload_dir['basedir'])),strlen($tmp_path));
430
431 if (Utils::check_existing_file_names($rel_temp_path, $uploaded_files) || file_exists($tmp_path)) {
432 $count++;
433 } else {
434 $found = false;
435 $new_file_name = $name . '-' . $count . $ext;
436 }
437 }
438 return $new_file_name;
439 }
440 } else {
441 if (file_exists($path)) {
442 $count = 1;
443 $new_file_name = '';
444 $found = true;
445
446 while ($found) {
447 $tmp_path = $dir . '/' . $name . '-' . $count . $ext;
448 if (file_exists($tmp_path)) {
449 $count++;
450 } else {
451 $found = false;
452 $new_file_name = $name . '-' . $count . $ext;
453 }
454 }
455 return $new_file_name;
456 }
457 }
458
459 return $filename;
460 }
461
462
463 /**
464 * Filters the audio & video shortcodes output to remove "&_=NN" params from source.src as it breaks signed URLs.
465 *
466 * @param string $html Shortcode HTML output.
467 * @param array $atts Array of shortcode attributes.
468 * @param string $media Media file.
469 * @param int $post_id Post ID.
470 * @param string $library Media library used for the shortcode.
471 *
472 * @return string
473 *
474 * Note: Depends on 30377.4.diff from https://core.trac.wordpress.org/ticket/30377
475 */
476 public function wp_media_shortcode( $html, $atts, $media, $post_id, $library ) {
477 return preg_replace( '/&#038;_=[0-9]+/', '', $html );
478 }
479
480 /**
481 * Return the provider URL when the server file is missing
482 * unless we know who the calling process is and we are happy
483 * to copy the file back to the server to be used.
484 *
485 * @handles get_attached_file
486 * @handles wp_get_original_image_path
487 * @since 1.0.0
488 * @param string $file
489 * @param int $attachment_id
490 *
491 * @return string
492 */
493 public function get_attached_file($file, $attachment_id) {
494 $attachment_id = (int)$attachment_id;
495
496 // During the deletion of an attachment, stream wrapper URLs should not be returned.
497 if ( $this->deleting_attachment ) {
498 return $file;
499 }
500
501 if (!Utils::is_ok_to_serve($attachment_id)) {
502 return $file;
503 }
504
505 if( isset($_REQUEST['action']) && $_REQUEST['action'] === 'image-editor' ) {
506 // Avoid rewriting URL when image restore in image editor
507 if(isset($_REQUEST['do']) && $_REQUEST['do']==='restore') {
508 return $file;
509 }
510 // Avoid rewriting URL when image save in image editor
511 if(isset($_REQUEST['do']) && $_REQUEST['do'] === 'save') {
512 return $file;
513 }
514 }
515
516 $wpmcsItem = Item::instance();
517
518 $item = $wpmcsItem->get($attachment_id, 'media_library');
519
520 if ( file_exists( $file ) || Utils::is_empty($item)) {
521 if(!Utils::is_empty($item)) {
522 /**
523 * Added filter to allow plugins to copy the pending size to the server
524 * before the file is served.
525 *
526 * @param string $file
527 * @param string $file
528 * @param int $attachment_id
529 */
530 return apply_filters( 'wpmcs_get_attached_file_noop', $file, $file, $attachment_id, $item );
531 } else {
532 return $file;
533 }
534 }
535
536 $url = $wpmcsItem->get_url($attachment_id, 'full', 'media_library');
537 if(Utils::is_empty($url)) {
538 return $file;
539 }
540 /**
541 * This filter gives filter implementors a chance to copy back missing item files
542 * from the provider before WordPress returns the file name/path for it. Defaults to
543 * returning the remote URL.
544 *
545 * @param string $url Item URL
546 * @param string $file Server file path
547 * @param int $attachment_id Attachment ID
548 * @param array $item Item data
549 */
550 return apply_filters('wpmcs_get_attached_file', $url, $file, $attachment_id, $item);
551 }
552
553
554 /**
555 * Change src attributes
556 * @since 1.0.0
557 */
558
559 public function wp_calculate_image_srcset($sources, $size_array, $image_src, $attachment_meta, $attachment_id = 0) {
560 $attachment_id = (int)$attachment_id;
561
562 // Must need $attachment_id other wise not possible to get data from the table
563 if (!Utils::is_ok_to_serve($attachment_id)) {
564 return $sources;
565 }
566
567 $wpmcsItem = Item::instance();
568
569 $item = $wpmcsItem->get($attachment_id, 'media_library');
570
571 if (Utils::is_empty($item)) {
572 return $sources;
573 }
574
575 $item_extra = $wpmcsItem->get_extras($attachment_id, false, 'media_library');
576
577 if (isset($item_extra['width']) && !empty($item_extra['width'])) {
578 $sources[$item_extra['width']]=[
579 'url' => $wpmcsItem->get_url($attachment_id, 'full', 'media_library'),
580 'descriptor' => 'w',
581 'value' => $item_extra['width']
582 ];
583 }
584
585 if ($item_extra) {
586 if (isset($item_extra['sizes']) && !empty($item_extra['sizes'])) {
587 foreach ($item_extra['sizes'] as $size => $size_array) {
588 if (isset($size_array['width']) && !empty($size_array['width'])) {
589 $w = $size_array['width'];
590 if (isset($sources[$w]) && !empty($sources[$w])) {
591 $sources[$w]['url'] = $wpmcsItem->get_url($attachment_id, $size, 'media_library');
592 }
593 }
594 }
595 }
596 }
597
598 return $sources;
599 }
600
601 /**
602 * Filters the list of attachment image attributes.
603 *
604 * @since 1.0.0
605 * @param array $attr Attributes for the image markup.
606 * @param WP_Post $attachment Image attachment post.
607 * @param string|array $size Requested size. Image size or array of width and height values (in that order).
608 *
609 * @return array
610 */
611 public function wp_get_attachment_image_attributes($attr, $attachment, $size='thumbnail') {
612 if (
613 !$attachment ||
614 !Utils::is_ok_to_serve($attachment->ID)
615 ) {
616 return $attr;
617 }
618
619 $wpmcsItem = Item::instance();
620
621 $item = $wpmcsItem->get($attachment->ID, 'media_library');
622
623 if (Utils::is_empty($item)) {
624 return $attr;
625 }
626
627 $size = Utils::maybe_convert_size_to_string($attachment->ID, $size);
628 if ($size === false) {
629 return $attr;
630 }
631
632
633
634 if (
635 isset($size) && !empty($size) &&
636 isset($attr['src']) && !empty($attr['src'])
637 ) {
638 $source = $wpmcsItem->get_url($attachment->ID, $size, 'media_library');
639 if (isset($source) && !empty($source)) {
640 $attr['src'] = $source;
641 }
642 }
643
644 /**
645 * Filtered list of attachment image attributes.
646 *
647 * @param array $attr Attributes for the image markup.
648 * @param WP_Post $attachment Image attachment post.
649 * @param string $size Requested size.
650 */
651 return apply_filters('wpmcs_wp_get_attachment_image_attributes', $attr, $attachment, $size, $item);
652 }
653
654 /**
655 * Get attachment url
656 * @since 1.0.0
657 * @param string $url
658 * @param int $attachment_id
659 *
660 * @return bool|mixed|WP_Error
661 */
662 public function wp_get_attachment_url($url, $attachment_id) {
663 if (!Utils::is_ok_to_serve($attachment_id)) {
664 return $url;
665 }
666
667 $new_url = Item::instance()->get_url($attachment_id, 'full', 'media_library');
668
669 if (Utils::is_empty($new_url)) {
670 return $url;
671 }
672
673 $new_url = apply_filters('wpmcs_wp_get_attachment_url', $new_url, $url, $attachment_id);
674
675 return $new_url;
676 }
677
678 /**
679 * Upload media item
680 */
681 public function uploadMedia($attachment_meta, $attachment_id, $source_path) {
682 $wpmcsItem = Item::instance();
683 $upload_dir = wp_get_upload_dir();
684 $is_image = wp_attachment_is_image($attachment_id);
685 $existing = $wpmcsItem->get($attachment_id, 'media_library');
686 $existing_extras = $wpmcsItem->get_extras($attachment_id, false, 'media_library');
687 $has_existing = !Utils::is_empty($existing);
688 $sizes = [];
689 $uploaded = [];
690 $extras = [];
691 $prefix = '';
692 $file_path = '';
693 $file_dir = '';
694 $original_file_path = '';
695 $original_file_source_path = '';
696
697
698 // Add prefix if object versioning is ON
699 if (isset($this->settings['object_versioning']) && $this->settings['object_versioning']) {
700 $prefix = ($existing_extras && isset($existing_extras['prefix']) && !empty($existing_extras['prefix']))
701 ? $existing_extras['prefix']
702 : Utils::generate_object_versioning_prefix();
703 $extras['prefix'] = $prefix;
704 }
705
706 // Get width and height from image meta
707 if (isset($attachment_meta) && !empty($attachment_meta)) {
708 $extras['width'] = (isset($attachment_meta['width']) && !empty($attachment_meta['width'])) ? $attachment_meta['width'] : 0;
709 $extras['height'] = (isset($attachment_meta['height']) && !empty($attachment_meta['height'])) ? $attachment_meta['height'] : 0;
710 }
711
712
713 // Get Original File Name/Path from Image meta
714 $original_file = isset($attachment_meta) && !empty($attachment_meta) &&
715 isset($attachment_meta['original_image']) && !empty($attachment_meta['original_image'])
716 ? $attachment_meta['original_image'] : '';
717
718 $file_path = trailingslashit($upload_dir['basedir']) . $source_path;
719 $file_dir = isset(pathinfo($file_path)['dirname']) ? pathinfo($file_path)['dirname'] : '';
720
721 // Check whether the extension is enabled for uploading
722 if (!Utils::is_extension_available($file_path)) {
723 return $attachment_meta;
724 }
725
726 // Upload the Full Size file
727 if( $has_existing && ( $existing['source_path'] == $source_path ) ) {
728 $uploaded = [
729 'success' => true,
730 'file_url' => $existing['url'],
731 'key' => $existing['key']
732 ];
733 } else if(file_exists($file_path)){
734 $uploaded = Service::instance()->uploadSingle($file_path, $source_path, $prefix);
735 }
736
737 if(
738 isset($uploaded) && !empty($uploaded) &&
739 isset($uploaded['success']) && $uploaded['success']
740 ) {
741 if(isset($original_file) && !empty($original_file)){
742 // Find original image relative and absolute path
743 $original_file_path = trailingslashit($file_dir) . $original_file;
744 $original_file_source_path = Utils::get_attachment_source_path($original_file_path);
745 $uploaded_original = [];
746
747 // Upload Original File
748 if(
749 !Utils::is_empty($existing_extras) &&
750 isset($existing_extras['original']) && !Utils::is_empty($existing_extras['original']) &&
751 $existing_extras['original']['source_path'] == $original_file_source_path
752 ) {
753 $uploaded_original = [
754 'success' => true,
755 'file_url' => $existing_extras['original']['url'],
756 'key' => $existing_extras['original']['key']
757 ];
758 } else if(file_exists($original_file_path)) {
759 $uploaded_original = Service::instance()->uploadSingle($original_file_path, $original_file_source_path, $prefix);
760 }
761
762 if(
763 isset($uploaded_original) && !empty($uploaded_original) &&
764 isset($uploaded_original['success']) && $uploaded_original['success']
765 ) {
766 $extras['original'] = array(
767 'source_path' => $original_file_source_path,
768 'url' => $uploaded_original['file_url'],
769 'key' => $uploaded_original['key']
770 );
771 }
772 }
773
774 if (
775 $is_image &&
776 isset($attachment_meta['sizes']) && !empty($attachment_meta['sizes']) &&
777 isset($file_dir) && !empty($file_dir)
778 ) {
779 foreach ($attachment_meta['sizes'] as $size => $sub_image) {
780 $sub_size = [];
781 $sub_file = isset($sub_image['file']) ? $sub_image['file'] : false;
782 $sub_file_path = '';
783 $sub_file_source_path = '';
784 $uploaded_sub_image = [];
785
786 if ($sub_file) {
787 $sub_file_path = $file_dir . '/' . $sub_file;
788 $sub_file_source_path = Utils::get_attachment_source_path($sub_file_path);
789 }
790
791 // Upload Image size
792 if(
793 !Utils::is_empty($existing_extras) &&
794 isset($existing_extras['sizes']) && !Utils::is_empty($existing_extras['sizes']) &&
795 isset($existing_extras['sizes'][$size]) && !Utils::is_empty($existing_extras['sizes'][$size]) &&
796 $existing_extras['sizes'][$size]['source_path'] == $sub_file_source_path
797 ) {
798 $uploaded_sub_image = [
799 'success' => true,
800 'file_url' => $existing_extras['sizes'][$size]['url'],
801 'key' => $existing_extras['sizes'][$size]['key']
802 ];
803 } else if(file_exists($sub_file_path)) {
804 $uploaded_sub_image = Service::instance()->uploadSingle($sub_file_path, $sub_file_source_path, $prefix);
805 }
806
807 if (
808 isset($uploaded_sub_image) && !empty($uploaded_sub_image) &&
809 isset($uploaded_sub_image['success']) && $uploaded_sub_image['success']
810 ) {
811 $sub_size['source_path'] = $sub_file_source_path;
812 $sub_size['url'] = $uploaded_sub_image['file_url'];
813 $sub_size['key'] = $uploaded_sub_image['key'];
814 $sub_size['width'] = isset($sub_image['width']) ? $sub_image['width']: 0;
815 $sub_size['height'] = isset($sub_image['height']) ? $sub_image['height']: 0;
816 }
817
818 $sizes[$size] = $sub_size;
819 }
820 }
821
822
823 if (isset($sizes) && !empty($sizes)) {
824 $extras['sizes'] = $sizes;
825 }
826
827 return [
828 'file' => [
829 'source_path' => $source_path,
830 'url' => $uploaded['file_url'],
831 'key' => $uploaded['key'],
832 ],
833 'extra' => $extras
834 ];
835
836 }
837
838 return false;
839 }
840
841
842 /**
843 * Get Total Media Count (queried)
844 *
845 * Param added because need a generic function name,
846 * if the function calls by source_type
847 */
848 public static function get_total_media($source_type) {
849 global $wpdb;
850
851 // Fetch the count of attachments with the 'inherit' status
852 $count = $wpdb->get_var(
853 $wpdb->prepare(
854 "SELECT COUNT(1) FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s",
855 'attachment',
856 'inherit'
857 )
858 );
859
860 return (int)$count;
861 }
862
863
864 /**
865 * Edit Image Meta In View Image
866 * @since 1.0.0
867 */
868 function attachment_submitbox_metadata( ) {
869 $post = get_post();
870 $attachment_id = $post->ID;
871
872 if (!Utils::is_ok_to_serve($attachment_id)) {
873 return;
874 }
875
876 $wpmcsItem = Item::instance();
877
878 $item = $wpmcsItem->get($attachment_id, 'media_library');
879
880 if (Utils::is_empty($item)) {
881 return;
882 }
883
884 $provider = $wpmcsItem->get_field($attachment_id, 'provider', 'media_library');
885 if($provider) {
886 $label = Schema::getServiceLabels($provider); ?>
887 <div class="misc-pub-section misc-pub-provider">
888 <?php esc_html_e( 'Provider :', 'media-cloud-sync' ); ?> <strong><?php echo esc_textarea(!empty($label) ? $label : $provider); ?></strong></a>
889 </div>
890 <?php
891 }
892
893 $region = $wpmcsItem->get_field($attachment_id, 'region', 'media_library');
894 if($region) { ?>
895 <div class="misc-pub-section misc-pub-provider">
896 <?php esc_html_e( 'Region :', 'media-cloud-sync' ); ?> <strong><?php echo esc_textarea($region); ?></strong></a>
897 </div>
898 <?php
899 }
900 $private = (int)$wpmcsItem->get_field($attachment_id, 'is_private', 'media_library');
901 ?>
902 <div class="misc-pub-section misc-pub-provider">
903 <?php esc_html_e( 'Access :', 'media-cloud-sync' ); ?> <strong><?php $private ? esc_html_e( 'Private', 'media-cloud-sync' ) : esc_html_e( 'Public', 'media-cloud-sync' ); ?></strong></a>
904 </div>
905 <?php
906 }
907
908
909 /**
910 * Function to get attachment details by ID
911 */
912 public function ajax_get_attachment_details() {
913 $result = array(
914 'status' => false,
915 'data' => array(),
916 'exclude' => false
917 );
918
919 if ( ! isset( $_POST['id'] ) ) {
920 wp_send_json_success( $result );
921 }
922
923 check_ajax_referer( 'get_media_provider_details', '_nonce' );
924
925 $id= intval( sanitize_text_field( $_POST['id'] ) );
926
927 // Return if extension not allowed
928 $path = get_attached_file( $id );
929 if(!Utils::is_extension_available($path)) {
930 $result['exclude'] = true;
931 wp_send_json_success( $result );
932 }
933
934 if (!Utils::is_ok_to_serve($id)) {
935 wp_send_json_success( $result );
936 }
937
938 $wpmcsItem = Item::instance();
939
940 $item = $wpmcsItem->get($id, 'media_library');
941
942 if (Utils::is_empty($item)) {
943 wp_send_json_success( $result );
944 }
945
946 $provider = $wpmcsItem->get_field($id, 'provider', 'media_library');
947 if($provider){
948 $label = Schema::getServiceLabels($provider);
949 $item['provider'] = !empty($label) ? $label : $provider;
950 }
951 $region = $wpmcsItem->get_field($id, 'region', 'media_library');
952 if($region){
953 $item['region'] = $region;
954 }
955 $item['private'] = $wpmcsItem->get_field($id, 'private', 'media_library');
956 if($item) {
957 $result= array(
958 'status' => true,
959 'data' => $item
960 );
961 }
962
963 wp_send_json_success( $result );
964 }
965
966 /**
967 * Takes notice that an attachment is about to be deleted and prepares for it.
968 *
969 * @handles pre_delete_attachment
970 *
971 * @param bool|null $delete Whether to go forward with deletion.
972 *
973 * @return bool|null
974 */
975 public function pre_delete_attachment( $delete ) {
976 if ( is_null( $delete ) ) {
977 $this->deleting_attachment = true;
978 }
979
980 return $delete;
981 }
982
983 /**
984 * Takes notice that an attachment has been deleted and undoes previous preparations for the event.
985 *
986 * @handles delete_post
987 *
988 * Note: delete_post is used as there is a potential that deleted_post is not reached.
989 */
990 public function delete_post() {
991 $this->deleting_attachment = false;
992 }
993
994 /**
995 * Is installed?
996 *
997 * @return bool
998 */
999 public static function is_installed(): bool {
1000 // It is inbuilt in worpress
1001 return true;
1002 }
1003
1004
1005
1006 public static function instance(){
1007 if (is_null(self::$instance)) {
1008 self::$instance = new self();
1009 }
1010 return self::$instance;
1011 }
1012 }