PluginProbe
Elementor Website Builder – more than just a page builder / 3.2.4
Elementor Website Builder – more than just a page builder v3.2.4
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / widgets / video.php

video.php in Elementor Website Builder – more than just a page builder 3.2.4, at includes/widgets/video.php

1,181 lines 26.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 use Elementor\Modules\DynamicTags\Module as TagsModule;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly.
8 }
9
10 /**
11 * Elementor video widget.
12 *
13 * Elementor widget that displays a video player.
14 *
15 * @since 1.0.0
16 */
17 class Widget_Video extends Widget_Base {
18
19 /**
20 * Get widget name.
21 *
22 * Retrieve video widget name.
23 *
24 * @since 1.0.0
25 * @access public
26 *
27 * @return string Widget name.
28 */
29 public function get_name() {
30 return 'video';
31 }
32
33 /**
34 * Get widget title.
35 *
36 * Retrieve video widget title.
37 *
38 * @since 1.0.0
39 * @access public
40 *
41 * @return string Widget title.
42 */
43 public function get_title() {
44 return __( 'Video', 'elementor' );
45 }
46
47 /**
48 * Get widget icon.
49 *
50 * Retrieve video widget icon.
51 *
52 * @since 1.0.0
53 * @access public
54 *
55 * @return string Widget icon.
56 */
57 public function get_icon() {
58 return 'eicon-youtube';
59 }
60
61 /**
62 * Get widget categories.
63 *
64 * Retrieve the list of categories the video widget belongs to.
65 *
66 * Used to determine where to display the widget in the editor.
67 *
68 * @since 2.0.0
69 * @access public
70 *
71 * @return array Widget categories.
72 */
73 public function get_categories() {
74 return [ 'basic' ];
75 }
76
77 /**
78 * Get widget keywords.
79 *
80 * Retrieve the list of keywords the widget belongs to.
81 *
82 * @since 2.1.0
83 * @access public
84 *
85 * @return array Widget keywords.
86 */
87 public function get_keywords() {
88 return [ 'video', 'player', 'embed', 'youtube', 'vimeo', 'dailymotion' ];
89 }
90
91 /**
92 * Register video widget controls.
93 *
94 * Adds different input fields to allow the user to change and customize the widget settings.
95 *
96 * @since 3.1.0
97 * @access protected
98 */
99 protected function register_controls() {
100 $this->start_controls_section(
101 'section_video',
102 [
103 'label' => __( 'Video', 'elementor' ),
104 ]
105 );
106
107 $this->add_control(
108 'video_type',
109 [
110 'label' => __( 'Source', 'elementor' ),
111 'type' => Controls_Manager::SELECT,
112 'default' => 'youtube',
113 'options' => [
114 'youtube' => __( 'YouTube', 'elementor' ),
115 'vimeo' => __( 'Vimeo', 'elementor' ),
116 'dailymotion' => __( 'Dailymotion', 'elementor' ),
117 'hosted' => __( 'Self Hosted', 'elementor' ),
118 ],
119 'frontend_available' => true,
120 ]
121 );
122
123 $this->add_control(
124 'youtube_url',
125 [
126 'label' => __( 'Link', 'elementor' ),
127 'type' => Controls_Manager::TEXT,
128 'dynamic' => [
129 'active' => true,
130 'categories' => [
131 TagsModule::POST_META_CATEGORY,
132 TagsModule::URL_CATEGORY,
133 ],
134 ],
135 'placeholder' => __( 'Enter your URL', 'elementor' ) . ' (YouTube)',
136 'default' => 'https://www.youtube.com/watch?v=XHOmBV4js_E',
137 'label_block' => true,
138 'condition' => [
139 'video_type' => 'youtube',
140 ],
141 'frontend_available' => true,
142 ]
143 );
144
145 $this->add_control(
146 'vimeo_url',
147 [
148 'label' => __( 'Link', 'elementor' ),
149 'type' => Controls_Manager::TEXT,
150 'dynamic' => [
151 'active' => true,
152 'categories' => [
153 TagsModule::POST_META_CATEGORY,
154 TagsModule::URL_CATEGORY,
155 ],
156 ],
157 'placeholder' => __( 'Enter your URL', 'elementor' ) . ' (Vimeo)',
158 'default' => 'https://vimeo.com/235215203',
159 'label_block' => true,
160 'condition' => [
161 'video_type' => 'vimeo',
162 ],
163 ]
164 );
165
166 $this->add_control(
167 'dailymotion_url',
168 [
169 'label' => __( 'Link', 'elementor' ),
170 'type' => Controls_Manager::TEXT,
171 'dynamic' => [
172 'active' => true,
173 'categories' => [
174 TagsModule::POST_META_CATEGORY,
175 TagsModule::URL_CATEGORY,
176 ],
177 ],
178 'placeholder' => __( 'Enter your URL', 'elementor' ) . ' (Dailymotion)',
179 'default' => 'https://www.dailymotion.com/video/x6tqhqb',
180 'label_block' => true,
181 'condition' => [
182 'video_type' => 'dailymotion',
183 ],
184 ]
185 );
186
187 $this->add_control(
188 'insert_url',
189 [
190 'label' => __( 'External URL', 'elementor' ),
191 'type' => Controls_Manager::SWITCHER,
192 'condition' => [
193 'video_type' => 'hosted',
194 ],
195 ]
196 );
197
198 $this->add_control(
199 'hosted_url',
200 [
201 'label' => __( 'Choose File', 'elementor' ),
202 'type' => Controls_Manager::MEDIA,
203 'dynamic' => [
204 'active' => true,
205 'categories' => [
206 TagsModule::MEDIA_CATEGORY,
207 ],
208 ],
209 'media_type' => 'video',
210 'condition' => [
211 'video_type' => 'hosted',
212 'insert_url' => '',
213 ],
214 ]
215 );
216
217 $this->add_control(
218 'external_url',
219 [
220 'label' => __( 'URL', 'elementor' ),
221 'type' => Controls_Manager::URL,
222 'autocomplete' => false,
223 'options' => false,
224 'label_block' => true,
225 'show_label' => false,
226 'dynamic' => [
227 'active' => true,
228 'categories' => [
229 TagsModule::POST_META_CATEGORY,
230 TagsModule::URL_CATEGORY,
231 ],
232 ],
233 'media_type' => 'video',
234 'placeholder' => __( 'Enter your URL', 'elementor' ),
235 'condition' => [
236 'video_type' => 'hosted',
237 'insert_url' => 'yes',
238 ],
239 ]
240 );
241
242 $this->add_control(
243 'start',
244 [
245 'label' => __( 'Start Time', 'elementor' ),
246 'type' => Controls_Manager::NUMBER,
247 'description' => __( 'Specify a start time (in seconds)', 'elementor' ),
248 'frontend_available' => true,
249 ]
250 );
251
252 $this->add_control(
253 'end',
254 [
255 'label' => __( 'End Time', 'elementor' ),
256 'type' => Controls_Manager::NUMBER,
257 'description' => __( 'Specify an end time (in seconds)', 'elementor' ),
258 'condition' => [
259 'video_type' => [ 'youtube', 'hosted' ],
260 ],
261 'frontend_available' => true,
262 ]
263 );
264
265 $this->add_control(
266 'video_options',
267 [
268 'label' => __( 'Video Options', 'elementor' ),
269 'type' => Controls_Manager::HEADING,
270 'separator' => 'before',
271 ]
272 );
273
274 $this->add_control(
275 'autoplay',
276 [
277 'label' => __( 'Autoplay', 'elementor' ),
278 'type' => Controls_Manager::SWITCHER,
279 'frontend_available' => true,
280 'conditions' => [
281 'relation' => 'or',
282 'terms' => [
283 [
284 'name' => 'show_image_overlay',
285 'value' => '',
286 ],
287 [
288 'name' => 'image_overlay[url]',
289 'value' => '',
290 ],
291 ],
292 ],
293 ]
294 );
295
296 $this->add_control(
297 'play_on_mobile',
298 [
299 'label' => __( 'Play On Mobile', 'elementor' ),
300 'type' => Controls_Manager::SWITCHER,
301 'condition' => [
302 'autoplay' => 'yes',
303 ],
304 'frontend_available' => true,
305 ]
306 );
307
308 $this->add_control(
309 'mute',
310 [
311 'label' => __( 'Mute', 'elementor' ),
312 'type' => Controls_Manager::SWITCHER,
313 'frontend_available' => true,
314 ]
315 );
316
317 $this->add_control(
318 'loop',
319 [
320 'label' => __( 'Loop', 'elementor' ),
321 'type' => Controls_Manager::SWITCHER,
322 'condition' => [
323 'video_type!' => 'dailymotion',
324 ],
325 'frontend_available' => true,
326 ]
327 );
328
329 $this->add_control(
330 'controls',
331 [
332 'label' => __( 'Player Controls', 'elementor' ),
333 'type' => Controls_Manager::SWITCHER,
334 'label_off' => __( 'Hide', 'elementor' ),
335 'label_on' => __( 'Show', 'elementor' ),
336 'default' => 'yes',
337 'condition' => [
338 'video_type!' => 'vimeo',
339 ],
340 'frontend_available' => true,
341 ]
342 );
343
344 $this->add_control(
345 'showinfo',
346 [
347 'label' => __( 'Video Info', 'elementor' ),
348 'type' => Controls_Manager::SWITCHER,
349 'label_off' => __( 'Hide', 'elementor' ),
350 'label_on' => __( 'Show', 'elementor' ),
351 'default' => 'yes',
352 'condition' => [
353 'video_type' => [ 'dailymotion' ],
354 ],
355 ]
356 );
357
358 $this->add_control(
359 'modestbranding',
360 [
361 'label' => __( 'Modest Branding', 'elementor' ),
362 'type' => Controls_Manager::SWITCHER,
363 'condition' => [
364 'video_type' => [ 'youtube' ],
365 'controls' => 'yes',
366 ],
367 'frontend_available' => true,
368 ]
369 );
370
371 $this->add_control(
372 'logo',
373 [
374 'label' => __( 'Logo', 'elementor' ),
375 'type' => Controls_Manager::SWITCHER,
376 'label_off' => __( 'Hide', 'elementor' ),
377 'label_on' => __( 'Show', 'elementor' ),
378 'default' => 'yes',
379 'condition' => [
380 'video_type' => [ 'dailymotion' ],
381 ],
382 ]
383 );
384
385 // YouTube.
386 $this->add_control(
387 'yt_privacy',
388 [
389 'label' => __( 'Privacy Mode', 'elementor' ),
390 'type' => Controls_Manager::SWITCHER,
391 'description' => __( 'When you turn on privacy mode, YouTube won\'t store information about visitors on your website unless they play the video.', 'elementor' ),
392 'condition' => [
393 'video_type' => 'youtube',
394 ],
395 'frontend_available' => true,
396 ]
397 );
398
399 $this->add_control(
400 'lazy_load',
401 [
402 'label' => __( 'Lazy Load', 'elementor' ),
403 'type' => Controls_Manager::SWITCHER,
404 'conditions' => [
405 'relation' => 'or',
406 'terms' => [
407 [
408 'name' => 'video_type',
409 'operator' => '===',
410 'value' => 'youtube',
411 ],
412 [
413 'relation' => 'and',
414 'terms' => [
415 [
416 'name' => 'show_image_overlay',
417 'operator' => '===',
418 'value' => 'yes',
419 ],
420 [
421 'name' => 'video_type',
422 'operator' => '!==',
423 'value' => 'hosted',
424 ],
425 ],
426 ],
427 ],
428 ],
429 'frontend_available' => true,
430 ]
431 );
432
433 $this->add_control(
434 'rel',
435 [
436 'label' => __( 'Suggested Videos', 'elementor' ),
437 'type' => Controls_Manager::SELECT,
438 'options' => [
439 '' => __( 'Current Video Channel', 'elementor' ),
440 'yes' => __( 'Any Video', 'elementor' ),
441 ],
442 'condition' => [
443 'video_type' => 'youtube',
444 ],
445 ]
446 );
447
448 // Vimeo.
449 $this->add_control(
450 'vimeo_title',
451 [
452 'label' => __( 'Intro Title', 'elementor' ),
453 'type' => Controls_Manager::SWITCHER,
454 'label_off' => __( 'Hide', 'elementor' ),
455 'label_on' => __( 'Show', 'elementor' ),
456 'default' => 'yes',
457 'condition' => [
458 'video_type' => 'vimeo',
459 ],
460 ]
461 );
462
463 $this->add_control(
464 'vimeo_portrait',
465 [
466 'label' => __( 'Intro Portrait', 'elementor' ),
467 'type' => Controls_Manager::SWITCHER,
468 'label_off' => __( 'Hide', 'elementor' ),
469 'label_on' => __( 'Show', 'elementor' ),
470 'default' => 'yes',
471 'condition' => [
472 'video_type' => 'vimeo',
473 ],
474 ]
475 );
476
477 $this->add_control(
478 'vimeo_byline',
479 [
480 'label' => __( 'Intro Byline', 'elementor' ),
481 'type' => Controls_Manager::SWITCHER,
482 'label_off' => __( 'Hide', 'elementor' ),
483 'label_on' => __( 'Show', 'elementor' ),
484 'default' => 'yes',
485 'condition' => [
486 'video_type' => 'vimeo',
487 ],
488 ]
489 );
490
491 $this->add_control(
492 'color',
493 [
494 'label' => __( 'Controls Color', 'elementor' ),
495 'type' => Controls_Manager::COLOR,
496 'default' => '',
497 'condition' => [
498 'video_type' => [ 'vimeo', 'dailymotion' ],
499 ],
500 ]
501 );
502
503 $this->add_control(
504 'download_button',
505 [
506 'label' => __( 'Download Button', 'elementor' ),
507 'type' => Controls_Manager::SWITCHER,
508 'label_off' => __( 'Hide', 'elementor' ),
509 'label_on' => __( 'Show', 'elementor' ),
510 'condition' => [
511 'video_type' => 'hosted',
512 ],
513 ]
514 );
515
516 $this->add_control(
517 'poster',
518 [
519 'label' => __( 'Poster', 'elementor' ),
520 'type' => Controls_Manager::MEDIA,
521 'dynamic' => [
522 'active' => true,
523 ],
524 'condition' => [
525 'video_type' => 'hosted',
526 ],
527 ]
528 );
529
530 $this->add_control(
531 'view',
532 [
533 'label' => __( 'View', 'elementor' ),
534 'type' => Controls_Manager::HIDDEN,
535 'default' => 'youtube',
536 ]
537 );
538
539 $this->end_controls_section();
540
541 $this->start_controls_section(
542 'section_image_overlay',
543 [
544 'label' => __( 'Image Overlay', 'elementor' ),
545 ]
546 );
547
548 $this->add_control(
549 'show_image_overlay',
550 [
551 'label' => __( 'Image Overlay', 'elementor' ),
552 'type' => Controls_Manager::SWITCHER,
553 'label_off' => __( 'Hide', 'elementor' ),
554 'label_on' => __( 'Show', 'elementor' ),
555 'frontend_available' => true,
556 ]
557 );
558
559 $this->add_control(
560 'image_overlay',
561 [
562 'label' => __( 'Choose Image', 'elementor' ),
563 'type' => Controls_Manager::MEDIA,
564 'default' => [
565 'url' => Utils::get_placeholder_image_src(),
566 ],
567 'dynamic' => [
568 'active' => true,
569 ],
570 'condition' => [
571 'show_image_overlay' => 'yes',
572 ],
573 'frontend_available' => true,
574 ]
575 );
576
577 $this->add_group_control(
578 Group_Control_Image_Size::get_type(),
579 [
580 'name' => 'image_overlay', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `image_overlay_size` and `image_overlay_custom_dimension`.
581 'default' => 'full',
582 'separator' => 'none',
583 'condition' => [
584 'show_image_overlay' => 'yes',
585 ],
586 ]
587 );
588
589 $this->add_control(
590 'show_play_icon',
591 [
592 'label' => __( 'Play Icon', 'elementor' ),
593 'type' => Controls_Manager::SWITCHER,
594 'default' => 'yes',
595 'condition' => [
596 'show_image_overlay' => 'yes',
597 'image_overlay[url]!' => '',
598 ],
599 ]
600 );
601
602 $this->add_control(
603 'lightbox',
604 [
605 'label' => __( 'Lightbox', 'elementor' ),
606 'type' => Controls_Manager::SWITCHER,
607 'frontend_available' => true,
608 'label_off' => __( 'Off', 'elementor' ),
609 'label_on' => __( 'On', 'elementor' ),
610 'condition' => [
611 'show_image_overlay' => 'yes',
612 'image_overlay[url]!' => '',
613 ],
614 'separator' => 'before',
615 ]
616 );
617
618 $this->end_controls_section();
619
620 $this->start_controls_section(
621 'section_video_style',
622 [
623 'label' => __( 'Video', 'elementor' ),
624 'tab' => Controls_Manager::TAB_STYLE,
625 ]
626 );
627
628 $this->add_control(
629 'aspect_ratio',
630 [
631 'label' => __( 'Aspect Ratio', 'elementor' ),
632 'type' => Controls_Manager::SELECT,
633 'options' => [
634 '169' => '16:9',
635 '219' => '21:9',
636 '43' => '4:3',
637 '32' => '3:2',
638 '11' => '1:1',
639 '916' => '9:16',
640 ],
641 'default' => '169',
642 'prefix_class' => 'elementor-aspect-ratio-',
643 'frontend_available' => true,
644 ]
645 );
646
647 $this->add_group_control(
648 Group_Control_Css_Filter::get_type(),
649 [
650 'name' => 'css_filters',
651 'selector' => '{{WRAPPER}} .elementor-wrapper',
652 ]
653 );
654
655 $this->add_control(
656 'play_icon_title',
657 [
658 'label' => __( 'Play Icon', 'elementor' ),
659 'type' => Controls_Manager::HEADING,
660 'condition' => [
661 'show_image_overlay' => 'yes',
662 'show_play_icon' => 'yes',
663 ],
664 'separator' => 'before',
665 ]
666 );
667
668 $this->add_control(
669 'play_icon_color',
670 [
671 'label' => __( 'Color', 'elementor' ),
672 'type' => Controls_Manager::COLOR,
673 'selectors' => [
674 '{{WRAPPER}} .elementor-custom-embed-play i' => 'color: {{VALUE}}',
675 ],
676 'condition' => [
677 'show_image_overlay' => 'yes',
678 'show_play_icon' => 'yes',
679 ],
680 ]
681 );
682
683 $this->add_responsive_control(
684 'play_icon_size',
685 [
686 'label' => __( 'Size', 'elementor' ),
687 'type' => Controls_Manager::SLIDER,
688 'range' => [
689 'px' => [
690 'min' => 10,
691 'max' => 300,
692 ],
693 ],
694 'selectors' => [
695 '{{WRAPPER}} .elementor-custom-embed-play i' => 'font-size: {{SIZE}}{{UNIT}}',
696 ],
697 'condition' => [
698 'show_image_overlay' => 'yes',
699 'show_play_icon' => 'yes',
700 ],
701 ]
702 );
703
704 $this->add_group_control(
705 Group_Control_Text_Shadow::get_type(),
706 [
707 'name' => 'play_icon_text_shadow',
708 'selector' => '{{WRAPPER}} .elementor-custom-embed-play i',
709 'fields_options' => [
710 'text_shadow_type' => [
711 'label' => _x( 'Shadow', 'Text Shadow Control', 'elementor' ),
712 ],
713 ],
714 'condition' => [
715 'show_image_overlay' => 'yes',
716 'show_play_icon' => 'yes',
717 ],
718 ]
719 );
720
721 $this->end_controls_section();
722
723 $this->start_controls_section(
724 'section_lightbox_style',
725 [
726 'label' => __( 'Lightbox', 'elementor' ),
727 'tab' => Controls_Manager::TAB_STYLE,
728 'condition' => [
729 'show_image_overlay' => 'yes',
730 'image_overlay[url]!' => '',
731 'lightbox' => 'yes',
732 ],
733 ]
734 );
735
736 $this->add_control(
737 'lightbox_color',
738 [
739 'label' => __( 'Background Color', 'elementor' ),
740 'type' => Controls_Manager::COLOR,
741 'selectors' => [
742 '#elementor-lightbox-{{ID}}' => 'background-color: {{VALUE}};',
743 ],
744 ]
745 );
746
747 $this->add_control(
748 'lightbox_ui_color',
749 [
750 'label' => __( 'UI Color', 'elementor' ),
751 'type' => Controls_Manager::COLOR,
752 'selectors' => [
753 '#elementor-lightbox-{{ID}} .dialog-lightbox-close-button' => 'color: {{VALUE}}',
754 ],
755 ]
756 );
757
758 $this->add_control(
759 'lightbox_ui_color_hover',
760 [
761 'label' => __( 'UI Hover Color', 'elementor' ),
762 'type' => Controls_Manager::COLOR,
763 'selectors' => [
764 '#elementor-lightbox-{{ID}} .dialog-lightbox-close-button:hover' => 'color: {{VALUE}}',
765 ],
766 'separator' => 'after',
767 ]
768 );
769
770 $this->add_control(
771 'lightbox_video_width',
772 [
773 'label' => __( 'Content Width', 'elementor' ),
774 'type' => Controls_Manager::SLIDER,
775 'default' => [
776 'unit' => '%',
777 ],
778 'range' => [
779 '%' => [
780 'min' => 30,
781 ],
782 ],
783 'selectors' => [
784 '(desktop+)#elementor-lightbox-{{ID}} .elementor-video-container' => 'width: {{SIZE}}{{UNIT}};',
785 ],
786 ]
787 );
788
789 $this->add_control(
790 'lightbox_content_position',
791 [
792 'label' => __( 'Content Position', 'elementor' ),
793 'type' => Controls_Manager::SELECT,
794 'frontend_available' => true,
795 'options' => [
796 '' => __( 'Center', 'elementor' ),
797 'top' => __( 'Top', 'elementor' ),
798 ],
799 'selectors' => [
800 '#elementor-lightbox-{{ID}} .elementor-video-container' => '{{VALUE}}; transform: translateX(-50%);',
801 ],
802 'selectors_dictionary' => [
803 'top' => 'top: 60px',
804 ],
805 ]
806 );
807
808 $this->add_responsive_control(
809 'lightbox_content_animation',
810 [
811 'label' => __( 'Entrance Animation', 'elementor' ),
812 'type' => Controls_Manager::ANIMATION,
813 'frontend_available' => true,
814 ]
815 );
816
817 $this->end_controls_section();
818 }
819
820 /**
821 * Render video widget output on the frontend.
822 *
823 * Written in PHP and used to generate the final HTML.
824 *
825 * @since 1.0.0
826 * @access protected
827 */
828 protected function render() {
829 $settings = $this->get_settings_for_display();
830
831 $video_url = $settings[ $settings['video_type'] . '_url' ];
832
833 if ( 'hosted' === $settings['video_type'] ) {
834 $video_url = $this->get_hosted_video_url();
835 } else {
836 $embed_params = $this->get_embed_params();
837 $embed_options = $this->get_embed_options();
838 }
839
840 if ( empty( $video_url ) ) {
841 return;
842 }
843
844 if ( 'youtube' === $settings['video_type'] ) {
845 $video_html = '<div class="elementor-video"></div>';
846 }
847
848 if ( 'hosted' === $settings['video_type'] ) {
849 $this->add_render_attribute( 'video-wrapper', 'class', 'e-hosted-video' );
850
851 ob_start();
852
853 $this->render_hosted_video();
854
855 $video_html = ob_get_clean();
856 } else {
857 $is_static_render_mode = Plugin::$instance->frontend->is_static_render_mode();
858 $post_id = get_queried_object_id();
859
860 if ( $is_static_render_mode ) {
861 $video_html = Embed::get_embed_thumbnail_html( $video_url, $post_id );
862 // YouTube API requires a different markup which was set above.
863 } else if ( 'youtube' !== $settings['video_type'] ) {
864 $video_html = Embed::get_embed_html( $video_url, $embed_params, $embed_options );
865 }
866 }
867
868 if ( empty( $video_html ) ) {
869 echo esc_url( $video_url );
870
871 return;
872 }
873
874 $this->add_render_attribute( 'video-wrapper', 'class', 'elementor-wrapper' );
875
876 if ( ! $settings['lightbox'] ) {
877 $this->add_render_attribute( 'video-wrapper', 'class', 'elementor-fit-aspect-ratio' );
878 }
879
880 $this->add_render_attribute( 'video-wrapper', 'class', 'elementor-open-' . ( $settings['lightbox'] ? 'lightbox' : 'inline' ) );
881 ?>
882 <div <?php echo $this->get_render_attribute_string( 'video-wrapper' ); ?>>
883 <?php
884 if ( ! $settings['lightbox'] ) {
885 echo $video_html; // XSS ok.
886 }
887
888 if ( $this->has_image_overlay() ) {
889 $this->add_render_attribute( 'image-overlay', 'class', 'elementor-custom-embed-image-overlay' );
890
891 if ( $settings['lightbox'] ) {
892 if ( 'hosted' === $settings['video_type'] ) {
893 $lightbox_url = $video_url;
894 } else {
895 $lightbox_url = Embed::get_embed_url( $video_url, $embed_params, $embed_options );
896 }
897
898 $lightbox_options = [
899 'type' => 'video',
900 'videoType' => $settings['video_type'],
901 'url' => $lightbox_url,
902 'modalOptions' => [
903 'id' => 'elementor-lightbox-' . $this->get_id(),
904 'entranceAnimation' => $settings['lightbox_content_animation'],
905 'entranceAnimation_tablet' => $settings['lightbox_content_animation_tablet'],
906 'entranceAnimation_mobile' => $settings['lightbox_content_animation_mobile'],
907 'videoAspectRatio' => $settings['aspect_ratio'],
908 ],
909 ];
910
911 if ( 'hosted' === $settings['video_type'] ) {
912 $lightbox_options['videoParams'] = $this->get_hosted_params();
913 }
914
915 $this->add_render_attribute( 'image-overlay', [
916 'data-elementor-open-lightbox' => 'yes',
917 'data-elementor-lightbox' => wp_json_encode( $lightbox_options ),
918 ] );
919
920 if ( Plugin::$instance->editor->is_edit_mode() ) {
921 $this->add_render_attribute( 'image-overlay', [
922 'class' => 'elementor-clickable',
923 ] );
924 }
925 } else {
926 // When there is an image URL but no ID, it means the overlay image is the placeholder. In this case, get the placeholder URL.
927 if ( empty( $settings['image_overlay']['id'] && ! empty( $settings['image_overlay']['url'] ) ) ) {
928 $image_url = $settings['image_overlay']['url'];
929 } else {
930 $image_url = Group_Control_Image_Size::get_attachment_image_src( $settings['image_overlay']['id'], 'image_overlay', $settings );
931 }
932
933 $this->add_render_attribute( 'image-overlay', 'style', 'background-image: url(' . $image_url . ');' );
934 }
935 ?>
936 <div <?php echo $this->get_render_attribute_string( 'image-overlay' ); ?>>
937 <?php if ( $settings['lightbox'] ) : ?>
938 <?php echo Group_Control_Image_Size::get_attachment_image_html( $settings, 'image_overlay' ); ?>
939 <?php endif; ?>
940 <?php if ( 'yes' === $settings['show_play_icon'] ) : ?>
941 <div class="elementor-custom-embed-play" role="button">
942 <i class="eicon-play" aria-hidden="true"></i>
943 <span class="elementor-screen-only"><?php echo __( 'Play Video', 'elementor' ); ?></span>
944 </div>
945 <?php endif; ?>
946 </div>
947 <?php } ?>
948 </div>
949 <?php
950 }
951
952 /**
953 * Render video widget as plain content.
954 *
955 * Override the default behavior, by printing the video URL insted of rendering it.
956 *
957 * @since 1.4.5
958 * @access public
959 */
960 public function render_plain_content() {
961 $settings = $this->get_settings_for_display();
962
963 if ( 'hosted' !== $settings['video_type'] ) {
964 $url = $settings[ $settings['video_type'] . '_url' ];
965 } else {
966 $url = $this->get_hosted_video_url();
967 }
968
969 echo esc_url( $url );
970 }
971
972 /**
973 * Get embed params.
974 *
975 * Retrieve video widget embed parameters.
976 *
977 * @since 1.5.0
978 * @access public
979 *
980 * @return array Video embed parameters.
981 */
982 public function get_embed_params() {
983 $settings = $this->get_settings_for_display();
984
985 $params = [];
986
987 if ( $settings['autoplay'] && ! $this->has_image_overlay() ) {
988 $params['autoplay'] = '1';
989
990 if ( $settings['play_on_mobile'] ) {
991 $params['playsinline'] = '1';
992 }
993 }
994
995 $params_dictionary = [];
996
997 if ( 'youtube' === $settings['video_type'] ) {
998 $params_dictionary = [
999 'loop',
1000 'controls',
1001 'mute',
1002 'rel',
1003 'modestbranding',
1004 ];
1005
1006 if ( $settings['loop'] ) {
1007 $video_properties = Embed::get_video_properties( $settings['youtube_url'] );
1008
1009 $params['playlist'] = $video_properties['video_id'];
1010 }
1011
1012 $params['start'] = $settings['start'];
1013
1014 $params['end'] = $settings['end'];
1015
1016 $params['wmode'] = 'opaque';
1017 } elseif ( 'vimeo' === $settings['video_type'] ) {
1018 $params_dictionary = [
1019 'loop',
1020 'mute' => 'muted',
1021 'vimeo_title' => 'title',
1022 'vimeo_portrait' => 'portrait',
1023 'vimeo_byline' => 'byline',
1024 ];
1025
1026 $params['color'] = str_replace( '#', '', $settings['color'] );
1027
1028 $params['autopause'] = '0';
1029 } elseif ( 'dailymotion' === $settings['video_type'] ) {
1030 $params_dictionary = [
1031 'controls',
1032 'mute',
1033 'showinfo' => 'ui-start-screen-info',
1034 'logo' => 'ui-logo',
1035 ];
1036
1037 $params['ui-highlight'] = str_replace( '#', '', $settings['color'] );
1038
1039 $params['start'] = $settings['start'];
1040
1041 $params['endscreen-enable'] = '0';
1042 }
1043
1044 foreach ( $params_dictionary as $key => $param_name ) {
1045 $setting_name = $param_name;
1046
1047 if ( is_string( $key ) ) {
1048 $setting_name = $key;
1049 }
1050
1051 $setting_value = $settings[ $setting_name ] ? '1' : '0';
1052
1053 $params[ $param_name ] = $setting_value;
1054 }
1055
1056 return $params;
1057 }
1058
1059 /**
1060 * Whether the video widget has an overlay image or not.
1061 *
1062 * Used to determine whether an overlay image was set for the video.
1063 *
1064 * @since 1.0.0
1065 * @access protected
1066 *
1067 * @return bool Whether an image overlay was set for the video.
1068 */
1069 protected function has_image_overlay() {
1070 $settings = $this->get_settings_for_display();
1071
1072 return ! empty( $settings['image_overlay']['url'] ) && 'yes' === $settings['show_image_overlay'];
1073 }
1074
1075 /**
1076 * @since 2.1.0
1077 * @access private
1078 */
1079 private function get_embed_options() {
1080 $settings = $this->get_settings_for_display();
1081
1082 $embed_options = [];
1083
1084 if ( 'youtube' === $settings['video_type'] ) {
1085 $embed_options['privacy'] = $settings['yt_privacy'];
1086 } elseif ( 'vimeo' === $settings['video_type'] ) {
1087 $embed_options['start'] = $settings['start'];
1088 }
1089
1090 $embed_options['lazy_load'] = ! empty( $settings['lazy_load'] );
1091
1092 return $embed_options;
1093 }
1094
1095 /**
1096 * @since 2.1.0
1097 * @access private
1098 */
1099 private function get_hosted_params() {
1100 $settings = $this->get_settings_for_display();
1101
1102 $video_params = [];
1103
1104 foreach ( [ 'autoplay', 'loop', 'controls' ] as $option_name ) {
1105 if ( $settings[ $option_name ] ) {
1106 $video_params[ $option_name ] = '';
1107 }
1108 }
1109
1110 if ( $settings['mute'] ) {
1111 $video_params['muted'] = 'muted';
1112 }
1113
1114 if ( $settings['play_on_mobile'] ) {
1115 $video_params['playsinline'] = '';
1116 }
1117
1118 if ( ! $settings['download_button'] ) {
1119 $video_params['controlsList'] = 'nodownload';
1120 }
1121
1122 if ( $settings['poster']['url'] ) {
1123 $video_params['poster'] = $settings['poster']['url'];
1124 }
1125
1126 return $video_params;
1127 }
1128
1129 /**
1130 * @param bool $from_media
1131 *
1132 * @return string
1133 * @since 2.1.0
1134 * @access private
1135 */
1136 private function get_hosted_video_url() {
1137 $settings = $this->get_settings_for_display();
1138
1139 if ( ! empty( $settings['insert_url'] ) ) {
1140 $video_url = $settings['external_url']['url'];
1141 } else {
1142 $video_url = $settings['hosted_url']['url'];
1143 }
1144
1145 if ( empty( $video_url ) ) {
1146 return '';
1147 }
1148
1149 if ( $settings['start'] || $settings['end'] ) {
1150 $video_url .= '#t=';
1151 }
1152
1153 if ( $settings['start'] ) {
1154 $video_url .= $settings['start'];
1155 }
1156
1157 if ( $settings['end'] ) {
1158 $video_url .= ',' . $settings['end'];
1159 }
1160
1161 return $video_url;
1162 }
1163
1164 /**
1165 *
1166 * @since 2.1.0
1167 * @access private
1168 */
1169 private function render_hosted_video() {
1170 $video_url = $this->get_hosted_video_url();
1171 if ( empty( $video_url ) ) {
1172 return;
1173 }
1174
1175 $video_params = $this->get_hosted_params();
1176 ?>
1177 <video class="elementor-video" src="<?php echo esc_url( $video_url ); ?>" <?php echo Utils::render_html_attributes( $video_params ); ?>></video>
1178 <?php
1179 }
1180 }
1181