]> _ Git - physioassist-wordpress.git/commitdiff
Wait #3632 @6
authorstephen@cubedesigners.com <stephen@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Mon, 11 May 2020 14:40:40 +0000 (14:40 +0000)
committerstephen@cubedesigners.com <stephen@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Mon, 11 May 2020 14:40:40 +0000 (14:40 +0000)
12 files changed:
wp-content/mu-plugins/physioassist/src/Elementor/Setup.php
wp-content/mu-plugins/physioassist/src/Elementor/Utils.php [new file with mode: 0644]
wp-content/mu-plugins/physioassist/src/Elementor/Widgets/MultimediaCarousel.php [new file with mode: 0644]
wp-content/mu-plugins/physioassist/src/Elementor/Widgets/VideoGallery.php
wp-content/themes/physioassist/resources/assets/config.json
wp-content/themes/physioassist/resources/assets/scripts/multimedia-carousel.js [new file with mode: 0644]
wp-content/themes/physioassist/resources/assets/styles/widgets/profile-carousel.styl
wp-content/themes/physioassist/resources/views/widgets/multimedia-carousel.blade.php [new file with mode: 0644]
wp-content/themes/physioassist/resources/views/widgets/partials/profile-slide.blade.php [new file with mode: 0644]
wp-content/themes/physioassist/resources/views/widgets/partials/video-slide.blade.php [new file with mode: 0644]
wp-content/themes/physioassist/resources/views/widgets/profile-carousel.blade.php
wp-content/themes/physioassist/resources/views/widgets/video-gallery-carousel.blade.php

index 8ab875b82acfb17fc78732c7512a0bb1b9f6b7a4..32aef5a4045929adee93a54f6d6d63731373243e 100644 (file)
@@ -71,6 +71,7 @@ class Setup {
         $elementor->widgets_manager->register_widget_type( new Widgets\ResourceGrid() );
         $elementor->widgets_manager->register_widget_type( new Widgets\VideoGallery() );
         $elementor->widgets_manager->register_widget_type( new Widgets\TextCarousel() );
+        $elementor->widgets_manager->register_widget_type( new Widgets\MultimediaCarousel() );
         $elementor->widgets_manager->register_widget_type( new Widgets\ModalList() );
         $elementor->widgets_manager->register_widget_type( new Widgets\BackgroundImage() );
     }
