image-size.php (11252B)
1 <?php 2 namespace Elementor; 3 4 if ( ! defined( 'ABSPATH' ) ) { 5 exit; // Exit if accessed directly. 6 } 7 8 /** 9 * Elementor image size control. 10 * 11 * A base control for creating image size control. Displays input fields to define 12 * one of the default image sizes (thumbnail, medium, medium_large, large) or custom 13 * image dimensions. 14 * 15 * @since 1.0.0 16 */ 17 class Group_Control_Image_Size extends Group_Control_Base { 18 19 /** 20 * Fields. 21 * 22 * Holds all the image size control fields. 23 * 24 * @since 1.2.2 25 * @access protected 26 * @static 27 * 28 * @var array Image size control fields. 29 */ 30 protected static $fields; 31 32 /** 33 * Get image size control type. 34 * 35 * Retrieve the control type, in this case `image-size`. 36 * 37 * @since 1.0.0 38 * @access public 39 * @static 40 * 41 * @return string Control type. 42 */ 43 public static function get_type() { 44 return 'image-size'; 45 } 46 47 /** 48 * Get attachment image HTML. 49 * 50 * Retrieve the attachment image HTML code. 51 * 52 * Note that some widgets use the same key for the media control that allows 53 * the image selection and for the image size control that allows the user 54 * to select the image size, in this case the third parameter should be null 55 * or the same as the second parameter. But when the widget uses different 56 * keys for the media control and the image size control, when calling this 57 * method you should pass the keys. 58 * 59 * @since 1.0.0 60 * @access public 61 * @static 62 * 63 * @param array $settings Control settings. 64 * @param string $image_size_key Optional. Settings key for image size. 65 * Default is `image`. 66 * @param string $image_key Optional. Settings key for image. Default 67 * is null. If not defined uses image size key 68 * as the image key. 69 * 70 * @return string Image HTML. 71 */ 72 public static function get_attachment_image_html( $settings, $image_size_key = 'image', $image_key = null ) { 73 if ( ! $image_key ) { 74 $image_key = $image_size_key; 75 } 76 77 $image = $settings[ $image_key ]; 78 79 // Old version of image settings. 80 if ( ! isset( $settings[ $image_size_key . '_size' ] ) ) { 81 $settings[ $image_size_key . '_size' ] = ''; 82 } 83 84 $size = $settings[ $image_size_key . '_size' ]; 85 86 $image_class = ! empty( $settings['hover_animation'] ) ? 'elementor-animation-' . $settings['hover_animation'] : ''; 87 88 $html = ''; 89 90 // If is the new version - with image size. 91 $image_sizes = get_intermediate_image_sizes(); 92 93 $image_sizes[] = 'full'; 94 95 if ( ! empty( $image['id'] ) && ! wp_attachment_is_image( $image['id'] ) ) { 96 $image['id'] = ''; 97 } 98 99 $is_static_render_mode = Plugin::$instance->frontend->is_static_render_mode(); 100 101 // On static mode don't use WP responsive images. 102 if ( ! empty( $image['id'] ) && in_array( $size, $image_sizes ) && ! $is_static_render_mode ) { 103 $image_class .= " attachment-$size size-$size"; 104 $image_attr = [ 105 'class' => trim( $image_class ), 106 ]; 107 108 $html .= wp_get_attachment_image( $image['id'], $size, false, $image_attr ); 109 } else { 110 $image_src = self::get_attachment_image_src( $image['id'], $image_size_key, $settings ); 111 112 if ( ! $image_src && isset( $image['url'] ) ) { 113 $image_src = $image['url']; 114 } 115 116 if ( ! empty( $image_src ) ) { 117 $image_class_html = ! empty( $image_class ) ? ' class="' . $image_class . '"' : ''; 118 119 $html .= sprintf( '<img src="%s" title="%s" alt="%s"%s />', esc_attr( $image_src ), Control_Media::get_image_title( $image ), Control_Media::get_image_alt( $image ), $image_class_html ); 120 } 121 } 122 123 /** 124 * Get Attachment Image HTML 125 * 126 * Filters the Attachment Image HTML 127 * 128 * @since 2.4.0 129 * @param string $html the attachment image HTML string 130 * @param array $settings Control settings. 131 * @param string $image_size_key Optional. Settings key for image size. 132 * Default is `image`. 133 * @param string $image_key Optional. Settings key for image. Default 134 * is null. If not defined uses image size key 135 * as the image key. 136 */ 137 return apply_filters( 'elementor/image_size/get_attachment_image_html', $html, $settings, $image_size_key, $image_key ); 138 } 139 140 /** 141 * Safe print attachment image HTML. 142 * 143 * @uses get_attachment_image_html. 144 * 145 * @access public 146 * @static 147 * 148 * @param array $settings Control settings. 149 * @param string $image_size_key Optional. Settings key for image size. 150 * Default is `image`. 151 * @param string $image_key Optional. Settings key for image. Default 152 * is null. If not defined uses image size key 153 * as the image key. 154 */ 155 public static function print_attachment_image_html( array $settings, $image_size_key = 'image', $image_key = null ) { 156 Utils::print_wp_kses_extended( self::get_attachment_image_html( $settings, $image_size_key, $image_key ), [ 'image' ] ); 157 } 158 159 /** 160 * Get all image sizes. 161 * 162 * Retrieve available image sizes with data like `width`, `height` and `crop`. 163 * 164 * @since 1.0.0 165 * @access public 166 * @static 167 * 168 * @return array An array of available image sizes. 169 */ 170 public static function get_all_image_sizes() { 171 global $_wp_additional_image_sizes; 172 173 $default_image_sizes = [ 'thumbnail', 'medium', 'medium_large', 'large' ]; 174 175 $image_sizes = []; 176 177 foreach ( $default_image_sizes as $size ) { 178 $image_sizes[ $size ] = [ 179 'width' => (int) get_option( $size . '_size_w' ), 180 'height' => (int) get_option( $size . '_size_h' ), 181 'crop' => (bool) get_option( $size . '_crop' ), 182 ]; 183 } 184 185 if ( $_wp_additional_image_sizes ) { 186 $image_sizes = array_merge( $image_sizes, $_wp_additional_image_sizes ); 187 } 188 189 /** This filter is documented in wp-admin/includes/media.php */ 190 return apply_filters( 'image_size_names_choose', $image_sizes ); 191 } 192 193 /** 194 * Get attachment image src. 195 * 196 * Retrieve the attachment image source URL. 197 * 198 * @since 1.0.0 199 * @access public 200 * @static 201 * 202 * @param string $attachment_id The attachment ID. 203 * @param string $image_size_key Settings key for image size. 204 * @param array $settings Control settings. 205 * 206 * @return string Attachment image source URL. 207 */ 208 public static function get_attachment_image_src( $attachment_id, $image_size_key, array $settings ) { 209 if ( empty( $attachment_id ) ) { 210 return false; 211 } 212 213 $size = $settings[ $image_size_key . '_size' ]; 214 215 if ( 'custom' !== $size ) { 216 $attachment_size = $size; 217 } else { 218 // Use BFI_Thumb script 219 // TODO: Please rewrite this code. 220 require_once ELEMENTOR_PATH . 'includes/libraries/bfi-thumb/bfi-thumb.php'; 221 222 $custom_dimension = $settings[ $image_size_key . '_custom_dimension' ]; 223 224 $attachment_size = [ 225 // Defaults sizes 226 0 => null, // Width. 227 1 => null, // Height. 228 229 'bfi_thumb' => true, 230 'crop' => true, 231 ]; 232 233 $has_custom_size = false; 234 if ( ! empty( $custom_dimension['width'] ) ) { 235 $has_custom_size = true; 236 $attachment_size[0] = $custom_dimension['width']; 237 } 238 239 if ( ! empty( $custom_dimension['height'] ) ) { 240 $has_custom_size = true; 241 $attachment_size[1] = $custom_dimension['height']; 242 } 243 244 if ( ! $has_custom_size ) { 245 $attachment_size = 'full'; 246 } 247 } 248 249 $image_src = wp_get_attachment_image_src( $attachment_id, $attachment_size ); 250 251 if ( empty( $image_src[0] ) && 'thumbnail' !== $attachment_size ) { 252 $image_src = wp_get_attachment_image_src( $attachment_id ); 253 } 254 255 return ! empty( $image_src[0] ) ? $image_src[0] : ''; 256 } 257 258 /** 259 * Get child default arguments. 260 * 261 * Retrieve the default arguments for all the child controls for a specific group 262 * control. 263 * 264 * @since 1.2.2 265 * @access protected 266 * 267 * @return array Default arguments for all the child controls. 268 */ 269 protected function get_child_default_args() { 270 return [ 271 'include' => [], 272 'exclude' => [], 273 ]; 274 } 275 276 /** 277 * Init fields. 278 * 279 * Initialize image size control fields. 280 * 281 * @since 1.2.2 282 * @access protected 283 * 284 * @return array Control fields. 285 */ 286 protected function init_fields() { 287 $fields = []; 288 289 $fields['size'] = [ 290 'label' => _x( 'Image Size', 'Image Size Control', 'elementor' ), 291 'type' => Controls_Manager::SELECT, 292 ]; 293 294 $fields['custom_dimension'] = [ 295 'label' => _x( 'Image Dimension', 'Image Size Control', 'elementor' ), 296 'type' => Controls_Manager::IMAGE_DIMENSIONS, 297 'description' => esc_html__( 'You can crop the original image size to any custom size. You can also set a single value for height or width in order to keep the original size ratio.', 'elementor' ), 298 'condition' => [ 299 'size' => 'custom', 300 ], 301 'separator' => 'none', 302 ]; 303 304 return $fields; 305 } 306 307 /** 308 * Prepare fields. 309 * 310 * Process image size control fields before adding them to `add_control()`. 311 * 312 * @since 1.2.2 313 * @access protected 314 * 315 * @param array $fields Image size control fields. 316 * 317 * @return array Processed fields. 318 */ 319 protected function prepare_fields( $fields ) { 320 $image_sizes = $this->get_image_sizes(); 321 322 $args = $this->get_args(); 323 324 if ( ! empty( $args['default'] ) && isset( $image_sizes[ $args['default'] ] ) ) { 325 $default_value = $args['default']; 326 } else { 327 // Get the first item for default value. 328 $default_value = array_keys( $image_sizes ); 329 $default_value = array_shift( $default_value ); 330 } 331 332 $fields['size']['options'] = $image_sizes; 333 334 $fields['size']['default'] = $default_value; 335 336 if ( ! isset( $image_sizes['custom'] ) ) { 337 unset( $fields['custom_dimension'] ); 338 } 339 340 return parent::prepare_fields( $fields ); 341 } 342 343 /** 344 * Get image sizes. 345 * 346 * Retrieve available image sizes after filtering `include` and `exclude` arguments. 347 * 348 * @since 2.0.0 349 * @access private 350 * 351 * @return array Filtered image sizes. 352 */ 353 private function get_image_sizes() { 354 $wp_image_sizes = self::get_all_image_sizes(); 355 356 $args = $this->get_args(); 357 358 if ( $args['include'] ) { 359 $wp_image_sizes = array_intersect_key( $wp_image_sizes, array_flip( $args['include'] ) ); 360 } elseif ( $args['exclude'] ) { 361 $wp_image_sizes = array_diff_key( $wp_image_sizes, array_flip( $args['exclude'] ) ); 362 } 363 364 $image_sizes = []; 365 366 foreach ( $wp_image_sizes as $size_key => $size_attributes ) { 367 $control_title = ucwords( str_replace( '_', ' ', $size_key ) ); 368 if ( is_array( $size_attributes ) ) { 369 $control_title .= sprintf( ' - %d x %d', $size_attributes['width'], $size_attributes['height'] ); 370 } 371 372 $image_sizes[ $size_key ] = $control_title; 373 } 374 375 $image_sizes['full'] = _x( 'Full', 'Image Size Control', 'elementor' ); 376 377 if ( ! empty( $args['include']['custom'] ) || ! in_array( 'custom', $args['exclude'] ) ) { 378 $image_sizes['custom'] = _x( 'Custom', 'Image Size Control', 'elementor' ); 379 } 380 381 return $image_sizes; 382 } 383 384 /** 385 * Get default options. 386 * 387 * Retrieve the default options of the image size control. Used to return the 388 * default options while initializing the image size control. 389 * 390 * @since 1.9.0 391 * @access protected 392 * 393 * @return array Default image size control options. 394 */ 395 protected function get_default_options() { 396 return [ 397 'popover' => false, 398 ]; 399 } 400 }