# media-cloud-sync/1.2.12/includes/integrations/media-library.php

Media Cloud Sync, version 1.2.12. 946 lines.

- Page: https://pluginprobe.com/plugins/media-cloud-sync/1.2.12/code/includes/integrations/media-library.php
- Raw: https://pluginprobe.com/plugins/media-cloud-sync/1.2.12/raw/includes/integrations/media-library.php
- Modified: 2025-08-06T10:37:34+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/media-cloud-sync/1.2.12/code/includes/integrations/media-library.php#L10-L20`.

```php
<?php
namespace Dudlewebs\WPMCS;

defined('ABSPATH') || exit;

class MediaLibrary {
    private static $instance = null;
    private $assets_url;
    private $version;
    private $token;

    protected $settings;
	private $deleting_attachment = false;


    public static $source_type_prefix = "media";
	public static $label = 'Media Library';

    // Map which meta to be updated
	public static $source_types = [
		"media_library" => [
            'table'         => 'posts',
			'class'			=> 'MediaLibrary'
        ]
	];

    /**
     * Admin constructor.
     * @since 1.0.0
     */
    public function __construct() {
        $this->assets_url   = WPMCS_ASSETS_URL;
        $this->version      = WPMCS_VERSION;
        $this->token        = WPMCS_TOKEN;
        $this->settings     = Utils::get_settings();

        // Initialize setup
        $this->registerActions();
    }

    /**
     * Register integration access
     */
    public function registerActions() {
        /** IMAGE EDITOR COMPATIBILITY */
        add_action( 'attachment_submitbox_misc_actions', array( $this, 'attachment_submitbox_metadata'),99 );
        //Media Modal Ajax
		add_action( 'wp_ajax_wpmcs_get_attachment_details', array( $this, 'ajax_get_attachment_details' ) );

        /** URL RE-WRITING HOOKS */
        add_filter( 'wp_get_attachment_url', [ $this, 'wp_get_attachment_url' ], 99, 2 );
        add_filter( 'wp_get_attachment_image_attributes', [ $this, 'wp_get_attachment_image_attributes' ], 99, 3 );
        add_filter( 'wp_calculate_image_srcset', [ $this, 'wp_calculate_image_srcset' ], 99, 5 );
        add_filter( 'get_attached_file', [ $this, 'get_attached_file' ], 10, 2 );
        add_filter( 'wp_get_original_image_path', [ $this, 'get_attached_file' ], 10, 2 );
        add_filter( 'wp_video_shortcode', [ $this, 'wp_media_shortcode' ], 100, 5  );
        add_filter( 'wp_audio_shortcode', [ $this, 'wp_media_shortcode' ], 100, 5  );

        /** FILE MANAGEMENT HOOKS */
        add_filter( 'wp_unique_filename', [ $this, 'wp_unique_filename' ], 10, 3 );
        add_filter( 'wp_update_attachment_metadata', [ $this, 'update_attachment_metadata' ], 110, 2 );
        add_filter( 'wp_generate_attachment_metadata', [ $this, 'wp_generate_attachment_metadata' ], 110, 3 );
		add_filter( 'pre_delete_attachment', [ $this, 'pre_delete_attachment' ], 20  );
        add_filter( 'delete_attachment', [ $this, 'delete_attachment' ], 20 );
		add_action( 'delete_post',  [$this, 'delete_post'] );
        add_filter( 'update_attached_file', [ $this, 'update_attached_file' ], 100, 2 ); 
        add_filter( 'load_image_to_edit_path', [ $this, 'load_image_to_edit_path' ], 10, 3 );
    }


    /**
     * Function to execute on load_image_to_edit_path
     * @since 1.0.0
     * @return string
     *
     */
    public function load_image_to_edit_path($path, $attachment_id, $size) {
        $wpmcsItem = Item::instance();
        if (!Utils::is_ok_to_serve($attachment_id) && !$wpmcsItem->is_available_from_provider($attachment, true, 'media_library') ) {
            return $path;
        }


        $server_file = false;
        //If operation is Image editor Image Save
        if(
            isset($_REQUEST['do']) &&
            isset($_REQUEST['action']) && 
            $_REQUEST['action'] === 'image-editor' &&
            $_REQUEST['do']==='save'
        ) {
            $server_file = $wpmcsItem->moveToServer($attachment_id, $size, false, 'media_library');
        }

        return $server_file ? $server_file : $path;
    }


    /**
     * Allow processes to update the file on provider via update_attached_file()
     * @since 1.0.0
     * @param string $file
     * @param int    $attachment_id
     *
     * @return string
     */
    public function update_attached_file($file, $attachment_id) {
        if( !Utils::is_ok_to_upload($attachment_id) ) {
            return $file;
        }

        $item = Item::instance()->get($attachment_id, 'media_library');

        if (Utils::is_empty($item)) {
            return $file;
        }

        $file = apply_filters('wpmcs_update_attached_file', $file, $attachment_id, $item);

        return $file;
    }


    /**
     * Function to remove data from provider by attachment ID
     * @since 1.0.0
     *
     */
    public function delete_attachment($attachment_id){
        if (!Utils::is_service_enabled()) {
            return $attachment_id;
        }

        $wpmcsItem  = Item::instance();
        $item       = $wpmcsItem->get($attachment_id, 'media_library');

        if (Utils::is_empty($item)) {
            return $attachment_id;
        }

        $wpmcsItem->delete_attachments_by_item($item);

        $wpmcsItem->delete($attachment_id, 'media_library');

        return $attachment_id;
    }

    /**
     * Function to execute on wp_update_attachment_metadata
     * @since 1.0.0
     *
     */
    public function update_attachment_metadata($attachment_meta, $attachment_id) {
        $wpmcsItem              = Item::instance();

        $attachment_id          = (int)$attachment_id;
        $type                   = get_post_mime_type($attachment_id);
        $is_image               = (0 === strpos($type, 'image/'));
        $is_image_edit          = false;

        if (!Utils::is_ok_to_upload($attachment_id)) return $attachment_meta;

        //Generate attachment meta if empty
        if (empty($attachment_meta)) {
            $attachment_meta = wp_get_attachment_metadata($attachment_id);
        }

        // Get File Name/Path from Image meta
        $file = isset($attachment_meta) && !empty($attachment_meta) && isset($attachment_meta['file']) && !empty($attachment_meta['file'])
                ?  $attachment_meta['file']
                :  Utils::get_post_meta((int) $attachment_id, '_wp_attached_file', true);

        if($file === basename($file)) {
            $file = Utils::get_post_meta((int) $attachment_id, '_wp_attached_file', true);
        }

        // Generate relative path of the file 
        $source_path = Utils::get_attachment_source_path($file);

        if($source_path){
            $existing   = $wpmcsItem->get($attachment_id, 'media_library'); 
            $backup     = $wpmcsItem->get_backup($attachment_id, 'media_library');

            if(Utils::is_empty($existing)) {   // First Upload attempt
                $uploaded_data = $this->uploadMedia($attachment_meta, $attachment_id, $source_path);
                if(isset($uploaded_data['file'])) {
                    $wpmcsItem->add(
                        $attachment_id,
                        $uploaded_data['file']['url'],
                        $uploaded_data['file']['key'],
                        $uploaded_data['file']['source_path'],
                        $uploaded_data['extra'],
                        'media_library'
                    );
                }
            } else {
                if(Utils::is_empty($backup)) { // if no backup available
                    $uploaded_data = $this->uploadMedia($attachment_meta, $attachment_id, $source_path);
                    
                    if( $existing['source_path'] != $source_path ) { // if existing item is different from new
                        $uploaded_data['extra']['backup']   = serialize($existing);
                        $is_image_edit                      = true;  //  if existing item is different from new it is image edit
                    } 

                    if(isset($uploaded_data['file'])) {
                        $wpmcsItem->update(
                            $attachment_id,
                            [
                                'source_path'   => $uploaded_data['file']['source_path'],
                                'url'           => $uploaded_data['file']['url'],
                                'key'           => $uploaded_data['file']['key'],
                                'extra'         => maybe_serialize($uploaded_data['extra']),
                            ],
                            'media_library'
                        );
                    }
                } else { // if backup available
                    if($backup['source_path'] != $source_path) {  
                        $uploaded_data = $this->uploadMedia($attachment_meta, $attachment_id, $source_path);
                        $uploaded_data['extra']['backup'] = maybe_serialize($backup);

                        if( $existing['source_path'] != $source_path ) { // if existing item is different from new
                            /**
                             * Since the backup is present and it is not the first edit
                             * It is a re-edit, So we don't need intermediate edit state.
                             * So removing cloud and server files immediately
                             */
                            Item::instance()->delete_attachments_by_item($existing, false);
                            Item::instance()->may_be_delete_server_files_by_item($existing, true);
                        
                            $is_image_edit = true;  //  if existing item is different from new it is image edit
                        }

                        if(isset($uploaded_data['file'])) {
                            $wpmcsItem->update(
                                $attachment_id,
                                [
                                    'source_path'   => $uploaded_data['file']['source_path'],
                                    'url'           => $uploaded_data['file']['url'],
                                    'key'           => $uploaded_data['file']['key'],
                                    'extra'         => maybe_serialize($uploaded_data['extra']),
                                ],
                                'media_library'
                            );
                        }
                    } else { // Restore backup
                        Item::instance()->delete_attachments_by_item($existing, false);
                        $wpmcsItem->update(
                            $attachment_id,
                            [
                                'source_path'   => $backup['source_path'],
                                'url'           => $backup['url'],
                                'key'           => $backup['key'],
                                'extra'         => $backup['extra'],
                            ],
                            'media_library'
                        );
                    }
                }
            }
        }
        
        // Remove files from server if enabled ---- Remove main file if it is not image or a new image source url (image edit)
        $delete_main_file   = !$is_image || $is_image_edit;
        // Remove files from server for backup ---- Remove backup from server if it is image edit (To remove restored file)
        $delete_backup      = $is_image_edit;
        Item::instance()->may_be_delete_server_files_by_id($attachment_id, 'media_library', $delete_main_file, $delete_backup);

        return $attachment_meta;
    }

    /**
     * Create unique names for files effects mainly on delete files from server settings
     * @since 1.0.0
     * @return string
     */
    public function wp_unique_filename($filename, $ext, $dir) {
        // Get Post ID if uploaded in post screen.
        $post_id = Utils::filter_input( 'post_id', INPUT_POST, FILTER_VALIDATE_INT );

        $filename = $this->filter_unique_filename($filename, $ext, $dir, $post_id);

        return $filename;
    }

    /**
     * filter unique file names
     * @since 1.0.0
     * @return string
     */
    private function filter_unique_filename($filename, $ext, $dir, $post_id = null) {
        if (!Utils::is_service_enabled()) {
            return $filename;
        }

        // sanitize the file name before we begin processing
        $filename   = sanitize_file_name($filename);
        $ext        = strtolower($ext);
        $name       = wp_basename($filename, $ext);

        // Edge case: if file is named '.ext', treat as an empty name.
        if ($name === $ext) {
            $name = '';
        }

        // Rebuild filename with lowercase extension as provider will have converted extension on upload.
        $filename = $name . $ext;

        return $this->generate_unique_filename($name, $ext, $dir);
    }


    /**
     * Generate unique filename
     * @since 1.0.0
     * @param string $name
     * @param string $ext
     * @param string $time
     *
     * @return string
     */
    private function generate_unique_filename($name, $ext, $dir) {
        $upload_dir         = wp_get_upload_dir();
        $filename           = $name . $ext;
        $no_ext_path        = $dir . '/' . $name;
        $rel_no_ext_path    = substr($no_ext_path, strlen(trailingslashit($upload_dir['basedir'])),strlen($no_ext_path));
        $path               = $dir . '/' . $name . $ext;
        $source_path        = substr($path, strlen(trailingslashit($upload_dir['basedir'])),strlen($path));


        $uploaded_files = Item::instance()->get_similar_files_by_path($rel_no_ext_path);

        if ($uploaded_files !== false) {
            if (Utils::check_existing_file_names($source_path, $uploaded_files) || file_exists($path)) {
                $count = 1;
                $new_file_name = '';
                $found = true;
                while ($found) {
                    $tmp_path   = $dir . '/' . $name . '-' . $count . $ext;
                    $rel_temp_path   = substr($tmp_path, strlen(trailingslashit($upload_dir['basedir'])),strlen($tmp_path));

                    if (Utils::check_existing_file_names($rel_temp_path, $uploaded_files) || file_exists($tmp_path)) {
                        $count++;
                    } else {
                        $found = false;
                        $new_file_name = $name . '-' . $count . $ext;
                    }
                }
                return $new_file_name;
            }
        } else {
            if (file_exists($path)) {
                $count = 1;
                $new_file_name = '';
                $found = true;

                while ($found) {
                    $tmp_path = $dir . '/' . $name . '-' . $count . $ext;
                    if (file_exists($tmp_path)) {
                        $count++;
                    } else {
                        $found = false;
                        $new_file_name = $name . '-' . $count . $ext;
                    }
                }
                return $new_file_name;
            }
        }

        return $filename;
    }


    /**
     * Function to execute on wp_generate_attachment_metadata
     * To delete files from server only after updating all meta
     * @since 1.0.0
     * 
     */

    public function wp_generate_attachment_metadata( $attachment_meta, $attachment_id, $action) {
        if($action == 'create') {
            $attachment_id = (int)$attachment_id;

            if (!Utils::is_ok_to_upload($attachment_id)) return $attachment_meta;

            $item = Item::instance()->get($attachment_id, 'media_library');
            if(!Utils::is_empty($item)) {
                Item::instance()->may_be_delete_server_files_by_id($attachment_id, 'media_library', true, true);
            }
        } 

        return $attachment_meta;
    }

    /**
	 * Filters the audio & video shortcodes output to remove "&_=NN" params from source.src as it breaks signed URLs.
	 *
	 * @param string $html    Shortcode HTML output.
	 * @param array  $atts    Array of shortcode attributes.
	 * @param string $media   Media file.
	 * @param int    $post_id Post ID.
	 * @param string $library Media library used for the shortcode.
	 *
	 * @return string
	 *
	 * Note: Depends on 30377.4.diff from https://core.trac.wordpress.org/ticket/30377
	 */
	public function wp_media_shortcode( $html, $atts, $media, $post_id, $library ) {
		return preg_replace( '/&#038;_=[0-9]+/', '', $html );
	}

    /**
     * Return the provider URL when the local file is missing
     * unless we know who the calling process is and we are happy
     * to copy the file back to the server to be used.
     *
     * @handles get_attached_file
     * @handles wp_get_original_image_path
     * @since 1.0.0
     * @param string $file
     * @param int    $attachment_id
     *
     * @return string
     */
    public function get_attached_file($file, $attachment_id) {
        $attachment_id = (int)$attachment_id;

        // During the deletion of an attachment, stream wrapper URLs should not be returned.
		if ( $this->deleting_attachment ) {
			return $file;
		}

        if (!Utils::is_ok_to_serve($attachment_id)) {
            return $file;
        }

        if( isset($_REQUEST['action']) &&  $_REQUEST['action'] === 'image-editor' ) {
            // Avoid rewriting URL when image restore in image editor
            if(isset($_REQUEST['do']) && $_REQUEST['do']==='restore') {
                return $file;
            }
            // Avoid rewriting URL when image save in image editor
            if(isset($_REQUEST['do']) && $_REQUEST['do'] === 'save') {
                return $file;
            }
        }

        $wpmcsItem = Item::instance();

        $item = $wpmcsItem->get($attachment_id, 'media_library');

        if ( file_exists( $file ) || Utils::is_empty($item)) {
            if(!Utils::is_empty($item)) {
                /**
                 * Added filter to allow plugins to copy the pending size to the server
                 * before the file is served.
                 * 
                 * @param string $file
                 * @param string $file
                 * @param int    $attachment_id
                 */
                return apply_filters( 'wpmcs_get_attached_file_noop', $file, $file, $attachment_id );
            } else {
                return $file;
            }
        }
        
        $url = $wpmcsItem->get_url($attachment_id, 'full', 'media_library');
        if(Utils::is_empty($url)) { 
            return $file;
        }
        /**
		 * This filter gives filter implementors a chance to copy back missing item files
		 * from the provider before WordPress returns the file name/path for it. Defaults to
		 * returning the remote URL.
		 *
		 * @param string             $url           Item URL
         * @param string             $file          Local file path
         * @param int                $attachment_id Attachment ID
         * @param array              $item          Item data
		 */
        return apply_filters('wpmcs_get_attached_file', $url, $file, $attachment_id, $item);
    }


    /**
     * Change src attributes
     * @since 1.0.0
     */

    public function wp_calculate_image_srcset($sources, $size_array, $image_src, $attachment_meta, $attachment_id = 0) {
        $attachment_id = (int)$attachment_id;

        // Must need $attachment_id other wise not possible to get data from the table
        if (!Utils::is_ok_to_serve($attachment_id)) {
            return $sources;
        }

        $wpmcsItem = Item::instance();

        $item = $wpmcsItem->get($attachment_id, 'media_library');

        if (Utils::is_empty($item)) {
            return $sources;
        }

        $item_extra = $wpmcsItem->get_extras($attachment_id, false, 'media_library');

        if (isset($item_extra['width']) && !empty($item_extra['width'])) {
            $sources[$item_extra['width']]=[
                'url'           => $wpmcsItem->get_url($attachment_id, 'full', 'media_library'),
                'descriptor'    => 'w',
				'value'         => $item_extra['width']
            ];
        }

        if ($item_extra) {
            if (isset($item_extra['sizes']) && !empty($item_extra['sizes'])) {
                foreach ($item_extra['sizes'] as $size => $size_array) {
                    if (isset($size_array['width']) && !empty($size_array['width'])) {
                        $w = $size_array['width'];
                        if (isset($sources[$w]) && !empty($sources[$w])) {
                            $sources[$w]['url'] = $wpmcsItem->get_url($attachment_id, $size, 'media_library');
                        }
                    }
                }
            }
        }

        return $sources;
    }

    /**
     * Filters the list of attachment image attributes.
     *
     * @since 1.0.0
     * @param array        $attr  Attributes for the image markup.
     * @param WP_Post      $attachment Image attachment post.
     * @param string|array $size  Requested size. Image size or array of width and height values (in that order).
     *
     * @return array
     */
    public function wp_get_attachment_image_attributes($attr, $attachment, $size='thumbnail') {
        if (
            !$attachment || 
            !Utils::is_ok_to_serve($attachment->ID)
        ) {
            return $attr;
        }

        $wpmcsItem = Item::instance();

        $item = $wpmcsItem->get($attachment->ID, 'media_library');

        if (Utils::is_empty($item)) {
            return $attr;
        }

        $size = Utils::maybe_convert_size_to_string($attachment->ID, $size);
        if ($size === false) {
            return $attr;
        }

        

        if (
            isset($size) && !empty($size) &&
            isset($attr['src']) && !empty($attr['src'])
        ) {
            $source = $wpmcsItem->get_url($attachment->ID, $size, 'media_library');
            if (isset($source) && !empty($source)) {
                $attr['src'] = $source;
            }
        }

        /**
         * Filtered list of attachment image attributes.
         *
         * @param array              $attr       Attributes for the image markup.
         * @param WP_Post            $attachment Image attachment post.
         * @param string             $size       Requested size.
         */
        return apply_filters('wpmcs_wp_get_attachment_image_attributes', $attr, $attachment, $size, $item);
    }

    /**
     * Get attachment url
     * @since 1.0.0
     * @param string $url
     * @param int    $attachment_id
     *
     * @return bool|mixed|WP_Error
     */
    public function wp_get_attachment_url($url, $attachment_id) {
        if (!Utils::is_ok_to_serve($attachment_id)) {
            return $url;
        }

        $new_url = Item::instance()->get_url($attachment_id, 'full', 'media_library');

        if (Utils::is_empty($new_url)) {
            return $url;
        }

        $new_url = apply_filters('wpmcs_wp_get_attachment_url', $new_url, $url, $attachment_id);

        return $new_url;
    }

     /**
     * Upload media item
     */
    public function uploadMedia($attachment_meta, $attachment_id, $source_path) {
        $wpmcsItem              = Item::instance();
        $upload_dir             = wp_get_upload_dir();
        $type                   = get_post_mime_type($attachment_id);
        $is_image               = (0 === strpos($type, 'image/'));
        $existing               = $wpmcsItem->get($attachment_id, 'media_library'); 
        $existing_extras        = $wpmcsItem->get_extras($attachment_id, false, 'media_library'); 
        $has_existing           = !Utils::is_empty($existing);
        $sizes                  = [];
        $uploaded               = [];
        $extras                 = [];
        $prefix                 = '';
        $file_path              = '';
        $file_dir               = '';
        $original_file_path     = '';
        $original_file_source_path = '';


        // Add prefix if object versioning is ON
        if (isset($this->settings['object_versioning']) && $this->settings['object_versioning']) {
            $prefix             = ($existing_extras && isset($existing_extras['prefix']) && !empty($existing_extras['prefix'])) 
                                    ? $existing_extras['prefix'] 
                                    : Utils::generate_object_versioning_prefix();
            $extras['prefix']   = $prefix;
        }

        // Get width and height from image meta
        if (isset($attachment_meta) && !empty($attachment_meta)) {
            $extras['width']  = (isset($attachment_meta['width']) && !empty($attachment_meta['width'])) ? $attachment_meta['width'] : 0;
            $extras['height'] = (isset($attachment_meta['height']) && !empty($attachment_meta['height'])) ? $attachment_meta['height'] : 0;
        }


        // Get Original File Name/Path from Image meta
        $original_file = isset($attachment_meta) && !empty($attachment_meta) && 
                         isset($attachment_meta['original_image']) && !empty($attachment_meta['original_image'])
                            ? $attachment_meta['original_image'] : '';

        $file_path  = trailingslashit($upload_dir['basedir']) . $source_path;
        $file_dir   = isset(pathinfo($file_path)['dirname']) ? pathinfo($file_path)['dirname'] : '';

        // Check whether the extension is enabled for uploading
        if (!Utils::is_extension_available($file_path)) {
            return $attachment_meta;
        }

        // Upload the Full Size file
        if( $has_existing && ( $existing['source_path'] == $source_path ) ) {
            $uploaded = [
                'success'   => true,
                'file_url'  => $existing['url'],
                'key'       => $existing['key']
            ];
        } else if(file_exists($file_path)){
            $uploaded = Service::instance()->uploadSingle($file_path, $source_path, $prefix);
        }

        if(
            isset($uploaded) && !empty($uploaded) &&
            isset($uploaded['success']) && $uploaded['success']
        ) {
            if(isset($original_file) && !empty($original_file)){
                // Find original image relative and absolute path
                $original_file_path = trailingslashit($file_dir) . $original_file;
                $original_file_source_path = Utils::get_attachment_source_path($original_file_path);
                $uploaded_original  = [];

                // Upload Original File
                if(
                    !Utils::is_empty($existing_extras) && 
                    isset($existing_extras['original']) && !Utils::is_empty($existing_extras['original']) &&
                    $existing_extras['original']['source_path'] == $original_file_source_path
                ) {
                    $uploaded_original = [
                        'success'   => true,
                        'file_url'  => $existing_extras['original']['url'],
                        'key'       => $existing_extras['original']['key']
                    ];
                } else if(file_exists($original_file_path)) {
                    $uploaded_original = Service::instance()->uploadSingle($original_file_path, $original_file_source_path, $prefix);
                }

                if(
                    isset($uploaded_original) && !empty($uploaded_original) &&
                    isset($uploaded_original['success']) && $uploaded_original['success']
                ) {
                    $extras['original'] = array(
                        'source_path'   => $original_file_source_path,
                        'url'           => $uploaded_original['file_url'],
                        'key'           => $uploaded_original['key']
                    );
                }
            }

            if (
                $is_image &&
                isset($attachment_meta['sizes']) && !empty($attachment_meta['sizes']) &&
                isset($file_dir) && !empty($file_dir)
            ) {
                foreach ($attachment_meta['sizes'] as $size => $sub_image) {
                    $sub_size           = [];
                    $sub_file           = isset($sub_image['file']) ? $sub_image['file'] : false;
                    $sub_file_path      = '';
                    $sub_file_source_path  = '';
                    $uploaded_sub_image = [];
    
                    if ($sub_file) {
                        $sub_file_path = $file_dir . '/' . $sub_file;
                        $sub_file_source_path = Utils::get_attachment_source_path($sub_file_path);
                    }

                    // Upload Image size
                    if(
                        !Utils::is_empty($existing_extras) && 
                        isset($existing_extras['sizes']) && !Utils::is_empty($existing_extras['sizes']) &&
                        isset($existing_extras['sizes'][$size]) && !Utils::is_empty($existing_extras['sizes'][$size]) &&
                        $existing_extras['sizes'][$size]['source_path'] == $sub_file_source_path
                    ) {
                        $uploaded_sub_image = [
                            'success'   => true,
                            'file_url'  => $existing_extras['sizes'][$size]['url'],
                            'key'       => $existing_extras['sizes'][$size]['key']
                        ];
                    } else if(file_exists($sub_file_path)) {
                        $uploaded_sub_image = Service::instance()->uploadSingle($sub_file_path, $sub_file_source_path, $prefix);
                    }

                    if (
                        isset($uploaded_sub_image) && !empty($uploaded_sub_image) &&
                        isset($uploaded_sub_image['success']) && $uploaded_sub_image['success']
                    ) {
                        $sub_size['source_path']    = $sub_file_source_path;
                        $sub_size['url']            = $uploaded_sub_image['file_url'];
                        $sub_size['key']            = $uploaded_sub_image['key'];
                        $sub_size['width']          = isset($sub_image['width']) ? $sub_image['width']: 0;
                        $sub_size['height']         = isset($sub_image['height']) ? $sub_image['height']: 0;
                    } 
    
                    $sizes[$size] = $sub_size;
                }
            }
    
            
            if (isset($sizes) && !empty($sizes)) {
                $extras['sizes'] = $sizes;
            }

            return [
                'file' => [
                    'source_path'   => $source_path,
                    'url'           => $uploaded['file_url'],
                    'key'           => $uploaded['key'],
                ],
                'extra' => $extras
            ];

        }

        return false;
    }


    /**
     * Get Total Media Count (queried)
     * 
     * Param added because need a generic function name, 
     * if the function calls by source_type
     */
    public static function get_total_media($source_type) {
        global $wpdb;
    
        // Fetch the count of attachments with the 'inherit' status
        $count = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s",
                'attachment',
                'inherit'
            )
        );
    
        return (int)$count;
    }


    /**
	 * Edit Image Meta In View Image
	 * @since 1.0.0
	 */
	function attachment_submitbox_metadata( ) {
        $post          = get_post();
	    $attachment_id = $post->ID;

        if (!Utils::is_ok_to_serve($attachment_id)) {
            return;
        }

        $wpmcsItem = Item::instance();

        $item = $wpmcsItem->get($attachment_id, 'media_library');

        if (Utils::is_empty($item)) {
            return;
        }
        
        $provider = $wpmcsItem->get_field($attachment_id, 'provider', 'media_library');
        if($provider) { 
            $label = Schema::getServiceLabels($provider); ?>
            <div class="misc-pub-section misc-pub-provider">
                <?php esc_html_e( 'Provider :', 'media-cloud-sync' ); ?> <strong><?php echo esc_textarea(!empty($label) ? $label : $provider); ?></strong></a>
            </div>
        <?php
        }

        $region = $wpmcsItem->get_field($attachment_id, 'region', 'media_library');
        if($region) { ?>
            <div class="misc-pub-section misc-pub-provider">
                <?php esc_html_e( 'Region :', 'media-cloud-sync' ); ?> <strong><?php echo esc_textarea($region); ?></strong></a>
            </div>
        <?php
        }
        $private = (int)$wpmcsItem->get_field($attachment_id, 'is_private', 'media_library');
        ?>
            <div class="misc-pub-section misc-pub-provider">
                <?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>
            </div>
        <?php
	}


    /**
     * Function to get attachment details by ID
     */
    public function ajax_get_attachment_details() {
        $result = array(
            'status'    => false,
            'data'      => array(),
            'exclude'   => false
        );

        if ( ! isset( $_POST['id'] ) ) {
            wp_send_json_success( $result );
		}

		check_ajax_referer( 'get_media_provider_details', '_nonce' );

		$id= intval( sanitize_text_field( $_POST['id'] ) );
        
        // Return if extension not allowed
        $path = get_attached_file( $id );
        if(!Utils::is_extension_available($path)) {
            $result['exclude'] = true;
            wp_send_json_success( $result );
        }

        if (!Utils::is_ok_to_serve($id)) {
            wp_send_json_success( $result );
        }

        $wpmcsItem = Item::instance();

        $item = $wpmcsItem->get($id, 'media_library');

        if (Utils::is_empty($item)) {
            wp_send_json_success( $result );
        }

        $provider = $wpmcsItem->get_field($id, 'provider', 'media_library');
        if($provider){
            $label = Schema::getServiceLabels($provider);
            $item['provider'] = !empty($label) ? $label : $provider;
        }
        $region = $wpmcsItem->get_field($id, 'region', 'media_library');
        if($region){
            $item['region'] = $region;
        }
        $item['private'] = $wpmcsItem->get_field($id, 'private', 'media_library');
        if($item) {
            $result= array(
                'status' => true,
                'data' => $item
            );
        }
        
        wp_send_json_success( $result );
    }

    /**
	 * Takes notice that an attachment is about to be deleted and prepares for it.
	 *
	 * @handles pre_delete_attachment
	 *
	 * @param bool|null $delete Whether to go forward with deletion.
	 *
	 * @return bool|null
	 */
	public function pre_delete_attachment( $delete ) {
		if ( is_null( $delete ) ) {
			$this->deleting_attachment = true;
		}

		return $delete;
	}

	/**
	 * Takes notice that an attachment has been deleted and undoes previous preparations for the event.
	 *
	 * @handles delete_post
	 *
	 * Note: delete_post is used as there is a potential that deleted_post is not reached.
	 */
	public function delete_post() {
		$this->deleting_attachment = false;
	}

    /**
     * Is installed?
     *
     * @return bool
     */
    public static function is_installed(): bool {
        // It is inbuilt in worpress
        return true;
    }


    
    public static function instance(){
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}
```
