Completed
Push — master ( 53745e...a97641 )
by Kirill
02:31
created

Client::__get()   D

Complexity

Conditions 9
Paths 2

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 4.909
c 0
b 0
f 0
cc 9
eloc 21
nc 2
nop 1
1
<?php declare(strict_types = 1);
2
/**
3
 * This file is part of GitterApi package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
namespace Gitter;
9
10
use Gitter\Adapters\AdapterInterface;
11
use Gitter\Adapters\HttpAdapter;
12
use Gitter\Adapters\StreamAdapter;
13
use Gitter\Adapters\StreamAdapterInterface;
14
use Gitter\Adapters\SyncAdapterInterface;
15
use Gitter\Resources\Groups;
16
use Gitter\Resources\Messages;
17
use Gitter\Resources\Rooms;
18
use Gitter\Resources\Users;
19
use Gitter\Support\Loggable;
20
use Monolog\Logger;
21
use Psr\Log\LoggerInterface;
22
use Psr\Log\NullLogger;
23
use React\EventLoop\Factory;
24
use React\EventLoop\LoopInterface;
25
26
/**
27
 * Class Client
28
 * @package Gitter
29
 *
30
 * @property-read Rooms $rooms
31
 * @property-read Users $users
32
 * @property-read Messages $messages
33
 * @property-read Groups $groups
34
 *
35
 * @property string $token
36
 * @property LoggerInterface|null $logger
37
 * @property LoopInterface $loop
38
 *
39
 */
40
class Client implements Loggable
41
{
42
    /**
43
     * @var string
44
     */
45
    const VERSION = '4.0.0';
46
47
    /**
48
     * @var string
49
     */
50
    protected $token;
51
52
    /**
53
     * @var LoggerInterface
54
     */
55
    protected $logger;
56
57
    /**
58
     * @var LoopInterface
59
     */
60
    protected $loop;
61
62
    /**
63
     * @var array
64
     */
65
    private $storage = [];
66
67
    /**
68
     * Client constructor.
69
     * @param string $token
70
     * @param LoggerInterface $logger
71
     */
72
    public function __construct(string $token, LoggerInterface $logger = null)
73
    {
74
        $this->token = $token;
75
        $this->loop = Factory::create();
76
77
        if (null === ($this->logger = $logger)) {
78
            $this->logger = new NullLogger();
79
        }
80
    }
81
82
    /**
83
     * @return void
84
     */
85
    public function clear()
86
    {
87
        $this->loop->stop();
88
        $this->storage = [];
89
    }
90
91
    /**
92
     * @param string $message
93
     * @param int $level
94
     * @return Loggable|$this
95
     */
96
    public function log(string $message, int $level = Logger::INFO): Loggable
97
    {
98
        $this->logger->log($level, $message);
99
100
        return $this;
101
    }
102
103
    /**
104
     * @return SyncAdapterInterface|AdapterInterface
105
     */
106
    public function viaHttp(): SyncAdapterInterface
107
    {
108
        return new HttpAdapter($this);
109
    }
110
111
    /**
112
     * @return StreamAdapterInterface|AdapterInterface
113
     */
114
    public function viaStream(): StreamAdapterInterface
115
    {
116
        return new StreamAdapter($this, $this->loop);
117
    }
118
119
    /**
120
     * @return void
121
     */
122
    public function connect()
123
    {
124
        $this->loop->run();
125
    }
126
127
    /**
128
     * @param string $hookId
129
     * @return WebHook
130
     * @throws \InvalidArgumentException
131
     */
132
    public function notify(string $hookId): WebHook
133
    {
134
        return new WebHook($this, $hookId);
135
    }
136
137
    /**
138
     * @param string $resource
139
     * @return Groups|Messages|Rooms|Users|null|LoggerInterface|LoopInterface|string
140
     */
141
    public function __get(string $resource)
142
    {
143
        $resolve = function (string $resource) {
144
            switch ($resource) {
145
                // == RESOURCES ==
146
                case 'users':
147
                    return new Users($this);
148
                case 'groups':
149
                    return new Groups($this);
150
                case 'messages':
151
                    return new Messages($this);
152
                case 'rooms':
153
                    return new Rooms($this);
154
155
                // == COMMON ===
156
                case 'loop':
157
                    return $this->loop();
158
                case 'token':
159
                    return $this->token();
160
                case 'logger':
161
                    return $this->logger();
162
            }
163
164
            return null;
165
        };
166
167
        if (!isset($this->storage[$resource])) {
168
            $this->storage[$resource] = $resolve($resource);
169
        }
170
171
        return $this->storage[$resource];
172
    }
173
174
    /**
175
     * @param string $name
176
     * @param $value
177
     * @return void
178
     */
179
    public function __set(string $name, $value)
180
    {
181
        switch ($name) {
182
            // == COMMON ===
183
            case 'loop':
184
                $this->loop($value);
185
                break;
186
187
            case 'token':
188
                $this->token($value);
189
                break;
190
191
            case 'logger':
192
                $this->logger($value);
193
                break;
194
195
            default:
196
                $this->{$name} = $value;
197
        }
198
    }
199
200
    /**
201
     * @return array
202
     * @throws \RuntimeException
203
     * @throws \InvalidArgumentException
204
     */
205
    public function auth(): array
206
    {
207
        return $this->users->current();
208
    }
209
210
    /**
211
     * @return string
212
     * @throws \RuntimeException
213
     * @throws \InvalidArgumentException
214
     */
215
    public function authId(): string
216
    {
217
        return $this->users->currentUserId();
218
    }
219
220
    /**
221
     * @param LoopInterface|null $loop
222
     * @return LoopInterface
223
     */
224
    public function loop(LoopInterface $loop = null): LoopInterface
225
    {
226
        if ($loop !== null) {
227
            $this->loop = $loop;
228
        }
229
230
        return $this->loop;
231
    }
232
233
    /**
234
     * @param string|null $token
235
     * @return string
236
     */
237
    public function token(string $token = null): string
238
    {
239
        if ($token !== null) {
240
            $this->token = $token;
241
        }
242
243
        return $this->token;
244
    }
245
246
    /**
247
     * @param LoggerInterface|null $logger
248
     * @return LoggerInterface
249
     */
250
    public function logger(LoggerInterface $logger = null): LoggerInterface
251
    {
252
        if ($logger !== null) {
253
            $this->logger = $logger;
254
        }
255
256
        return $this->logger;
257
    }
258
259
    /**
260
     * @param string $name
261
     * @throws \LogicException
262
     */
263
    public function __unset(string $name)
264
    {
265
        switch ($name) {
266
            case 'logger':
267
                $this->logger = null;
268
                break;
269
            case 'loop':
270
                throw new \LogicException('Can not remove EventLoop');
271
            case 'token':
272
                throw new \LogicException('Can not remove token value.');
273
            case 'users':
274
            case 'groups':
275
            case 'messages':
276
            case 'rooms':
277
                throw new \LogicException('Resource ' . $name . ' can not be removed');
278
        }
279
    }
280
281
    /**
282
     * @param string $name
283
     * @return bool
284
     */
285
    public function __isset(string $name): bool
286
    {
287
        if (in_array($name, ['users', 'groups', 'messages', 'rooms', 'loop', 'token'], true)) {
288
            return true;
289
        } elseif ($name === 'logger') {
290
            return $this->logger !== null;
291
        }
292
293
        return property_exists($this, $name) && $this->{$name} !== null;
294
    }
295
}
296