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 ( 4e3ef8...2ad6a2 )
by Ivan
01:51
created

ScrollPager.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 int $delay Minimal number of milliseconds to stay in a loading state.
79
     */
80
    public $delay = 600;
81
82
    /**
83
     * @var int $thresholdMargin On default IAS starts loading new items when you scroll to the latest .item element.
84
     * The negativeMargin will be added to the items' offset, giving you the ability to load new items earlier
85
     * (please note that the margin is always transformed to a negative integer).
86
     * <br><br>
87
     * <i>For example:</i>
88
     * <br>
89
     * Setting a negativeMargin of 250 means that IAS will start loading 250 pixel before the last item has scrolled into view.
90
     */
91
    public $negativeMargin = 10;
92
93
    /**
94
     * @var string $triggerText Text of trigger the link.
95
     * Default: "Load more items".
96
     */
97
    public $triggerText;
98
99
    /**
100
     * @var string $triggerTemplate Allows you to override the trigger html template.
101
     */
102
    public $triggerTemplate = '<div class="ias-trigger" style="text-align: center; cursor: pointer;"><a>{text}</a></div>';
103
104
    /**
105
     * @var int $triggerOffset The number of pages which should load automatically.
106
     * After that the trigger is shown for every subsequent page.
107
     * <br><br>
108
     * <i>For example:</i>
109
     * <br>
110
     * if you set the offset to 2, the pages 2 and 3 (page 1 is always shown) would load automatically and for every
111
     * subsequent page the user has to press the trigger to load it.
112
     */
113
    public $triggerOffset = 0;
114
115
    /**
116
     * @var string $spinnerSrc The src attribute of the spinner image.
117
     */
118
    public $spinnerSrc;
119
120
    /**
121
     * @var string $spinnerTemplate Allows you to override the spinner html template.
122
     */
123
    public $spinnerTemplate = '<div class="ias-spinner" style="text-align: center;"><img src="{src}"/></div>';
124
125
    /**
126
     * @var string $noneLeftText Text of the "nothing left" message.
127
     * Default: "You reached the end".
128
     */
129
    public $noneLeftText;
130
131
    /**
132
     * @var string $noneLeftTemplate Allows you to override the "nothing left" message html template.
133
     */
134
    public $noneLeftTemplate = '<div class="ias-noneleft" style="text-align: center;">{text}</div>';
135
136
    /**
137
     * @var string $historyPrev Enter the selector of the link element that links to the previous page.
138
     * The href attribute of this element will be used to get the items from the previous page.
139
     * Make sure there is only one element that matches the selector.
140
     */
141
    public $historyPrev = '.previous';
142
143
    /**
144
     * @var string $overflowContainer A selector for "div" HTML element to use as an overflow container.
145
     * @see http://infiniteajaxscroll.com/examples/overflow.html
146
     */
147
    public $overflowContainer;
148
149
    /**
150
     * @var string|JsExpression $eventOnScroll Triggered when the visitors scrolls.
151
     * @see http://infiniteajaxscroll.com/docs/events.html
152
     */
153
    public $eventOnScroll;
154
155
    /**
156
     * @var string|JsExpression $eventOnLoad Triggered when a new url will be loaded from the server.
157
     * @see http://infiniteajaxscroll.com/docs/events.html
158
     */
159
    public $eventOnLoad;
160
161
    /**
162
     * @var string|JsExpression $eventOnLoaded Triggered after a new page was loaded from the server.
163
     * @see http://infiniteajaxscroll.com/docs/events.html
164
     */
165
    public $eventOnLoaded;
166
167
    /**
168
     * @var string|JsExpression $eventOnRender Triggered before new items will be rendered.
169
     * @see http://infiniteajaxscroll.com/docs/events.html
170
     */
171
    public $eventOnRender;
172
173
    /**
174
     * @var string|JsExpression $eventOnRendered Triggered after new items have rendered.
175
     * Note: This event is only fired once.
176
     * @see http://infiniteajaxscroll.com/docs/events.html
177
     */
178
    public $eventOnRendered;
179
180
    /**
181
     * @var string|JsExpression $eventOnNoneLeft Triggered when there are no more pages left.
182
     * @see http://infiniteajaxscroll.com/docs/events.html
183
     */
184
    public $eventOnNoneLeft;
