Completed
Push — master ( fe47f8...2aa7aa )
by Brian
09:43
created

Channels   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 553
Duplicated Lines 26.04 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 19.16%

Importance

Changes 0
Metric Value
wmc 45
lcom 1
cbo 7
dl 144
loc 553
ccs 41
cts 214
cp 0.1916
rs 8.3673
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A getChannels() 12 12 2
B createChannel() 38 38 2
A getChannel() 11 11 2
B createChannelWithId() 37 37 2
A deleteChannel() 0 9 2
A hangup() 0 8 2
A continueDialplan() 0 15 2
A answer() 0 9 2
A startRinging() 0 9 2
A stopRinging() 0 9 2
A sendDtmf() 0 17 2
A mute() 0 13 2
A unmute() 9 9 2
A hold() 0 9 2
A unhold() 0 9 2
A startSilence() 0 9 2
A stopSilence() 0 9 2
B getVariable() 0 23 4
A setVariable() 0 16 2
A startSnoop() 19 19 2
A startSnoopWithId() 18 18 2
A getType() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Channels often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Channels, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * Copyright 2014 Brian Smith <[email protected]>.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *      http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace phparia\Api;
20
21
use GuzzleHttp\Exception\RequestException;
22
use phparia\Resources\Channel;
23
use phparia\Resources\Variable;
24
use phparia\Exception\ConflictException;
25
use phparia\Exception\InvalidParameterException;
26
use phparia\Exception\NotFoundException;
27
use phparia\Exception\ServerException;
28
29
/**
30
 * Channels API
31
 *
32
 * @author Brian Smith <[email protected]>
33
 */
