Completed
Push — master ( e2e764...278c93 )
by Viktor
01:45
created

LongPoll::createJsOptions()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 2
nop 0
dl 0
loc 12
ccs 9
cts 9
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link https://github.com/Izumi-kun/yii2-longpoll
4
 * @copyright Copyright (c) 2017 Viktor Khokhryakov
5
 * @license http://opensource.org/licenses/BSD-3-Clause
6
 */
7
8
namespace izumi\longpoll\widgets;
9
10
use izumi\longpoll\EventCollectionInterface;
11
use Yii;
12
use yii\base\InvalidConfigException;
13
use yii\base\InvalidParamException;
14
use yii\base\Widget;
15
use yii\helpers\Json;
16
use yii\helpers\Url;
17
use yii\web\JsExpression;
18
use yii\web\View;
19
20
/**
21
 * Usage:
22
 *
23
 * ```php
24
 * LongPoll::widget([
25
 *     'url' => ['site/polling'],
26
 *     'events' => ['eventId'],
27
 *     'callback' => 'console.log',
28
 * ]);
29
 * ```
30
 *
31
 * @author Viktor Khokhryakov <[email protected]>
32
 */
33
class LongPoll extends Widget
34
{
35
    public $url;
36
    /**
37
     * @var EventCollectionInterface
38
     */
39
    public $eventCollection;
40
    /**
41
     * @var string event collection class name.
42
     */
43
    public $eventCollectionClass = 'izumi\longpoll\EventCollection';
44
    /**
45
     * @var array additional options to be passed to JS registerer.
46
     */
47
    public $clientOptions;
48
    /**
49
     * @var array params will be passed to JS XHR
50
     */
51
    public $requestParams = [];
52
    /**
53
     * @var string
54
     */
55
    public $callback;
56
57
    /**
58
     * @inheritdoc
59
     */
60 5 View Code Duplication
    public function init()
61
    {
62 5
        if (!$this->eventCollection instanceof EventCollectionInterface) {
63 2
            $this->eventCollection = Yii::createObject([
64 2
                'class' => $this->eventCollectionClass,
65
            ]);
66
        }
67 5
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72 1
    public function run()
73
    {
74 1
        $id = $this->getId();
75 1
        $options = Json::htmlEncode($this->createJsOptions());
76 1
        $view = $this->getView();
77 1
        LongPollAsset::register($view);
78 1
        $view->registerJs("jQuery.longpoll.register('$id', $options);", View::POS_END);
79 1
        $view->registerJs("jQuery.longpoll.get('$id').start();", View::POS_READY);
80 1
    }
81
82
    /**
83
     * @param EventCollectionInterface $eventCollection
84
     * @param array $params
85
     * @return array
86
     * @throws InvalidConfigException
87
     */
88 7
    public static function createPollParams(EventCollectionInterface $eventCollection, $params = [])
89
    {
90 7
        $events = [];
91 7
        foreach ($eventCollection->getEvents() as $event) {
92 6
            $events[$event->getParamName()] = $event->getState();
93
        }
94 7
        if (empty($events)) {
95 1
            throw new InvalidConfigException('At least one event should be added.');
96
        }
97 6
        if (array_intersect_key($events, $params)) {
98 1
            throw new InvalidParamException('The "params" property contains keys that intersect with events.');
99
        }
100
101 5
        return $params + $events;
102
    }
103
104
    /**
105
     * @return array
106
     * @throws InvalidConfigException
107
     */
108 3
    public function createJsOptions()
109
    {
110 3
        if (!isset($this->url)) {
111 1
            throw new InvalidConfigException('The "url" property must be set.');
112
        }
113 2
        $options = $this->clientOptions;
114 2
        $options['url'] = Url::to($this->url);
115 2
        $options['params'] = self::createPollParams($this->eventCollection, $this->requestParams);
116 2
        if ($this->callback) {
117 2
            $options['callback'] = new JsExpression($this->callback);
118
        }
119 2
        return $options;
120
    }
121
122
    /**
123
     * @param array $events
124
     */
125 4
    public function setEvents($events)
126
    {
127 4
        $this->eventCollection = Yii::createObject([
128 4
            'class' => $this->eventCollectionClass,
129 4
            'events' => $events,
130
        ]);
131 4
    }
132
}
133