185
186
    /**
187
     * @var string|JsExpression $eventOnNext Triggered when the next page should be loaded.
188
     * Happens before loading of the next page starts. With this event it is possible to cancel the loading of the next page.
189
     * You can do this by returning false from your callback.
190
     * @see http://infiniteajaxscroll.com/docs/events.html
191
     */
192
    public $eventOnNext;
193
194
    /**
195
     * @var string|JsExpression $eventOnReady Triggered when IAS and all the extensions have been initialized.
196
     * @see http://infiniteajaxscroll.com/docs/events.html
197
     */
198
    public $eventOnReady;
199
200
    /**
201
     * @var string|JsExpression $eventOnPageChange Triggered when a used scroll to another page.
202
     * @see http://infiniteajaxscroll.com/docs/extension-paging.html
203
     */
204
    public $eventOnPageChange;
205
206
    /**
207
     * @var array $enabledExtensions The list of the enabled plugin extensions.
208
     */
209
    public $enabledExtensions = [
210
        self::EXTENSION_TRIGGER,
211
        self::EXTENSION_SPINNER,
212
        self::EXTENSION_NONE_LEFT,
213
        self::EXTENSION_PAGING,
214
        self::EXTENSION_HISTORY
215
    ];
216
217
    /**
218
     * @var \yii\data\Pagination The pagination object that this pager is associated with.
219
     * You must set this property in order to make ScrollPager work.
220
     */
221
    public $pagination;
222
223
    /**
224
     * Initializes the pager.
225
     */
226
    public function init()
227
    {
228
        parent::init();
229
230
        // Register translations source
231
        Yii::$app->i18n->translations = ArrayHelper::merge(Yii::$app->i18n->translations, [
232
            'kop\y2sp' => [
233
                'class' => PhpMessageSource::className(),
234
                'basePath' => '@vendor/kop/yii2-scroll-pager/messages',
235
                'fileMap' => [
236
                    'kop\y2sp' => 'general.php'
237
                ]
238
            ]
239
        ]);
240
241
        // Register required assets
242
        $this->registerAssets();
243
244
        // Set default trigger text if not set
245
        if ($this->triggerText === null) {
246
            $this->triggerText = Yii::t('kop\y2sp', 'Load more items');
247
        }
248
249
        // Set default "none left" message text if not set
250
        if ($this->noneLeftText === null) {
251
            $this->noneLeftText = Yii::t('kop\y2sp', 'You reached the end');
252
        }
253
    }
254
255
    /**
256
     * Executes the widget.
257
     *
258
     * This overrides the parent implementation by initializing jQuery IAS and displaying the generated page buttons.
259
     *
260
     * @throws \yii\base\InvalidConfigException
261
     * @return mixed
262
     */
263
    public function run()
264
    {
265
        // Initialize jQuery IAS plugin
266
        $pluginSettings = Json::encode([
267
            'container' => $this->container,
268
            'item' => $this->item,
269
            'pagination' => "{$this->container} .pagination",
270
            'next' => '.next a',
271
            'delay' => $this->delay,
272
            'negativeMargin' => $this->negativeMargin
273
        ]);
274
        $initString = empty($this->overflowContainer)
275
            ? "var {$this->id}_ias = jQuery.ias({$pluginSettings});"
276
            : "var {$this->id}_ias = jQuery('{$this->overflowContainer}').ias({$pluginSettings});";
277
        $this->view->registerJs($initString, View::POS_READY, "{$this->id}_ias_main");
278
279
        // Register IAS extensions
280
        $this->registerExtensions([
281
            [
282
                'name' => self::EXTENSION_PAGING
283
            ],
284
            [
285
                'name' => self::EXTENSION_SPINNER,
286
                'options' =>
287
                    !empty($this->spinnerSrc)
288
                        ? ['html' => $this->spinnerTemplate, 'src' => $this->spinnerSrc]
289
                        : ['html' => $this->spinnerTemplate]
290
            ],
291
            [
292
                'name' => self::EXTENSION_TRIGGER,
293
                'options' => [
294
                    'text' => $this->triggerText,
295
                    'html' => $this->triggerTemplate,
296
                    'offset' => $this->triggerOffset
297
                ]
298
            ],
299
            [
300
                'name' => self::EXTENSION_NONE_LEFT,
301
                'options' => [
302
                    'text' => $this->noneLeftText,
303
                    'html' => $this->noneLeftTemplate
304
                ]
305
            ],
306
            [
307
                'name' => self::EXTENSION_HISTORY,
308
                'options' => [
309
                    'prev' => $this->historyPrev
310
                ],
311
                'depends' => [
312
                    self::EXTENSION_TRIGGER,
313
                    self::EXTENSION_PAGING
314
                ]
315
            ]
316
        ]);
317
318
        // Register event handlers
319
        $this->registerEventHandlers([
320
            'scroll' => [],
321
            'load' => [],
322
            'loaded' => [],
323
            'render' => [],
324
            'rendered' => [],
325
            'noneLeft' => [],
326
            'next' => [],
327
            'ready' => [],
328
            'pageChange' => [
329
                self::EXTENSION_PAGING
330
            ]
331
        ]);
332
333
        // Render pagination links
334
        echo LinkPager::widget([
335
            'pagination' => $this->pagination,
336
            'options' => [
337
                'class' => 'pagination hidden'
338
            ]
339
        ]);
340
    }
