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

Rooms::getIterator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
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\Resources;
9
10
use Gitter\Route;
11
use Gitter\Support\Observer;
12
13
/**
14
 * A Room in Gitter can represent a GitHub Organisation, a GitHub Repository, a Gitter Channel
15
 *  or a One-to-one conversation.
16
 *
17
 * In the case of the Organisations and Repositories, the access control policies are inherited from GitHub.
18
 *
19
 * The following types of room exist:
20
 *  - ORG:          A room that represents a GitHub Organisation.
21
 *  - REPO:         A room that represents a GitHub Repository.
22
 *  - ONETOONE:     A one-to-one chat.
23
 *  - ORG_CHANNEL:  A Gitter channel nested under a GitHub Organisation.
24
 *  - REPO_CHANNEL: A Gitter channel nested under a GitHub Repository.
25
 *  - USER_CHANNEL: A Gitter channel nested under a GitHub User.
26
 *
27
 * Room schema:
28
 *  - id:              Room ID.
29
 *  - name:            Room name.
30
 *  - topic:           Room topic. (default: GitHub repo description)
31
 *  - uri:             Room URI on Gitter.
32
 *  - oneToOne:        Indicates if the room is a one-to-one chat.
33
 *  - users:           List of users in the room.
34
 *  - userCount:       Count of users in the room.
35
 *  - unreadItems:     Number of unread messages for the current user.
36
 *  - mentions:        Number of unread mentions for the current user.
37
 *  - lastAccessTime:  Last time the current user accessed the room in ISO format.
38
 *  - favourite:       Indicates if the room is on of your favourites.
39
 *  - lurk:            Indicates if the current user has disabled notifications.
40
 *  - url:             Path to the room on gitter.
41
 *  - githubType:      Type of the room.
42
 *  - tags:            Tags that define the room.
43
 *  - v:               Room version.
44
 *
45
 * @package Gitter\Resources
46
 */
