Passed
Push — master ( e56d31...fe40bb )
by Sugeng
02:12
created

SlickCarousel::init()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 18
rs 9.2222
cc 6
nc 5
nop 0
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 dropify assets
47
     */
48
    public $skipCoreAssets = false;
49
50
    /**
51
     * @var array default `[]`, for option `$(#options['id']).slick(pluginOptions);`
52
     */
53
    public $pluginOptions = [];
54
55
    /**
56
     * @var array default `[]`, JQuery events
57
     * 
58
     * ```php
59
     * 'pluginEvents' => [
60
     *     'afterChange' => 'function(event, slick, currentSlide) {
61
     *         console.log("After slide change callback");
62
     *     }',
63
     *     'beforeChange' => 'function(event, slick, currentSlide, nextSlide) {
64
     *         console.log("Before slide change callback");
65
     *     }',
66
     *     'breakpoint' => 'function(event, slick, breakpoint) {
67
     *         console.log("Fires after a breakpoint is hit");
68
     *     }',
69
     *     'destroy' => 'function(event, slick) {
70
     *         console.log("When slider is destroyed, or unslicked.");
71
     *     }',
72
     *     'edge' => 'function(event, slick, direction) {
73
     *         console.log("Fires when an edge is overscrolled in non-infinite mode.");
74
     *     }',
75
     *     'init' => 'function(event, slick) {
76
     *         console.log("When Slick initializes for the first time callback. Note that this event should be defined before initializing the slider.");
77
     *     }',
78
     *     'reInit' => 'function(event, slick) {
79
     *         console.log("Every time Slick (re-)initializes callback");
80
     *     }',
81
     *     'setPosition' => 'function(event, slick) {
82
     *         console.log("Every time Slick recalculates position");
83
     *     }',
84
     *     'swipe' => 'function(event, slick, direction) {
85
     *         console.log("Fires after swipe/drag");
86
     *     }',
87
     *     'lazyLoaded' => 'function(event, slick, image, imageSource) {
88
     *         console.log("Fires after image loads lazily");
89
     *     }',
90
     *     'lazyLoadError' => 'function(event, slick, image, imageSource) {
91
     *         console.log("Fires after image fails to load");
92
     *     }',
93
     * ];
94
     * ```
95
     */
96
    public $pluginEvents = [];
97
98
    /**
99
     * @inheritdoc
100
     * @throws InvalidConfigException
101
     */
102
    public function init()
103
    {
104
        if (empty($this->items)) {
105
            throw new InvalidConfigException("Not allowed without or empty 'items'");
106
        }
107
108
        if ($this->skipCoreAssets === false) {
109
            $this->view->registerAssetBundle(SlickCarouselAsset::class);
110
        }
111
112
        $this->containerTag = $this->containerTag ?: 'div';
113
        $this->itemTag      = $this->itemTag ?: 'div';
114
115
        if (!isset($this->containerOptions['id'])) {
116
            $this->containerOptions['id'] = $this->getId();
117
        }
118
119
        parent::init();
120
    }
121
122
    /**
123
     * @inheritdoc
124
     */
125
    public function run()
126
    {
127
        $pluginOptions = Json::encode($this->pluginOptions);
128
129
        $this->view->registerJs("$('#{$this->containerOptions['id']}').slick({$pluginOptions});");
130
131
        if (!empty($this->pluginEvents)) {
132
            foreach ($this->pluginEvents as $event => $handler) {
133
                $function = $handler instanceof JsExpression ? $handler : new JsExpression($handler);
134
                $this->view->registerJs("$('#{$this->containerOptions['id']}').on('{$event}', {$function});");
135
            }
136
        }
137
138
        $slider = Html::beginTag($this->containerTag, $this->containerOptions);
139
        foreach ($this->items as $item) {
140
            $slider .= Html::tag($this->itemTag, $item, $this->itemOptions);
141
        }
142
        $slider .= Html::endTag($this->containerTag);
143
144
        return $slider;
145
    }
146
}
147