Completed
Push — master ( 1b605f...95b7c3 )
by Dan
06:00
created

Client::say()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 6
nop 3
1
<?php
2
3
namespace Nopolabs\Yabot\Slack;
4
5
6
use Closure;
7
use Nopolabs\Yabot\Helpers\ConfigTrait;
8
use React\Promise\PromiseInterface;
9
use Slack\Channel;
10
use Slack\ChannelInterface;
11
use Slack\Payload;
12
use Slack\RealTimeClient;
13
use Slack\User;
14
15
class Client
16
{
17
    use ConfigTrait;
18
19
    /** @var RealTimeClient */
20
    private $realTimeClient;
21
22
    /** @var Users */
23
    private $users;
24
25
    /** @var Channels */
26
    private $channels;
27
28
    /** @var User */
29
    protected $authedUser;
30
31
    public function __construct(RealTimeClient $realTimeClient, Users $users, Channels $channels, array $config = [])
32
    {
33
        $this->realTimeClient = $realTimeClient;
34
        $this->users = $users;
35
        $this->channels = $channels;
36
        $this->setConfig($config);
37
    }
38
39
    public function getRealTimeClient()
40
    {
41
        return $this->realTimeClient;
42
    }
43
44
    public function init() : Client
45
    {
46
        $this->initChannelUpdateHandlers();
47
        $this->initUserUpdateHandlers();
48
49
        return $this;
50
    }
51
52
    public function update(Closure $authedUserUpdated)
53
    {
54
        $this->updateUsers();
55
        $this->updateChannels();
56
        $this->updateAuthedUser($authedUserUpdated);
57
    }
58
59
    public function getAuthedUser()
60
    {
61
        return $this->authedUser;
62
    }
63
64
    public function getAuthedUsername()
65
    {
66
        return $this->authedUser->getUsername();
67
    }
68
69
    public function connect() : PromiseInterface
70
    {
71
        return $this->realTimeClient->connect();
72
    }
73
74
    public function disconnect()
75
    {
76
        return $this->realTimeClient->disconnect();
77
    }
78
79
    public function useWebSocket() : bool
80
    {
81
        return (bool) $this->get('use.websocket', false);
82
    }
83
84
    public function say($text, $channel, array $additionalParameters = [])
85
    {
86
        if (!($channel instanceof ChannelInterface)) {
87
            $channel = $this->getChannelByName($channel);
88
            if (!$channel) {
89
                $channel = $this->getChannelById($channel);
90
            }
91
        }
92
93
        if (empty($additionalParameters) && $this->useWebSocket()) {
94
            // WebSocket send does not support message formatting.
95
            $this->send($text, $channel);
0 ignored issues
show
Bug introduced by
It seems like $channel can be null; however, send() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
96
        } else {
97
            // Http post send supports message formatting.
98
            $this->post($text, $channel, $additionalParameters);
0 ignored issues
show
Bug introduced by
It seems like $channel can be null; however, post() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
99
        }
100
    }
101
102
    public function send($text, ChannelInterface $channel)
103
    {
104
        $this->realTimeClient->send($text, $channel);
105
    }
106
107
    public function post($text, ChannelInterface $channel, array $additionalParameters = [])
108
    {
109
        $parameters = array_merge([
110
            'text' => $text,
111
            'channel' => $channel->getId(),
112
            'as_user' => true,
113
        ], $additionalParameters);
114
115
        $this->realTimeClient->apiCall('chat.postMessage', $parameters);
116
    }
117
118
    public function on($event, array $onMessage)
119
    {
120
        $this->realTimeClient->on($event, function (Payload $payload) use ($onMessage) {
121
            call_user_func($onMessage, $payload);
122
        });
123
    }
124
125
    /**
126
     * @param $id
127
     * @return null|User
128
     */
129
    public function getUserById($id)
130
    {
131
        return $this->users->byId($id);
132
    }
133
134
    /**
135
     * @param $name
136
     * @return null|User
137
     */
138
    public function getUserByName($name)
139
    {
140
        return $this->users->byName($name);
141
    }
142
143
    /**
144
     * @param $id
145
     * @return null|Channel
146
     */
147
    public function getChannelById($id)
148
    {
149
        return $this->channels->byId($id);
150
    }
151
152
    /**
153
     * @param $name
154
     * @return null|Channel
155
     */
156
    public function getChannelByName($name)
157
    {
158
        return $this->channels->byName($name);
159
    }
160
161
    public function updateUsers()
162
    {
163
        $this->realTimeClient->getUsers()->then(function(array $users) {
164
            $this->users->update($users);
165
        });
166
    }
167
168
    public function updateChannels()
169
    {
170
        $this->realTimeClient->getChannels()->then(function(array $channels) {
171
            $this->channels->update($channels);
172
        });
173
    }
174
175
    public function updateAuthedUser(Closure $authedUserUpdated)
176
    {
177
        $this->realTimeClient->getAuthedUser()->then(function (User $user) use ($authedUserUpdated) {
178
            $this->authedUser = $user;
179
            $authedUserUpdated($user);
180
        });
181
    }
182
183
    protected function initChannelUpdateHandlers()
184
    {
185
        $events = ['channel_created', 'channel_deleted', 'channel_rename'];
186
        foreach ($events as $event) {
187
            $this->on($event, [$this, 'updateChannels']);
188
        }
189
    }
190
191
    protected function initUserUpdateHandlers()
192
    {
193
        $events = ['user_change'];
194
        foreach ($events as $event) {
195
            $this->on($event, [$this, 'updateUsers']);
196
        }
197
    }
198
}