diff --git a/wp-content/mu-plugins/physioassist/src/Elementor/Utils.php b/wp-content/mu-plugins/physioassist/src/Elementor/Utils.php
new file mode 100644 (file)
index 0000000..43e2fea
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+namespace PhysioAssist\Elementor;
+
+use Elementor\Embed;
+
+class Utils
+{
+    // Create lightbox configuration for opening video in Elmentor popup
+    // This can also be used by other elements like TextBlock for the CTA links
+    public static function lightbox($url, $element_ID) {
+
+        // 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($url, $embed_params),
+            'modalOptions' => [
+                'id'                => 'elementor-lightbox-' . $element_ID,
+                'entranceAnimation' => 'zoomIn',
+                'videoAspectRatio'  => '169',
+            ],
+        ];
+
+        return wp_json_encode($lightbox_options);
+    }
+
+
+    // 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
+    public static function youtube_image($id) {
+
+        $resolution = [
+            'maxresdefault',
+            'hqdefault', // Might have black bars
+            'mqdefault', // No black bars on this size normally
+            'sddefault',
+            'default'
+        ];
+
+        $url = '';
+
+        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;
+    }
+
+}
diff --git a/wp-content/mu-plugins/physioassist/src/Elementor/Widgets/MultimediaCarousel.php b/wp-content/mu-plugins/physioassist/src/Elementor/Widgets/MultimediaCarousel.php
new file mode 100644 (file)
index 0000000..d645b36
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+
+namespace PhysioAssist\Elementor\Widgets;
+
+use Elementor\Embed;
+use Elementor\Widget_Base;
+use Elementor\Controls_Manager;
+use Elementor\Utils as ElementorUtils;
+
+use PhysioAssist\Elementor\Utils;
+
+use function App\template;
+use function App\asset_path;
+
+
+class MultimediaCarousel extends Widget_Base {
+
+    // Widget name / ID
+    public function get_name() {
+        return 'cube-multimedia-carousel';
+    }
+
+    // Elementor widget title
+    public function get_title() {
+        return __( 'Multimedia Carousel', 'cube' );
+    }
+
+    // Elementor interface icon
+    public function get_icon() {
+        return 'eicon-media-carousel';
+    }
+
+    // Where to display the widget in the Elementor interface
+    public function get_categories() {
+        return [ 'theme-elements' ];
+    }
+
+    /**
+     * 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() {
+
+        wp_register_script('lity', asset_path('scripts/lity.js'), ['jquery'], null, true);
+
+        wp_register_script(
+            'cube-multimedia-carousel',
+            asset_path('scripts/multimedia-carousel.js'),
+            ['jquery', 'lity'], // Dependencies
+            null, // Version
+            true // In footer?
+        );
+
+        // Use script already registered by Elementor so we don't have to include another copy of Slick
+        return ['jquery-slick', 'cube-multimedia-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' => __( 'Multimedia Carousel', 'cube' ),
+            ]
+        );
+
+
+        $this->add_control(
+            'items',
+            [
+                'label' => __( 'Items', 'cube' ),
+                'type' => Controls_Manager::REPEATER,
+                'fields' => [
+
+
+                    // TODO: finish video / text fields integration. Think about which fields can be used by both (image?)
+                    // TODO: refactor blade partials so same partial can be used by individual carousels + mixed carousel to output content (switch based on item type)
+
+
+
+                    [
+                        'name' => 'type',
+                        'label' => __('Slide Type', 'cube'),
+                        'type' => Controls_Manager::SELECT,
+                        'default' => '',
+                        'options' => [
+                            '' => __('(Select)'),
+                            'video' => __( 'Video', 'cube' ),
+                            'text' => __( 'Text', 'cube' ),
+                        ],
+                    ],
+
+
+                    [
+                        'name' => 'image',
+                        'label' => __('Image', 'cube'),
+                        'label_block' => true,
+                        'type' => Controls_Manager::MEDIA,
+                        'default' => [
+                            'url' => ElementorUtils::get_placeholder_image_src(),
+                        ],
+                        'condition' => [
+                            'type' => ['text', 'video']
+                        ],
+                    ],
+
+                    // Video URL only used for video slides
+                    [
+                        'name' => 'url',
+                        'label' => __( 'Video URL', 'cube' ),
+                        'placeholder' => __( 'Enter YouTube link', 'cube' ),
+                        'type' => Controls_Manager::TEXT,
+                        'label_block' => true,
+                        'condition' => [
+                            'type' => 'video'
+                        ],
+                    ],
+
+                    [
+                        'name' => 'title',
+                        'label' => __( 'Title', 'cube' ),
+                        'type' => Controls_Manager::TEXT,
+                        'label_block' => true,
+                        'default' => '',
+                        'condition' => [
+                            'type' => ['text', 'video']
+                        ],
+                    ],
+                    [
+                        'name' => 'subtitle',
+                        'label' => __( 'Subtitle', 'cube' ),
+                        'type' => Controls_Manager::TEXT,
+                        'label_block' => true,
+                        'condition' => [
+                            'type' => ['text', 'video']
+                        ],
+                    ],
+
+                    // Body field is only used for "text" slides
+                    [
+                        'name' => 'body',
+                        'label' => __('Body', 'cube'),
+                        'type' => Controls_Manager::WYSIWYG,
+                        'default' => '',
+                        'dynamic' => [
+                            'active' => false,
+                        ],
+                        'condition' => [
+                            'type' => 'text'
+                        ],
+                    ],
+                ],
+                'title_field' => '{{{ type == "text" ? \'<i class="eicon-text-align-left"></i>\' : "" }}} {{{ type == "video" ? \'<i class="eicon-video-camera"></i>\' : "" }}} {{{ 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() {
+
+        $items = $this->get_settings('items');
+
+        // Process items to get extra information needed for videos
+        foreach ($items as $index => $item) {
+            if ($item['type'] == 'video') {
+                $item['lightbox'] = Utils::lightbox($item['url'], $this->get_id());
+
+                $video_properties = Embed::get_video_properties($item['url']);
+
+                // If no preview image is set, fetch the one from Youtube
+                if (empty($item['image']['id'])) {
+                    $item['preview'] = Utils::youtube_image($video_properties['video_id']);
+                } else {
+                    $item['preview'] = wp_get_attachment_image_url($item['image']['id'], 'video-preview');
+                }
+
+                $item['details'] = $item['subtitle']; // Allow us to use the same 'subtitle' field for both slide types
+
+                $items[$index] = $item;
+            }
+        }
+
+        echo template('widgets/multimedia-carousel', compact('items'));
+    }
+
+
+}
index e7122c19a4079f8777cbca56b05e8af647305d8f..cbf03895ac5df30b45ef0e9d881549c5611403b5 100644 (file)
@@ -4,9 +4,12 @@ namespace PhysioAssist\Elementor\Widgets;
 
 use Elementor\Widget_Base;
 use Elementor\Controls_Manager;
-use Elementor\Utils;
+use Elementor\Utils as ElementorUtils;
 use Elementor\Embed;
 
+use PhysioAssist\Elementor\Utils;
+
+use function App\template;
 
 class VideoGallery extends Widget_Base {
 
@@ -115,7 +118,7 @@ class VideoGallery extends Widget_Base {
                         'label_block' => true,
                         'type' => Controls_Manager::MEDIA,
                         'default' => [
-                            'url' => Utils::get_placeholder_image_src(),
+                            'url' => ElementorUtils::get_placeholder_image_src(),
                         ],
                     ],
                 ],
@@ -146,13 +149,13 @@ class VideoGallery extends Widget_Base {
         // Get videos and process each video URL so it can be used with Elementor lightbox
         $videos = array_map(function($video) {
 
-            $video['lightbox'] = self::lightbox($video['url'], $this->get_id());
+            $video['lightbox'] = Utils::lightbox($video['url'], $this->get_id());
 
             $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']);
+                $video['preview'] = Utils::youtube_image($video_properties['video_id']);
             } else {
                 $video['preview'] = wp_get_attachment_image_url($video['image']['id'], 'video-preview');
             }
@@ -161,58 +164,11 @@ class VideoGallery extends Widget_Base {
         }, $videos);
 
         if ($gallery_type == 'carousel') {
-            echo \App\template('widgets/video-gallery-carousel', compact('videos'));
+            echo template('widgets/video-gallery-carousel', compact('videos'));
         } else {
-            echo \App\template('widgets/video-gallery-grid', compact('videos'));
+            echo template('widgets/video-gallery-grid', compact('videos'));
         }
 
     }
 
-
-    // Create lightbox configuration for opening video in Elmentor popup
-    // This can also be used by other elements like TextBlock for the CTA links
-    public static function lightbox($url, $element_ID) {
-
-        // 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($url, $embed_params),
-            'modalOptions' => [
-                'id'                => 'elementor-lightbox-' . $element_ID,
-                'entranceAnimation' => 'zoomIn',
-                'videoAspectRatio'  => '169',
-            ],
-        ];
-
-        return wp_json_encode($lightbox_options);
-    }
-
-
-    // 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;
-    }
-
 }
index 8a4126027b21671fe6ac75f84563cd72d423636a..d337bbf5a04986d14df18905876956483b29a2cb 100644 (file)
@@ -22,6 +22,9 @@
     "resource-carousel": [
       "./scripts/resource-carousel.js"
     ],
+    "multimedia-carousel": [
+      "./scripts/multimedia-carousel.js"
+    ],
     "modal-list": [
       "./scripts/modal-list.js"
     ],
diff --git a/wp-content/themes/physioassist/resources/assets/scripts/multimedia-carousel.js b/wp-content/themes/physioassist/resources/assets/scripts/multimedia-carousel.js
new file mode 100644 (file)
index 0000000..4b6a122
--- /dev/null
@@ -0,0 +1,12 @@
+// ELEMENTOR Trigger
+(function($) {
+  // Trigger handler when element ready
+  $(window).on( 'elementor/frontend/init', function() {
+    // eslint-disable-next-line
+    elementorFrontend.hooks.addAction('frontend/element_ready/cube-multimedia-carousel.default', function ($scope) {
+
+      $scope.find('.multimedia-carousel').slick(); // Note: settings come from data-attribute in HTML
+
+    });
+  });
+})(jQuery);
index 291bcce41da0fb1dcd2ef7f83cf08cf9f392661a..3c7ade10e3bd690df60991287bdc2b874599f147 100644 (file)
@@ -5,18 +5,22 @@
     text-align: center
     margin: 0 20px
 
+  &-link
+    display: block
+    outline: none
+
   &-image
     display: block
     width: 100%
-    max-width: 195px
+    max-width: 240px
     margin: 0 auto 1.75em
     background-size: cover
     background-position: center
     background-repeat: no-repeat
     border-radius: 50%
 
-    .profile-carousel-item:focus &
-      border: 2px solid $colors.headings
+    //.profile-carousel-link:focus &
+    //  box-shadow: inset 0 0 0 2px $colors.headings
 
     &-sizer
       padding-bottom: 100% // Make a square
diff --git a/wp-content/themes/physioassist/resources/views/widgets/multimedia-carousel.blade.php b/wp-content/themes/physioassist/resources/views/widgets/multimedia-carousel.blade.php
new file mode 100644 (file)
index 0000000..c537701
--- /dev/null
@@ -0,0 +1,47 @@
+{{--MULTIMEDIA CAROUSEL--}}
+@php
+  $settings = [
+    'slidesToShow' => 4,
+    'slidesToScroll' => 4,
+    'dots' => count($items) > 4, // Only show dots when there are enough items
+    'infinite' => true,
+    'responsive' => [
+      [
+        'breakpoint' => 1300,
+        'settings' => [
+          'slidesToShow' => 3,
+          'slidesToScroll' => 3,
+          'dots' => count($items) > 3,
+        ]
+      ],
+      [
+        'breakpoint' => 850,
+        'settings' => [
+          'slidesToShow' => 2,
+          'slidesToScroll' => 2,
+          'dots' => count($items) > 2,
+        ]
+      ],
+      [
+        'breakpoint' => 650,
+        'settings' => [
+          'slidesToShow' => 1,
+          'slidesToScroll' => 1,
+          'dots' => count($items) > 1,
+        ]
+      ],
+    ]
+  ];
+
+  $slick = json_encode($settings);
+
+@endphp
+
+<div class="multimedia-carousel elementor-slick-slider" data-slick="{{ $slick }}">
+
+  @foreach ($items as $item)
+    @includeWhen($item['type'] == 'text', 'widgets/partials/profile-slide')
+    @includeWhen($item['type'] == 'video', 'widgets/partials/video-slide', ['video' => $item])
+  @endforeach
+
+</div>
diff --git a/wp-content/themes/physioassist/resources/views/widgets/partials/profile-slide.blade.php b/wp-content/themes/physioassist/resources/views/widgets/partials/profile-slide.blade.php
new file mode 100644 (file)
index 0000000..9776303
--- /dev/null
@@ -0,0 +1,35 @@
+@php
+  $lightbox_ID = 'lightbox_'. $item['_id']; // Unique ID for lightbox content
+@endphp
+
+<div class="profile-carousel-item slick-slide">
+
+  <a href="#{{ $lightbox_ID }}" data-lity class="profile-carousel-link">
+
+    <div class="profile-carousel-image" style="background-image:url('{{ wp_get_attachment_image_url($item['image']['id'], 'post-thumbnail') }}')">
+      <div class="profile-carousel-image-sizer"></div>
+    </div>
+
+    <h3 class="profile-carousel-title">{!! str_replace('-', '&#8209;', $item['title']) /* make hyphens non-breaking */ !!}</h3>
+
+    @if ($item['subtitle'])
+      <h4 class="profile-carousel-subtitle">{{ $item['subtitle'] }}</h4>
+    @endif
+
+  </a>  {{-- .profile-carousel-item --}}
+
+  {{-- Lightbox Content --}}
+  <div id="{{ $lightbox_ID }}" class="lity-hide profile-carousel-lightbox">
+
+    <div class="profile-carousel-image" style="background-image:url('{{ wp_get_attachment_image_url($item['image']['id'], 'post-thumbnail') }}')">
+      <div class="profile-carousel-image-sizer"></div>
+    </div>
+
+    <h3 class="profile-carousel-title">{{ $item['title'] }}</h3>
+
+    <div class="profile-carousel-body">
+      {!! $item['body'] !!}
+    </div>
+  </div>
+
+</div>
diff --git a/wp-content/themes/physioassist/resources/views/widgets/partials/video-slide.blade.php b/wp-content/themes/physioassist/resources/views/widgets/partials/video-slide.blade.php
new file mode 100644 (file)
index 0000000..857417d
--- /dev/null
@@ -0,0 +1,9 @@
+<div class="video-carousel-item slick-slide">
+  <div class="slick-slide-inner" data-elementor-lightbox="{{ $video['lightbox'] }}" data-elementor-open-lightbox="yes">
+    <div class="video-carousel-item-image" style="background-image:url('{{  $video['preview'] }}')">
+      <div class="video-carousel-item-image-sizer"></div>
+    </div>
+    <h4 class="video-carousel-item-title">{{ $video['title'] }}</h4>
+    <p class="video-carousel-item-details">{{ $video['details'] }}</p>
+  </div>
+</div>
index d1f0a3a99900b692cc43914c7e71a3bedca87c9f..b41cb613c721d458a23789c294c94dbcf5703eea 100644 (file)
 <div class="profile-carousel elementor-slick-slider" data-slick="{{ $slick }}">
 
   @foreach ($items as $item)
