GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 2ad6a2...acb768 )
by Ivan
01:49
created

ScrollPager::init()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 28
rs 8.8571
cc 3
eloc 13
nc 4
nop 0
1
<?php
2
3
namespace kop\y2sp;
4
5
use kop\y2sp\assets\InfiniteAjaxScrollAsset;
6
use Yii;
7
use yii\base\InvalidConfigException;
8
use yii\base\Widget;
9
use yii\helpers\ArrayHelper;
10
use yii\helpers\Json;
11
use yii\i18n\PhpMessageSource;
12
use yii\web\JsExpression;
13
use yii\web\View;
14
use yii\widgets\LinkPager;
15
16
/**
17
 * ScrollPager turns your regular paginated page into an infinite scrolling page using AJAX.
18
 *
19
 * ScrollPager works with a [[Pagination]] object which specifies the totally number of pages and the current page number.
20
 *
21
 * <br>
22
 * <i>Example usage:</i>
23
 * <code>
24
 * echo ListView::widget([
25
 *      'dataProvider' => $dataProvider,
26
 *      'itemOptions' => ['class' => 'item'],
27
 *      'itemView' => '_item_view',
28
 *      'pager' => ['class' => \kop\y2sp\ScrollPager::className()]
29
 * ]);
30
 * </code>
31
 *
32
 * This widget is using {@link http://infiniteajaxscroll.com/ JQuery Infinite Ajax Scroll plugin}.
33
 *
34
 * @link      http://kop.github.io/yii2-scroll-pager Y2SP project page.
35
 * @license   https://github.com/kop/yii2-scroll-pager/blob/master/LICENSE.md MIT
36
 *
37
 * @author    Ivan Koptiev <[email protected]>
38
 */