47
class Rooms extends AbstractResource implements \IteratorAggregate
48
{
49
    const GITHUB_ORG   = 'ORG';
50
    const ORG_CHANNEL  = 'ORG_CHANNEL';
51
52
    const GITHUB_REPO  = 'REPO';
53
    const REPO_CHANNEL = 'REPO_CHANNEL';
54
55
    const ONE_TO_ONE   = 'ONETOONE';
56
    const USER_CHANNEL = 'USER_CHANNEL';
57
58
    /**
59
     * List rooms the current user is in
60
     *
61
     * @param string $query Search query
62
     * @return array
63
     * @throws \RuntimeException
64
     * @throws \InvalidArgumentException
65
     */
66
    public function all(string $query = null): array
67
    {
68
        if ($query !== null) {
69
            return $this->fetch(Route::get('rooms')->with('q', $query));
70
        }
71
72
        return $this->fetch(Route::get('rooms'));
73
    }
74
75
    /**
76
     * To join a room you'll need to provide a URI for it.
77
     * Said URI can represent a GitHub Org, a GitHub Repo or a Gitter Channel.
78
     *  - If the room exists and the user has enough permission to access it, it'll be added to the room.
79
     *  - If the room doesn't exist but the supplied URI represents a GitHub Org or GitHub Repo the user
80
     * is an admin of, the room will be created automatically and the user added.
81
     *
82
     * @param string $roomId Required ID of the room you would like to join
83
     * @param string $userId Required ID of the user
84
     * @return array
85
     * @throws \RuntimeException
86
     * @throws \InvalidArgumentException
87
     */
88
    public function joinUser(string $roomId, string $userId): array
89
    {
90
        return $this->fetch(
91
            Route::post('user/{userId}/rooms')->with('userId', $userId)
92
                ->withBody('id', $roomId)
93
        );
94
    }
95
96
    /**
97
     * Join to target room
98
     *
99
     * @param string $roomId Required ID of the room you would like to join
100
     * @return array
101
     * @throws \RuntimeException
102
     * @throws \InvalidArgumentException
103
     */
104
    public function join(string $roomId): array
105
    {
106
        return $this->joinUser($roomId, $this->client()->authId());
107
    }
108
109
    /**
110
     * To join a room you'll need to provide a URI for it.
111
     *
112
     * Said URI can represent a GitHub Org, a GitHub Repo or a Gitter Channel.
113
     *  - If the room exists and the user has enough permission to access it, it'll be added to the room.
114
     *  - If the room doesn't exist but the supplied URI represents a GitHub Org or GitHub Repo the user
115
     *
116
     * is an admin of, the room will be created automatically and the user added.
117
     *
118
     * @param string $name Required URI of the room you would like to join
119
     * @return array
120
     * @throws \RuntimeException
121
     * @throws \InvalidArgumentException
122
     */
123
    public function joinByName(string $name): array
124
    {
125
        return $this->fetch(Route::post('rooms')->withBody('uri', $name));
126
    }
127
128
    /**
129
     * @param string $name
130
     * @return array
131
     * @throws \RuntimeException
132
     * @throws \InvalidArgumentException
133
     */
134
    public function findByName(string $name): array
135
    {
136
        return $this->joinByName($name);
137
    }
138
139
    /**
140
     * Kick target user from target room
141
     *
142
     * @param string $roomId Required ID of the room
143
     * @param string $userId Required ID of the user
144
     * @return array
145
     * @throws \RuntimeException
146
     * @throws \InvalidArgumentException
147
     */
148
    public function kick(string $roomId, string $userId): array
149
    {
150
        return $this->fetch(
151
            Route::delete('rooms/{roomId}/users/{userId}')
152
                ->with('roomId', $roomId)
153
                ->with('userId', $userId)
154
        );
155
    }
156
157
    /**
158
     * This can be self-inflicted to leave the the room and remove room from your left menu.
159
     *
160
     * @param string $roomId Required ID of the room
161
     * @return array
162
     * @throws \RuntimeException
163
     * @throws \InvalidArgumentException
164
     */
165
    public function leave(string $roomId): array
166
    {
167
        return $this->kick($roomId, $this->client()->authId());
168
    }
169
170
    /**
171
     * Sets up a new topic of target room
172
     *
173
     * @param string $roomId Room id
174
     * @param string $topic Room topic
175
     * @return mixed
176
     * @throws \RuntimeException
177
     * @throws \InvalidArgumentException
178
     */
179
    public function topic(string $roomId, string $topic): array
180
    {
181
        return $this->fetch(
182
            Route::put('rooms/{roomId}')
183
                ->with('roomId', $roomId)
184
                ->withBody('topic', $topic)
185
        );
186
    }
187
188
    /**
189
     * Sets the room is indexed by search engines
190
     *
191
     * @param string $roomId Room id
192
     * @param bool $enabled Enable or disable room indexing
193
     * @return array
194
     * @throws \RuntimeException
195
     * @throws \InvalidArgumentException
196
     */
197
    public function searchIndex(string $roomId, bool $enabled = true): array
198
    {
199
        return $this->fetch(
200
            Route::put('rooms/{roomId}')
201
                ->with('roomId', $roomId)
202
                ->withBody('noindex', !$enabled)
203
        );
204
    }
205
206
    /**
207
     * Sets the tags that define the room
208
     *
209
     * @param string $roomId Room id
210
     * @param array $tags Target tags
211
     * @return array
212
     * @throws \RuntimeException
213
     * @throws \InvalidArgumentException
214
     *
215
     */
216
    public function tags(string $roomId, array $tags = []): array
217
    {
218
        return $this->fetch(
219
            Route::put('rooms/{roomId}')
220
                ->with('roomId', $roomId)
221
                ->withBody('tags', implode(', ', $tags))
222
        );
223
    }
224
225
    /**
226
     * If you hate one of the rooms - you can destroy it!
227
     * Fatality.
228
     *
229
     * @internal BE CAREFUL: THIS IS VERY DANGEROUS OPERATION.
230
     *
231
     * @param string $roomId Target room id
232
     * @return array
233
     * @throws \RuntimeException
234
     * @throws \InvalidArgumentException
235
     */
236
    public function delete(string $roomId): array
237
    {
238
        return $this->fetch(
239
            Route::delete('rooms/{roomId}')
240
                ->with('roomId', $roomId)
241
        );
242
    }
243
244
    /**
245
     * List of Users currently in the room.
246
     *
247
     * @param string $roomId Target room id
248
     * @param string $query Optional query for users search
249
     * @return \Generator
250
     * @throws \RuntimeException
251
     * @throws \InvalidArgumentException
252
     */
253
    public function users(string $roomId, string $query = null): \Generator
254
    {
255
        $skip    = 0;
256
        $limit   = 30;
257
258
        do {
259
            $route = Route::get('rooms/{roomId}/users')
260
                ->withMany([
261
                    'roomId' => $roomId,
262
                    'skip'   => $skip,
263
                    'limit'  => $limit,
264
                ]);
265
266
            if ($query !== null) {
267
                $route->with('q', $query);
268
            }
269
270
            yield from $response = $this->fetch($route);
271
272
        } while(count($response) >= $limit && ($skip += $limit));
273
    }
274
275
    /**
276
     * Use the streaming API to listen events.
277
     * The streaming API allows real-time access to messages fetching.
278
     *
279
     * @param string $roomId
280
     * @return Observer
281
     * @throws \InvalidArgumentException
282
     */
283
    public function events(string $roomId): Observer
284
    {
285
        return $this->stream(
286
                Route::get('rooms/{roomId}/events')
287
                    ->with('roomId', $roomId)
288
                    ->toStream()
289
            );
290
    }
291
292
    /**
293
     * Use the streaming API to listen messages.
294
     * The streaming API allows real-time access to messages fetching.
295
     *
296
     * @param string $roomId
297
     * @return Observer
298
     * @throws \InvalidArgumentException
299
     */
300
    public function messages(string $roomId): Observer
301
    {
302
        return $this->stream(
303
                Route::get('rooms/{roomId}/chatMessages')
304
                    ->with('roomId', $roomId)
305
                    ->toStream()
306
            );
307
    }
308
309
    /**
310
     * @return \Generator
311
     * @throws \RuntimeException
312
     * @throws \InvalidArgumentException
313
     */
314
    public function getIterator(): \Generator
315
    {
316
        $rooms = $this->all();
317
318
        foreach ($rooms as $i => $room) {
319
            yield $i => $room;
320
        }
321
    }
322
}
323