start_controls_section( 'section_video', [ 'label' => __( 'Video', 'admore-widgets-suite' ), ] ); $this->add_control( 'video_type', [ 'label' => __( 'Source', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'youtube', 'options' => [ 'youtube' => 'YouTube', 'vimeo' => 'Vimeo', 'hosted' => __( 'Self Hosted', 'admore-widgets-suite' ), ], ] ); $this->add_control( 'youtube_url', [ 'label' => __( 'YouTube URL', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'label_block' => true, 'condition' => [ 'video_type' => 'youtube' ], 'dynamic' => [ 'active' => true ], ] ); $this->add_control( 'vimeo_url', [ 'label' => __( 'Vimeo URL', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => 'https://vimeo.com/76979871', 'label_block' => true, 'condition' => [ 'video_type' => 'vimeo' ], 'dynamic' => [ 'active' => true ], ] ); $this->add_control( 'hosted_url', [ 'label' => __( 'Video File URL', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::MEDIA, 'media_type' => 'video', 'condition' => [ 'video_type' => 'hosted' ], 'dynamic' => [ 'active' => true ], ] ); $this->add_control( 'start_time', [ 'label' => __( 'Start Time (seconds)', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::NUMBER, 'min' => 0, 'default' => 0, 'condition' => [ 'video_type!' => 'hosted' ], ] ); $this->end_controls_section(); /* ── Video Options ── */ $this->start_controls_section( 'section_options', [ 'label' => __( 'Options', 'admore-widgets-suite' ), ] ); $this->add_control( 'autoplay', [ 'label' => __( 'Autoplay', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', ] ); $this->add_control( 'mute', [ 'label' => __( 'Mute', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', ] ); $this->add_control( 'loop', [ 'label' => __( 'Loop', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', ] ); $this->add_control( 'controls', [ 'label' => __( 'Show Controls', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', ] ); $this->add_control( 'rel', [ 'label' => __( 'Suggested Videos', 'admore-widgets-suite' ), 'description' => __( 'Show related videos after playback ends.', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', 'condition' => [ 'video_type' => 'youtube' ], ] ); $this->add_control( 'privacy_mode', [ 'label' => __( 'Privacy-Enhanced Mode', 'admore-widgets-suite' ), 'description' => __( 'Uses youtube-nocookie.com domain.', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', 'condition' => [ 'video_type' => 'youtube' ], ] ); $this->end_controls_section(); /* ── Poster / Overlay ── */ $this->start_controls_section( 'section_poster', [ 'label' => __( 'Poster / Overlay', 'admore-widgets-suite' ), ] ); $this->add_control( 'show_poster', [ 'label' => __( 'Show Poster Image', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', ] ); $this->add_control( 'poster_image', [ 'label' => __( 'Poster Image', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::MEDIA, 'condition' => [ 'show_poster' => 'yes' ], 'dynamic' => [ 'active' => true ], ] ); $this->add_control( 'use_youtube_thumb', [ 'label' => __( 'Auto-fetch YouTube Thumbnail', 'admore-widgets-suite' ), 'description' => __( 'Uses hqdefault thumbnail from YouTube if no poster is set.', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', 'condition' => [ 'show_poster' => 'yes', 'video_type' => 'youtube', 'poster_image[url]' => '' ], ] ); $this->add_control( 'lightbox', [ 'label' => __( 'Open in Lightbox', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'show_play_btn', [ 'label' => __( 'Show Play Button', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', ] ); $this->add_control( 'play_btn_style', [ 'label' => __( 'Play Button Style', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'circle', 'options' => [ 'circle' => __( 'Circle', 'admore-widgets-suite' ), 'youtube' => __( 'YouTube Style', 'admore-widgets-suite' ), 'minimal' => __( 'Minimal', 'admore-widgets-suite' ), ], 'condition' => [ 'show_play_btn' => 'yes' ], ] ); $this->end_controls_section(); /* ── Style: Video ── */ $this->start_controls_section( 'section_style_video', [ 'label' => __( 'Video', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'aspect_ratio', [ 'label' => __( 'Aspect Ratio', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => '169', 'options' => [ '169' => '16:9', '43' => '4:3', '11' => '1:1', '219' => '21:9', '916' => '9:16 (portrait)', ], ] ); $this->add_responsive_control( 'max_width', [ 'label' => __( 'Max Width', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px', '%' ], 'range' => [ 'px' => [ 'min' => 200, 'max' => 1600 ], '%' => [ 'min' => 10, 'max' => 100 ] ], 'selectors' => [ '{{WRAPPER}} .eppro-video-wrapper' => 'max-width: {{SIZE}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'border_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%' ], 'selectors' => [ '{{WRAPPER}} .eppro-video-wrapper' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; overflow: hidden;' ], ] ); $this->add_group_control( \Elementor\Group_Control_Box_Shadow::get_type(), [ 'name' => 'video_shadow', 'selector' => '{{WRAPPER}} .eppro-video-wrapper', ] ); $this->end_controls_section(); /* ── Style: Play Button ── */ $this->start_controls_section( 'section_style_btn', [ 'label' => __( 'Play Button', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_responsive_control( 'play_btn_size', [ 'label' => __( 'Size', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 30, 'max' => 160 ] ], 'default' => [ 'size' => 72, 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-play-btn' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};' ], ] ); $this->add_control( 'play_btn_color', [ 'label' => __( 'Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => '#ffffff', 'selectors' => [ '{{WRAPPER}} .eppro-play-btn' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'play_btn_bg', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => 'rgba(0,0,0,0.6)', 'selectors' => [ '{{WRAPPER}} .eppro-play-btn--circle' => 'background-color: {{VALUE}};' ], ] ); $this->add_control( 'play_btn_hover_bg', [ 'label' => __( 'Hover Background', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-video-overlay:hover .eppro-play-btn--circle' => 'background-color: {{VALUE}};' ], ] ); $this->add_control( 'overlay_color', [ 'label' => __( 'Overlay Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'default' => 'rgba(0,0,0,0.2)', 'selectors' => [ '{{WRAPPER}} .eppro-video-overlay::before' => 'background-color: {{VALUE}};' ], 'separator' => 'before', ] ); $this->end_controls_section(); $this->eppro_register_entrance_animation_controls(); } // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- private function get_embed_url( array $s ): string { $type = $s['video_type'] ?? 'youtube'; $autoplay = 'yes' === ( $s['autoplay'] ?? '' ) ? 1 : 0; $mute = 'yes' === ( $s['mute'] ?? '' ) ? 1 : 0; $loop = 'yes' === ( $s['loop'] ?? '' ) ? 1 : 0; $controls = 'yes' === ( $s['controls'] ?? 'yes' ) ? 1 : 0; $start = (int) ( $s['start_time'] ?? 0 ); if ( 'youtube' === $type ) { $raw_url = $s['youtube_url'] ?? ''; preg_match( '/(?:v=|youtu\.be\/)([A-Za-z0-9_\-]{11})/', $raw_url, $m ); $vid = $m[1] ?? ''; if ( ! $vid ) return ''; $domain = ( 'yes' === ( $s['privacy_mode'] ?? '' ) ) ? 'youtube-nocookie.com' : 'youtube.com'; $rel = 'yes' === ( $s['rel'] ?? '' ) ? 1 : 0; // Build params manually — do NOT use array_filter() because it strips 0 // values and YouTube needs controls=0 / rel=0 to honour those settings. $yt_params = [ 'autoplay' => $autoplay, 'mute' => $mute, 'loop' => $loop, 'controls' => $controls, 'rel' => $rel, ]; if ( $start > 0 ) $yt_params['start'] = $start; if ( $loop ) $yt_params['playlist'] = $vid; $params = http_build_query( $yt_params ); return "https://www.{$domain}/embed/{$vid}?{$params}"; } if ( 'vimeo' === $type ) { $raw_url = $s['vimeo_url'] ?? ''; preg_match( '/vimeo\.com\/(\d+)/', $raw_url, $m ); $vid = $m[1] ?? ''; if ( ! $vid ) return ''; // Only send params when non-zero (Vimeo defaults are fine without them). $vimeo_params = []; if ( $autoplay ) $vimeo_params['autoplay'] = 1; if ( $mute ) $vimeo_params['muted'] = 1; if ( $loop ) $vimeo_params['loop'] = 1; $url = "https://player.vimeo.com/video/{$vid}"; if ( $vimeo_params ) $url .= '?' . http_build_query( $vimeo_params ); // Start time must be a URL fragment (#t=Ns), NOT a query param. if ( $start > 0 ) $url .= '#t=' . $start . 's'; return $url; } // Hosted file: only a real http(s) URL is accepted (it is also used by the lightbox script). return esc_url_raw( (string) ( $s['hosted_url']['url'] ?? '' ), [ 'http', 'https' ] ); } private function get_youtube_id( string $url ): string { preg_match( '/(?:v=|youtu\.be\/)([A-Za-z0-9_\-]{11})/', $url, $m ); return $m[1] ?? ''; } private function get_ratio_padding( string $ratio ): string { $map = [ '169' => '56.25%', '43' => '75%', '11' => '100%', '219' => '42.86%', '916' => '177.78%', ]; return $map[ $ratio ] ?? '56.25%'; } // ------------------------------------------------------------------------- // Render // ------------------------------------------------------------------------- protected function render(): void { $s = $this->get_settings_for_display(); $type = $s['video_type'] ?? 'youtube'; $ratio = $s['aspect_ratio'] ?? '169'; $show_poster = 'yes' === ( $s['show_poster'] ?? 'yes' ); $show_play = 'yes' === ( $s['show_play_btn'] ?? 'yes' ); $lightbox = 'yes' === ( $s['lightbox'] ?? '' ); $btn_style = $s['play_btn_style'] ?? 'circle'; $embed_url = $this->get_embed_url( $s ); if ( ! $embed_url && 'hosted' !== $type ) return; $poster_url = ''; if ( $show_poster ) { if ( ! empty( $s['poster_image']['url'] ) ) { $poster_url = $s['poster_image']['url']; } elseif ( 'youtube' === $type && 'yes' === ( $s['use_youtube_thumb'] ?? 'yes' ) ) { $vid = $this->get_youtube_id( $s['youtube_url'] ?? '' ); if ( $vid ) $poster_url = "https://img.youtube.com/vi/{$vid}/hqdefault.jpg"; } } $padding_bottom = $this->get_ratio_padding( $ratio ); $data = [ 'type' => $type, 'embedUrl' => $embed_url, 'autoplay' => 'yes' === ( $s['autoplay'] ?? '' ), 'lightbox' => $lightbox, 'hasPoster' => (bool) $poster_url, ]; ?>