39
class ScrollPager extends Widget
40
{
41
    /**
42
     * @const EXTENSION_TRIGGER IAS Extension "IASTriggerExtension".
43
     */
44
    const EXTENSION_TRIGGER = 'IASTriggerExtension';
45
46
    /**
47
     * @const EXTENSION_SPINNER IAS Extension "IASSpinnerExtension".
48
     */
49
    const EXTENSION_SPINNER = 'IASSpinnerExtension';
50
51
    /**
52
     * @const EXTENSION_NONE_LEFT IAS Extension "IASNoneLeftExtension".
53
     */
54
    const EXTENSION_NONE_LEFT = 'IASNoneLeftExtension';
55
56
    /**
57
     * @const EXTENSION_PAGING IAS Extension "IASPagingExtension".
58
     */
59
    const EXTENSION_PAGING = 'IASPagingExtension';
60
61
    /**
62
     * @const EXTENSION_HISTORY IAS Extension "IASHistoryExtension".
63
     */
64
    const EXTENSION_HISTORY = 'IASHistoryExtension';
65
66
    /**
67
     * @var string $container Enter the selector of the element containing your items that you want to paginate.
68
     */
69
    public $container = '.list-view';
70
71
    /**
72
     * @var string $item Enter the selector of the element that each item has.
73
     * Make sure the elements are inside the container element.
74
     */
75
    public $item = '.item';
76
    
77
    /**
78
     * @var string $next Enter the selector of the link element that links to the next page. 
79
     * The href attribute of this element will be used to get the items from the next page. 
80
     * Make sure there is only one(1) element that matches the selector.
81
     */
82
    public $next = '.next a';
83
84
    /**
85
     * @var int $delay Minimal number of milliseconds to stay in a loading state.
86
     */
87
    public $delay = 600;
88
89
    /**
90
     * @var int $thresholdMargin On default IAS starts loading new items when you scroll to the latest .item element.
91
     * The negativeMargin will be added to the items' offset, giving you the ability to load new items earlier
92
     * (please note that the margin is always transformed to a negative integer).
93
     * <br><br>
94
     * <i>For example:</i>
95
     * <br>
96
     * Setting a negativeMargin of 250 means that IAS will start loading 250 pixel before the last item has scrolled into view.
97
     */
98
    public $negativeMargin = 10;
99
100
    /**
101
     * @var string $triggerText Text of trigger the link.
102
     * Default: "Load more items".
103
     */
104
    public $triggerText;
105
106
    /**
107
     * @var string $triggerTemplate Allows you to override the trigger html template.
108
     */
109
    public $triggerTemplate = '<div class="ias-trigger" style="text-align: center; cursor: pointer;"><a>{text}</a></div>';
110
111
    /**
112
     * @var int $triggerOffset The number of pages which should load automatically.
113
     * After that the trigger is shown for every subsequent page.
114
     * <br><br>
115
     * <i>For example:</i>
116
     * <br>
117
     * if you set the offset to 2, the pages 2 and 3 (page 1 is always shown) would load automatically and for every
118
     * subsequent page the user has to press the trigger to load it.
119
     */
120
    public $triggerOffset = 0;
121
122
    /**
123
     * @var string $spinnerSrc The src attribute of the spinner image.
124
     */
125
    public $spinnerSrc;
126
127
    /**
128
     * @var string $spinnerTemplate Allows you to override the spinner html template.
129
     */
130
    public $spinnerTemplate = '<div class="ias-spinner" style="text-align: center;"><img src="{src}"/></div>';
131
132
    /**
133
     * @var string $noneLeftText Text of the "nothing left" message.
134
     * Default: "You reached the end".
135
     */
136
    public $noneLeftText;
137
138
    /**
139
     * @var string $noneLeftTemplate Allows you to override the "nothing left" message html template.
140
     */
141
    public $noneLeftTemplate = '<div class="ias-noneleft" style="text-align: center;">{text}</div>';
142
143
    /**
144
     * @var string $historyPrev Enter the selector of the link element that links to the previous page.
145
     * The href attribute of this element will be used to get the items from the previous page.
146
     * Make sure there is only one element that matches the selector.
147
     */
148
    public $historyPrev = '.previous';
149
150
    /**
151
     * @var string $overflowContainer A selector for "div" HTML element to use as an overflow container.
152
     * @see http://infiniteajaxscroll.com/examples/overflow.html
153
     */
154
    public $overflowContainer;
155
156
    /**
157
     * @var string|JsExpression $eventOnScroll Triggered when the visitors scrolls.
158
     * @see http://infiniteajaxscroll.com/docs/events.html
159
     */
160
    public $eventOnScroll;
161
162
    /**
163
     * @var string|JsExpression $eventOnLoad Triggered when a new url will be loaded from the server.
164
     * @see http://infiniteajaxscroll.com/docs/events.html
165
     */
166
    public $eventOnLoad;
167
168
    /**
169
     * @var string|JsExpression $eventOnLoaded Triggered after a new page was loaded from the server.
170
     * @see http://infiniteajaxscroll.com/docs/events.html
171
     */
172
    public $eventOnLoaded;
173
174
    /**
175
     * @var string|JsExpression $eventOnRender Triggered before new items will be rendered.
176
     * @see http://infiniteajaxscroll.com/docs/events.html
177
     */
178
    public $eventOnRender;
179
180
    /**
181
     * @var string|JsExpression $eventOnRendered Triggered after new items have rendered.
182
     * Note: This event is only fired once.
183
     * @see http://infiniteajaxscroll.com/docs/events.html
184
     */
185
    public $eventOnRendered;
186
187
    /**
188
     * @var string|JsExpression $eventOnNoneLeft Triggered when there are no more pages left.
189
     * @see http://infiniteajaxscroll.com/docs/events.html
190
     */
191
    public $eventOnNoneLeft;
192
193
    /**
194
     * @var string|JsExpression $eventOnNext Triggered when the next page should be loaded.
195
     * Happens before loading of the next page starts. With this event it is possible to cancel the loading of the next page.
196
     * You can do this by returning false from your callback.
197
     * @see http://infiniteajaxscroll.com/docs/events.html
198
     */
199
    public $eventOnNext;
200
201
    /**
202
     * @var string|JsExpression $eventOnReady Triggered when IAS and all the extensions have been initialized.
203
     * @see http://infiniteajaxscroll.com/docs/events.html
204
     */
205
    public $eventOnReady;
206
207
    /**
208
     * @var string|JsExpression $eventOnPageChange Triggered when a used scroll to another page.
209
     * @see http://infiniteajaxscroll.com/docs/extension-paging.html
210
     */
211
    public $eventOnPageChange;
212
213
    /**
214
     * @var array $enabledExtensions The list of the enabled plugin extensions.
215
     */
216
    public $enabledExtensions = [
217
        self::EXTENSION_TRIGGER,
218
        self::EXTENSION_SPINNER,
219
        self::EXTENSION_NONE_LEFT,
220
        self::EXTENSION_PAGING,
221
        self::EXTENSION_HISTORY
222
    ];
223
224
    /**
225
     * @var \yii\data\Pagination The pagination object that this pager is associated with.
226
     * You must set this property in order to make ScrollPager work.
227
     */
228
    public $pagination;
229
230
    /**
231
     * Initializes the pager.
232
     */
233
    public function init()
234
    {
235
        parent::init();
236
237
        // Register translations source
238
        Yii::$app->i18n->translations = ArrayHelper::merge(Yii::$app->i18n->translations, [
239
            'kop\y2sp' => [
240
                'class' => PhpMessageSource::className(),
241
                'basePath' => '@vendor/kop/yii2-scroll-pager/messages',
242
                'fileMap' => [
243
                    'kop\y2sp' => 'general.php'
244
                ]
245
            ]
246
        ]);
247
248
        // Register required assets
249
        $this->registerAssets();
250
251
        // Set default trigger text if not set
252
        if ($this->triggerText === null) {
253
            $this->triggerText = Yii::t('kop\y2sp', 'Load more items');
254
        }
255
256
        // Set default "none left" message text if not set
257
        if ($this->noneLeftText === null) {
258
            $this->noneLeftText = Yii::t('kop\y2sp', 'You reached the end');
259
        }
260
    }
261
262
    /**
263
     * Executes the widget.
264
     *
265
     * This overrides the parent implementation by initializing jQuery IAS and displaying the generated page buttons.
266
     *
267
     * @throws \yii\base\InvalidConfigException
268
     * @return mixed
269
     */
270
    public function run()
271
    {
272
        // Initialize jQuery IAS plugin
273
        $pluginSettings = Json::encode([
274
            'container' => $this->container,
275
            'item' => $this->item,
276
            'pagination' => "{$this->container} .pagination",
277
            'next' => $this->next,
278
            'delay' => $this->delay,
279
            'negativeMargin' => $this->negativeMargin
280
        ]);
281
        $initString = empty($this->overflowContainer)
282
            ? "var {$this->id}_ias = jQuery.ias({$pluginSettings});"
283
            : "var {$this->id}_ias = jQuery('{$this->overflowContainer}').ias({$pluginSettings});";
284
        $this->view->registerJs($initString, View::POS_READY, "{$this->id}_ias_main");
285
286
        // Register IAS extensions
287
        $this->registerExtensions([
288
            [
289
                'name' => self::EXTENSION_PAGING
290
            ],
291
            [
292
                'name' => self::EXTENSION_SPINNER,
293
                'options' =>
294
                    !empty($this->spinnerSrc)
295
                        ? ['html' => $this->spinnerTemplate, 'src' => $this->spinnerSrc]
296
                        : ['html' => $this->spinnerTemplate]
297
            ],
298
            [
299
                'name' => self::EXTENSION_TRIGGER,
300
                'options' => [
301
                    'text' => $this->triggerText,
302
                    'html' => $this->triggerTemplate,
303
                    'offset' => $this->triggerOffset
304
                ]
305
            ],
306
            [
307
                'name' => self::EXTENSION_NONE_LEFT,
308
                'options' => [
309
                    'text' => $this->noneLeftText,
310
                    'html' => $this->noneLeftTemplate
311
                ]
312
            ],
313
            [
314
                'name' => self::EXTENSION_HISTORY,
315
                'options' => [
316
                    'prev' => $this->historyPrev
317
                ],
318
                'depends' => [
319
                    self::EXTENSION_TRIGGER,
320
                    self::EXTENSION_PAGING
321
                ]
322
            ]
323
        ]);
324
325
        // Register event handlers
326
        $this->registerEventHandlers([
327
            'scroll' => [],
328
            'load' => [],
329
            'loaded' => [],
330
            'render' => [],
331
            'rendered' => [],
332
            'noneLeft' => [],
333
            'next' => [],
334
            'ready' => [],
335
            'pageChange' => [
336
                self::EXTENSION_PAGING
337
            ]
338
        ]);
339
340
        // Render pagination links
341
        echo LinkPager::widget([
342
            'pagination' => $this->pagination,
343
            'options' => [
344
                'class' => 'pagination hidden'
345
            ]
346
        ]);
347
    }
348
349
    /**
350
     * Register required asset bundles.
351
     *
352
     * You can override this method in case if you want to use your own JQuery Infinite Ajax Scroll plugin files
353
     * (for example, some forked plugin version).
354
     */
355
    protected function registerAssets()
356
    {
357
        InfiniteAjaxScrollAsset::register($this->view);
358
    }
359
360
    /**
361
     * Register jQuery IAS extensions.
362
     *
363
     * This method takes jQuery IAS extensions definition as a parameter and registers this extensions.
364
     *
365
     * @param array $config jQuery IAS extensions definition.
366
     * @throws \yii\base\InvalidConfigException If extension dependencies are not met.
367
     */
368
    protected function registerExtensions(array $config)
369
    {
370
        foreach ($config as $entry) {
371
372
            // Parse config entry values
373
            $name = ArrayHelper::getValue($entry, 'name', false);
374
            $options = ArrayHelper::getValue($entry, 'options', '');
375
            $depends = ArrayHelper::getValue($entry, 'depends', []);
376
377
            // If extension is enabled
378
            if (in_array($name, $this->enabledExtensions)) {
379
380
                // Make sure dependencies are met
381 View Code Duplication
                if (!$this->checkEnabledExtensions($depends)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
382
                    throw new InvalidConfigException(
383
                        "Extension {$name} requires " . implode(', ', $depends) . " extensions to be enabled."
384
                    );
385
                }
386
387
                // Register extension
388
                $options = Json::encode($options);
389
                $this->view->registerJs(
390
                    "{$this->id}_ias.extension(new {$name}({$options}));",
391
                    View::POS_READY,
392
                    "{$this->id}_ias_{$name}"
393
                );
394
            }
395
        }
396
    }
397
398
    /**
399
     * Register jQuery IAS event handlers.
400
     *
401
     * This method takes jQuery IAS event handlers definition as a parameter and registers this event handlers.
402
     *
403
     * @param array $config jQuery IAS event handlers definition.
404
     * @throws \yii\base\InvalidConfigException If vent handlers dependencies are not met.
405
     */
406
    protected function registerEventHandlers(array $config)
407
    {
408
        foreach ($config as $name => $depends) {
409
410
            // If event is enabled
411
            $eventName = 'eventOn' . ucfirst($name);
412
            if (!empty($this->$eventName)) {
413
414
                // Make sure dependencies are met
415 View Code Duplication
                if (!$this->checkEnabledExtensions($depends)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
416
                    throw new InvalidConfigException(
417
                        "The \"{$name}\" event requires " . implode(', ', $depends) . " extensions to be enabled."
418
                    );
419
                }
420
421
                // Register event
422
                $this->view->registerJs(
423
                    "jQuery.ias().on('{$name}', {$this->$eventName});",
424
                    View::POS_READY,
425
                    "{$this->id}_ias_{$name}"
426
                );
427
            }
428
        }
429
    }
430
431
    /**
432
     * Check whether the given extensions are enabled.
433
     *
434
     * @param string|array $extensions Single or multiple extensions names.
435
     * @return bool Operation result.
436
     */
437
    protected function checkEnabledExtensions($extensions)
438
    {
439
        $extensions = (array)$extensions;
440
        if (empty($extensions)) {
441
            return true;
442
        } else {
443
            return (count(array_intersect($this->enabledExtensions, $extensions)) == count($extensions));
444
        }
445
    }
446
}
447