# media-cloud-sync/1.2.12/includes/compatbility/compatibility.php

Media Cloud Sync, version 1.2.12. 262 lines.

- Page: https://pluginprobe.com/plugins/media-cloud-sync/1.2.12/code/includes/compatbility/compatibility.php
- Raw: https://pluginprobe.com/plugins/media-cloud-sync/1.2.12/raw/includes/compatbility/compatibility.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/compatbility/compatibility.php#L10-L20`.

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

defined('ABSPATH') || exit;

use WP_CLI;

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

    /**
     * Compatibility constructor.
     * @since 1.0.0
     */
    private function __construct() {
        $this->assets_url = WPMCS_ASSETS_URL;
        $this->version = WPMCS_VERSION;
        $this->token = WPMCS_TOKEN;

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

    public function init() {
        /*
         * WP_Customize_Control
         * /wp-includes/class-wp-customize_control.php
         */
        add_filter('attachment_url_to_postid', [$this, 'customizer_background_image'], 10, 2);

        /*
         * Legacy filter
         * 'wpmcs_get_attached_file_copy_back_to_local'
         */
        add_filter('wpmcs_get_attached_file', [$this, 'legacy_copy_back_to_local'], 10, 4);

        /*
         * Regenerate Thumbnails (before v3)
         * https://wordpress.org/plugins/regenerate-thumbnails/
         */
        add_filter('wpmcs_get_attached_file', [$this, 'regenerate_thumbnails_download_file'], 10, 4);

        /**
         * Regenerate Thumbnails v3+ and other REST-API using plugins that need a local file.
         */
        add_filter('rest_dispatch_request', [$this, 'rest_dispatch_request_copy_back_to_local'], 10, 4);

        /*
         * WP-CLI Compatibility
         */
        if (defined('WP_CLI') && class_exists('WP_CLI')) {
            WP_CLI::add_hook('before_invoke:media regenerate', [$this, 'enable_copy_back_media']);
        }
    }

    /**
     * Filters the REST dispatch request to determine whether route needs compatibility actions.
     *
     * @param bool            $dispatch_result Dispatch result, will be used if not empty.
     * @param WP_REST_Request $request         Request used to generate the response.
     * @param string          $route           Route matched for the request.
     * @param array           $handler         Route handler used for the request.
     *
     * @return bool
     */
    public function rest_dispatch_request_copy_back_to_local($dispatch_result, $request, $route, $handler) {
        $routes = [
            '/regenerate-thumbnails/v\d+/regenerate/',
        ];

        $routes = apply_filters('wpmcs_rest_api_enable_get_attached_file_copy_back_to_local', $routes);
        $routes = is_array($routes) ? $routes : (array)$routes;

        if (!empty($routes)) {
            foreach ($routes as $match_route) {
                if (preg_match('@' . $match_route . '@i', $route)) {
                    $this->enable_copy_back_media();
                    break;
                }
            }
        }

        return $dispatch_result;
    }

    /**
     * Enable copying back attachments from provider
     * and waiting for their metadata to be regenerated
     * before re-offloading.
     *
     * @handles WP_CLI:before_invoke:media regenerate
     */
    public function enable_copy_back_media() {
        add_filter('wpmcs_get_attached_file_copy_back_to_local', '__return_true');
    }

    /**
     * Allow the Regenerate Thumbnails plugin to copy the bucket file back to the local
     * server when the file is missing on the server via get_attached_file.
     *
     * @param string $url
     * @param string $file
     * @param int    $attachment_id
     *
     * @return string
     */
    public function regenerate_thumbnails_download_file($url, $file, $attachment_id, $item) {
        return $this->copy_image_to_server_on_action('regeneratethumbnail', true, $url, $file, $attachment_id);
    }

    /**
     * Allow any process to trigger the copy back to local with
     * the filter 'wpmcs_get_attached_file_copy_back_to_local'
     *
     * @param string $url
     * @param string $file
     * @param int    $attachment_id
     *
     * @return string
     */
    public function legacy_copy_back_to_local($url, $file, $attachment_id, $wpmcs_item) {
        $copy_back_to_local = apply_filters('wpmcs_get_attached_file_copy_back_to_local', false, $file, $attachment_id, $wpmcs_item);
        if (false === $copy_back_to_local) {
            // Not copying back file
            return $url;
        }

        if (($file = $this->copy_provider_file_to_server($attachment_id, $file))) {
            // Return the file if successfully downloaded from S3
            return $file;
        }

        // Return S3 URL as a fallback
        return $url;
    }

    /**
     * Show the correct background image in the customizer
     *
     * @param int|null $post_id
     * @param string   $url
     *
     * @return int|null
     */
    public function customizer_background_image($post_id, $url) {
        if (!is_null($post_id)) {
            return $post_id;
        }

        // There seems to be a bug in the WP Customizer whereby sometimes it puts the attachment ID on the URL.
        if (is_numeric($url)) {
            $item = Item::get($url);

            // If we found an offloaded Media Library item for that ID, job's a good'n'.
            if (!Utils::is_empty($item)) {
                $post_id = $url;
            }
        } else {
            $path = Utils::get_attachment_source_path($url);
            if (!Utils::is_empty($path)) {
                $items = Item::instance()->get_items_by_source_paths([$path]);
                if (!Utils::is_empty($items)) {
                    // If we found an offloaded Media Library item for that path, job's a good'n'.
                    $post_id = $items[0]['source_id'];
                }
            }
        }

        // Must return null if not found.
        return empty($post_id) ? null : $post_id;
    }

    /**
     * Check the current request is a specific one based on action and
     * optional context
     *
     * @param string            $action_key
     * @param bool              $ajax
     * @param null|string|array $context_key
     *
     * @return bool
     */
    public function maybe_process_on_action($action_key, $ajax, $context_key = null) {
        if ($ajax !== Utils::is_ajax()) {
            return false;
        }

        $var_type = 'GET';

        if (isset($_GET['action'])) {
            $action = Utils::filter_input('action');
        } elseif (isset($_POST['action'])) {
            $var_type = 'POST';
            $action = Utils::filter_input('action', INPUT_POST);
        } else {
            return false;
        }

        $context_check = true;
        if (!is_null($context_key)) {
            $global = constant('INPUT_' . $var_type);
            $context = Utils::filter_input('context', $global);

            if (is_array($context_key)) {
                $context_check = in_array($context, $context_key);
            } else {
                $context_check = ($context_key === $context);
            }
        }

        return ($action_key === sanitize_key($action) && $context_check);
    }

    /**
     * Generic method for copying back an S3 file to the server on a specific AJAX action
     *
     * @return string
     */
    public function copy_image_to_server_on_action($action_key, $ajax, $url, $file, $attachment_id) {
        if (false === $this->maybe_process_on_action($action_key, $ajax)) {
            return $url;
        }

        if (($file = $this->copy_provider_file_to_server($attachment_id, $file))) {
            // Return the file if successfully downloaded from S3
            return $file;
        }

        return $url;
    }

    /**
     * Download a file from bucket if the file does not exist locally and places it where
     * the attachment's file should be.
     *
     * @return string|bool File if downloaded, false on failure
     */
    public function copy_provider_file_to_server($attachment_id, $file) {
        // Download files
        if (!Item::instance()->moveToServerBySourcePath($attachment_id, $file)) {
            return false;
        }

        return $file;
    }

    /**
     * Get the singleton instance of the Compatibility class.
     *
     * @return Compatibility
     */
    public static function instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

```
