class-import-images.php (4431B)
1 <?php 2 namespace Elementor\TemplateLibrary\Classes; 3 4 if ( ! defined( 'ABSPATH' ) ) { 5 exit; // Exit if accessed directly. 6 } 7 8 /** 9 * Elementor template library import images. 10 * 11 * Elementor template library import images handler class is responsible for 12 * importing remote images used by the template library. 13 * 14 * @since 1.0.0 15 */ 16 class Import_Images { 17 18 /** 19 * Replaced images IDs. 20 * 21 * The IDs of all the new imported images. An array containing the old 22 * attachment ID and the new attachment ID generated after the import. 23 * 24 * @since 1.0.0 25 * @access private 26 * 27 * @var array 28 */ 29 private $_replace_image_ids = []; 30 31 /** 32 * Get image hash. 33 * 34 * Retrieve the sha1 hash of the image URL. 35 * 36 * @since 2.0.0 37 * @access private 38 * 39 * @param string $attachment_url The attachment URL. 40 * 41 * @return string Image hash. 42 */ 43 private function get_hash_image( $attachment_url ) { 44 return sha1( $attachment_url ); 45 } 46 47 /** 48 * Get saved image. 49 * 50 * Retrieve new image ID, if the image has a new ID after the import. 51 * 52 * @since 2.0.0 53 * @access private 54 * 55 * @param array $attachment The attachment. 56 * 57 * @return false|array New image ID or false. 58 */ 59 private function get_saved_image( $attachment ) { 60 global $wpdb; 61 62 if ( isset( $this->_replace_image_ids[ $attachment['id'] ] ) ) { 63 return $this->_replace_image_ids[ $attachment['id'] ]; 64 } 65 66 $post_id = $wpdb->get_var( 67 $wpdb->prepare( 68 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` 69 WHERE `meta_key` = \'_elementor_source_image_hash\' 70 AND `meta_value` = %s 71 ;', 72 $this->get_hash_image( $attachment['url'] ) 73 ) 74 ); 75 76 if ( $post_id ) { 77 $new_attachment = [ 78 'id' => $post_id, 79 'url' => wp_get_attachment_url( $post_id ), 80 ]; 81 $this->_replace_image_ids[ $attachment['id'] ] = $new_attachment; 82 83 return $new_attachment; 84 } 85 86 return false; 87 } 88 89 /** 90 * Import image. 91 * 92 * Import a single image from a remote server, upload the image WordPress 93 * uploads folder, create a new attachment in the database and updates the 94 * attachment metadata. 95 * 96 * @since 1.0.0 97 * @since 3.2.0 New `$parent_post_id` option added 98 * @access public 99 * 100 * @param array $attachment The attachment. 101 * @param int $parent_post_id Optional 102 * 103 * @return false|array Imported image data, or false. 104 */ 105 public function import( $attachment, $parent_post_id = null ) { 106 if ( ! empty( $attachment['id'] ) ) { 107 $saved_image = $this->get_saved_image( $attachment ); 108 109 if ( $saved_image ) { 110 return $saved_image; 111 } 112 } 113 114 // Extract the file name and extension from the url. 115 $filename = basename( $attachment['url'] ); 116 117 $file_content = wp_remote_retrieve_body( wp_safe_remote_get( $attachment['url'] ) ); 118 119 if ( empty( $file_content ) ) { 120 return false; 121 } 122 123 $upload = wp_upload_bits( 124 $filename, 125 null, 126 $file_content 127 ); 128 129 $post = [ 130 'post_title' => $filename, 131 'guid' => $upload['url'], 132 ]; 133 134 $info = wp_check_filetype( $upload['file'] ); 135 if ( $info ) { 136 $post['post_mime_type'] = $info['type']; 137 } else { 138 // For now just return the origin attachment 139 return $attachment; 140 // return new \WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type.', 'elementor' ) ); 141 } 142 143 $post_id = wp_insert_attachment( $post, $upload['file'], $parent_post_id ); 144 145 // On REST requests. 146 if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) { 147 require_once ABSPATH . '/wp-admin/includes/image.php'; 148 } 149 150 if ( ! function_exists( 'wp_read_video_metadata' ) ) { 151 require_once ABSPATH . '/wp-admin/includes/media.php'; 152 } 153 154 wp_update_attachment_metadata( 155 $post_id, 156 wp_generate_attachment_metadata( $post_id, $upload['file'] ) 157 ); 158 update_post_meta( $post_id, '_elementor_source_image_hash', $this->get_hash_image( $attachment['url'] ) ); 159 160 $new_attachment = [ 161 'id' => $post_id, 162 'url' => $upload['url'], 163 ]; 164 165 if ( ! empty( $attachment['id'] ) ) { 166 $this->_replace_image_ids[ $attachment['id'] ] = $new_attachment; 167 } 168 169 return $new_attachment; 170 } 171 172 /** 173 * Template library import images constructor. 174 * 175 * Initializing the images import class used by the template library through 176 * the WordPress Filesystem API. 177 * 178 * @since 1.0.0 179 * @access public 180 */ 181 public function __construct() { 182 if ( ! function_exists( 'WP_Filesystem' ) ) { 183 require_once ABSPATH . 'wp-admin/includes/file.php'; 184 } 185 186 WP_Filesystem(); 187 } 188 }