Issues (5)

src/widgets/LongPoll.php (1 issue)

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