341
342
    /**
343
     * Register required asset bundles.
344
     *
345
     * You can override this method in case if you want to use your own JQuery Infinite Ajax Scroll plugin files
346
     * (for example, some forked plugin version).
347
     */
348
    protected function registerAssets()
349
    {
350
        InfiniteAjaxScrollAsset::register($this->view);
351
    }
352
353
    /**
354
     * Register jQuery IAS extensions.
355
     *
356
     * This method takes jQuery IAS extensions definition as a parameter and registers this extensions.
357
     *
358
     * @param array $config jQuery IAS extensions definition.
359
     * @throws \yii\base\InvalidConfigException If extension dependencies are not met.
360
     */
361
    protected function registerExtensions(array $config)
362
    {
363
        foreach ($config as $entry) {
364
365
            // Parse config entry values
366
            $name = ArrayHelper::getValue($entry, 'name', false);
367
            $options = ArrayHelper::getValue($entry, 'options', '');
368
            $depends = ArrayHelper::getValue($entry, 'depends', []);
369
370
            // If extension is enabled
371
            if (in_array($name, $this->enabledExtensions)) {
372
373
                // Make sure dependencies are met
374 View Code Duplication
                if (!$this->checkEnabledExtensions($depends)) {
0 ignored issues
show
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...
375
                    throw new InvalidConfigException(
376
                        "Extension {$name} requires " . implode(', ', $depends) . " extensions to be enabled."
377
                    );
378
                }
379
380
                // Register extension
381
                $options = Json::encode($options);
382
                $this->view->registerJs(
383
                    "{$this->id}_ias.extension(new {$name}({$options}));",
384
                    View::POS_READY,
385
                    "{$this->id}_ias_{$name}"
386
                );
387
            }
388
        }
389
    }
390
391
    /**
392
     * Register jQuery IAS event handlers.
393
     *
394
     * This method takes jQuery IAS event handlers definition as a parameter and registers this event handlers.
395
     *
396
     * @param array $config jQuery IAS event handlers definition.
397
     * @throws \yii\base\InvalidConfigException If vent handlers dependencies are not met.
398
     */
399
    protected function registerEventHandlers(array $config)
400
    {
401
        foreach ($config as $name => $depends) {
402
403
            // If event is enabled
404
            $eventName = 'eventOn' . ucfirst($name);
405
            if (!empty($this->$eventName)) {
406
407
                // Make sure dependencies are met
408 View Code Duplication
                if (!$this->checkEnabledExtensions($depends)) {
0 ignored issues
show
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...
409
                    throw new InvalidConfigException(
410
                        "The \"{$name}\" event requires " . implode(', ', $depends) . " extensions to be enabled."
411
                    );
412
                }
413
414
                // Register event
415
                $this->view->registerJs(
416
                    "jQuery.ias().on('{$name}', {$this->$eventName});",
417
                    View::POS_READY,
418
                    "{$this->id}_ias_{$name}"
419
                );
420
            }
421
        }
422
    }
423
424
    /**
425
     * Check whether the given extensions are enabled.
426
     *
427
     * @param string|array $extensions Single or multiple extensions names.
428
     * @return bool Operation result.
429
     */
430
    protected function checkEnabledExtensions($extensions)
431
    {
432
        $extensions = (array)$extensions;
433
        if (empty($extensions)) {
434
            return true;
435
        } else {
436
            return (count(array_intersect($this->enabledExtensions, $extensions)) == count($extensions));
437
        }
438
    }
439
}