balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

image.php (18674B)


      1 <?php
      2 namespace Elementor;
      3 
      4 if ( ! defined( 'ABSPATH' ) ) {
      5 	exit; // Exit if accessed directly.
      6 }
      7 
      8 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
      9 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
     10 
     11 /**
     12  * Elementor image widget.
     13  *
     14  * Elementor widget that displays an image into the page.
     15  *
     16  * @since 1.0.0
     17  */
     18 class Widget_Image extends Widget_Base {
     19 
     20 	/**
     21 	 * Get widget name.
     22 	 *
     23 	 * Retrieve image widget name.
     24 	 *
     25 	 * @since 1.0.0
     26 	 * @access public
     27 	 *
     28 	 * @return string Widget name.
     29 	 */
     30 	public function get_name() {
     31 		return 'image';
     32 	}
     33 
     34 	/**
     35 	 * Get widget title.
     36 	 *
     37 	 * Retrieve image widget title.
     38 	 *
     39 	 * @since 1.0.0
     40 	 * @access public
     41 	 *
     42 	 * @return string Widget title.
     43 	 */
     44 	public function get_title() {
     45 		return esc_html__( 'Image', 'elementor' );
     46 	}
     47 
     48 	/**
     49 	 * Get widget icon.
     50 	 *
     51 	 * Retrieve image widget icon.
     52 	 *
     53 	 * @since 1.0.0
     54 	 * @access public
     55 	 *
     56 	 * @return string Widget icon.
     57 	 */
     58 	public function get_icon() {
     59 		return 'eicon-image';
     60 	}
     61 
     62 	/**
     63 	 * Get widget categories.
     64 	 *
     65 	 * Retrieve the list of categories the image widget belongs to.
     66 	 *
     67 	 * Used to determine where to display the widget in the editor.
     68 	 *
     69 	 * @since 2.0.0
     70 	 * @access public
     71 	 *
     72 	 * @return array Widget categories.
     73 	 */
     74 	public function get_categories() {
     75 		return [ 'basic' ];
     76 	}
     77 
     78 	/**
     79 	 * Get widget keywords.
     80 	 *
     81 	 * Retrieve the list of keywords the widget belongs to.
     82 	 *
     83 	 * @since 2.1.0
     84 	 * @access public
     85 	 *
     86 	 * @return array Widget keywords.
     87 	 */
     88 	public function get_keywords() {
     89 		return [ 'image', 'photo', 'visual' ];
     90 	}
     91 
     92 	/**
     93 	 * Register image widget controls.
     94 	 *
     95 	 * Adds different input fields to allow the user to change and customize the widget settings.
     96 	 *
     97 	 * @since 3.1.0
     98 	 * @access protected
     99 	 */
    100 	protected function register_controls() {
    101 		$this->start_controls_section(
    102 			'section_image',
    103 			[
    104 				'label' => esc_html__( 'Image', 'elementor' ),
    105 			]
    106 		);
    107 
    108 		$this->add_control(
    109 			'image',
    110 			[
    111 				'label' => esc_html__( 'Choose Image', 'elementor' ),
    112 				'type' => Controls_Manager::MEDIA,
    113 				'dynamic' => [
    114 					'active' => true,
    115 				],
    116 				'default' => [
    117 					'url' => Utils::get_placeholder_image_src(),
    118 				],
    119 			]
    120 		);
    121 
    122 		$this->add_group_control(
    123 			Group_Control_Image_Size::get_type(),
    124 			[
    125 				'name' => 'image', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `image_size` and `image_custom_dimension`.
    126 				'default' => 'large',
    127 				'separator' => 'none',
    128 			]
    129 		);
    130 
    131 		$this->add_responsive_control(
    132 			'align',
    133 			[
    134 				'label' => esc_html__( 'Alignment', 'elementor' ),
    135 				'type' => Controls_Manager::CHOOSE,
    136 				'options' => [
    137 					'left' => [
    138 						'title' => esc_html__( 'Left', 'elementor' ),
    139 						'icon' => 'eicon-text-align-left',
    140 					],
    141 					'center' => [
    142 						'title' => esc_html__( 'Center', 'elementor' ),
    143 						'icon' => 'eicon-text-align-center',
    144 					],
    145 					'right' => [
    146 						'title' => esc_html__( 'Right', 'elementor' ),
    147 						'icon' => 'eicon-text-align-right',
    148 					],
    149 				],
    150 				'selectors' => [
    151 					'{{WRAPPER}}' => 'text-align: {{VALUE}};',
    152 				],
    153 			]
    154 		);
    155 
    156 		$this->add_control(
    157 			'caption_source',
    158 			[
    159 				'label' => esc_html__( 'Caption', 'elementor' ),
    160 				'type' => Controls_Manager::SELECT,
    161 				'options' => [
    162 					'none' => esc_html__( 'None', 'elementor' ),
    163 					'attachment' => esc_html__( 'Attachment Caption', 'elementor' ),
    164 					'custom' => esc_html__( 'Custom Caption', 'elementor' ),
    165 				],
    166 				'default' => 'none',
    167 			]
    168 		);
    169 
    170 		$this->add_control(
    171 			'caption',
    172 			[
    173 				'label' => esc_html__( 'Custom Caption', 'elementor' ),
    174 				'type' => Controls_Manager::TEXT,
    175 				'default' => '',
    176 				'placeholder' => esc_html__( 'Enter your image caption', 'elementor' ),
    177 				'condition' => [
    178 					'caption_source' => 'custom',
    179 				],
    180 				'dynamic' => [
    181 					'active' => true,
    182 				],
    183 			]
    184 		);
    185 
    186 		$this->add_control(
    187 			'link_to',
    188 			[
    189 				'label' => esc_html__( 'Link', 'elementor' ),
    190 				'type' => Controls_Manager::SELECT,
    191 				'default' => 'none',
    192 				'options' => [
    193 					'none' => esc_html__( 'None', 'elementor' ),
    194 					'file' => esc_html__( 'Media File', 'elementor' ),
    195 					'custom' => esc_html__( 'Custom URL', 'elementor' ),
    196 				],
    197 			]
    198 		);
    199 
    200 		$this->add_control(
    201 			'link',
    202 			[
    203 				'label' => esc_html__( 'Link', 'elementor' ),
    204 				'type' => Controls_Manager::URL,
    205 				'dynamic' => [
    206 					'active' => true,
    207 				],
    208 				'placeholder' => esc_html__( 'https://your-link.com', 'elementor' ),
    209 				'condition' => [
    210 					'link_to' => 'custom',
    211 				],
    212 				'show_label' => false,
    213 			]
    214 		);
    215 
    216 		$this->add_control(
    217 			'open_lightbox',
    218 			[
    219 				'label' => esc_html__( 'Lightbox', 'elementor' ),
    220 				'type' => Controls_Manager::SELECT,
    221 				'default' => 'default',
    222 				'options' => [
    223 					'default' => esc_html__( 'Default', 'elementor' ),
    224 					'yes' => esc_html__( 'Yes', 'elementor' ),
    225 					'no' => esc_html__( 'No', 'elementor' ),
    226 				],
    227 				'condition' => [
    228 					'link_to' => 'file',
    229 				],
    230 			]
    231 		);
    232 
    233 		$this->add_control(
    234 			'view',
    235 			[
    236 				'label' => esc_html__( 'View', 'elementor' ),
    237 				'type' => Controls_Manager::HIDDEN,
    238 				'default' => 'traditional',
    239 			]
    240 		);
    241 
    242 		$this->end_controls_section();
    243 
    244 		$this->start_controls_section(
    245 			'section_style_image',
    246 			[
    247 				'label' => esc_html__( 'Image', 'elementor' ),
    248 				'tab'   => Controls_Manager::TAB_STYLE,
    249 			]
    250 		);
    251 
    252 		$this->add_responsive_control(
    253 			'width',
    254 			[
    255 				'label' => esc_html__( 'Width', 'elementor' ),
    256 				'type' => Controls_Manager::SLIDER,
    257 				'default' => [
    258 					'unit' => '%',
    259 				],
    260 				'tablet_default' => [
    261 					'unit' => '%',
    262 				],
    263 				'mobile_default' => [
    264 					'unit' => '%',
    265 				],
    266 				'size_units' => [ '%', 'px', 'vw' ],
    267 				'range' => [
    268 					'%' => [
    269 						'min' => 1,
    270 						'max' => 100,
    271 					],
    272 					'px' => [
    273 						'min' => 1,
    274 						'max' => 1000,
    275 					],
    276 					'vw' => [
    277 						'min' => 1,
    278 						'max' => 100,
    279 					],
    280 				],
    281 				'selectors' => [
    282 					'{{WRAPPER}} img' => 'width: {{SIZE}}{{UNIT}};',
    283 				],
    284 			]
    285 		);
    286 
    287 		$this->add_responsive_control(
    288 			'space',
    289 			[
    290 				'label' => esc_html__( 'Max Width', 'elementor' ),
    291 				'type' => Controls_Manager::SLIDER,
    292 				'default' => [
    293 					'unit' => '%',
    294 				],
    295 				'tablet_default' => [
    296 					'unit' => '%',
    297 				],
    298 				'mobile_default' => [
    299 					'unit' => '%',
    300 				],
    301 				'size_units' => [ '%', 'px', 'vw' ],
    302 				'range' => [
    303 					'%' => [
    304 						'min' => 1,
    305 						'max' => 100,
    306 					],
    307 					'px' => [
    308 						'min' => 1,
    309 						'max' => 1000,
    310 					],
    311 					'vw' => [
    312 						'min' => 1,
    313 						'max' => 100,
    314 					],
    315 				],
    316 				'selectors' => [
    317 					'{{WRAPPER}} img' => 'max-width: {{SIZE}}{{UNIT}};',
    318 				],
    319 			]
    320 		);
    321 
    322 		$this->add_responsive_control(
    323 			'height',
    324 			[
    325 				'label' => esc_html__( 'Height', 'elementor' ),
    326 				'type' => Controls_Manager::SLIDER,
    327 				'default' => [
    328 					'unit' => 'px',
    329 				],
    330 				'tablet_default' => [
    331 					'unit' => 'px',
    332 				],
    333 				'mobile_default' => [
    334 					'unit' => 'px',
    335 				],
    336 				'size_units' => [ 'px', 'vh' ],
    337 				'range' => [
    338 					'px' => [
    339 						'min' => 1,
    340 						'max' => 500,
    341 					],
    342 					'vh' => [
    343 						'min' => 1,
    344 						'max' => 100,
    345 					],
    346 				],
    347 				'selectors' => [
    348 					'{{WRAPPER}} img' => 'height: {{SIZE}}{{UNIT}};',
    349 				],
    350 			]
    351 		);
    352 
    353 		$this->add_responsive_control(
    354 			'object-fit',
    355 			[
    356 				'label' => esc_html__( 'Object Fit', 'elementor' ),
    357 				'type' => Controls_Manager::SELECT,
    358 				'condition' => [
    359 					'height[size]!' => '',
    360 				],
    361 				'options' => [
    362 					'' => esc_html__( 'Default', 'elementor' ),
    363 					'fill' => esc_html__( 'Fill', 'elementor' ),
    364 					'cover' => esc_html__( 'Cover', 'elementor' ),
    365 					'contain' => esc_html__( 'Contain', 'elementor' ),
    366 				],
    367 				'default' => '',
    368 				'selectors' => [
    369 					'{{WRAPPER}} img' => 'object-fit: {{VALUE}};',
    370 				],
    371 			]
    372 		);
    373 
    374 		$this->add_control(
    375 			'separator_panel_style',
    376 			[
    377 				'type' => Controls_Manager::DIVIDER,
    378 				'style' => 'thick',
    379 			]
    380 		);
    381 
    382 		$this->start_controls_tabs( 'image_effects' );
    383 
    384 		$this->start_controls_tab( 'normal',
    385 			[
    386 				'label' => esc_html__( 'Normal', 'elementor' ),
    387 			]
    388 		);
    389 
    390 		$this->add_control(
    391 			'opacity',
    392 			[
    393 				'label' => esc_html__( 'Opacity', 'elementor' ),
    394 				'type' => Controls_Manager::SLIDER,
    395 				'range' => [
    396 					'px' => [
    397 						'max' => 1,
    398 						'min' => 0.10,
    399 						'step' => 0.01,
    400 					],
    401 				],
    402 				'selectors' => [
    403 					'{{WRAPPER}} img' => 'opacity: {{SIZE}};',
    404 				],
    405 			]
    406 		);
    407 
    408 		$this->add_group_control(
    409 			Group_Control_Css_Filter::get_type(),
    410 			[
    411 				'name' => 'css_filters',
    412 				'selector' => '{{WRAPPER}} img',
    413 			]
    414 		);
    415 
    416 		$this->end_controls_tab();
    417 
    418 		$this->start_controls_tab( 'hover',
    419 			[
    420 				'label' => esc_html__( 'Hover', 'elementor' ),
    421 			]
    422 		);
    423 
    424 		$this->add_control(
    425 			'opacity_hover',
    426 			[
    427 				'label' => esc_html__( 'Opacity', 'elementor' ),
    428 				'type' => Controls_Manager::SLIDER,
    429 				'range' => [
    430 					'px' => [
    431 						'max' => 1,
    432 						'min' => 0.10,
    433 						'step' => 0.01,
    434 					],
    435 				],
    436 				'selectors' => [
    437 					'{{WRAPPER}}:hover img' => 'opacity: {{SIZE}};',
    438 				],
    439 			]
    440 		);
    441 
    442 		$this->add_group_control(
    443 			Group_Control_Css_Filter::get_type(),
    444 			[
    445 				'name' => 'css_filters_hover',
    446 				'selector' => '{{WRAPPER}}:hover img',
    447 			]
    448 		);
    449 
    450 		$this->add_control(
    451 			'background_hover_transition',
    452 			[
    453 				'label' => esc_html__( 'Transition Duration', 'elementor' ),
    454 				'type' => Controls_Manager::SLIDER,
    455 				'range' => [
    456 					'px' => [
    457 						'max' => 3,
    458 						'step' => 0.1,
    459 					],
    460 				],
    461 				'selectors' => [
    462 					'{{WRAPPER}} img' => 'transition-duration: {{SIZE}}s',
    463 				],
    464 			]
    465 		);
    466 
    467 		$this->add_control(
    468 			'hover_animation',
    469 			[
    470 				'label' => esc_html__( 'Hover Animation', 'elementor' ),
    471 				'type' => Controls_Manager::HOVER_ANIMATION,
    472 			]
    473 		);
    474 
    475 		$this->end_controls_tab();
    476 
    477 		$this->end_controls_tabs();
    478 
    479 		$this->add_group_control(
    480 			Group_Control_Border::get_type(),
    481 			[
    482 				'name' => 'image_border',
    483 				'selector' => '{{WRAPPER}} img',
    484 				'separator' => 'before',
    485 			]
    486 		);
    487 
    488 		$this->add_responsive_control(
    489 			'image_border_radius',
    490 			[
    491 				'label' => esc_html__( 'Border Radius', 'elementor' ),
    492 				'type' => Controls_Manager::DIMENSIONS,
    493 				'size_units' => [ 'px', '%' ],
    494 				'selectors' => [
    495 					'{{WRAPPER}} img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
    496 				],
    497 			]
    498 		);
    499 
    500 		$this->add_group_control(
    501 			Group_Control_Box_Shadow::get_type(),
    502 			[
    503 				'name' => 'image_box_shadow',
    504 				'exclude' => [
    505 					'box_shadow_position',
    506 				],
    507 				'selector' => '{{WRAPPER}} img',
    508 			]
    509 		);
    510 
    511 		$this->end_controls_section();
    512 
    513 		$this->start_controls_section(
    514 			'section_style_caption',
    515 			[
    516 				'label' => esc_html__( 'Caption', 'elementor' ),
    517 				'tab'   => Controls_Manager::TAB_STYLE,
    518 				'condition' => [
    519 					'caption_source!' => 'none',
    520 				],
    521 			]
    522 		);
    523 
    524 		$this->add_control(
    525 			'caption_align',
    526 			[
    527 				'label' => esc_html__( 'Alignment', 'elementor' ),
    528 				'type' => Controls_Manager::CHOOSE,
    529 				'options' => [
    530 					'left' => [
    531 						'title' => esc_html__( 'Left', 'elementor' ),
    532 						'icon' => 'eicon-text-align-left',
    533 					],
    534 					'center' => [
    535 						'title' => esc_html__( 'Center', 'elementor' ),
    536 						'icon' => 'eicon-text-align-center',
    537 					],
    538 					'right' => [
    539 						'title' => esc_html__( 'Right', 'elementor' ),
    540 						'icon' => 'eicon-text-align-right',
    541 					],
    542 					'justify' => [
    543 						'title' => esc_html__( 'Justified', 'elementor' ),
    544 						'icon' => 'eicon-text-align-justify',
    545 					],
    546 				],
    547 				'default' => '',
    548 				'selectors' => [
    549 					'{{WRAPPER}} .widget-image-caption' => 'text-align: {{VALUE}};',
    550 				],
    551 			]
    552 		);
    553 
    554 		$this->add_control(
    555 			'text_color',
    556 			[
    557 				'label' => esc_html__( 'Text Color', 'elementor' ),
    558 				'type' => Controls_Manager::COLOR,
    559 				'default' => '',
    560 				'selectors' => [
    561 					'{{WRAPPER}} .widget-image-caption' => 'color: {{VALUE}};',
    562 				],
    563 				'global' => [
    564 					'default' => Global_Colors::COLOR_TEXT,
    565 				],
    566 			]
    567 		);
    568 
    569 		$this->add_control(
    570 			'caption_background_color',
    571 			[
    572 				'label' => esc_html__( 'Background Color', 'elementor' ),
    573 				'type' => Controls_Manager::COLOR,
    574 				'selectors' => [
    575 					'{{WRAPPER}} .widget-image-caption' => 'background-color: {{VALUE}};',
    576 				],
    577 			]
    578 		);
    579 
    580 		$this->add_group_control(
    581 			Group_Control_Typography::get_type(),
    582 			[
    583 				'name' => 'caption_typography',
    584 				'selector' => '{{WRAPPER}} .widget-image-caption',
    585 				'global' => [
    586 					'default' => Global_Typography::TYPOGRAPHY_TEXT,
    587 				],
    588 			]
    589 		);
    590 
    591 		$this->add_group_control(
    592 			Group_Control_Text_Shadow::get_type(),
    593 			[
    594 				'name' => 'caption_text_shadow',
    595 				'selector' => '{{WRAPPER}} .widget-image-caption',
    596 			]
    597 		);
    598 
    599 		$this->add_responsive_control(
    600 			'caption_space',
    601 			[
    602 				'label' => esc_html__( 'Spacing', 'elementor' ),
    603 				'type' => Controls_Manager::SLIDER,
    604 				'range' => [
    605 					'px' => [
    606 						'min' => 0,
    607 						'max' => 100,
    608 					],
    609 				],
    610 				'selectors' => [
    611 					'{{WRAPPER}} .widget-image-caption' => 'margin-top: {{SIZE}}{{UNIT}};',
    612 				],
    613 			]
    614 		);
    615 
    616 		$this->end_controls_section();
    617 	}
    618 
    619 	/**
    620 	 * Check if the current widget has caption
    621 	 *
    622 	 * @access private
    623 	 * @since 2.3.0
    624 	 *
    625 	 * @param array $settings
    626 	 *
    627 	 * @return boolean
    628 	 */
    629 	private function has_caption( $settings ) {
    630 		return ( ! empty( $settings['caption_source'] ) && 'none' !== $settings['caption_source'] );
    631 	}
    632 
    633 	/**
    634 	 * Get the caption for current widget.
    635 	 *
    636 	 * @access private
    637 	 * @since 2.3.0
    638 	 * @param $settings
    639 	 *
    640 	 * @return string
    641 	 */
    642 	private function get_caption( $settings ) {
    643 		$caption = '';
    644 		if ( ! empty( $settings['caption_source'] ) ) {
    645 			switch ( $settings['caption_source'] ) {
    646 				case 'attachment':
    647 					$caption = wp_get_attachment_caption( $settings['image']['id'] );
    648 					break;
    649 				case 'custom':
    650 					$caption = ! Utils::is_empty( $settings['caption'] ) ? $settings['caption'] : '';
    651 			}
    652 		}
    653 		return $caption;
    654 	}
    655 
    656 	/**
    657 	 * Render image widget output on the frontend.
    658 	 *
    659 	 * Written in PHP and used to generate the final HTML.
    660 	 *
    661 	 * @since 1.0.0
    662 	 * @access protected
    663 	 */
    664 	protected function render() {
    665 		$settings = $this->get_settings_for_display();
    666 
    667 		if ( empty( $settings['image']['url'] ) ) {
    668 			return;
    669 		}
    670 
    671 		if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) {
    672 			$this->add_render_attribute( 'wrapper', 'class', 'elementor-image' );
    673 		}
    674 
    675 		$has_caption = $this->has_caption( $settings );
    676 
    677 		$link = $this->get_link_url( $settings );
    678 
    679 		if ( $link ) {
    680 			$this->add_link_attributes( 'link', $link );
    681 
    682 			if ( Plugin::$instance->editor->is_edit_mode() ) {
    683 				$this->add_render_attribute( 'link', [
    684 					'class' => 'elementor-clickable',
    685 				] );
    686 			}
    687 
    688 			if ( 'custom' !== $settings['link_to'] ) {
    689 				$this->add_lightbox_data_attributes( 'link', $settings['image']['id'], $settings['open_lightbox'] );
    690 			}
    691 		} ?>
    692 		<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
    693 			<div <?php $this->print_render_attribute_string( 'wrapper' ); ?>>
    694 		<?php } ?>
    695 			<?php if ( $has_caption ) : ?>
    696 				<figure class="wp-caption">
    697 			<?php endif; ?>
    698 			<?php if ( $link ) : ?>
    699 					<a <?php $this->print_render_attribute_string( 'link' ); ?>>
    700 			<?php endif; ?>
    701 				<?php Group_Control_Image_Size::print_attachment_image_html( $settings ); ?>
    702 			<?php if ( $link ) : ?>
    703 					</a>
    704 			<?php endif; ?>
    705 			<?php if ( $has_caption ) : ?>
    706 					<figcaption class="widget-image-caption wp-caption-text"><?php
    707 						echo wp_kses_post( $this->get_caption( $settings ) );
    708 					?></figcaption>
    709 			<?php endif; ?>
    710 			<?php if ( $has_caption ) : ?>
    711 				</figure>
    712 			<?php endif; ?>
    713 		<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
    714 			</div>
    715 		<?php } ?>
    716 		<?php
    717 	}
    718 
    719 	/**
    720 	 * Render image widget output in the editor.
    721 	 *
    722 	 * Written as a Backbone JavaScript template and used to generate the live preview.
    723 	 *
    724 	 * @since 2.9.0
    725 	 * @access protected
    726 	 */
    727 	protected function content_template() {
    728 		?>
    729 		<# if ( settings.image.url ) {
    730 			var image = {
    731 				id: settings.image.id,
    732 				url: settings.image.url,
    733 				size: settings.image_size,
    734 				dimension: settings.image_custom_dimension,
    735 				model: view.getEditModel()
    736 			};
    737 
    738 			var image_url = elementor.imagesManager.getImageUrl( image );
    739 
    740 			if ( ! image_url ) {
    741 				return;
    742 			}
    743 
    744 			var hasCaption = function() {
    745 				if( ! settings.caption_source || 'none' === settings.caption_source ) {
    746 					return false;
    747 				}
    748 				return true;
    749 			}
    750 
    751 			var ensureAttachmentData = function( id ) {
    752 				if ( 'undefined' === typeof wp.media.attachment( id ).get( 'caption' ) ) {
    753 					wp.media.attachment( id ).fetch().then( function( data ) {
    754 						view.render();
    755 					} );
    756 				}
    757 			}
    758 
    759 			var getAttachmentCaption = function( id ) {
    760 				if ( ! id ) {
    761 					return '';
    762 				}
    763 				ensureAttachmentData( id );
    764 				return wp.media.attachment( id ).get( 'caption' );
    765 			}
    766 
    767 			var getCaption = function() {
    768 				if ( ! hasCaption() ) {
    769 					return '';
    770 				}
    771 				return 'custom' === settings.caption_source ? settings.caption : getAttachmentCaption( settings.image.id );
    772 			}
    773 
    774 			var link_url;
    775 
    776 			if ( 'custom' === settings.link_to ) {
    777 				link_url = settings.link.url;
    778 			}
    779 
    780 			if ( 'file' === settings.link_to ) {
    781 				link_url = settings.image.url;
    782 			}
    783 
    784 			<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
    785 				#><div class="elementor-image{{ settings.shape ? ' elementor-image-shape-' + settings.shape : '' }}"><#
    786 			<?php } ?>
    787 
    788 			var imgClass = '';
    789 
    790 			if ( '' !== settings.hover_animation ) {
    791 				imgClass = 'elementor-animation-' + settings.hover_animation;
    792 			}
    793 
    794 			if ( hasCaption() ) {
    795 				#><figure class="wp-caption"><#
    796 			}
    797 
    798 			if ( link_url ) {
    799 					#><a class="elementor-clickable" data-elementor-open-lightbox="{{ settings.open_lightbox }}" href="{{ link_url }}"><#
    800 			}
    801 						#><img src="{{ image_url }}" class="{{ imgClass }}" /><#
    802 
    803 			if ( link_url ) {
    804 					#></a><#
    805 			}
    806 
    807 			if ( hasCaption() ) {
    808 					#><figcaption class="widget-image-caption wp-caption-text">{{{ getCaption() }}}</figcaption><#
    809 			}
    810 
    811 			if ( hasCaption() ) {
    812 				#></figure><#
    813 			}
    814 
    815 			<?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
    816 				#></div><#
    817 			<?php } ?>
    818 
    819 		} #>
    820 		<?php
    821 	}
    822 
    823 	/**
    824 	 * Retrieve image widget link URL.
    825 	 *
    826 	 * @since 1.0.0
    827 	 * @access private
    828 	 *
    829 	 * @param array $settings
    830 	 *
    831 	 * @return array|string|false An array/string containing the link URL, or false if no link.
    832 	 */
    833 	private function get_link_url( $settings ) {
    834 		if ( 'none' === $settings['link_to'] ) {
    835 			return false;
    836 		}
    837 
    838 		if ( 'custom' === $settings['link_to'] ) {
    839 			if ( empty( $settings['link']['url'] ) ) {
    840 				return false;
    841 			}
    842 
    843 			return $settings['link'];
    844 		}
    845 
    846 		return [
    847 			'url' => $settings['image']['url'],
    848 		];
    849 	}
    850 }