-
-    @php
-      $lightbox_ID = 'lightbox_'. $item['_id']; // Unique ID for lightbox content
-    @endphp
-
-    <a href="#{{ $lightbox_ID }}" data-lity class="profile-carousel-item slick-slide">
-
-      <div class="profile-carousel-image" style="background-image:url('{{ wp_get_attachment_image_url($item['image']['id'], 'post-thumbnail') }}')">
-        <div class="profile-carousel-image-sizer"></div>
-      </div>
-
-      <h3 class="profile-carousel-title">{!! str_replace('-', '&#8209;', $item['title']) /* make hyphens non-breaking */ !!}</h3>
-
-      @if ($item['subtitle'])
-        <h4 class="profile-carousel-subtitle">{{ $item['subtitle'] }}</h4>
-      @endif
-
-      {{-- Lightbox Content --}}
-      <div id="{{ $lightbox_ID }}" class="lity-hide profile-carousel-lightbox">
-
-        <div class="profile-carousel-image" style="background-image:url('{{ wp_get_attachment_image_url($item['image']['id'], 'post-thumbnail') }}')">
-          <div class="profile-carousel-image-sizer"></div>
-        </div>
-
-        <h3 class="profile-carousel-title">{{ $item['title'] }}</h3>
-
-        <div class="profile-carousel-body">
-          {!! $item['body'] !!}
-        </div>
-
-      </div>
-
-    </a>  {{-- .profile-carousel-item --}}
-
+    @include('widgets/partials/profile-slide')
   @endforeach
 
 </div>
index 7d5ad57a5829a0dd0b95a47769df324ccd1cf008..b5eafe67d1d2bcd8422a44ecfbaad9ca2da2cd0e 100644 (file)
 
 <div class="video-carousel elementor-slick-slider" data-slick="{{ $slick }}">
   @foreach ($videos as $video)
-    <div class="video-carousel-item slick-slide">
-      <div class="slick-slide-inner" data-elementor-lightbox="{{ $video['lightbox'] }}" data-elementor-open-lightbox="yes">
-        <div class="video-carousel-item-image" style="background-image:url('{{  $video['preview'] }}')">
-          <div class="video-carousel-item-image-sizer"></div>
-        </div>
-        <h4 class="video-carousel-item-title">{{ $video['title'] }}</h4>
-        <p class="video-carousel-item-details">{{ $video['details'] }}</p>
-      </div>
-    </div>
+    @include('widgets/partials/video-slide')
   @endforeach
 </div>