--- /dev/null
+<?php
+
+namespace PhysioAssist\Elementor\Widgets;
+
+use Elementor\Widget_Base;
+use Elementor\Controls_Manager;
+use Elementor\Utils;
+use Elementor\Embed;
+
+
+class VideoGallery extends Widget_Base {
+
+ // Widget name / ID
+ public function get_name() {
+ return 'cube-video-gallery';
+ }
+
+ // Elementor widget title
+ public function get_title() {
+ return __( 'Video Gallery', 'cube' );
+ }
+
+ // Elementor interface icon
+ public function get_icon() {
+ return 'eicon-play';
+ }
+
+ // Where to display the widget in the Elementor interface
+ public function get_categories() {
+ return [ 'theme-elements' ];
+ }
+
+
+ // Register scripts related to this widget (called by the Elementor\Setup)
+ // See also get_script_depends()
+ public static function register_scripts() {
+ wp_register_script(
+ 'cube-video-carousel',
+ \App\asset_path('scripts/video-carousel.js'),
+ ['jquery'], // Dependencies
+ null, // Version
+ true // In footer?
+ );
+ }
+
+
+ /**
+ * List of scripts the widget depends on.
+ * Used to set scripts dependencies required to run the widget.
+ *
+ * @since 1.0.0
+ * @access public
+ * @return array Widget scripts dependencies.
+ */
+ public function get_script_depends() {
+ // Use script already registered by Elementor so we don't have to include another copy of Slick
+ return [ 'jquery-slick', 'cube-video-carousel' ];
+ }
+ /**
+ * Register the widget controls.
+ * Adds different input fields to allow the user to change and customize the widget settings.
+ *
+ * @since 1.0.0
+ * @access protected
+ */
+ protected function _register_controls() {
+
+ $this->start_controls_section(
+ 'section_content',
+ [
+ 'label' => __( 'Video Gallery', 'cube' ),
+ ]
+ );
+
+ $this->add_control(
+ 'type',
+ [
+ 'label' => __('Gallery Type', 'cube'),
+ 'type' => Controls_Manager::SELECT,
+ 'options' => [
+ 'grid' => __( 'Grid', 'cube' ),
+ 'carousel' => __( 'Carousel', 'cube' ),
+ ],
+ 'default' => 'grid',
+ 'render_type' => 'template', // Make editor re-render when this changes
+ 'prefix_class' => 'video-gallery-type-',
+ ]
+ );
+
+ $this->add_control(
+ 'videos',
+ [
+ 'label' => __( 'Videos', 'cube' ),
+ 'type' => Controls_Manager::REPEATER,
+ 'fields' => [
+ [
+ 'name' => 'url',
+ 'label' => __( 'Video URL', 'cube' ),
+ 'placeholder' => __( 'Enter YouTube link', 'cube' ),
+ 'type' => Controls_Manager::TEXT,
+ 'label_block' => true,
+ ],
+ [
+ 'name' => 'title',
+ 'label' => __( 'Title', 'cube' ),
+ 'type' => Controls_Manager::TEXT,
+ 'label_block' => true,
+ ],
+ [
+ 'name' => 'details',
+ 'label' => __( 'Additional Details', 'cube' ),
+ 'placeholder' => __( 'Extra information for slider view', 'cube' ),
+ 'type' => Controls_Manager::TEXT,
+ 'label_block' => true,
+ ],
+ [
+ 'name' => 'image',
+ 'label' => __('Preview Image (optional)', 'cube'),
+ 'label_block' => true,
+ 'type' => Controls_Manager::MEDIA,
+ 'default' => [
+ 'url' => Utils::get_placeholder_image_src(),
+ ],
+ ],
+ ],
+ 'title_field' => '{{{ title }}}',
+ ]
+ );
+ $this->end_controls_section();
+
+
+ }
+ /**
+ * Render the widget output on the frontend.
+ * Written in PHP and used to generate the final HTML.
+ *
+ * @since 1.0.0
+ * @access protected
+ */
+ protected function render() {
+
+ $gallery_type = $this->get_settings('type');
+ $videos = $this->get_settings('videos');
+
+ // First, filter out any items that don't have a video URL
+ $videos = array_filter($videos, function($v) {
+ return (!empty($v['url']));
+ });
+
+ // Get videos and process each video URL so it can be used with Elementor lightbox
+ $videos = array_map(function($video) {
+
+ // Video settings for lightbox embed
+ $embed_params = [
+ 'rel' => 0, // Don't show related videos at the end of playback
+ 'showinfo' => 0 // Hide info
+ ];
+
+ $lightbox_options = [
+ 'type' => 'video',
+ 'url' => Embed::get_embed_url($video['url'], $embed_params),
+ 'modalOptions' => [
+ 'id' => 'elementor-lightbox-' . $this->get_id(),
+ 'entranceAnimation' => 'zoomIn',
+ 'videoAspectRatio' => '169',
+ ],
+ ];
+
+ $video['lightbox'] = wp_json_encode($lightbox_options);
+
+ $video_properties = Embed::get_video_properties($video['url']);
+
+
+ // If no preview image is set, fetch the one from Youtube
+ if (empty($video['image']['id'])) {
+ $video['preview'] = $this->youtube_image($video_properties['video_id']);
+ } else {
+ $video['preview'] = wp_get_attachment_image_url($video['image']['id'], 'video-preview');
+ }
+
+ return $video;
+ }, $videos);
+
+ if ($gallery_type == 'carousel') {
+ echo \App\template('widgets/video-gallery-carousel', compact('videos'));
+ } else {
+ echo \App\template('widgets/video-gallery-grid', compact('videos'));
+ }
+
+ }
+
+
+ // We can't guarantee that the video's maxresdefault.jpg will exist (it's not created for non-HD uploads)
+ // So this function will find the highest res image available...
+ // Ref: https://stackoverflow.com/a/20655623
+ function youtube_image($id) {
+ $resolution = [
+ 'maxresdefault',
+ 'hqdefault', // Might have black bars
+ 'mqdefault', // No black bars on this size normally
+ 'sddefault',
+ 'default'
+ ];
+
+ for ($x = 0; $x < sizeof($resolution); $x++) {
+ $url = 'https://img.youtube.com/vi/' . $id . '/' . $resolution[$x] . '.jpg';
+ // Make sure we get a 200 OK HTTP response
+ if (strpos(get_headers($url)[0], '200 OK') !== false) {
+ break;
+ }
+ }
+ return $url;
+ }
+
+}