SlickCarousel   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 29
c 1
b 0
f 0
dl 0
loc 183
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 20 5
A init() 0 18 6
1
<?php
2
3
namespace diecoding\slick;
4
5
use yii\base\InvalidConfigException;
6
use yii\base\Widget;
7
use yii\helpers\Html;
8
use yii\helpers\Json;
9
use yii\web\JsExpression;
10
11
/**
12
 * SlickCarousel is class for widgets that collect user file inputs.
13
 * 
14
 * @link [sugeng-sulistiyawan.github.io](sugeng-sulistiyawan.github.io)
15
 * @author Sugeng Sulistiyawan <[email protected]>
16
 * @copyright Copyright (c) 2023
17
 */
18
class SlickCarousel extends Widget
19
{
20
    /**
21
     * @var array widget elements for the carousel
22
     */
23
    public $items = [];
24
25
    /**
26
     * @var array HTML attributes to render on the container
27
     */
28
    public $containerOptions = [];
29
30
    /**
31
     * @var string HTML tag to render the container
32
     */
33
    public $containerTag = 'div';
34
35
    /**
36
     * @var array HTML attributes for the one item
37
     */
38
    public $itemOptions = [];
39
40
    /**
41
     * @var string HTML tag to render items for the carousel
42
     */
43
    public $itemTag = 'div';
44
45
    /**
46
     * @var bool default `false`, `true` if use custom or external slick assets
47
     */
48
    public $skipCoreAssets = false;
49
50
    /**
51
     * @var array default `[]`, for option `$(#options['id']).slick(pluginOptions);`
52
     * @see https://github.com/kenwheeler/slick/#settings
53
     * 
54
     * ```php
55
     * 'pluginOptions' => [
56
     *     'accessibility'    => true,                                                         // boolean, default `true`
57
     *     'adaptiveHeight'   => false,                                                        // boolean, default `false`
58
     *     'appendArrows'     => $(element),                                                   // string, default `$(element)`
59
     *     'appendDots'       => $(element),                                                   // string, default `$(element)`
60
     *     'arrows'           => true,                                                         // boolean, default `true`
61
     *     'asNavFor'         => $(element),                                                   // string, default `$(element)`
62
     *     'autoplay'         => false,                                                        // boolean, default `false`
63
     *     'autoplaySpeed'    => 3000,                                                         // int, default `3000`
64
     *     'centerMode'       => false,                                                        // boolean, default `false`
65
     *     'centerPadding'    => '50px',                                                       // string, default `'50px'`
66
     *     'cssEase'          => 'ease',                                                       // string, default `'ease'`
67
     *     'customPaging'     => n/a,                                                          // function, default `n/a`
68
     *     'dots'             => false,                                                        // boolean, default `false`
69
     *     'dotsClass'        => 'slick-dots',                                                 // string, default `'slick-dots'`
70
     *     'draggable'        => true,                                                         // boolean, default `true`
71
     *     'easing'           => 'linear',                                                     // string, default `'linear'`
72
     *     'edgeFriction'     => 0.15,                                                         // integer, default `0.15`
73
     *     'fade'             => false,                                                        // boolean, default `false`
74
     *     'focusOnSelect'    => false,                                                        // boolean, default `false`
75
     *     'focusOnChange'    => false,                                                        // boolean, default `false`
76
     *     'infinite'         => true,                                                         // boolean, default `true`
77
     *     'initialSlide'     => 0,                                                            // integer, default `0`
78
     *     'lazyLoad'         => 'ondemand',                                                   // string, default `'ondemand'`
79
     *     'mobileFirst'      => false,                                                        // boolean, default `false`
80
     *     'nextArrow'        => <button type="button" class="slick-next">next</button>,       // string (html | jQuery selector) | object (DOM node | jQuery object), default `<button type="button" class="slick-next">next</button>`
81
     *     'pauseOnDotsHover' => false,                                                        // boolean, default `false`
82
     *     'pauseOnFocus'     => true,                                                         // boolean, default `true`
83
     *     'pauseOnHover'     => true,                                                         // boolean, default `true`
84
     *     'prevArrow'        => <button type="button" class="slick-prev">previous</button>,   // string (html | jQuery selector) | object (DOM node | jQuery object), default `<button type="button" class="slick-prev">previous</button>`
85
     *     'respondTo'        => 'window',                                                     // string, default `'window'`
86
     *     'responsive'       => null,                                                         // array, default `null`
87
     *     'rows'             => 1,                                                            // int, default `1`
88
     *     'rtl'              => false,                                                        // boolean, default `false`
89
     *     'slide'            => '',                                                           // string, default `''`
90
     *     'slidesPerRow'     => 1,                                                            // int, default `1`
91
     *     'slidesToScroll'   => 1,                                                            // int, default `1`
92
     *     'slidesToShow'     => 1,                                                            // int, default `1`
93
     *     'speed'            => 300,                                                          // int, default `300`
94
     *     'swipe'            => true,                                                         // boolean, default `true`
95
     *     'swipeToSlide'     => false,                                                        // boolean, default `false`
96
     *     'touchMove'        => true,                                                         // boolean, default `true`
97
     *     'touchThreshold'   => 5,                                                            // int, default `5`
98
     *     'useCSS'           => true,                                                         // boolean, default `true`
99
     *     'useTransform'     => true,                                                         // boolean, default `true`
100
     *     'variableWidth'    => false,                                                        // boolean, default `false`
101
     *     'vertical'         => false,                                                        // boolean, default `false`
102
     *     'verticalSwiping'  => false,                                                        // boolean, default `false`
103
     *     'waitForAnimate'   => true,                                                         // boolean, default `true`
104
     *     'zIndex'           => 1000,                                                         // number, default `1000`'
105
     * ],
106
     * ```
107
     */
108
    public $pluginOptions = [];
109
110
    /**
111
     * @var array default `[]`, JQuery events
112
     * @see https://github.com/kenwheeler/slick/#events
113
     * 
114
     * ```php
115
     * 'pluginEvents' => [
116
     *     'afterChange' => 'function(event, slick, currentSlide) {
117
     *         console.log("After slide change callback");
118
     *     }',
119
     *     'beforeChange' => 'function(event, slick, currentSlide, nextSlide) {
120
     *         console.log("Before slide change callback");
121
     *     }',
122
     *     'breakpoint' => 'function(event, slick, breakpoint) {
123
     *         console.log("Fires after a breakpoint is hit");
124
     *     }',
125
     *     'destroy' => 'function(event, slick) {
126
     *         console.log("When slider is destroyed, or unslicked.");
127
     *     }',
128
     *     'edge' => 'function(event, slick, direction) {
129
     *         console.log("Fires when an edge is overscrolled in non-infinite mode.");
130
     *     }',
131
     *     'init' => 'function(event, slick) {
132
     *         console.log("When Slick initializes for the first time callback. Note that this event should be defined before initializing the slider.");
133
     *     }',
134
     *     'reInit' => 'function(event, slick) {
135
     *         console.log("Every time Slick (re-)initializes callback");
136
     *     }',
137
     *     'setPosition' => 'function(event, slick) {
138
     *         console.log("Every time Slick recalculates position");
139
     *     }',
140
     *     'swipe' => 'function(event, slick, direction) {
141
     *         console.log("Fires after swipe/drag");
142
     *     }',
143
     *     'lazyLoaded' => 'function(event, slick, image, imageSource) {
144
     *         console.log("Fires after image loads lazily");
145
     *     }',
146
     *     'lazyLoadError' => 'function(event, slick, image, imageSource) {
147
     *         console.log("Fires after image fails to load");
148
     *     }',
149
     * ],
150
     * ```
151
     */
152
    public $pluginEvents = [];
153
154
    /**
155
     * @inheritdoc
156
     * @throws InvalidConfigException
157
     */
158
    public function init()
159
    {
160
        if (empty($this->items)) {
161
            throw new InvalidConfigException("Not allowed without or empty 'items'");
162
        }
163
164
        if ($this->skipCoreAssets === false) {
165
            $this->view->registerAssetBundle(SlickCarouselAsset::class);
166
        }
167
168
        $this->containerTag = $this->containerTag ?: 'div';
169
        $this->itemTag      = $this->itemTag ?: 'div';
170
171
        if (!isset($this->containerOptions['id'])) {
172
            $this->containerOptions['id'] = $this->getId();
173
        }
174
175
        parent::init();
176
    }
177
178
    /**
179
     * @inheritdoc
180
     */
181
    public function run()
182
    {
183
        $pluginOptions = Json::encode($this->pluginOptions);
184
185
        $this->view->registerJs("$('#{$this->containerOptions['id']}').slick({$pluginOptions});");
186
187
        if (!empty($this->pluginEvents)) {
188
            foreach ($this->pluginEvents as $event => $handler) {
189
                $function = $handler instanceof JsExpression ? $handler : new JsExpression($handler);
190
                $this->view->registerJs("$('#{$this->containerOptions['id']}').on('{$event}', {$function});");
191
            }
192
        }
193
194
        $slider = Html::beginTag($this->containerTag, $this->containerOptions);
195
        foreach ($this->items as $item) {
196
            $slider .= Html::tag($this->itemTag, $item, $this->itemOptions);
197
        }
198
        $slider .= Html::endTag($this->containerTag);
199
200
        return $slider;
201
    }
202
}
203