Plugin Directory

Changeset 3203373


Ignore:
Timestamp:
12/06/2024 04:13:15 AM (16 months ago)
Author:
dudleynguyen
Message:

Update

Location:
exmage-wp-image-links/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • exmage-wp-image-links/trunk/CHANGELOG.txt

    r3193842 r3203373  
     1/**1.0.20 - 2024.12.06**/
     2– Updated: Compatible with WP 6.7.1 and  WC 9.4.3
     3- Fixed: Cannot add image by URL in Media
     4
    15/**1.0.19 - 2024.11.21**/
    26– Updated: Compatible with WP 6.7 and  WC 9.4
  • exmage-wp-image-links/trunk/exmage-wp-image-links.php

    r3193842 r3203373  
    44 * Plugin URI: https://villatheme.com/extensions/exmage-wordpress-image-links/
    55 * Description: Add images using external links - Save your storage with EXMAGE effortlessly
    6  * Version: 1.0.19
     6 * Version: 1.0.20
    77 * Author: VillaTheme(villatheme.com)
    88 * Author URI: https://villatheme.com
     
    1111 * Text Domain: exmage-wp-image-links
    1212 * Copyright 2021-2024 VillaTheme.com. All rights reserved.
    13  * Tested up to: 6.7
     13 * Tested up to: 6.7.1
    1414 * Requires PHP: 7.0
    1515 **/
    1616
    17 if ( ! defined( 'ABSPATH' ) ) {
    18     exit;
     17if (!defined('ABSPATH')) {
     18    exit;
    1919}
    2020
    21 define( 'EXMAGE_WP_IMAGE_LINKS_VERSION', '1.0.19' );
    22 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
    23 define( 'EXMAGE_WP_IMAGE_LINKS_DIR', plugin_dir_path( __FILE__ ) );
    24 define( 'EXMAGE_WP_IMAGE_LINKS_INCLUDES', EXMAGE_WP_IMAGE_LINKS_DIR . "includes" . DIRECTORY_SEPARATOR );
     21define('EXMAGE_WP_IMAGE_LINKS_VERSION', '1.0.20');
     22include_once(ABSPATH . 'wp-admin/includes/plugin.php');
     23define('EXMAGE_WP_IMAGE_LINKS_DIR', plugin_dir_path(__FILE__));
     24define('EXMAGE_WP_IMAGE_LINKS_INCLUDES', EXMAGE_WP_IMAGE_LINKS_DIR . "includes" . DIRECTORY_SEPARATOR);
    2525require_once EXMAGE_WP_IMAGE_LINKS_INCLUDES . "define.php";
    2626
     
    2828 * Class EXMAGE_WP_IMAGE_LINKS
    2929 */
    30 if ( ! class_exists( 'EXMAGE_WP_IMAGE_LINKS' ) ) {
    31     class EXMAGE_WP_IMAGE_LINKS {
    32         public static $background_process;
    33 
    34         public function __construct() {
    35             add_action( 'plugins_loaded', array( $this, 'check_environment' ) );
    36         }
    37         public function check_environment(){
    38             $environment = new VillaTheme_Require_Environment( [
    39                     'plugin_name'     => 'EXMAGE - WordPress Image Links',
    40                     'php_version'     => '7.0',
    41                 ]
    42             );
    43             if ( $environment->has_error() ) {
    44                 return;
    45             }
     30if (!class_exists('EXMAGE_WP_IMAGE_LINKS')) {
     31    class EXMAGE_WP_IMAGE_LINKS {
     32        public static $background_process;
     33
     34        public function __construct() {
     35            add_action('plugins_loaded', array($this, 'check_environment'));
     36        }
     37
     38        public function check_environment() {
     39            $environment = new VillaTheme_Require_Environment([
     40                    'plugin_name' => 'EXMAGE - WordPress Image Links',
     41                    'php_version' => '7.0',
     42                ]
     43            );
     44            if ($environment->has_error()) {
     45                return;
     46            }
    4647            $this->background_process();
    47             add_action( 'init', array( $this, 'init' ) );
    48             add_action( 'admin_init', array( $this, 'admin_init' ) );
    49             add_action( 'admin_notices', array( $this, 'admin_notices' ) );
    50             add_action( 'wp_enqueue_media', array( $this, 'wp_enqueue_media' ), PHP_INT_MAX );
    51             /*Short link to Add new media*/
    52             add_filter( 'plugin_action_links_exmage-wp-image-links/exmage-wp-image-links.php', array( $this, 'settings_link' ) );
    53             /*wp.media*/
    54             add_action( 'post-upload-ui', array( $this, 'post_upload_ui' ), 20 );
    55             add_action( 'print_media_templates', array( $this, 'override_media_template_attachment_detail' ) );
    56             add_filter( 'wp_prepare_attachment_for_js', array( $this, 'wp_prepare_attachment_for_js' ) );
    57             /*External URL column in Media library/mode=list*/
    58             add_filter( 'manage_media_columns', array( $this, 'is_external' ) );
    59             add_action( 'manage_media_custom_column', array( $this, 'column_callback_media' ) );
    60             /*Return error when saving external image*/
    61             add_filter( 'load_image_to_edit_path', array( $this, 'load_image_to_edit_path' ), 10, 3 );
    62             /*Filter attachment url and image source set*/
    63             add_filter( 'wp_get_attachment_url', array( $this, 'wp_get_attachment_url' ), 10, 2 );
    64             add_filter( 'wp_calculate_image_srcset', array( $this, 'wp_calculate_image_srcset' ), 10, 5 );
    65             /*Ajax add image from URLs*/
    66             add_action( 'wp_ajax_exmage_handle_url', array( $this, 'handle_url' ) );
    67             /*Ajax store external images to server*/
    68             add_action( 'wp_ajax_exmage_convert_external_image', array( $this, 'convert_external_image' ) );
    69             /*Jetpack - Photon CDN*/
    70             add_filter( 'jetpack_photon_skip_image', array( $this, 'jetpack_photon_skip_image' ), 10, 3 );
    71             /*WPML*/
    72             add_action( 'wpml_after_duplicate_attachment', array( $this, 'wpml_after_duplicate_attachment' ), 10, 2 );
    73 
    74             add_action( 'woocommerce_product_import_before_process_item', function () {
    75                 remove_action( 'pre_get_posts', [ $this, 'search_exmage_url_when_import_product' ] );
    76                 add_action( 'pre_get_posts', [ $this, 'search_exmage_url_when_import_product' ] );
    77             } );
    78 
    79             add_action( 'woocommerce_product_import_inserted_product_object', function () {
    80                 remove_action( 'pre_get_posts', [ $this, 'search_exmage_url_when_import_product' ] );
    81             } );
    82         }
    83 
    84         /**
    85         * Add needed post meta when an external image is cloned by WPML
    86         *
    87         * @param $attachment_id
    88         * @param $duplicated_attachment_id
    89         */
    90         public function wpml_after_duplicate_attachment( $attachment_id, $duplicated_attachment_id ) {
    91             $_exmage_external_url = get_post_meta( $attachment_id, '_exmage_external_url', true );
    92             if ( $_exmage_external_url && ! get_post_meta( $attachment_id, '_exmage_imported', true ) ) {
    93                 update_post_meta( $duplicated_attachment_id, '_exmage_external_url', $_exmage_external_url );
    94             }
    95         }
    96 
    97         public function stop_processing_button() {
    98             $href = add_query_arg( [ 'exmage_stop_processing' => 1, 'exmage_nonce' => wp_create_nonce( 'exmage_stop_processing' ) ] );
    99             printf( "<a href='%s' class='button' style='vertical-align: middle;'>%s</a>", esc_url( $href ), esc_html__( 'Stop processing', 'exmage-wp-image-links' ) );
    100         }
    101 
    102         /**
    103         * Show status of background processing
    104         */
    105         public function admin_notices() {
    106             if ( get_site_option( 'exmage_background_process_image_kill_process' ) ) {
    107                 return;
    108             }
    109 
    110             if ( self::$background_process->is_downloading() ) {
    111                 ?>
     48            add_action('init', array($this, 'init'));
     49            add_action('admin_init', array($this, 'admin_init'));
     50            add_action('admin_notices', array($this, 'admin_notices'));
     51            add_action('admin_enqueue_scripts', array($this, 'wp_enqueue_media'), PHP_INT_MAX, false);
     52            /*Short link to Add new media*/
     53            add_filter('plugin_action_links_exmage-wp-image-links/exmage-wp-image-links.php', array($this, 'settings_link'));
     54            /*wp.media*/
     55            add_action('post-upload-ui', array($this, 'post_upload_ui'), 20);
     56            add_action('print_media_templates', array($this, 'override_media_template_attachment_detail'));
     57            add_filter('wp_prepare_attachment_for_js', array($this, 'wp_prepare_attachment_for_js'));
     58            /*External URL column in Media library/mode=list*/
     59            add_filter('manage_media_columns', array($this, 'is_external'));
     60            add_action('manage_media_custom_column', array($this, 'column_callback_media'));
     61            /*Return error when saving external image*/
     62            add_filter('load_image_to_edit_path', array($this, 'load_image_to_edit_path'), 10, 3);
     63            /*Filter attachment url and image source set*/
     64            add_filter('wp_get_attachment_url', array($this, 'wp_get_attachment_url'), 10, 2);
     65            add_filter('wp_calculate_image_srcset', array($this, 'wp_calculate_image_srcset'), 10, 5);
     66            /*Ajax add image from URLs*/
     67            add_action('wp_ajax_exmage_handle_url', array($this, 'handle_url'));
     68            /*Ajax store external images to server*/
     69            add_action('wp_ajax_exmage_convert_external_image', array($this, 'convert_external_image'));
     70            /*Jetpack - Photon CDN*/
     71            add_filter('jetpack_photon_skip_image', array($this, 'jetpack_photon_skip_image'), 10, 3);
     72            /*WPML*/
     73            add_action('wpml_after_duplicate_attachment', array($this, 'wpml_after_duplicate_attachment'), 10, 2);
     74
     75            add_action('woocommerce_product_import_before_process_item', function () {
     76                remove_action('pre_get_posts', [$this, 'search_exmage_url_when_import_product']);
     77                add_action('pre_get_posts', [$this, 'search_exmage_url_when_import_product']);
     78            });
     79
     80            add_action('woocommerce_product_import_inserted_product_object', function () {
     81                remove_action('pre_get_posts', [$this, 'search_exmage_url_when_import_product']);
     82            });
     83        }
     84
     85        /**
     86        * Add needed post meta when an external image is cloned by WPML
     87        *
     88        * @param $attachment_id
     89        * @param $duplicated_attachment_id
     90        */
     91        public function wpml_after_duplicate_attachment( $attachment_id, $duplicated_attachment_id ) {
     92            $_exmage_external_url = get_post_meta($attachment_id, '_exmage_external_url', true);
     93            if ($_exmage_external_url && !get_post_meta($attachment_id, '_exmage_imported', true)) {
     94                update_post_meta($duplicated_attachment_id, '_exmage_external_url', $_exmage_external_url);
     95            }
     96        }
     97
     98        public function stop_processing_button() {
     99            $href = add_query_arg(['exmage_stop_processing' => 1, 'exmage_nonce' => wp_create_nonce('exmage_stop_processing')]);
     100            printf("<a href='%s' class='button' style='vertical-align: middle;'>%s</a>", esc_url($href), esc_html__('Stop processing', 'exmage-wp-image-links'));
     101        }
     102
     103        /**
     104        * Show status of background processing
     105        */
     106        public function admin_notices() {
     107            if (get_site_option('exmage_background_process_image_kill_process')) {
     108                return;
     109            }
     110
     111            if (self::$background_process->is_downloading()) {
     112                ?>
    112113                <div class="updated">
    113114                    <h4>
    114                         <?php /* translators: %s: url left in the queue */
    115                         printf( esc_html__( 'EXMAGE - WordPress Image Links: %s URLs are being processed in the background.', 'exmage-wp-image-links' ), esc_html( self::$background_process->get_items_left() ) );
    116                         $this->stop_processing_button();
    117                         ?>
     115                        <?php /* translators: %s: url left in the queue */
     116                        printf(esc_html__('EXMAGE - WordPress Image Links: %s URLs are being processed in the background.', 'exmage-wp-image-links'), esc_html(self::$background_process->get_items_left()));
     117                        $this->stop_processing_button();
     118                        ?>
    118119                    </h4>
    119120                </div>
    120                 <?php
    121             } elseif ( ! self::$background_process->is_queue_empty() ) {
    122                 ?>
     121                <?php
     122            } elseif (!self::$background_process->is_queue_empty()) {
     123                ?>
    123124                <div class="updated">
    124125                    <h4>
    125                         <?php /* translators: %s: url left in the queue */
    126                         printf( esc_html__( 'EXMAGE - WordPress Image Links: %s URLs are in the queue.', 'exmage-wp-image-links' ), esc_html( self::$background_process->get_items_left() ) );
    127                         $this->stop_processing_button();
    128                         ?>
     126                        <?php /* translators: %s: url left in the queue */
     127                        printf(esc_html__('EXMAGE - WordPress Image Links: %s URLs are in the queue.', 'exmage-wp-image-links'), esc_html(self::$background_process->get_items_left()));
     128                        $this->stop_processing_button();
     129                        ?>
    129130                    </h4>
    130131                </div>
    131                 <?php
    132             } elseif ( get_transient( 'exmage_background_process_image_complete' ) ) {
    133                 delete_transient( 'exmage_background_process_image_complete' );
    134                 ?>
     132                <?php
     133            } elseif (get_transient('exmage_background_process_image_complete')) {
     134                delete_transient('exmage_background_process_image_complete');
     135                ?>
    135136                <div class="updated">
    136137                    <p>
    137                         <?php esc_html_e( 'EXMAGE - WordPress Image Links: all URLs are processed.', 'exmage-wp-image-links' ) ?>
     138                        <?php esc_html_e('EXMAGE - WordPress Image Links: all URLs are processed.', 'exmage-wp-image-links') ?>
    138139                    </p>
    139140                </div>
    140                 <?php
    141             }
    142         }
    143 
    144         public function admin_init() {
    145             if ( isset( $_GET['exmage_stop_processing'], $_GET['exmage_nonce'] ) && wp_verify_nonce( $_GET['exmage_nonce'], 'exmage_stop_processing' ) ) {
    146                 if ( ! empty( self::$background_process ) ) {
    147                     self::$background_process->kill_process();
    148                     $url = remove_query_arg( [ 'exmage_stop_processing', 'exmage_nonce' ] );
    149                     wp_safe_redirect( $url );
    150                     die;
    151                 }
    152             }
    153         }
    154 
    155         /**
    156         * Background process
    157         */
    158         public function background_process() {
    159             self::$background_process = new EXMAGE_Background_Process_Images();
    160         }
    161 
    162         /**
    163         * Skip if the image src is external
    164         *
    165         * @param $skip_image
    166         * @param $src
    167         * @param $tag
    168         *
    169         * @return mixed
    170         */
    171         public function jetpack_photon_skip_image( $skip_image, $src, $tag ) {
    172             if ( ! $skip_image ) {
    173                 if ( strpos( $src, get_site_url() ) !== 0 ) {
    174                     $skip_image = true;
    175                 }
    176             }
    177 
    178             return $skip_image;
    179         }
    180 
    181         /**
    182         * Do not allow to edit external images
    183         *
    184         * @param $filepath
    185         * @param $attachment_id
    186         * @param $size
    187         *
    188         * @return bool
    189         */
    190         public function load_image_to_edit_path( $filepath, $attachment_id, $size ) {
    191             if ( get_post_meta( $attachment_id, '_exmage_external_url', true ) && ! get_post_meta( $attachment_id, '_exmage_imported', true ) ) {
    192                 return false;
    193             }
    194 
    195             return $filepath;
    196         }
    197 
    198         /**
    199         * @param $links
    200         *
    201         * @return mixed
    202         */
    203         public function settings_link( $links ) {
    204             /* translators: %s: admin url */
    205             $links[] = sprintf( wp_kses_post( __( '<a href="%s">Add images from URLs</a>', 'exmage-wp-image-links' ) ), esc_url( admin_url( 'media-new.php' ) ) );
    206 
    207             return $links;
    208         }
    209 
    210         /**
    211         *
    212         */
    213         public function post_upload_ui() {
    214             global $pagenow;
    215             ?>
     141                <?php
     142            }
     143        }
     144
     145        public function admin_init() {
     146            if (isset($_GET['exmage_stop_processing'], $_GET['exmage_nonce']) && wp_verify_nonce($_GET['exmage_nonce'], 'exmage_stop_processing')) {
     147                if (!empty(self::$background_process)) {
     148                    self::$background_process->kill_process();
     149                    $url = remove_query_arg(['exmage_stop_processing', 'exmage_nonce']);
     150                    wp_safe_redirect($url);
     151                    die;
     152                }
     153            }
     154        }
     155
     156        /**
     157        * Background process
     158        */
     159        public function background_process() {
     160            self::$background_process = new EXMAGE_Background_Process_Images();
     161        }
     162
     163        /**
     164        * Skip if the image src is external
     165        *
     166        * @param $skip_image
     167        * @param $src
     168        * @param $tag
     169        *
     170        * @return mixed
     171        */
     172        public function jetpack_photon_skip_image( $skip_image, $src, $tag ) {
     173            if (!$skip_image) {
     174                if (strpos($src, get_site_url()) !== 0) {
     175                    $skip_image = true;
     176                }
     177            }
     178
     179            return $skip_image;
     180        }
     181
     182        /**
     183        * Do not allow to edit external images
     184        *
     185        * @param $filepath
     186        * @param $attachment_id
     187        * @param $size
     188        *
     189        * @return bool
     190        */
     191        public function load_image_to_edit_path( $filepath, $attachment_id, $size ) {
     192            if (get_post_meta($attachment_id, '_exmage_external_url', true) && !get_post_meta($attachment_id, '_exmage_imported', true)) {
     193                return false;
     194            }
     195
     196            return $filepath;
     197        }
     198
     199        /**
     200        * @param $links
     201        *
     202        * @return mixed
     203        */
     204        public function settings_link( $links ) {
     205            /* translators: %s: admin url */
     206            $links[] = sprintf(wp_kses_post(__('<a href="%s">Add images from URLs</a>', 'exmage-wp-image-links')), esc_url(admin_url('media-new.php')));
     207
     208            return $links;
     209        }
     210
     211        /**
     212        *
     213        */
     214        public function post_upload_ui() {
     215            global $pagenow;
     216            ?>
    216217            <div>
    217                 <p class="exmage-use-url-instructions upload-instructions drop-instructions"><?php esc_html_x( 'or', 'Uploader: Upload file - or - Use an external image URL', 'exmage-wp-image-links' ); ?></p>
     218                <p class="exmage-use-url-instructions upload-instructions drop-instructions"><?php esc_html_x('or', 'Uploader: Upload file - or - Use an external image URL', 'exmage-wp-image-links'); ?></p>
    218219                <div class="exmage-use-url-container">
    219220                    <label for="exmage-use-url-input"><?php /* translators: %s: admin url */
    220                         $pagenow === 'media-new.php' ? esc_html_e( 'Save storage by using external image URLs(one line each):', 'exmage-wp-image-links' ) : printf( wp_kses_post( __( 'Save storage by using an external image URL(need to add multiple URLs? <a target="_blank" href="%s">Click here</a>):', 'exmage-wp-image-links' ) ), esc_url( admin_url( 'media-new.php' ) ) ); ?></label>
     221                        $pagenow === 'media-new.php' ? esc_html_e('Save storage by using external image URLs(one line each):', 'exmage-wp-image-links') : printf(wp_kses_post(__('Save storage by using an external image URL(need to add multiple URLs? <a target="_blank" href="%s">Click here</a>):', 'exmage-wp-image-links')), esc_url(admin_url('media-new.php'))); ?></label>
    221222                    <div class="exmage-use-url-input-container">
    222                         <?php
    223                         if ( $pagenow === 'media-new.php' ) {
    224                             ?>
     223                        <?php
     224                        if ($pagenow === 'media-new.php') {
     225                            ?>
    225226                            <textarea class="exmage-use-url-input-multiple" rows="10"></textarea>
    226227                            <p>
    227                                 <span class="exmage-use-url-input-multiple-add button button-primary"><?php esc_html_e( 'Add', 'exmage-wp-image-links' ) ?></span>
     228                                <span class="exmage-use-url-input-multiple-add button button-primary"><?php esc_html_e('Add', 'exmage-wp-image-links') ?></span>
    228229                            </p>
    229                             <?php
    230                         } else {
    231                             ?>
     230                            <?php
     231                        } else {
     232                            ?>
    232233                            <input type="search" id="exmage-use-url-input" class="exmage-use-url-input"
    233                                    placeholder="<?php esc_attr_e( 'Paste an external image URL here or press Enter after you type to process', 'exmage-wp-image-links' ) ?>">
    234                             <?php
    235                         }
    236                         ?>
     234                                   placeholder="<?php esc_attr_e('Paste an external image URL here or press Enter after you type to process', 'exmage-wp-image-links') ?>">
     235                            <?php
     236                        }
     237                        ?>
    237238                        <div class="exmage-use-url-input-overlay exmage-hidden"></div>
    238239                    </div>
     
    240241                </div>
    241242            </div>
    242             <?php
    243         }
    244 
    245         /**
    246         * @param $response
    247         *
    248         * @return mixed
    249         */
    250         public function wp_prepare_attachment_for_js( $response ) {
    251             $_exmage_external_url = '';
    252             if ( ! get_post_meta( $response['id'], '_exmage_imported', true ) ) {
    253                 $_exmage_external_url = get_post_meta( $response['id'], '_exmage_external_url', true );
     243            <?php
     244        }
     245
     246        /**
     247        * @param $response
     248        *
     249        * @return mixed
     250        */
     251        public function wp_prepare_attachment_for_js( $response ) {
     252            $_exmage_external_url = '';
     253            if (!get_post_meta($response['id'], '_exmage_imported', true)) {
     254                $_exmage_external_url = get_post_meta($response['id'], '_exmage_external_url', true);
    254255//              if ( $_exmage_external_url ) {
    255256//                  $response['can']['save'] = false;
    256257//              }
    257             }
    258             $response['_exmage_external_url'] = $_exmage_external_url;
    259 
    260             return $response;
    261         }
    262 
    263         /**
    264         * Override templates
    265         */
    266         public function override_media_template_attachment_detail() {
    267             ?>
     258            }
     259            $response['_exmage_external_url'] = $_exmage_external_url;
     260
     261            return $response;
     262        }
     263
     264        /**
     265        * Override templates
     266        */
     267        public function override_media_template_attachment_detail() {
     268            ?>
    268269            <script type="text/html" id="tmpl-exmage-attachment">
    269270                <div class="attachment-preview js--select-attachment type-{{ data.type }} subtype-{{ data.subtype }} {{ data.orientation }}">
     
    294295                    <# if ( data.buttons.close ) { #>
    295296                    <button type="button" class="button-link attachment-close media-modal-icon"><span
    296                                 class="screen-reader-text"><?php esc_html_e( 'Remove', 'exmage-wp-image-links' ); ?></span></button>
     297                                class="screen-reader-text"><?php esc_html_e('Remove', 'exmage-wp-image-links'); ?></span></button>
    297298                    <# } #>
    298299                </div>
    299300                <# if ( data.buttons.check ) { #>
    300301                <button type="button" class="check" tabindex="-1"><span class="media-modal-icon"></span><span
    301                             class="screen-reader-text"><?php esc_html_e( 'Deselect', 'exmage-wp-image-links' ); ?></span></button>
     302                            class="screen-reader-text"><?php esc_html_e('Deselect', 'exmage-wp-image-links'); ?></span></button>
    302303                <# } #>
    303304                <# if ( data.hasOwnProperty('_exmage_external_url')&&data._exmage_external_url ) { #>
    304305                <span class="exmage-is-external-link"
    305                       title="<?php esc_html_e( 'This is an external media file', 'exmage-wp-image-links' ); ?>"><span
     306                      title="<?php esc_html_e('This is an external media file', 'exmage-wp-image-links'); ?>"><span
    306307                            class="dashicons dashicons-external"></span></span>
    307308                <# } #>
     
    311312                if ( 'image' === data.type ) { #>
    312313                <input type="text" value="{{ data.caption }}" class="describe" data-setting="caption"
    313                        aria-label="<?php esc_attr_e( 'Caption' ); ?>"
    314                        placeholder="<?php esc_attr_e( 'Caption&hellip;' ); ?>" {{ maybeReadOnly }}/>
     314                       aria-label="<?php esc_attr_e('Caption'); ?>"
     315                       placeholder="<?php esc_attr_e('Caption&hellip;'); ?>" {{ maybeReadOnly }}/>
    315316                <# } else { #>
    316317                <input type="text" value="{{ data.title }}" class="describe" data-setting="title"
    317318                <# if ( 'video' === data.type ) { #>
    318                 aria-label="<?php esc_attr_e( 'Video title' ); ?>"
    319                 placeholder="<?php esc_attr_e( 'Video title&hellip;' ); ?>"
     319                aria-label="<?php esc_attr_e('Video title'); ?>"
     320                placeholder="<?php esc_attr_e('Video title&hellip;'); ?>"
    320321                <# } else if ( 'audio' === data.type ) { #>
    321                 aria-label="<?php esc_attr_e( 'Audio title' ); ?>"
    322                 placeholder="<?php esc_attr_e( 'Audio title&hellip;' ); ?>"
     322                aria-label="<?php esc_attr_e('Audio title'); ?>"
     323                placeholder="<?php esc_attr_e('Audio title&hellip;'); ?>"
    323324                <# } else { #>
    324                 aria-label="<?php esc_attr_e( 'Media title' ); ?>"
    325                 placeholder="<?php esc_attr_e( 'Media title&hellip;' ); ?>"
     325                aria-label="<?php esc_attr_e('Media title'); ?>"
     326                placeholder="<?php esc_attr_e('Media title&hellip;'); ?>"
    326327                <# } #> {{ maybeReadOnly }} />
    327328                <# }
    328329                } #>
    329330            </script>
    330             <?php
    331         }
    332 
    333         /**
    334         * Add External URL column to media list view
    335         *
    336         * @param $cols
    337         *
    338         * @return mixed
    339         */
    340         public function is_external( $cols ) {
    341             $cols['exmage_is_external'] = '<span>' . esc_html__( 'External URL', 'exmage-wp-image-links' ) . '</span>';
    342 
    343             return $cols;
    344         }
    345 
    346         /**
    347         * @param $col
    348         */
    349         public function column_callback_media( $col ) {
    350             global $post;
    351             if ( $col === 'exmage_is_external' && $post ) {
    352                 ?>
     331            <?php
     332        }
     333
     334        /**
     335        * Add External URL column to media list view
     336        *
     337        * @param $cols
     338        *
     339        * @return mixed
     340        */
     341        public function is_external( $cols ) {
     342            $cols['exmage_is_external'] = '<span>' . esc_html__('External URL', 'exmage-wp-image-links') . '</span>';
     343
     344            return $cols;
     345        }
     346
     347        /**
     348        * @param $col
     349        */
     350        public function column_callback_media( $col ) {
     351            global $post;
     352            if ($col === 'exmage_is_external' && $post) {
     353                ?>
    353354                <div class="exmage-external-url-container">
    354355                    <div class="exmage-external-url-content">
    355                         <?php
    356                         $_exmage_imported = get_post_meta( $post->ID, '_exmage_imported', true );
    357                         $external_link    = get_post_meta( $post->ID, '_exmage_external_url', true );
    358                         if ( ! $_exmage_imported && $external_link ) {
    359                             self::html_for_external_image( $external_link, $post->ID );
    360                         } elseif ( $_exmage_imported || get_post_meta( $post->ID, '_vi_wad_image_id', true ) ) {
     356                        <?php
     357                        $_exmage_imported = get_post_meta($post->ID, '_exmage_imported', true);
     358                        $external_link = get_post_meta($post->ID, '_exmage_external_url', true);
     359                        if (!$_exmage_imported && $external_link) {
     360                            self::html_for_external_image($external_link, $post->ID);
     361                        } elseif ($_exmage_imported || get_post_meta($post->ID, '_vi_wad_image_id', true)) {
    361362//                          self::html_for_convertable_external_image( $post->ID );
    362                         }
    363                         ?>
     363                        }
     364                        ?>
    364365                    </div>
    365366                    <p class="exmage-migrate-message"></p>
    366367                </div>
    367                 <?php
    368             }
    369         }
    370 
    371         /**
    372         * @param $attachment_id
    373         */
    374         private static function html_for_convertable_external_image( $attachment_id ) {
    375             ?>
     368                <?php
     369            }
     370        }
     371
     372        /**
     373        * @param $attachment_id
     374        */
     375        private static function html_for_convertable_external_image( $attachment_id ) {
     376            ?>
    376377            <p class="exmage-action-buttons-container">
    377378                <span class="button exmage-convert-external-button"
    378                       data-attachment_id="<?php echo esc_attr( $attachment_id ) ?>"
    379                       title="<?php esc_attr_e( 'Change this image to use external link. The existing image file stored on your server will be deleted.', 'exmage-wp-image-links' ) ?>">
     379                      data-attachment_id="<?php echo esc_attr($attachment_id) ?>"
     380                      title="<?php esc_attr_e('Change this image to use external link. The existing image file stored on your server will be deleted.', 'exmage-wp-image-links') ?>">
    380381                    <span class="dashicons dashicons-cloud-upload"></span>
    381382                    <span class="exmage-migrate-button-overlay"></span>
    382383                </span>
    383384            </p>
    384             <?php
    385         }
    386 
    387         /**
    388         * @param $external_link
    389         * @param $attachment_id
    390         */
    391         private static function html_for_external_image( $external_link, $attachment_id ) {
    392             ?>
     385            <?php
     386        }
     387
     388        /**
     389        * @param $external_link
     390        * @param $attachment_id
     391        */
     392        private static function html_for_external_image( $external_link, $attachment_id ) {
     393            ?>
    393394            <a target="_blank"
    394                href="<?php echo esc_url( $external_link ) ?>"><span
    395                         class="exmage-external-url"><?php echo esc_html( $external_link ) ?></span><span
     395               href="<?php echo esc_url($external_link) ?>"><span
     396                        class="exmage-external-url"><?php echo esc_html($external_link) ?></span><span
    396397                        class="dashicons dashicons-external"></span>
    397398            </a>
    398399            <p class="exmage-action-buttons-container">
    399400                <span class="button exmage-migrate-button"
    400                       data-attachment_id="<?php echo esc_attr( $attachment_id ) ?>"
    401                       title="<?php esc_attr_e( 'Save this image to your WordPress server like normal images so that it will be editable', 'exmage-wp-image-links' ) ?>">
     401                      data-attachment_id="<?php echo esc_attr($attachment_id) ?>"
     402                      title="<?php esc_attr_e('Save this image to your WordPress server like normal images so that it will be editable', 'exmage-wp-image-links') ?>">
    402403                    <span class="dashicons dashicons-cloud-saved"></span>
    403404                    <span class="exmage-migrate-button-overlay"></span>
    404405                </span>
    405406            </p>
    406             <?php
    407         }
    408 
    409         /**
    410         * Check if an url is a valid image
    411         *
    412         * @param $url
    413         * @param $width
    414         * @param $height
    415         *
    416         * @return bool
    417         */
    418         private static function is_image_url_valid( $url, &$width, &$height ) {
    419             $is_valid_image_url = false;
    420             $request = wp_safe_remote_get( $url );
    421             if ( ! is_wp_error( $request ) && wp_remote_retrieve_response_code( $request ) === 200 && in_array( wp_remote_retrieve_header( $request, 'content-type' ), self::get_supported_mime_types(), true ) ) {
    422                 $is_valid_image_url = true;
    423             }
    424             if ($is_valid_image_url) {
    425                 $image_size         = function_exists( 'wp_getimagesize' ) ? wp_getimagesize( $url ) : getimagesize( $url );
    426                 if ( $image_size !== false ) {
    427                     $width = $image_size[0];
    428                     $height = $image_size[1];
    429                 }
    430             }
    431             return $is_valid_image_url;
    432         }
    433 
    434         /**
    435         * Save external images
    436         */
    437         public function convert_external_image() {
    438             global $wpdb;
    439             if ( ! current_user_can( 'manage_options' ) ) {
    440                 wp_die( 'Sorry, you do not have permission.' );
    441             }
    442             check_ajax_referer( 'exmage_ajax_handle_url', '_exmage_ajax_nonce' );
    443             $response      = array(
    444                 'status' => 'error',
    445                 'message' => '',
    446             );
    447             $attachment_id = isset( $_POST['attachment_id'] ) ? sanitize_text_field( $_POST['attachment_id'] ) : '';
    448             $to_external   = isset( $_POST['to_external'] ) ? sanitize_text_field( $_POST['to_external'] ) : '';
    449 
    450             if ( $attachment_id ) {
    451                 $attachment = get_post( $attachment_id );
    452                 if ( $attachment && $attachment->post_type === 'attachment' ) {
    453                     $url              = get_post_meta( $attachment_id, '_exmage_external_url', true );
    454                     $_exmage_imported = get_post_meta( $attachment_id, '_exmage_imported', true );
    455                     if ( $to_external ) {
    456                         $to_url = '';
    457                         if ( $_exmage_imported ) {
    458                             if ( $url ) {
    459                                 $to_url = $url;
    460                             }
    461                         } else {
    462                             $ali_image_id = get_post_meta( $attachment_id, '_vi_wad_image_id', true );
    463                             if ( $ali_image_id ) {
    464                                 $to_url = $ali_image_id;
    465                                 if ( 'https' !== substr( $to_url, 0, 5 ) ) {
    466                                     $to_url = set_url_scheme( '//' . $to_url, 'https' );
    467                                 }
    468                             }
    469                         }
    470 
    471                         if ( $to_url ) {
    472                             $width              = $height = 800;
    473                             $is_valid_image_url = self::is_image_url_valid( $to_url, $width, $height );
    474 
    475                             if ( $is_valid_image_url ) {
    476                                 $file = get_attached_file( $attachment_id, true );
    477                                 if ( is_multisite() ) {
    478                                     clean_dirsize_cache( $file );
    479                                 }
    480                                 if ( wp_delete_attachment_files( $attachment_id, wp_get_attachment_metadata( $attachment_id ), get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true ), $file ) ) {
    481                                     $to_url = self::process_image_url( $to_url, $image_id, $is_ali_cdn );
    482                                     update_post_meta( $attachment_id, '_wp_attached_file', $to_url );
    483                                     if ( $_exmage_imported ) {
    484                                         delete_post_meta( $attachment_id, '_exmage_imported' );
    485                                     } else {
     407            <?php
     408        }
     409
     410        /**
     411        * Check if an url is a valid image
     412        *
     413        * @param $url
     414        * @param $width
     415        * @param $height
     416        *
     417        * @return bool
     418        */
     419        private static function is_image_url_valid( $url, &$width, &$height ) {
     420            $is_valid_image_url = false;
     421            $request = wp_safe_remote_get($url);
     422            if (!is_wp_error($request) && wp_remote_retrieve_response_code($request) === 200 && in_array(wp_remote_retrieve_header($request, 'content-type'), self::get_supported_mime_types(), true)) {
     423                $is_valid_image_url = true;
     424            }
     425            if ($is_valid_image_url) {
     426                $image_size = function_exists('wp_getimagesize') ? wp_getimagesize($url) : getimagesize($url);
     427                if ($image_size !== false) {
     428                    $width = $image_size[0];
     429                    $height = $image_size[1];
     430                }
     431            }
     432            return $is_valid_image_url;
     433        }
     434
     435        /**
     436        * Save external images
     437        */
     438        public function convert_external_image() {
     439            global $wpdb;
     440            if (!current_user_can('manage_options')) {
     441                wp_die('Sorry, you do not have permission.');
     442            }
     443            check_ajax_referer('exmage_ajax_handle_url', '_exmage_ajax_nonce');
     444            $response = array(
     445                'status' => 'error',
     446                'message' => '',
     447            );
     448            $attachment_id = isset($_POST['attachment_id']) ? sanitize_text_field($_POST['attachment_id']) : '';
     449            $to_external = isset($_POST['to_external']) ? sanitize_text_field($_POST['to_external']) : '';
     450
     451            if ($attachment_id) {
     452                $attachment = get_post($attachment_id);
     453                if ($attachment && $attachment->post_type === 'attachment') {
     454                    $url = get_post_meta($attachment_id, '_exmage_external_url', true);
     455                    $_exmage_imported = get_post_meta($attachment_id, '_exmage_imported', true);
     456                    if ($to_external) {
     457                        $to_url = '';
     458                        if ($_exmage_imported) {
     459                            if ($url) {
     460                                $to_url = $url;
     461                            }
     462                        } else {
     463                            $ali_image_id = get_post_meta($attachment_id, '_vi_wad_image_id', true);
     464                            if ($ali_image_id) {
     465                                $to_url = $ali_image_id;
     466                                if ('https' !== substr($to_url, 0, 5)) {
     467                                    $to_url = set_url_scheme('//' . $to_url, 'https');
     468                                }
     469                            }
     470                        }
     471
     472                        if ($to_url) {
     473                            $width = $height = 800;
     474                            $is_valid_image_url = self::is_image_url_valid($to_url, $width, $height);
     475
     476                            if ($is_valid_image_url) {
     477                                $file = get_attached_file($attachment_id, true);
     478                                if (is_multisite()) {
     479                                    clean_dirsize_cache($file);
     480                                }
     481                                if (wp_delete_attachment_files($attachment_id, wp_get_attachment_metadata($attachment_id), get_post_meta($attachment_id, '_wp_attachment_backup_sizes', true), $file)) {
     482                                    $to_url = self::process_image_url($to_url, $image_id, $is_ali_cdn);
     483                                    update_post_meta($attachment_id, '_wp_attached_file', $to_url);
     484                                    if ($_exmage_imported) {
     485                                        delete_post_meta($attachment_id, '_exmage_imported');
     486                                    } else {
    486487//                                      delete_post_meta( $attachment_id, '_vi_wad_image_id' );
    487                                     }
    488                                     self::update_attachment_metadata( $attachment_id, $to_url, $is_ali_cdn, $width, $height );
    489                                     /*guid cannot be changed with wp_update_post function*/
    490                                     $wpdb->update( $wpdb->posts, array(// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    491                                         'guid'       => strlen( $to_url ) > 255 ? '' : $to_url,//guid is varchar(255)
    492                                         'post_title' => apply_filters( 'exmage_insert_attachment_image_name', basename( $image_id ), $image_id, $to_url, $attachment->post_parent ),
    493                                     ), array( 'ID' => $attachment_id ) );
    494                                     $response['status'] = 'success';
    495                                     ob_start();
    496                                     self::html_for_external_image( $to_url, $attachment_id );
    497                                     $response['message'] = ob_get_clean();
    498 
    499                                 } else {
    500                                     $response['message'] = esc_html__( 'Cannot delete file', 'exmage-wp-image-links' );
    501                                 }
    502                             } else {
    503                                 $response['message'] = esc_html__( 'Invalid or not supported image URL', 'exmage-wp-image-links' );
    504                             }
    505                         } else {
    506                             $response['message'] = esc_html__( 'Cannot find external URL', 'exmage-wp-image-links' );
    507                         }
    508                     } else {
    509                         if ( ! $_exmage_imported ) {
    510                             if ( $url ) {
    511                                 $tmp                    = download_url( $url );
    512                                 $file_array['name']     = $attachment->post_title ? $attachment->post_title : basename( $url );
    513                                 $file_array['tmp_name'] = $tmp;
    514                                 if ( ! is_wp_error( $tmp ) ) {
    515                                     $file = wp_handle_sideload( $file_array, array( 'test_form' => false ) );
    516                                     if ( ! isset( $file['error'] ) ) {
    517                                         $file_url = $file['url'];
    518                                         $type    = $file['type'];
    519                                         $file    = $file['file'];
    520                                         $title    = preg_replace( '/\.[^.]+$/', '', wp_basename( $file ) );
    521                                         $content = '';
    522                                         // Use image exif/iptc data for title and caption defaults if possible.
    523                                         $image_meta = wp_read_image_metadata( $file );
    524 
    525                                         if ( $image_meta ) {
    526                                             if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
    527                                                 $title = $image_meta['title'];
    528                                             }
    529 
    530                                             if ( trim( $image_meta['caption'] ) ) {
    531                                                 $content = $image_meta['caption'];
    532                                             }
    533                                         }
    534                                         $update_data = array(
    535                                             'ID'            => $attachment_id,
    536                                             'post_mime_type' => $type,
    537                                             'post_content'  => $content,
    538                                         );
    539                                         if ( ! $attachment->post_title ) {
    540                                             $update_data['post_title'] = $title;
    541                                         }
    542                                         // Save the attachment metadata.
    543                                         $update_post = wp_update_post( $update_data, true );
    544                                         if ( ! is_wp_error( $update_post ) ) {
    545                                             /*guid cannot be changed with wp_update_post function*/
    546                                             $wpdb->update( $wpdb->posts, array(// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    547                                                 'guid' => strlen( $file_url ) > 255 ? '' : $file_url,
    548                                                 //guid is varchar(255)
    549                                             ), array( 'ID' => $attachment_id ) );
    550                                             $response['status'] = 'success';
    551                                             ob_start();
    552                                             self::html_for_convertable_external_image( $attachment_id );
    553                                             $response['message'] = ob_get_clean();
    554                                             $upload_dir          = wp_get_upload_dir();
    555                                             $image_baseurl       = trailingslashit( $upload_dir['baseurl'] );
    556                                             update_post_meta( $attachment_id, '_wp_attached_file', str_replace( $image_baseurl, '', $file_url ) );
    557                                             update_post_meta( $attachment_id, '_exmage_imported', time() );
    558                                             wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
    559                                         } else {
    560                                             $response['message'] = $update_post->get_error_message();
    561                                         }
    562                                     } else {
    563                                         $response['message'] = $file['error'];
    564                                     }
    565                                 } else {
    566                                     @wp_delete_file( $file_array['tmp_name'] );
    567                                     $response['message'] = $tmp->get_error_message();
    568                                 }
    569                             } else {
    570                                 $response['message'] = esc_html__( 'Cannot find external URL', 'exmage-wp-image-links' );
    571                             }
    572                         } else {
    573                             $response['message'] = esc_html__( 'Saved already, please reload the page', 'exmage-wp-image-links' );
    574                         }
    575                     }
    576                 }
    577             }
    578 
    579             wp_send_json( $response );
    580         }
    581 
    582         /**
    583         * @param $url
    584         * @param $image_id
    585         * @param $is_ali_cdn
    586         *
    587         * @return string|string[]|null
    588         */
    589         public static function process_image_url( $url, &$image_id, &$is_ali_cdn ) {
    590             $new_url = $url;
     488                                    }
     489                                    self::update_attachment_metadata($attachment_id, $to_url, $is_ali_cdn, $width, $height);
     490                                    /*guid cannot be changed with wp_update_post function*/
     491                                    $wpdb->update($wpdb->posts, array(// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
     492                                        'guid' => strlen($to_url) > 255 ? '' : $to_url,//guid is varchar(255)
     493                                        'post_title' => apply_filters('exmage_insert_attachment_image_name', basename($image_id), $image_id, $to_url, $attachment->post_parent),
     494                                    ), array('ID' => $attachment_id));
     495                                    $response['status'] = 'success';
     496                                    ob_start();
     497                                    self::html_for_external_image($to_url, $attachment_id);
     498                                    $response['message'] = ob_get_clean();
     499
     500                                } else {
     501                                    $response['message'] = esc_html__('Cannot delete file', 'exmage-wp-image-links');
     502                                }
     503                            } else {
     504                                $response['message'] = esc_html__('Invalid or not supported image URL', 'exmage-wp-image-links');
     505                            }
     506                        } else {
     507                            $response['message'] = esc_html__('Cannot find external URL', 'exmage-wp-image-links');
     508                        }
     509                    } else {
     510                        if (!$_exmage_imported) {
     511                            if ($url) {
     512                                $tmp = download_url($url);
     513                                $file_array['name'] = $attachment->post_title ? $attachment->post_title : basename($url);
     514                                $file_array['tmp_name'] = $tmp;
     515                                if (!is_wp_error($tmp)) {
     516                                    $file = wp_handle_sideload($file_array, array('test_form' => false));
     517                                    if (!isset($file['error'])) {
     518                                        $file_url = $file['url'];
     519                                        $type = $file['type'];
     520                                        $file = $file['file'];
     521                                        $title = preg_replace('/\.[^.]+$/', '', wp_basename($file));
     522                                        $content = '';
     523                                        // Use image exif/iptc data for title and caption defaults if possible.
     524                                        $image_meta = wp_read_image_metadata($file);
     525
     526                                        if ($image_meta) {
     527                                            if (trim($image_meta['title']) && !is_numeric(sanitize_title($image_meta['title']))) {
     528                                                $title = $image_meta['title'];
     529                                            }
     530
     531                                            if (trim($image_meta['caption'])) {
     532                                                $content = $image_meta['caption'];
     533                                            }
     534                                        }
     535                                        $update_data = array(
     536                                            'ID' => $attachment_id,
     537                                            'post_mime_type' => $type,
     538                                            'post_content' => $content,
     539                                        );
     540                                        if (!$attachment->post_title) {
     541                                            $update_data['post_title'] = $title;
     542                                        }
     543                                        // Save the attachment metadata.
     544                                        $update_post = wp_update_post($update_data, true);
     545                                        if (!is_wp_error($update_post)) {
     546                                            /*guid cannot be changed with wp_update_post function*/
     547                                            $wpdb->update($wpdb->posts, array(// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
     548                                                'guid' => strlen($file_url) > 255 ? '' : $file_url,
     549                                                //guid is varchar(255)
     550                                            ), array('ID' => $attachment_id));
     551                                            $response['status'] = 'success';
     552                                            ob_start();
     553                                            self::html_for_convertable_external_image($attachment_id);
     554                                            $response['message'] = ob_get_clean();
     555                                            $upload_dir = wp_get_upload_dir();
     556                                            $image_baseurl = trailingslashit($upload_dir['baseurl']);
     557                                            update_post_meta($attachment_id, '_wp_attached_file', str_replace($image_baseurl, '', $file_url));
     558                                            update_post_meta($attachment_id, '_exmage_imported', time());
     559                                            wp_update_attachment_metadata($attachment_id, wp_generate_attachment_metadata($attachment_id, $file));
     560                                        } else {
     561                                            $response['message'] = $update_post->get_error_message();
     562                                        }
     563                                    } else {
     564                                        $response['message'] = $file['error'];
     565                                    }
     566                                } else {
     567                                    @wp_delete_file($file_array['tmp_name']);
     568                                    $response['message'] = $tmp->get_error_message();
     569                                }
     570                            } else {
     571                                $response['message'] = esc_html__('Cannot find external URL', 'exmage-wp-image-links');
     572                            }
     573                        } else {
     574                            $response['message'] = esc_html__('Saved already, please reload the page', 'exmage-wp-image-links');
     575                        }
     576                    }
     577                }
     578            }
     579
     580            wp_send_json($response);
     581        }
     582
     583        /**
     584        * @param $url
     585        * @param $image_id
     586        * @param $is_ali_cdn
     587        *
     588        * @return string|string[]|null
     589        */
     590        public static function process_image_url( $url, &$image_id, &$is_ali_cdn ) {
     591            $new_url = $url;
    591592//          $new_url    = preg_replace( "/(.+?)(.jpg|.jpeg)(.*)/", "$1$2", $new_url );
    592             $parse_url  = wp_parse_url( $new_url );
    593             $scheme     = empty( $parse_url['scheme'] ) ? 'http' : $parse_url['scheme'];
    594             $image_id   = "{$parse_url['host']}{$parse_url['path']}";
    595             $new_url    = "{$scheme}://{$image_id}";
    596             $is_ali_cdn = in_array( $parse_url['host'], array(
    597                 'ae01.alicdn.com',
    598                 'ae02.alicdn.com',
    599                 'ae03.alicdn.com',
    600                 'ae04.alicdn.com',
    601                 'ae05.alicdn.com',
    602             ), true );
    603             preg_match( '/[^?]+\.(jpg|JPG|jpeg|JPEG|jpe|JPE|gif|GIF|png|PNG)/', $new_url, $matches );
    604             if ( ! is_array( $matches ) || ! count( $matches ) ) {
    605                 preg_match( '/[^?]+\.(jpg|JPG|jpeg|JPEG|jpe|JPE|gif|GIF|png|PNG)/', $url, $matches );
    606                 if ( is_array( $matches ) && count( $matches ) ) {
    607                     $new_url  .= "?{$matches[0]}";
    608                     $image_id .= "?{$matches[0]}";
    609                 } elseif ( ! empty( $parse_url['query'] ) ) {
    610                     $new_url .= '?' . $parse_url['query'];
    611                 }
    612             } elseif ( ! empty( $parse_url['query'] ) ) {
    613                 $new_url .= '?' . $parse_url['query'];
    614             }
    615 
    616             return $new_url;
    617         }
    618 
    619         /**
    620          *
    621          */
    622         public function handle_url() {
    623             if ( ! current_user_can( 'manage_options' ) ) {
    624                 wp_die( 'Sorry, you do not have permission.' );
    625             }
    626             check_ajax_referer( 'exmage_ajax_handle_url', '_exmage_ajax_nonce' );
    627             $response  = array(
    628                 'status'  => 'error',
    629                 'message' => '',
    630                 'id'      => '',
    631                 'details' => array(),
    632             );
    633             $post_id   = isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : '';
    634             $is_single = isset( $_POST['is_single'] ) ? sanitize_text_field( $_POST['is_single'] ) : '';
    635             $urls      = isset( $_POST['urls'] ) ? sanitize_trackback_urls( $_POST['urls'] ) : '';
    636             if ( ! empty( $urls ) ) {
    637                 $urls_array = explode( "\n", $urls );
    638                 $urls_array = array_filter( $urls_array );
    639                 $urls_array = array_values( array_unique( $urls_array ) );
    640                 if ( $is_single ) {
    641                     $urls_array = array_slice( $urls_array, 0, 1 );
    642                 }
    643                 $urls_count     = count( $urls_array );
    644                 $urls_threshold = apply_filters( 'exmage_ajax_handle_url_threshold', 20 );
    645                 if ( $urls_count <= $urls_threshold ) {
    646                     foreach ( $urls_array as $url ) {
    647                         $response['details'][] = self::add_image( $url, $image_id, $post_id );
    648                     }
    649                 } else {
    650                     foreach ( $urls_array as $url ) {
    651                         self::$background_process->push_to_queue( array( 'url' => $url, 'post_id' => $post_id ) );
    652                     }
    653                     self::$background_process->save()->dispatch();
    654                     /* translators: %1$s: number of url, %2$s: threshold of url */
    655                     $response['message'] = sprintf( esc_html__( 'The number of URLs(%1$s) is greater than threshold(%2$s), they will be processed in the background.(You can change the threshold via exmage_ajax_handle_url_threshold filter hook.)', 'exmage-wp-image-links' ), $urls_count, $urls_threshold );
    656                     $response['status']  = 'queue';
    657                 }
    658             }
    659             if ( count( $response['details'] ) ) {
    660                 $response['status'] = 'success';
    661             } elseif ( $response['status'] !== 'queue' ) {
    662                 $response['message'] = esc_html__( 'No valid image URLs found', 'exmage-wp-image-links' );
    663             }
    664 
    665             wp_send_json( $response );
    666         }
    667 
    668         /**
    669          * Add an external image
    670          *
    671          * @param $url
    672          * @param $image_id
    673          * @param string $parent_id
    674          *
    675          * @return array
    676          */
    677         public static function add_image( $url, &$image_id, $parent_id = '' ) {
    678             $result = array(
    679                 'url'       => $url,
    680                 'message'   => '',
    681                 'status'    => 'error',
    682                 'id'        => '',
    683                 'edit_link' => '',
    684             );
    685 
    686             $url = sanitize_trackback_urls( $url );
    687             $url = wp_http_validate_url( $url );
    688 
    689             if ( ! $url ) {
    690                 $result['message'] = esc_html__( 'Invalid image URL', 'exmage-wp-image-links' );
    691 
    692                 return $result;
    693             }
    694 
    695             $width              = $height = 800;
    696             $is_valid_image_url = self::is_image_url_valid( $url, $width, $height );
    697             if ( $is_valid_image_url ) {
    698                 $url   = self::process_image_url( $url, $image_id, $is_ali_cdn );
    699                 $exist = attachment_url_to_postid( $url );
    700                 if ( ! $exist ) {
    701                     $check_filetype   = wp_check_filetype( basename( $url ), null );
    702                     $attachment_image = array(
    703                         'post_title'     => apply_filters( 'exmage_insert_attachment_image_name', basename( $image_id ), $image_id, $url, $parent_id ),
    704                         'post_mime_type' => empty( $check_filetype['type'] ) ? 'image/url' : $check_filetype['type'],
    705                         'guid'           => strlen( $url ) > 255 ? '' : $url,//guid is varchar(255)
    706                         'post_status'    => 'inherit'
    707                     );
    708                     if ( class_exists( 'WPML_Media_Attachments_Duplication' ) ) {
    709                         /*Prevent WPML from duplicating this external image*/
    710                         exmage_remove_filter( 'add_attachment', 'WPML_Media_Attachments_Duplication', 'save_attachment_actions' );
    711                         exmage_remove_filter( 'add_attachment', 'WPML_Media_Attachments_Duplication', 'save_translated_attachments' );
    712                     }
    713                     $attachment_id = wp_insert_attachment( $attachment_image, $url, $parent_id, true );
    714                     if ( $attachment_id && ! is_wp_error( $attachment_id ) ) {
    715                         self::update_attachment_metadata( $attachment_id, $url, $is_ali_cdn, $width, $height );
    716                         $result['id']        = $attachment_id;
    717                         $result['status']    = 'success';
    718                         $result['message']   = esc_html__( 'Successful', 'exmage-wp-image-links' );
    719                         $result['edit_link'] = esc_url( add_query_arg( array(
    720                             'post'   => $attachment_id,
    721                             'action' => 'edit'
    722                         ), admin_url( 'post.php' ) ) );
    723                     } else {
    724                         $result['message'] = $attachment_id->get_error_message();
    725                     }
    726                 } else {
    727                     $edit_link           = add_query_arg( array(
    728                         'post'   => $exist,
    729                         'action' => 'edit'
    730                     ), admin_url( 'post.php' ) );
    731                     $result['id']        = $exist;
    732                     $result['message']   = esc_html__( 'Image exists', 'exmage-wp-image-links' );
    733                     $result['edit_link'] = esc_url( $edit_link );
    734                 }
    735             } else {
    736                 $result['message'] = esc_html__( 'Invalid or not supported image URL', 'exmage-wp-image-links' );
    737             }
    738 
    739             return $result;
    740         }
    741 
    742         /**
    743          * Update metadata
    744          *
    745          * @param $attachment_id
    746          * @param $url
    747          * @param $is_ali_cdn
    748          * @param $width
    749          * @param $height
    750          */
    751         private static function update_attachment_metadata( $attachment_id, $url, $is_ali_cdn, $width, $height ) {
    752             if ( ! get_post_meta( $attachment_id, '_exmage_external_url', true ) ) {
    753                 update_post_meta( $attachment_id, '_exmage_external_url', $url );
    754             }
    755             $wp_sizes    = self::get_sizes();
    756             $image_sizes = array();
    757             $pathinfo    = pathinfo( $url );
    758             if ( ! empty( $pathinfo['extension'] ) ) {
    759                 $common_sizes = $is_ali_cdn ? array(
    760                     'thumbnail'    => 50,
    761                     'small1'       => 100,
    762                     'small2'       => 200,
    763                     'medium'       => 350,
    764                     'medium_large' => 640
    765                 ) : apply_filters( 'exmage_get_supported_image_sizes', array(
    766                     'thumbnail'    => 150,
    767                     'medium'       => 300,
    768                     'medium_large' => 768,
    769                     'large'        => 1024
    770                 ), $url );
    771                 foreach ( $common_sizes as $size_name => $size_width ) {
    772                     if ( $is_ali_cdn ) {
    773                         /*Ali cdn image size format: original-image-name.jpg_100x100.jpg*/
    774                         $size_url = $url . "_{$size_width}x{$size_width}.{$pathinfo['extension']}";
    775                     } else {
    776                         /*WordPress image size format: original-image-name-100x100.jpg*/
    777                         $size_url = apply_filters( 'exmage_image_size_url', substr( $url, 0, strlen( $url ) - strlen( $pathinfo['extension'] ) - 1 ) . "-{$size_width}x{$size_width}.{$pathinfo['extension']}", $url, $size_width );
    778                     }
    779                     $is_valid_image_url = self::is_image_url_valid( $size_url, $_width, $_height );
    780                     if ( ! $is_valid_image_url ) {
    781                         /*Use original url if the image size url is invalid*/
    782                         $size_url = $url;
    783                     }
    784                     $image_sizes[ $size_name ] = array(
    785                         'url'    => $size_url,
    786                         'width'  => $size_width,
    787                         'height' => $size_width
    788                     );
    789                 }
    790             }
    791             if ( ! isset( $image_sizes['large'] ) ) {
    792                 $image_sizes['large'] = array(
    793                     'url'    => $url,
    794                     'width'  => $width,
    795                     'height' => $height
    796                 );
    797             } else {
    798                 $image_sizes['full'] = array(
    799                     'url'    => $url,
    800                     'width'  => $width,
    801                     'height' => $height
    802                 );
    803             }
    804             /*Build attachment metadata*/
    805             $attach_data = array(
    806                 'file'       => $url,
    807                 'width'      => $width,
    808                 'height'     => $height,
    809                 'sizes'      => array(),
    810                 'image_meta' => array(
    811                     'aperture'          => '0',
    812                     'credit'            => '',
    813                     'camera'            => '',
    814                     'caption'           => '',
    815                     'created_timestamp' => '0',
    816                     'copyright'         => '',
    817                     'focal_length'      => '0',
    818                     'iso'               => '0',
    819                     'shutter_speed'     => '0',
    820                     'title'             => '',
    821                     'orientation'       => '0',
    822                     'keywords'          => array(),
    823                 ),
    824             );
    825 
    826             foreach ( $wp_sizes as $size => $props ) {
    827                 $select_size = self::select_size( $props, $image_sizes );
    828                 if ( ! empty( $select_size ) ) {
    829                     $check_filetype                  = wp_check_filetype( basename( $select_size['url'] ), null );
    830                     $attach_data['sizes']["{$size}"] = array(
    831                         'file'      => basename( $select_size['url'] ),
    832                         'width'     => $select_size['width'],
    833                         'height'    => $select_size['height'],
    834                         'mime-type' => $check_filetype['type'],
    835                     );
    836                 }
    837             }
    838             if ( isset( $attach_data['sizes']['full'] ) ) {
    839                 unset( $attach_data['sizes']['full'] );
    840             }
    841             wp_update_attachment_metadata( $attachment_id, $attach_data );
    842         }
    843 
    844         /**
    845          * Generate sizes if any
    846          *
    847          * @return array
    848          */
    849         private static function get_sizes() {
    850             global $_wp_additional_image_sizes;
    851 
    852             $sizes = array();
    853 
    854             foreach ( get_intermediate_image_sizes() as $_size ) {
    855                 if ( in_array( $_size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
    856                     $sizes[ $_size ]['width']  = get_option( "{$_size}_size_w" );
    857                     $sizes[ $_size ]['height'] = get_option( "{$_size}_size_h" );
    858                     $sizes[ $_size ]['crop']   = (bool) get_option( "{$_size}_crop" );
    859                 } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
    860                     $sizes[ $_size ] = array(
    861                         'width'  => $_wp_additional_image_sizes[ $_size ]['width'],
    862                         'height' => $_wp_additional_image_sizes[ $_size ]['height'],
    863                         'crop'   => $_wp_additional_image_sizes[ $_size ]['crop'],
    864                     );
    865                 }
    866             }
    867 
    868             return $sizes;
    869         }
    870 
    871         /**
    872          * @param $size
    873          * @param array $image_sizes
    874          *
    875          * @return bool|mixed
    876          */
    877         private static function select_size( $size, $image_sizes = array() ) {
    878             if ( empty( $image_sizes ) ) {
    879                 return $size;
    880             }
    881 
    882             $min_size = $max_size = false;
    883             foreach ( $image_sizes as $props ) {
    884                 if ( (int) $size['width'] == (int) $props['width'] ) {
    885                     return $props;
    886                 }
    887 
    888                 if ( intval( $size['width'] ) < intval( $props['width'] ) && ( ! $min_size || intval( $min_size['width'] ) > intval( $props['width'] ) ) ) {
    889                     $min_size = $props;
    890                 }
    891 
    892                 if ( ! $max_size || ( intval( $max_size['width'] ) < intval( $props['width'] ) ) ) {
    893                     $max_size = $props;
    894                 }
    895             }
    896 
    897             return ! $min_size ? $max_size : $min_size;
    898         }
    899 
    900         /**
    901          * Enqueue script wherever media is used
    902          */
    903         public function wp_enqueue_media() {
    904             wp_enqueue_script( 'exmage-media', EXMAGE_WP_IMAGE_LINKS_JS . 'media.js', array( 'jquery' ), EXMAGE_WP_IMAGE_LINKS_VERSION, false );
    905             wp_enqueue_style( 'exmage-media', EXMAGE_WP_IMAGE_LINKS_CSS . 'media.css', [], EXMAGE_WP_IMAGE_LINKS_VERSION );
    906             wp_enqueue_script( 'exmage-script', EXMAGE_WP_IMAGE_LINKS_JS . 'exmage.js', array( 'jquery' ), EXMAGE_WP_IMAGE_LINKS_VERSION, false );
    907             wp_localize_script( 'exmage-script', 'exmage_admin_params', array(
    908                 'ajaxurl'                    => admin_url( 'admin-ajax.php' ),
    909                 'uploadurl'                  => admin_url( 'async-upload.php' ),
    910                 'post_id'                    => get_the_ID(),
    911                 '_exmage_ajax_nonce'         => wp_create_nonce( 'exmage_ajax_handle_url' ),
    912                 'i18n_select_existing_image' => esc_html__( 'Click here to select this image', 'exmage-wp-image-links' ),
    913             ) );
    914         }
    915 
    916         /**
    917          *
    918          */
    919         public function init() {
    920             load_plugin_textdomain( 'exmage-wp-image-links' );
    921             $this->load_plugin_textdomain();
    922             if ( class_exists( 'VillaTheme_Support' ) ) {
    923                 new VillaTheme_Support(
    924                     array(
    925                         'support'    => 'https://wordpress.org/support/plugin/exmage-wp-image-links/',
    926                         'docs'       => 'http://docs.villatheme.com/?item=exmage',
    927                         'review'     => 'https://wordpress.org/support/plugin/exmage-wp-image-links/reviews/?rate=5#rate-response',
    928                         'pro_url'    => '',
    929                         'css'        => EXMAGE_WP_IMAGE_LINKS_CSS,
    930                         'image'      => EXMAGE_WP_IMAGE_LINKS_IMAGES,
    931                         'slug'       => 'exmage-wp-image-links',
    932                         'menu_slug'  => '',
    933                         'version'    => EXMAGE_WP_IMAGE_LINKS_VERSION,
    934                         'survey_url' => 'https://script.google.com/macros/s/AKfycbzppiR3CI9GOk_xRYllxRzH-6cuWEZAlJ3VQOu1l2fJ11mrFCgib_cNlvjxfBIGwGFh/exec'
    935                     )
    936                 );
    937             }
    938         }
    939 
    940         /**
    941          *
    942          */
    943         public function load_plugin_textdomain() {
    944             $locale = apply_filters( 'plugin_locale', get_locale(), 'exmage-wp-image-links' );
    945             load_textdomain( 'exmage-wp-image-links', EXMAGE_WP_IMAGE_LINKS_LANGUAGES . "exmage-wp-image-links-$locale.mo" );
    946             load_plugin_textdomain( 'exmage-wp-image-links', false, EXMAGE_WP_IMAGE_LINKS_LANGUAGES );
    947         }
    948 
    949         /**
    950          * @param $url
    951          * @param $id
    952          *
    953          * @return mixed
    954          */
    955         public function wp_get_attachment_url( $url, $id ) {
    956             if ( get_post_meta( $id, '_exmage_imported', true ) ) {
    957                 return $url;
    958             }
    959             if ( ! get_post_meta( $id, '_exmage_external_url', true ) ) {
    960                 return $url;
    961             }
    962             $post = get_post( $id );
    963             if ( $post && 'attachment' === $post->post_type ) {
    964                 $_wp_attached_file = get_post_meta( $id, '_wp_attached_file', true );
    965                 if ( $_wp_attached_file ) {
    966                     if ( substr( $_wp_attached_file, 0, 7 ) === "http://" || substr( $_wp_attached_file, 0, 8 ) === "https://" ) {
    967                         $url = $_wp_attached_file;
    968                     }
    969                 }
    970             }
    971 
    972             return $url;
    973         }
    974 
    975         /**
    976          * @param $sources
    977          * @param $size_array
    978          * @param $image_src
    979          * @param $image_meta
    980          * @param $attachment_id
    981          *
    982          * @return mixed
    983          */
    984         public function wp_calculate_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
    985             if ( get_post_meta( $attachment_id, '_exmage_imported', true ) ) {
    986                 return $sources;
    987             }
    988             if ( ! get_post_meta( $attachment_id, '_exmage_external_url', true ) ) {
    989                 return $sources;
    990             }
    991             if ( $sources ) {
    992                 $upload_dir    = wp_get_upload_dir();
    993                 $image_baseurl = trailingslashit( $upload_dir['baseurl'] );
    994                 if ( is_ssl() && 'https' !== substr( $image_baseurl, 0, 5 ) && ! empty( $_SERVER['HTTP_HOST'] ) && wp_parse_url( $image_baseurl, PHP_URL_HOST ) === $_SERVER['HTTP_HOST'] ) {
    995                     $image_baseurl = set_url_scheme( $image_baseurl, 'https' );
    996                 }
    997                 $_wp_attached_file = get_post_meta( $attachment_id, '_wp_attached_file', true );
    998                 foreach ( $sources as &$src ) {
    999                     $pos = strpos( $_wp_attached_file, 'wp-content/uploads/' );
    1000                     if ( false !== $pos ) {
    1001                         $src['url'] = str_replace( $image_baseurl, substr( $_wp_attached_file, 0, $pos - 1 ) . '/wp-content/uploads/', $src['url'] );
    1002                     } else {
    1003                         $src['url'] = str_replace( $image_baseurl, '', $src['url'] );
    1004                     }
    1005                 }
    1006             }
    1007 
    1008             return $sources;
    1009         }
    1010 
    1011         /**
    1012          * @return mixed|void
    1013          */
    1014         private static function get_supported_mime_types() {
    1015             return apply_filters( 'exmage_get_supported_mime_types', array(
    1016                 'image/png',
    1017                 'image/jpeg',
    1018                 'image/jpg',
    1019                 'image/gif',
    1020                 'image/webp',
    1021             ) );
    1022         }
    1023 
    1024         public function search_exmage_url_when_import_product( &$q ) {
    1025             if ( ! empty( $q->query_vars['meta_query'] ) ) {
    1026                 $file = '';
    1027                 foreach ( $q->query_vars['meta_query'] as $key => &$mt_qr ) {
    1028                     if ( ! empty( $mt_qr['key'] ) && $mt_qr['key'] == '_wc_attachment_source' ) {
    1029                         $file = $mt_qr['value'];
    1030                         break;
    1031                     }
    1032                 }
    1033                 if ( $file ) {
    1034                     $q->query_vars['meta_query'][] = [
    1035                         'key'     => '_exmage_external_url',
    1036                         'value'   => $file,
    1037                         'compare' => 'LIKE',
    1038                     ];
    1039 
    1040                     $q->query_vars['meta_query']['relation'] = 'OR';
    1041                 }
    1042             }
    1043 
    1044         }
    1045     }
     593            $parse_url = wp_parse_url($new_url);
     594            $scheme = empty($parse_url['scheme']) ? 'http' : $parse_url['scheme'];
     595            $image_id = "{$parse_url['host']}{$parse_url['path']}";
     596            $new_url = "{$scheme}://{$image_id}";
     597            $is_ali_cdn = in_array($parse_url['host'], array(
     598                'ae01.alicdn.com',
     599                'ae02.alicdn.com',
     600                'ae03.alicdn.com',
     601                'ae04.alicdn.com',
     602                'ae05.alicdn.com',
     603            ), true);
     604            preg_match('/[^?]+\.(jpg|JPG|jpeg|JPEG|jpe|JPE|gif|GIF|png|PNG)/', $new_url, $matches);
     605            if (!is_array($matches) || !count($matches)) {
     606                preg_match('/[^?]+\.(jpg|JPG|jpeg|JPEG|jpe|JPE|gif|GIF|png|PNG)/', $url, $matches);
     607                if (is_array($matches) && count($matches)) {
     608                    $new_url .= "?{$matches[0]}";
     609                    $image_id .= "?{$matches[0]}";
     610                } elseif (!empty($parse_url['query'])) {
     611                    $new_url .= '?' . $parse_url['query'];
     612                }
     613            } elseif (!empty($parse_url['query'])) {
     614                $new_url .= '?' . $parse_url['query'];
     615            }
     616
     617            return $new_url;
     618        }
     619
     620        /**
     621         *
     622         */
     623        public function handle_url() {
     624            if (!current_user_can('manage_options')) {
     625                wp_die('Sorry, you do not have permission.');
     626            }
     627            check_ajax_referer('exmage_ajax_handle_url', '_exmage_ajax_nonce');
     628            $response = array(
     629                'status' => 'error',
     630                'message' => '',
     631                'id' => '',
     632                'details' => array(),
     633            );
     634            $post_id = isset($_POST['post_id']) ? sanitize_text_field($_POST['post_id']) : '';
     635            $is_single = isset($_POST['is_single']) ? sanitize_text_field($_POST['is_single']) : '';
     636            $urls = isset($_POST['urls']) ? sanitize_trackback_urls($_POST['urls']) : '';
     637            if (!empty($urls)) {
     638                $urls_array = explode("\n", $urls);
     639                $urls_array = array_filter($urls_array);
     640                $urls_array = array_values(array_unique($urls_array));
     641                if ($is_single) {
     642                    $urls_array = array_slice($urls_array, 0, 1);
     643                }
     644                $urls_count = count($urls_array);
     645                $urls_threshold = apply_filters('exmage_ajax_handle_url_threshold', 20);
     646                if ($urls_count <= $urls_threshold) {
     647                    foreach ($urls_array as $url) {
     648                        $response['details'][] = self::add_image($url, $image_id, $post_id);
     649                    }
     650                } else {
     651                    foreach ($urls_array as $url) {
     652                        self::$background_process->push_to_queue(array('url' => $url, 'post_id' => $post_id));
     653                    }
     654                    self::$background_process->save()->dispatch();
     655                    /* translators: %1$s: number of url, %2$s: threshold of url */
     656                    $response['message'] = sprintf(esc_html__('The number of URLs(%1$s) is greater than threshold(%2$s), they will be processed in the background.(You can change the threshold via exmage_ajax_handle_url_threshold filter hook.)', 'exmage-wp-image-links'), $urls_count, $urls_threshold);
     657                    $response['status'] = 'queue';
     658                }
     659            }
     660            if (count($response['details'])) {
     661                $response['status'] = 'success';
     662            } elseif ($response['status'] !== 'queue') {
     663                $response['message'] = esc_html__('No valid image URLs found', 'exmage-wp-image-links');
     664            }
     665
     666            wp_send_json($response);
     667        }
     668
     669        /**
     670         * Add an external image
     671         *
     672         * @param $url
     673         * @param $image_id
     674         * @param string $parent_id
     675         *
     676         * @return array
     677         */
     678        public static function add_image( $url, &$image_id, $parent_id = '' ) {
     679            $result = array(
     680                'url' => $url,
     681                'message' => '',
     682                'status' => 'error',
     683                'id' => '',
     684                'edit_link' => '',
     685            );
     686
     687            $url = sanitize_trackback_urls($url);
     688            $url = wp_http_validate_url($url);
     689
     690            if (!$url) {
     691                $result['message'] = esc_html__('Invalid image URL', 'exmage-wp-image-links');
     692
     693                return $result;
     694            }
     695
     696            $width = $height = 800;
     697            $is_valid_image_url = self::is_image_url_valid($url, $width, $height);
     698            if ($is_valid_image_url) {
     699                $url = self::process_image_url($url, $image_id, $is_ali_cdn);
     700                $exist = attachment_url_to_postid($url);
     701                if (!$exist) {
     702                    $check_filetype = wp_check_filetype(basename($url), null);
     703                    $attachment_image = array(
     704                        'post_title' => apply_filters('exmage_insert_attachment_image_name', basename($image_id), $image_id, $url, $parent_id),
     705                        'post_mime_type' => empty($check_filetype['type']) ? 'image/url' : $check_filetype['type'],
     706                        'guid' => strlen($url) > 255 ? '' : $url,//guid is varchar(255)
     707                        'post_status' => 'inherit'
     708                    );
     709                    if (class_exists('WPML_Media_Attachments_Duplication')) {
     710                        /*Prevent WPML from duplicating this external image*/
     711                        exmage_remove_filter('add_attachment', 'WPML_Media_Attachments_Duplication', 'save_attachment_actions');
     712                        exmage_remove_filter('add_attachment', 'WPML_Media_Attachments_Duplication', 'save_translated_attachments');
     713                    }
     714                    $attachment_id = wp_insert_attachment($attachment_image, $url, $parent_id, true);
     715                    if ($attachment_id && !is_wp_error($attachment_id)) {
     716                        self::update_attachment_metadata($attachment_id, $url, $is_ali_cdn, $width, $height);
     717                        $result['id'] = $attachment_id;
     718                        $result['status'] = 'success';
     719                        $result['message'] = esc_html__('Successful', 'exmage-wp-image-links');
     720                        $result['edit_link'] = esc_url(add_query_arg(array(
     721                            'post' => $attachment_id,
     722                            'action' => 'edit'
     723                        ), admin_url('post.php')));
     724                    } else {
     725                        $result['message'] = $attachment_id->get_error_message();
     726                    }
     727                } else {
     728                    $edit_link = add_query_arg(array(
     729                        'post' => $exist,
     730                        'action' => 'edit'
     731                    ), admin_url('post.php'));
     732                    $result['id'] = $exist;
     733                    $result['message'] = esc_html__('Image exists', 'exmage-wp-image-links');
     734                    $result['edit_link'] = esc_url($edit_link);
     735                }
     736            } else {
     737                $result['message'] = esc_html__('Invalid or not supported image URL', 'exmage-wp-image-links');
     738            }
     739
     740            return $result;
     741        }
     742
     743        /**
     744         * Update metadata
     745         *
     746         * @param $attachment_id
     747         * @param $url
     748         * @param $is_ali_cdn
     749         * @param $width
     750         * @param $height
     751         */
     752        private static function update_attachment_metadata( $attachment_id, $url, $is_ali_cdn, $width, $height ) {
     753            if (!get_post_meta($attachment_id, '_exmage_external_url', true)) {
     754                update_post_meta($attachment_id, '_exmage_external_url', $url);
     755            }
     756            $wp_sizes = self::get_sizes();
     757            $image_sizes = array();
     758            $pathinfo = pathinfo($url);
     759            if (!empty($pathinfo['extension'])) {
     760                $common_sizes = $is_ali_cdn ? array(
     761                    'thumbnail' => 50,
     762                    'small1' => 100,
     763                    'small2' => 200,
     764                    'medium' => 350,
     765                    'medium_large' => 640
     766                ) : apply_filters('exmage_get_supported_image_sizes', array(
     767                    'thumbnail' => 150,
     768                    'medium' => 300,
     769                    'medium_large' => 768,
     770                    'large' => 1024
     771                ), $url);
     772                foreach ($common_sizes as $size_name => $size_width) {
     773                    if ($is_ali_cdn) {
     774                        /*Ali cdn image size format: original-image-name.jpg_100x100.jpg*/
     775                        $size_url = $url . "_{$size_width}x{$size_width}.{$pathinfo['extension']}";
     776                    } else {
     777                        /*WordPress image size format: original-image-name-100x100.jpg*/
     778                        $size_url = apply_filters('exmage_image_size_url', substr($url, 0, strlen($url) - strlen($pathinfo['extension']) - 1) . "-{$size_width}x{$size_width}.{$pathinfo['extension']}", $url, $size_width);
     779                    }
     780                    $is_valid_image_url = self::is_image_url_valid($size_url, $_width, $_height);
     781                    if (!$is_valid_image_url) {
     782                        /*Use original url if the image size url is invalid*/
     783                        $size_url = $url;
     784                    }
     785                    $image_sizes[$size_name] = array(
     786                        'url' => $size_url,
     787                        'width' => $size_width,
     788                        'height' => $size_width
     789                    );
     790                }
     791            }
     792            if (!isset($image_sizes['large'])) {
     793                $image_sizes['large'] = array(
     794                    'url' => $url,
     795                    'width' => $width,
     796                    'height' => $height
     797                );
     798            } else {
     799                $image_sizes['full'] = array(
     800                    'url' => $url,
     801                    'width' => $width,
     802                    'height' => $height
     803                );
     804            }
     805            /*Build attachment metadata*/
     806            $attach_data = array(
     807                'file' => $url,
     808                'width' => $width,
     809                'height' => $height,
     810                'sizes' => array(),
     811                'image_meta' => array(
     812                    'aperture' => '0',
     813                    'credit' => '',
     814                    'camera' => '',
     815                    'caption' => '',
     816                    'created_timestamp' => '0',
     817                    'copyright' => '',
     818                    'focal_length' => '0',
     819                    'iso' => '0',
     820                    'shutter_speed' => '0',
     821                    'title' => '',
     822                    'orientation' => '0',
     823                    'keywords' => array(),
     824                ),
     825            );
     826
     827            foreach ($wp_sizes as $size => $props) {
     828                $select_size = self::select_size($props, $image_sizes);
     829                if (!empty($select_size)) {
     830                    $check_filetype = wp_check_filetype(basename($select_size['url']), null);
     831                    $attach_data['sizes']["{$size}"] = array(
     832                        'file' => basename($select_size['url']),
     833                        'width' => $select_size['width'],
     834                        'height' => $select_size['height'],
     835                        'mime-type' => $check_filetype['type'],
     836                    );
     837                }
     838            }
     839            if (isset($attach_data['sizes']['full'])) {
     840                unset($attach_data['sizes']['full']);
     841            }
     842            wp_update_attachment_metadata($attachment_id, $attach_data);
     843        }
     844
     845        /**
     846         * Generate sizes if any
     847         *
     848         * @return array
     849         */
     850        private static function get_sizes() {
     851            global $_wp_additional_image_sizes;
     852
     853            $sizes = array();
     854
     855            foreach (get_intermediate_image_sizes() as $_size) {
     856                if (in_array($_size, array('thumbnail', 'medium', 'medium_large', 'large'))) {
     857                    $sizes[$_size]['width'] = get_option("{$_size}_size_w");
     858                    $sizes[$_size]['height'] = get_option("{$_size}_size_h");
     859                    $sizes[$_size]['crop'] = (bool)get_option("{$_size}_crop");
     860                } elseif (isset($_wp_additional_image_sizes[$_size])) {
     861                    $sizes[$_size] = array(
     862                        'width' => $_wp_additional_image_sizes[$_size]['width'],
     863                        'height' => $_wp_additional_image_sizes[$_size]['height'],
     864                        'crop' => $_wp_additional_image_sizes[$_size]['crop'],
     865                    );
     866                }
     867            }
     868
     869            return $sizes;
     870        }
     871
     872        /**
     873         * @param $size
     874         * @param array $image_sizes
     875         *
     876         * @return bool|mixed
     877         */
     878        private static function select_size( $size, $image_sizes = array() ) {
     879            if (empty($image_sizes)) {
     880                return $size;
     881            }
     882
     883            $min_size = $max_size = false;
     884            foreach ($image_sizes as $props) {
     885                if ((int)$size['width'] == (int)$props['width']) {
     886                    return $props;
     887                }
     888
     889                if (intval($size['width']) < intval($props['width']) && (!$min_size || intval($min_size['width']) > intval($props['width']))) {
     890                    $min_size = $props;
     891                }
     892
     893                if (!$max_size || (intval($max_size['width']) < intval($props['width']))) {
     894                    $max_size = $props;
     895                }
     896            }
     897
     898            return !$min_size ? $max_size : $min_size;
     899        }
     900
     901        /**
     902         * Enqueue script wherever media is used
     903         */
     904        public function wp_enqueue_media() {
     905            if (is_admin()) {
     906                if (!did_action('wp_enqueue_media')) {
     907                    wp_enqueue_media();
     908                }
     909                wp_enqueue_script('exmage-media', EXMAGE_WP_IMAGE_LINKS_JS . 'media.js', array('jquery'), EXMAGE_WP_IMAGE_LINKS_VERSION, false);
     910                wp_enqueue_style('exmage-media', EXMAGE_WP_IMAGE_LINKS_CSS . 'media.css', [], EXMAGE_WP_IMAGE_LINKS_VERSION);
     911                wp_enqueue_script('exmage-script', EXMAGE_WP_IMAGE_LINKS_JS . 'exmage.js', array('jquery'), EXMAGE_WP_IMAGE_LINKS_VERSION, false);
     912                wp_localize_script('exmage-script', 'exmage_admin_params', array(
     913                    'ajaxurl' => admin_url('admin-ajax.php'),
     914                    'uploadurl' => admin_url('async-upload.php'),
     915                    'post_id' => get_the_ID(),
     916                    '_exmage_ajax_nonce' => wp_create_nonce('exmage_ajax_handle_url'),
     917                    'i18n_select_existing_image' => esc_html__('Click here to select this image', 'exmage-wp-image-links'),
     918                ));
     919            }
     920        }
     921
     922        /**
     923         *
     924         */
     925        public function init() {
     926            load_plugin_textdomain('exmage-wp-image-links');
     927            $this->load_plugin_textdomain();
     928            if (class_exists('VillaTheme_Support')) {
     929                new VillaTheme_Support(
     930                    array(
     931                        'support' => 'https://wordpress.org/support/plugin/exmage-wp-image-links/',
     932                        'docs' => 'http://docs.villatheme.com/?item=exmage',
     933                        'review' => 'https://wordpress.org/support/plugin/exmage-wp-image-links/reviews/?rate=5#rate-response',
     934                        'pro_url' => '',
     935                        'css' => EXMAGE_WP_IMAGE_LINKS_CSS,
     936                        'image' => EXMAGE_WP_IMAGE_LINKS_IMAGES,
     937                        'slug' => 'exmage-wp-image-links',
     938                        'menu_slug' => '',
     939                        'version' => EXMAGE_WP_IMAGE_LINKS_VERSION,
     940                        'survey_url' => 'https://script.google.com/macros/s/AKfycbzppiR3CI9GOk_xRYllxRzH-6cuWEZAlJ3VQOu1l2fJ11mrFCgib_cNlvjxfBIGwGFh/exec'
     941                    )
     942                );
     943            }
     944        }
     945
     946        /**
     947         *
     948         */
     949        public function load_plugin_textdomain() {
     950            $locale = apply_filters('plugin_locale', get_locale(), 'exmage-wp-image-links');
     951            load_textdomain('exmage-wp-image-links', EXMAGE_WP_IMAGE_LINKS_LANGUAGES . "exmage-wp-image-links-$locale.mo");
     952            load_plugin_textdomain('exmage-wp-image-links', false, EXMAGE_WP_IMAGE_LINKS_LANGUAGES);
     953        }
     954
     955        /**
     956         * @param $url
     957         * @param $id
     958         *
     959         * @return mixed
     960         */
     961        public function wp_get_attachment_url( $url, $id ) {
     962            if (get_post_meta($id, '_exmage_imported', true)) {
     963                return $url;
     964            }
     965            if (!get_post_meta($id, '_exmage_external_url', true)) {
     966                return $url;
     967            }
     968            $post = get_post($id);
     969            if ($post && 'attachment' === $post->post_type) {
     970                $_wp_attached_file = get_post_meta($id, '_wp_attached_file', true);
     971                if ($_wp_attached_file) {
     972                    if (substr($_wp_attached_file, 0, 7) === "http://" || substr($_wp_attached_file, 0, 8) === "https://") {
     973                        $url = $_wp_attached_file;
     974                    }
     975                }
     976            }
     977
     978            return $url;
     979        }
     980
     981        /**
     982         * @param $sources
     983         * @param $size_array
     984         * @param $image_src
     985         * @param $image_meta
     986         * @param $attachment_id
     987         *
     988         * @return mixed
     989         */
     990        public function wp_calculate_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
     991            if (get_post_meta($attachment_id, '_exmage_imported', true)) {
     992                return $sources;
     993            }
     994            if (!get_post_meta($attachment_id, '_exmage_external_url', true)) {
     995                return $sources;
     996            }
     997            if ($sources) {
     998                $upload_dir = wp_get_upload_dir();
     999                $image_baseurl = trailingslashit($upload_dir['baseurl']);
     1000                if (is_ssl() && 'https' !== substr($image_baseurl, 0, 5) && !empty($_SERVER['HTTP_HOST']) && wp_parse_url($image_baseurl, PHP_URL_HOST) === $_SERVER['HTTP_HOST']) {
     1001                    $image_baseurl = set_url_scheme($image_baseurl, 'https');
     1002                }
     1003                $_wp_attached_file = get_post_meta($attachment_id, '_wp_attached_file', true);
     1004                foreach ($sources as &$src) {
     1005                    $pos = strpos($_wp_attached_file, 'wp-content/uploads/');
     1006                    if (false !== $pos) {
     1007                        $src['url'] = str_replace($image_baseurl, substr($_wp_attached_file, 0, $pos - 1) . '/wp-content/uploads/', $src['url']);
     1008                    } else {
     1009                        $src['url'] = str_replace($image_baseurl, '', $src['url']);
     1010                    }
     1011                }
     1012            }
     1013
     1014            return $sources;
     1015        }
     1016
     1017        /**
     1018         * @return mixed|void
     1019         */
     1020        private static function get_supported_mime_types() {
     1021            return apply_filters('exmage_get_supported_mime_types', array(
     1022                'image/png',
     1023                'image/jpeg',
     1024                'image/jpg',
     1025                'image/gif',
     1026                'image/webp',
     1027            ));
     1028        }
     1029
     1030        public function search_exmage_url_when_import_product( &$q ) {
     1031            if (!empty($q->query_vars['meta_query'])) {
     1032                $file = '';
     1033                foreach ($q->query_vars['meta_query'] as $key => &$mt_qr) {
     1034                    if (!empty($mt_qr['key']) && $mt_qr['key'] == '_wc_attachment_source') {
     1035                        $file = $mt_qr['value'];
     1036                        break;
     1037                    }
     1038                }
     1039                if ($file) {
     1040                    $q->query_vars['meta_query'][] = [
     1041                        'key' => '_exmage_external_url',
     1042                        'value' => $file,
     1043                        'compare' => 'LIKE',
     1044                    ];
     1045
     1046                    $q->query_vars['meta_query']['relation'] = 'OR';
     1047                }
     1048            }
     1049
     1050        }
     1051    }
    10461052}
    10471053
  • exmage-wp-image-links/trunk/readme.txt

    r3193842 r3203373  
    44Tags: elementor gallery with links, woocommerce product image external url,wordpress gallery custom links, wordpress gallery with links, wordpress image links
    55Requires at least: 5.0.0
    6 Tested up to: 6.7
     6Tested up to: 6.7.1
    77Requires PHP: 7.0
    88License: GPL v2 or later
     
    162162
    163163== Changelog ==
     164/**1.0.20 - 2024.12.06**/
     165– Updated: Compatible with WP 6.7.1 and  WC 9.4.3
     166- Fixed: Cannot add image by URL in Media
     167
    164168/**1.0.19 - 2024.11.21**/
    165169– Updated: Compatible with WP 6.7 and  WC 9.4
Note: See TracChangeset for help on using the changeset viewer.