34
class Channels extends MediaBase
35
{
36
    const AST_STATE_DOWN = 'Down'; // Channel is down and available
37
    const AST_STATE_RESERVED = 'Rsrvd'; // Channel is down, but reserved
38
    const AST_STATE_OFFHOOK = 'OffHook'; // Channel is off hook
39
    const AST_STATE_DIALING = 'Dialing'; // Digits (or equivalent) have been dialed
40
    const AST_STATE_RING = 'Ring'; // Line is ringing
41
    const AST_STATE_RINGING = 'Ringing'; // Remote end is ringing
42
    const AST_STATE_UP = 'Up'; // Line is up
43
    const AST_STATE_BUSY = 'Busy'; // Line is busy
44
    const AST_STATE_DIALING_OFFHOOK = 'Dialing Offhook'; // Digits (or equivalent) have been dialed while offhook
45
    const AST_STATE_PRERING = 'Pre-ring'; // Channel has detected an incoming call and is waiting for ring
46
    const AST_STATE_MUTE = 'Mute'; // Do not transmit voice data
47
    const AST_STATE_UNKNOWN = 'Unknown';
48
49
    /**
50
     * List all active channels in Asterisk.
51
     *
52
     * @return Channel[]
53
     */
54 View Code Duplication
    public function getChannels()
0 ignored issues
show
Duplication introduced by Brian Smith
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
    {
56
        $uri = '/channels';
57 98
        $response = $this->client->getEndpoint()->get($uri);
58
59 98
        $channels = [];
60 98
        foreach (\GuzzleHttp\json_decode($response->getBody()) as $channel) {
61
            $channels[] = new Channel($this->client, $channel);
62 98
        }
63 98
64 36
        return $channels;
65 98
    }
66
67 98
    /**
68
     * Create a new channel (originate). The new channel is created immediately and a snapshot of it
69
     * returned. If a Stasis application is provided it will be automatically subscribed to the originated
70
     * channel for further events and updates.
71
     *
72
     * @param string $endpoint (required) Endpoint to call.
73
     * @param string $extension The extension to dial after the endpoint answers
74
     * @param string $context The context to dial after the endpoint answers. If omitted, uses 'default'
75
     * @param int $priority The priority to dial after the endpoint answers. If omitted, uses 1
76
     * @param string $label Asterisk 13+ The label to dial after the endpoint answers. Will supersede 'priority' if provided. Mutually exclusive with 'app'.
77
     * @param string $app The application that is subscribed to the originated channel. When the channel is answered, it will be passed to this Stasis application. Mutually exclusive with 'context', 'extension', 'priority', and 'label'.
78
     * @param string $appArgs The application arguments to pass to the Stasis application.
79
     * @param string $callerId CallerID to use when dialing the endpoint or extension.
80
     * @param int $timeout (default 30) Timeout (in seconds) before giving up dialing, or -1 for no timeout.
81
     * @param string $channelId The unique id to assign the channel on creation.
82
     * @param string $otherChannelId The unique id to assign the second channel when using local channels.
83
     * @param array $variables The "variables" key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { "endpoint": "SIP/Alice", "variables": { "CALLERID(name)": "Alice" } }
84
     * @return Channel
85
     * @throws InvalidParameterException
86
     * @throws ServerException
87
     */
88 View Code Duplication
    public function createChannel(
0 ignored issues
show
Duplication introduced by Brian Smith
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
        $endpoint,
90
        $extension = null,
91 38
        $context = null,
92
        $priority = null,
93
        $label = null,
94
        $app = null,
95
        $appArgs = null,
96
        $callerId = null,
97
        $timeout = null,
98
        $channelId = null,
99
        $otherChannelId = null,
100
        $variables = array()
101
    ) {
102
        $uri = 'channels';
103
        try {
104
            $response = $this->client->getEndpoint()->post($uri, [
105 38
                'form_params' => [
106
                    'endpoint' => $endpoint,
107 38
                    'extension' => $extension,
108 38
                    'context' => $context,
109 38
                    'priority' => $priority,
110 38
                    'label' => $label,
111 38
                    'app' => $app,
112 38
                    'appArgs' => $appArgs,
113 38
                    'callerId' => $callerId,
114 38
                    'timeout' => $timeout,
115 38
                    'channelId' => $channelId,
116 38
                    'otherChannelId' => $otherChannelId,
117 38
                    'variables' => array_map('strval', $variables),
118 38
                ]
119 38
            ]);
120 38
        } catch (RequestException $e) {
121 38
            $this->processRequestException($e);
122
        }
123
124
        return new Channel($this->client, \GuzzleHttp\json_decode($response->getBody()));
125
    }
126
127 38
    /**
128
     * Channel details.
129
     *
130
     * @param string $channelId
131
     * @return Channel
132
     * @throws NotFoundException
133
     */
134 View Code Duplication
    public function getChannel($channelId)
0 ignored issues
show
Duplication introduced by wormling
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
    {
136
        $uri = "channels/$channelId";
137
        try {
138
            $response = $this->client->getEndpoint()->get($uri);
139
        } catch (RequestException $e) {
140
            $this->processRequestException($e);
141
        }
142
143
        return new Channel($this->client, \GuzzleHttp\json_decode($response->getBody()));
144
    }
145
146
    /**
147
     * Create a new channel (originate). The new channel is created immediately and a snapshot of it
148
     * returned. If a Stasis application is provided it will be automatically subscribed to the originated
149
     * channel for further events and updates.
150
     *
151
     * @param string $endpoint (required) Endpoint to call.
152
     * @param string $extension The extension to dial after the endpoint answers
153
     * @param string $context The context to dial after the endpoint answers. If omitted, uses 'default'
154
     * @param int $priority The priority to dial after the endpoint answers. If omitted, uses 1
155
     * @param string $label Asterisk 13+ The label to dial after the endpoint answers. Will supersede 'priority' if provided. Mutually exclusive with 'app'.
156
     * @param string $app The application that is subscribed to the originated channel, and passed to the Stasis application.
157
     * @param string $appArgs The application arguments to pass to the Stasis application.
158
     * @param string $callerId CallerID to use when dialing the endpoint or extension.
159
     * @param int $timeout (default 30) Timeout (in seconds) before giving up dialing, or -1 for no timeout.
160
     * @param string $channelId The unique id to assign the channel on creation.
161
     * @param string $otherChannelId The unique id to assign the second channel when using local channels.
162
     * @param array $variables The "variables" key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { "endpoint": "SIP/Alice", "variables": { "CALLERID(name)": "Alice" } }
163
     * @return Channel
164
     * @throws InvalidParameterException
165
     * @throws ServerException
166
     */
167 View Code Duplication
    public function createChannelWithId(
0 ignored issues
show
Duplication introduced by Brian Smith
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
        $endpoint,
169
        $extension = null,
170
        $context = null,
171
        $priority = null,
172
        $label = null,
173
        $app = null,
174
        $appArgs = null,
175
        $callerId = null,
176
        $timeout = null,
177
        $channelId = null,
178
        $otherChannelId = null,
179
        $variables = array()
180
    ) {
181
        $uri = "channels/$channelId";
182
        try {
183
            $response = $this->client->getEndpoint()->post($uri, [
184
                'form_params' => [
185
                    'endpoint' => $endpoint,
186
                    'extension' => $extension,
187
                    'context' => $context,
188
                    'priority' => $priority,
189
                    'label' => $label,
190
                    'app' => $app,
191
                    'appArgs' => $appArgs,
192
                    'callerId' => $callerId,
193
                    'timeout' => $timeout,
194
                    'otherChannelId' => $otherChannelId,
195
                    'variables' => array_map('strval', $variables),
196
                ]
197
            ]);
198
        } catch (RequestException $e) {
199
            $this->processRequestException($e);
200
        }
201
202
        return new Channel($this->client, \GuzzleHttp\json_decode($response->getBody()));
203
    }
204
205
    /**
206
     * Delete (i.e. hangup) a channel.
207
     *
208
     * @param string $channelId Channel's id
209
     * @throws NotFoundException
210
     */
211 37
    public function deleteChannel($channelId)
212
    {
213 37
        $uri = "channels/$channelId";
214
        try {
215 37
            $this->client->getEndpoint()->delete($uri);
216 37
        } catch (RequestException $e) {
217 37
            $this->processRequestException($e);
218
        }
219 37
    }
220
221
    /**
222
     * Hangup a channel if it still exists.
223
     *
224
     * @param string $channelId Channel's id
225
     */
226 37
    public function hangup($channelId)
227
    {
228
        try {
229 37
            $this->deleteChannel($channelId);
230 37
        } catch (\Exception $ignore) {
231
            // Don't throw exception if the channel doesn't exist
232
        }
233 37
    }
234
235
    /**
236
     * Exit application; continue execution in the dialplan.
237
     *
238
     * @param string $channelId Channel's id
239
     * @param string $context The context to continue to.
240
     * @param string $extension The extension to continue to.
241
     * @param int $priority The priority to continue to.
242
     * @throws NotFoundException
243
     * @throws ConflictException
244
     */
245
    public function continueDialplan($channelId, $context, $extension, $priority)
246
    {
247
        $uri = "channels/$channelId/continue";
248
        try {
249
            $this->client->getEndpoint()->post($uri, [
250
                'form_params' => [
251
                    'context' => $context,
252
                    'extension' => $extension,
253
                    'priority' => $priority,
254
                ]
255
            ]);
256
        } catch (RequestException $e) {
257
            $this->processRequestException($e);
258
        }
259
    }
260
261
    /**
262
     * Answer a channel.
263
     *
264
     * @param string $channelId Channel's id
265
     * @throws NotFoundException
266
     * @throws ConflictException
267
     */
268 37
    public function answer($channelId)
269
    {
270 37
        $uri = "channels/$channelId/answer";
271
        try {
272 37
            $this->client->getEndpoint()->post($uri);
273 37
        } catch (RequestException $e) {
274
            $this->processRequestException($e);
275
        }
276
    }
277
278 37
    /**
279
     * Indicate ringing to a channel.
280
     *
281
     * @param string $channelId
282
     * @throws NotFoundException
283
     * @throws ConflictException
284
     */
285
    public function startRinging($channelId)
286
    {
287
        $uri = "channels/$channelId/ring";
288
        try {
289
            $this->client->getEndpoint()->post($uri);
290
        } catch (RequestException $e) {
291
            $this->processRequestException($e);
292
        }
293
    }
294
295
    /**
296
     * Stop ringing indication on a channel if locally generated.
297
     *
298
     * @param string $channelId
299
     * @throws NotFoundException
300
     * @throws ConflictException
301
     */
302
    public function stopRinging($channelId)
303
    {
304
        $uri = "channels/$channelId/ring";
305
        try {
306
            $this->client->getEndpoint()->delete($uri);
307
        } catch (RequestException $e) {
308
            $this->processRequestException($e);
309
        }
310
    }
311
312
    /**
313
     * Send provided DTMF to a given channel.
314
     *
315
     * @param string $channelId
316
     * @param string $dtmf DTMF To send.
317
     * @param int $before Amount of time to wait before DTMF digits (specified in milliseconds) start.
318
     * @param int $between Amount of time in between DTMF digits (specified in milliseconds).  Default: 100
319
     * @param int $duration Length of each DTMF digit (specified in milliseconds).  Default: 100
320
     * @param int $after Amount of time to wait after DTMF digits (specified in milliseconds) end.
321
     * @throws InvalidParameterException
322
     * @throws NotFoundException
323
     * @throws ConflictException
324
     */
325
    public function sendDtmf($channelId, $dtmf, $before = null, $between = null, $duration = null, $after = null)
326
    {
327
        $uri = "channels/$channelId/dtmf";
328
        try {
329
            $this->client->getEndpoint()->post($uri, [
330
                'form_params' => [
331
                    'dtmf' => $dtmf,
332
                    'before' => $before,
333
                    'between' => $between,
334
                    'duration' => $duration,
335
                    'after' => $after,
336
                ]
337
            ]);
338
        } catch (RequestException $e) {
339
            $this->processRequestException($e);
340
        }
341
    }
342
343
    /**
344
     * Mute a channel.
345
     *
346
     * @param string $channelId Channel's id
347
     * @param string $direction (default both) Direction in which to mute audio.  Allowed values: both, in, out
348
     * @throws NotFoundException
349
     * @throws ConflictException
350
     */
351
    public function mute($channelId, $direction)
352
    {
353
        $uri = "channels/$channelId/mute";
354
        try {
355
            $this->client->getEndpoint()->post($uri, [
356
                'form_params' => [
357
                    'direction' => $direction,
358
                ]
359
            ]);
360
        } catch (RequestException $e) {
361
            $this->processRequestException($e);
362
        }
363
    }
364
365
    /**
366
     * Unmute a channel.
367
     *
368
     * @param string $channelId Channel's id
369
     * @param string $direction (default both) Direction in which to unmute audio
370
     * @throws NotFoundException
371
     * @throws ConflictException
372
     */
373 View Code Duplication
    public function unmute($channelId, $direction)
0 ignored issues
show
Duplication introduced by wormling
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
374
    {
375
        $uri = "channels/$channelId/mute?direction=".\GuzzleHttp\json_encode($direction);
376
        try {
377
            $this->client->getEndpoint()->delete($uri);
378
        } catch (RequestException $e) {
379
            $this->processRequestException($e);
380
        }
381
    }
382
383
    /**
384
     * Hold a channel.
385
     *
386
     * @param string $channelId Channel's id
387
     * @throws NotFoundException
388
     * @throws ConflictException
389
     */
390
    public function hold($channelId)
391
    {
392
        $uri = "channels/$channelId/hold";
393
        try {
394
            $this->client->getEndpoint()->post($uri);
395
        } catch (RequestException $e) {
396
            $this->processRequestException($e);
397
        }
398
    }
399
400
    /**
401
     * Remove a channel from hold.
402
     *
403
     * @param string $channelId Channel's id
404
     * @throws NotFoundException
405
     * @throws ConflictException
406
     */
407
    public function unhold($channelId)
408
    {
409
        $uri = "channels/$channelId/hold";
410
        try {
411
            $this->client->getEndpoint()->delete($uri);
412
        } catch (RequestException $e) {
413
            $this->processRequestException($e);
414
        }
415
    }
416
417
    /**
418
     * Play silence to a channel. Using media operations such as /play on a channel playing silence in this manner will suspend silence without resuming automatically.
419
     *
420
     * @param string $channelId Channel's id
421
     * @throws NotFoundException
422
     * @throws ConflictException
423
     */
424
    public function startSilence($channelId)
425
    {
426
        $uri = "channels/$channelId/silence";
427
        try {
428
            $this->client->getEndpoint()->post($uri);
429
        } catch (RequestException $e) {
430
            $this->processRequestException($e);
431
        }
432
    }
433
434
    /**
435
     * Stop playing silence to a channel.
436
     *
437
     * @param string $channelId Channel's id
438
     * @throws NotFoundException
439
     * @throws ConflictException
440
     */
441
    public function stopSilence($channelId)
442
    {
443
        $uri = "channels/$channelId/silence";
444
        try {
445
            $this->client->getEndpoint()->delete($uri);
446
        } catch (RequestException $e) {
447
            $this->processRequestException($e);
448
        }
449
    }
450
451
    /**
452
     * Get the value of a channel variable or function.
453
     *
454
     * @param string $channelId
455
     * @param string $variable
456
     * @param null|string $default The value to return if the variable does not exist
457
     * @return string|Variable
458
     * @throws ConflictException
459
     * @throws InvalidParameterException
460
     * @throws NotFoundException
461
     */
462
    public function getVariable($channelId, $variable, $default = null)
463
    {
464
        $uri = "channels/$channelId/variable";
465
        try {
466
            $response = $this->client->getEndpoint()->get($uri, [
467
                'form_params' => [
468
                    'variable' => $variable,
469
                ]
470
            ]);
471
        } catch (RequestException $e) {
472
            try {
473
                $this->processRequestException($e);
474
            } catch (NotFoundException $notFoundException) {
475
                if ($default === null) {
476
                    throw $notFoundException;
477
                }
478
479
                return $default;
480
            }
481
        }
482
483
        return new Variable(\GuzzleHttp\json_decode($response->getBody()));
484
    }
485
486
    /**
487
     * Set the value of a channel variable or function.
488
     *
489
     * @param string $channelId
490
     * @param string $variable
491
     * @param string $value
492
     * @return Variable
493
     * @throws InvalidParameterException
494
     * @throws NotFoundException
495
     * @throws ConflictException
496
     */
497
    public function setVariable($channelId, $variable, $value)
498
    {
499
        $uri = "channels/$channelId/variable";
500
        try {
501
            $response = $this->client->getEndpoint()->post($uri, [
502
                'form_params' => [
503
                    'variable' => $variable,
504
                    'value' => $value,
505
                ]
506
            ]);
507
        } catch (RequestException $e) {
508
            $this->processRequestException($e);
509
        }
510
511
        return new Variable(\GuzzleHttp\json_decode($response->getBody()));
512
    }
513
514
    /**
515
     * Start snooping. Snoop (spy/whisper) on a specific channel.
516
     *
517
     * @param string $channelId Channel's id
518
     * @param string $spy (default none) Direction of audio to spy on
519
     * @param string $whisper (default none) Direction of audio to whisper into
520
     * @param string $app (required) Application the snooping channel is placed into
521
     * @param string $appArgs The application arguments to pass to the Stasis application
522
     * @param string $snoopId Unique ID to assign to snooping channel
523
     * @return Channel
524
     * @throws InvalidParameterException
525
     * @throws NotFoundException
526
     */
527 View Code Duplication
    public function startSnoop($channelId, $spy, $whisper, $app, $appArgs, $snoopId)
0 ignored issues
show
Duplication introduced by wormling
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
528
    {
529
        $uri = "channels/$channelId/snoop";
530
        try {
531
            $response = $this->client->getEndpoint()->post($uri, [
532
                'form_params' => [
533
                    'spy' => $spy,
534
                    'whisper' => $whisper,
535
                    'app' => $app,
536
                    'appArgs' => $appArgs,
537
                    'snoopId' => $snoopId,
538
                ]
539
            ]);
540
        } catch (RequestException $e) {
541
            $this->processRequestException($e);
542
        }
543
544
        return new Channel($this->client, \GuzzleHttp\json_decode($response->getBody()));
545
    }
546
547
    /**
548
     * Start snooping. Snoop (spy/whisper) on a specific channel.
549
     *
550
     * @param string $channelId Channel's id
551
     * @param string $spy (default none) Direction of audio to spy on
552
     * @param string $whisper (default none) Direction of audio to whisper into
553
     * @param string $app (required) Application the snooping channel is placed into
554
     * @param string $appArgs The application arguments to pass to the Stasis application
555
     * @param string $snoopId Unique ID to assign to snooping channel
556
     * @return Channel
557
     * @throws InvalidParameterException
558
     * @throws NotFoundException
559
     */
560 View Code Duplication
    public function startSnoopWithId($channelId, $spy, $whisper, $app, $appArgs, $snoopId)
0 ignored issues
show
Duplication introduced by wormling
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
561
    {
562
        $uri = "channels/$channelId/snoop/$snoopId";
563
        try {
564
            $response = $this->client->getEndpoint()->post($uri, [
565
                'form_params' => [
566
                    'spy' => $spy,
567
                    'whisper' => $whisper,
568
                    'app' => $app,
569
                    'appArgs' => $appArgs,
570
                ]
571
            ]);
572
        } catch (RequestException $e) {
573
            $this->processRequestException($e);
574
        }
575
576
        return new Channel($this->client, \GuzzleHttp\json_decode($response->getBody()));
577
    }
578
579
    /**
580
     * @return string
581
     */
582
    public function getType()
583
    {
584
        return 'channels';
585
    }
586
}
587