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

src/wormling/phparia/Api/Channels.php (8 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 Pest_BadRequest;
22
use Pest_Conflict;
23
use Pest_NotFound;
24
use Pest_ServerError;
25
use phparia\Resources\Channel;
26
use phparia\Resources\Variable;
27
use phparia\Exception\ConflictException;
28
use phparia\Exception\InvalidParameterException;
29
use phparia\Exception\NotFoundException;
30
use phparia\Exception\ServerException;
31
32
/**
33
 * Channels API
34
 *
35
 * @author Brian Smith <[email protected]>
36
 */
37
class Channels extends MediaBase
38
{
39
    const AST_STATE_DOWN = 'Down'; // Channel is down and available
40
    const AST_STATE_RESERVED = 'Rsrvd'; // Channel is down, but reserved
41
    const AST_STATE_OFFHOOK = 'OffHook'; // Channel is off hook
42
    const AST_STATE_DIALING = 'Dialing'; // Digits (or equivalent) have been dialed
43
    const AST_STATE_RING = 'Ring'; // Line is ringing
44
    const AST_STATE_RINGING = 'Ringing'; // Remote end is ringing
45
    const AST_STATE_UP = 'Up'; // Line is up
46
    const AST_STATE_BUSY = 'Busy'; // Line is busy
47
    const AST_STATE_DIALING_OFFHOOK = 'Dialing Offhook'; // Digits (or equivalent) have been dialed while offhook
48
    const AST_STATE_PRERING = 'Pre-ring'; // Channel has detected an incoming call and is waiting for ring
49
    const AST_STATE_MUTE = 'Mute'; // Do not transmit voice data
50
    const AST_STATE_UNKNOWN = 'Unknown';
51
52
    /**
53
     * List all active channels in Asterisk.
54
     *
55
     * @return Channel[]
56
     */
57 98
    public function getChannels()
58
    {
59 98
        $uri = '/channels';
60 98
        $response = $this->client->getEndpoint()->get($uri);
61
62 98
        $channels = [];
63 98
        foreach ((array)$response as $channel) {
64 36
            $channels[] = new Channel($this->client, $channel);
65 98
        }
66
67 98
        return $channels;
68
    }
69
70
    /**
71
     * Create a new channel (originate). The new channel is created immediately and a snapshot of it
72
     * returned. If a Stasis application is provided it will be automatically subscribed to the originated
73
     * channel for further events and updates.
74
     *
75
     * @param string $endpoint (required) Endpoint to call.
76
     * @param string $extension The extension to dial after the endpoint answers
77
     * @param string $context The context to dial after the endpoint answers. If omitted, uses 'default'
78
     * @param int $priority The priority to dial after the endpoint answers. If omitted, uses 1
79
     * @param string $label Asterisk 13+ The label to dial after the endpoint answers. Will supersede 'priority' if provided. Mutually exclusive with 'app'.
80
     * @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'.
81
     * @param string $appArgs The application arguments to pass to the Stasis application.
82
     * @param string $callerId CallerID to use when dialing the endpoint or extension.
83
     * @param int $timeout (default 30) Timeout (in seconds) before giving up dialing, or -1 for no timeout.
84
     * @param string $channelId The unique id to assign the channel on creation.
85
     * @param string $otherChannelId The unique id to assign the second channel when using local channels.
86
     * @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" } }
87
     * @return Channel
88
     * @throws InvalidParameterException
89
     * @throws ServerException
90
     */
91 38 View Code Duplication
    public function createChannel(
92
        $endpoint,
93
        $extension = null,
94
        $context = null,
95
        $priority = null,
96
        $label = null,
97
        $app = null,
98
        $appArgs = null,
99
        $callerId = null,
100
        $timeout = null,
101
        $channelId = null,
102
        $otherChannelId = null,
103
        $variables = array()
104
    ) {
105 38
        $uri = '/channels';
106
        try {
107 38
            $response = $this->client->getEndpoint()->post($uri, array(
108 38
                'endpoint' => $endpoint,
109 38
                'extension' => $extension,
110 38
                'context' => $context,
111 38
                'priority' => $priority,
112 38
                'label' => $label,
113 38
                'app' => $app,
114 38
                'appArgs' => $appArgs,
115 38
                'callerId' => $callerId,
116 38
                'timeout' => $timeout,
117 38
                'channelId' => $channelId,
118 38
                'otherChannelId' => $otherChannelId,
119 38
                'variables' => array_map('strval', $variables),
120 38
            ));
121 38
        } catch (Pest_BadRequest $e) { // Invalid parameters for originating a channel.
122
            throw new InvalidParameterException($e);
123
        } catch (Pest_ServerError $e) {
124
            throw new ServerException($e); // Couldn't create the channel.
125
        }
126
127 38
        return new Channel($this->client, $response);
128
    }
129
130
    /**
131
     * Channel details.
132
     *
133
     * @param string $channelId
134
     * @return Channel
135
     * @throws NotFoundException
136
     */
137
    public function getChannel($channelId)
138
    {
139
        $uri = "/channels/$channelId";
140
        try {
141
            $response = $this->client->getEndpoint()->get($uri);
142
        } catch (Pest_NotFound $e) { // Channel not found
143
            throw new NotFoundException($e);
144
        }
145
146
        return new Channel($this->client, $response);
147
    }
148
149
    /**
150
     * Create a new channel (originate). The new channel is created immediately and a snapshot of it
151
     * returned. If a Stasis application is provided it will be automatically subscribed to the originated
152
     * channel for further events and updates.
153
     *
154
     * @param string $endpoint (required) Endpoint to call.
155
     * @param string $extension The extension to dial after the endpoint answers
156
     * @param string $context The context to dial after the endpoint answers. If omitted, uses 'default'
157
     * @param int $priority The priority to dial after the endpoint answers. If omitted, uses 1
158
     * @param string $label Asterisk 13+ The label to dial after the endpoint answers. Will supersede 'priority' if provided. Mutually exclusive with 'app'.
159
     * @param string $app The application that is subscribed to the originated channel, and passed to the Stasis application.
160
     * @param string $appArgs The application arguments to pass to the Stasis application.
161
     * @param string $callerId CallerID to use when dialing the endpoint or extension.
162
     * @param int $timeout (default 30) Timeout (in seconds) before giving up dialing, or -1 for no timeout.
163
     * @param string $channelId The unique id to assign the channel on creation.
164
     * @param string $otherChannelId The unique id to assign the second channel when using local channels.
165
     * @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" } }
166
     * @return Channel
167
     * @throws InvalidParameterException
168
     * @throws ServerException
169
     */
170 View Code Duplication
    public function createChannelWithId(
171
        $endpoint,
172
        $extension = null,
173
        $context = null,
174
        $priority = null,
175
        $label = null,
176
        $app = null,
177
        $appArgs = null,
178
        $callerId = null,
179
        $timeout = null,
180
        $channelId = null,
181
        $otherChannelId = null,
182
        $variables = array()
183
    ) {
184
        $uri = "/channels/$channelId";
185
        try {
186
            $response = $this->client->getEndpoint()->post($uri, array(
187
                'endpoint' => $endpoint,
188
                'extension' => $extension,
189
                'context' => $context,
190
                'priority' => $priority,
191
                'label' => $label,
192
                'app' => $app,
193
                'appArgs' => $appArgs,
194
                'callerId' => $callerId,
195
                'timeout' => $timeout,
196
                'otherChannelId' => $otherChannelId,
197
                'variables' => array_map('strval', $variables),
198
            ));
199
        } catch (Pest_BadRequest $e) { // Invalid parameters for originating a channel.
200
            throw new InvalidParameterException($e);
201
        } catch (Pest_ServerError $e) {
202
            throw new ServerException($e); // Couldn't create the channel.
203
        }
204
205
        return new Channel($this->client, $response);
206
    }
207
208
    /**
209
     * Delete (i.e. hangup) a channel.
210
     *
211 37
     * @param string $channelId Channel's id
212
     * @throws NotFoundException
213 37
     */
214 View Code Duplication
    public function deleteChannel($channelId)
0 ignored issues
show
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...
215 37
    {
216 37
        $uri = "/channels/$channelId";
217 37
        try {
218
            $this->client->getEndpoint()->delete($uri);
219 37
        } catch (Pest_NotFound $e) {
220
            throw new NotFoundException($e);
221
        }
222
    }
223
224
    /**
225
     * Hangup a channel if it still exists.
226 37
     *
227
     * @param string $channelId Channel's id
228
     */
229 37
    public function hangup($channelId)
230 37
    {
231
        try {
232
            $this->deleteChannel($channelId);
233 37
        } catch (\Exception $ignore) {
234
            // Don't throw exception if the channel doesn't exist
235
        }
236
    }
237
238
    /**
239
     * Exit application; continue execution in the dialplan.
240
     *
241
     * @param string $channelId Channel's id
242
     * @param string $context The context to continue to.
243
     * @param string $extension The extension to continue to.
244
     * @param int $priority The priority to continue to.
245
     * @throws NotFoundException
246
     * @throws ConflictException
247
     */
248
    public function continueDialplan($channelId, $context, $extension, $priority)
249
    {
250
        $uri = "/channels/$channelId/continue";
251
        try {
252
            $this->client->getEndpoint()->post($uri, array(
253
                'context' => $context,
254
                'extension' => $extension,
255
                'priority' => $priority,
256
            ));
257
        } catch (Pest_NotFound $e) {
258
            throw new NotFoundException($e);
259
        } catch (Pest_Conflict $e) {
260
            throw new ConflictException($e);
261
        }
262
    }
263
264
    /**
265
     * Answer a channel.
266
     *
267
     * @param string $channelId Channel's id
268 37
     * @throws NotFoundException
269
     * @throws ConflictException
270 37
     */
271 View Code Duplication
    public function answer($channelId)
0 ignored issues
show
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...
272 37
    {
273 37
        $uri = "/channels/$channelId/answer";
274
        try {
275
            $this->client->getEndpoint()->post($uri, array());
276
        } catch (Pest_NotFound $e) {
277
            throw new NotFoundException($e);
278 37
        } catch (Pest_Conflict $e) {
279
            throw new ConflictException($e);
280
        }
281
    }
282
283
    /**
284
     * Indicate ringing to a channel.
285
     *
286
     * @param string $channelId
287
     * @throws NotFoundException
288
     * @throws ConflictException
289
     */
290 View Code Duplication
    public function startRinging($channelId)
0 ignored issues
show
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...
291
    {
292
        $uri = "/channels/$channelId/ring";
293
        try {
294
            $this->client->getEndpoint()->post($uri, array());
295
        } catch (Pest_NotFound $e) {
296
            throw new NotFoundException($e);
297
        } catch (Pest_Conflict $e) {
298
            throw new ConflictException($e);
299
        }
300
    }
301
302
    /**
303
     * Stop ringing indication on a channel if locally generated.
304
     *
305
     * @param string $channelId
306
     * @throws NotFoundException
307
     * @throws ConflictException
308
     */
309 View Code Duplication
    public function stopRinging($channelId)
0 ignored issues
show
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...
310
    {
311
        $uri = "/channels/$channelId/ring";
312
        try {
313
            $this->client->getEndpoint()->delete($uri);
314
        } catch (Pest_NotFound $e) {
315
            throw new NotFoundException($e);
316
        } catch (Pest_Conflict $e) {
317
            throw new ConflictException($e);
318
        }
319
    }
320
321
    /**
322
     * Send provided DTMF to a given channel.
323
     *
324
     * @param string $channelId
325
     * @param string $dtmf DTMF To send.
326
     * @param int $before Amount of time to wait before DTMF digits (specified in milliseconds) start.
327
     * @param int $between Amount of time in between DTMF digits (specified in milliseconds).  Default: 100
328
     * @param int $duration Length of each DTMF digit (specified in milliseconds).  Default: 100
329
     * @param int $after Amount of time to wait after DTMF digits (specified in milliseconds) end.
330
     * @throws InvalidParameterException
331
     * @throws NotFoundException
332
     * @throws ConflictException
333
     */
334
    public function sendDtmf($channelId, $dtmf, $before = null, $between = null, $duration = null, $after = null)
335
    {
336
        $uri = "/channels/$channelId/dtmf";
337
        try {
338
            $this->client->getEndpoint()->post($uri, array(
339
                'dtmf' => $dtmf,
340
                'before' => $before,
341
                'between' => $between,
342
                'duration' => $duration,
343
                'after' => $after,
344
            ));
345
        } catch (Pest_BadRequest $e) {
346
            throw new InvalidParameterException($e);
347
        } catch (Pest_NotFound $e) {
348
            throw new NotFoundException($e);
349
        } catch (Pest_Conflict $e) {
350
            throw new ConflictException($e);
351
        }
352
    }
353
354
    /**
355
     * Mute a channel.
356
     *
357
     * @param string $channelId Channel's id
358
     * @param string $direction (default both) Direction in which to mute audio.  Allowed values: both, in, out
359
     * @throws NotFoundException
360
     * @throws ConflictException
361
     */
362
    public function mute($channelId, $direction)
363
    {
364
        $uri = "/channels/$channelId/mute";
365
        try {
366
            $this->client->getEndpoint()->post($uri, array(
367
                'direction' => $direction,
368
            ));
369
        } catch (Pest_NotFound $e) {
370
            throw new NotFoundException($e);
371
        } catch (Pest_Conflict $e) {
372
            throw new ConflictException($e);
373
        }
374
    }
375
376
    /**
377
     * Unmute a channel.
378
     *
379
     * @param string $channelId Channel's id
380
     * @param string $direction (default both) Direction in which to unmute audio
381
     * @throws NotFoundException
382
     * @throws ConflictException
383
     */
384 View Code Duplication
    public function unmute($channelId, $direction)
385
    {
386
        $uri = "/channels/$channelId/mute?direction=".$this->client->getEndpoint()->jsonEncode($direction);
387
        try {
388
            $this->client->getEndpoint()->delete($uri);
389
        } catch (Pest_NotFound $e) {
390
            throw new NotFoundException($e);
391
        } catch (Pest_Conflict $e) {
392
            throw new ConflictException($e);
393
        }
394
    }
395
396
    /**
397
     * Hold a channel.
398
     *
399
     * @param string $channelId Channel's id
400
     * @throws NotFoundException
401
     * @throws ConflictException
402
     */
403 View Code Duplication
    public function hold($channelId)
0 ignored issues
show
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...
404
    {
405
        $uri = "/channels/$channelId/hold";
406
        try {
407
            $this->client->getEndpoint()->post($uri, array());
408
        } catch (Pest_NotFound $e) {
409
            throw new NotFoundException($e);
410
        } catch (Pest_Conflict $e) {
411
            throw new ConflictException($e);
412
        }
413
    }
414
415
    /**
416
     * Remove a channel from hold.
417
     *
418
     * @param string $channelId Channel's id
419
     * @throws NotFoundException
420
     * @throws ConflictException
421
     */
422 View Code Duplication
    public function unhold($channelId)
0 ignored issues
show
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...
423
    {
424
        $uri = "/channels/$channelId/hold";
425
        try {
426
            $this->client->getEndpoint()->delete($uri);
427
        } catch (Pest_NotFound $e) {
428
            throw new NotFoundException($e);
429
        } catch (Pest_Conflict $e) {
430
            throw new ConflictException($e);
431
        }
432
    }
433
434
    /**
435
     * 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.
436
     *
437
     * @param string $channelId Channel's id
438
     * @throws NotFoundException
439
     * @throws ConflictException
440
     */
441 View Code Duplication
    public function startSilence($channelId)
0 ignored issues
show
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...
442
    {
443
        $uri = "/channels/$channelId/silence";
444
        try {
445
            $this->client->getEndpoint()->post($uri, array());
446
        } catch (Pest_NotFound $e) {
447
            throw new NotFoundException($e);
448
        } catch (Pest_Conflict $e) {
449
            throw new ConflictException($e);
450
        }
451
    }
452
453
    /**
454
     * Stop playing silence to a channel.
455
     *
456
     * @param string $channelId Channel's id
457
     * @throws NotFoundException
458
     * @throws ConflictException
459
     */
460 View Code Duplication
    public function stopSilence($channelId)
0 ignored issues
show
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...
461
    {
462
        $uri = "/channels/$channelId/silence";
463
        try {
464
            $this->client->getEndpoint()->delete($uri);
465
        } catch (Pest_NotFound $e) {
466
            throw new NotFoundException($e);
467
        } catch (Pest_Conflict $e) {
468
            throw new ConflictException($e);
469
        }
470
    }
471
472
    /**
473
     * Get the value of a channel variable or function.
474
     *
475
     * @param string $channelId
476
     * @param string $variable
477
     * @param null|string $default The value to return if the variable does not exist
478
     * @return string|Variable
479
     * @throws ConflictException
480
     * @throws InvalidParameterException
481
     * @throws NotFoundException
482
     */
483
    public function getVariable($channelId, $variable, $default = null)
484
    {
485
        $uri = "/channels/$channelId/variable";
486
        try {
487
            $response = $this->client->getEndpoint()->get($uri, array(
488
                'variable' => $variable,
489
            ));
490
        } catch (Pest_BadRequest $e) { // Missing variable parameter.
491
            throw new InvalidParameterException($e);
492
        } catch (Pest_NotFound $e) { // Variable not found
493
            if ($default !== null) {
494
                return $default;
495
            }
496
            throw new NotFoundException($e);
497
        } catch (Pest_Conflict $e) { // Channel not in a Stasis application
498
            throw new ConflictException($e);
499
        }
500
501
        return new Variable($response);
502
    }
503
504
    /**
505
     * Set the value of a channel variable or function.
506
     *
507
     * @param string $channelId
508
     * @param string $variable
509
     * @param string $value
510
     * @return Variable
511
     * @throws InvalidParameterException
512
     * @throws NotFoundException
513
     * @throws ConflictException
514
     */
515
    public function setVariable($channelId, $variable, $value)
516
    {
517
        $uri = "/channels/$channelId/variable";
518
        try {
519
            $response = $this->client->getEndpoint()->post($uri, array(
520
                'variable' => $variable,
521
                'value' => $value,
522
            ));
523
        } catch (Pest_BadRequest $e) { // Missing variable parameter.
524
            throw new InvalidParameterException($e);
525
        } catch (Pest_NotFound $e) { // Channel not found
526
            throw new NotFoundException($e);
527
        } catch (Pest_Conflict $e) { // Channel not in a Stasis application
528
            throw new ConflictException($e);
529
        }
530
531
        return new Variable($response);
532
    }
533
534
    /**
535
     * Start snooping. Snoop (spy/whisper) on a specific channel.
536
     *
537
     * @param string $channelId Channel's id
538
     * @param string $spy (default none) Direction of audio to spy on
539
     * @param string $whisper (default none) Direction of audio to whisper into
540
     * @param string $app (required) Application the snooping channel is placed into
541
     * @param string $appArgs The application arguments to pass to the Stasis application
542
     * @param string $snoopId Unique ID to assign to snooping channel
543
     * @return Channel
544
     * @throws InvalidParameterException
545
     * @throws NotFoundException
546
     */
547 View Code Duplication
    public function startSnoop($channelId, $spy, $whisper, $app, $appArgs, $snoopId)
548
    {
549
        $uri = "/channels/$channelId/snoop";
550
        try {
551
            $response = $this->client->getEndpoint()->post($uri, array(
552
                'spy' => $spy,
553
                'whisper' => $whisper,
554
                'app' => $app,
555
                'appArgs' => $appArgs,
556
                'snoopId' => $snoopId,
557
            ));
558
        } catch (Pest_BadRequest $e) { // Missing parameters
559
            throw new InvalidParameterException($e);
560
        } catch (Pest_NotFound $e) { // Channel not found
561
            throw new NotFoundException($e);
562
        }
563
564
        return new Channel($this->client, $response);
565
    }
566
567
    /**
568
     * Start snooping. Snoop (spy/whisper) on a specific channel.
569
     *
570
     * @param string $channelId Channel's id
571
     * @param string $spy (default none) Direction of audio to spy on
572
     * @param string $whisper (default none) Direction of audio to whisper into
573
     * @param string $app (required) Application the snooping channel is placed into
574
     * @param string $appArgs The application arguments to pass to the Stasis application
575
     * @param string $snoopId Unique ID to assign to snooping channel
576
     * @return Channel
577
     * @throws InvalidParameterException
578
     * @throws NotFoundException
579
     */
580 View Code Duplication
    public function startSnoopWithId($channelId, $spy, $whisper, $app, $appArgs, $snoopId)
581
    {
582
        $uri = "/channels/$channelId/snoop/$snoopId";
583
        try {
584
            $response = $this->client->getEndpoint()->post($uri, array(
585
                'spy' => $spy,
586
                'whisper' => $whisper,
587
                'app' => $app,
588
                'appArgs' => $appArgs,
589
            ));
590
        } catch (Pest_BadRequest $e) { // Missing parameters
591
            throw new InvalidParameterException($e);
592
        } catch (Pest_NotFound $e) { // Channel not found
593
            throw new NotFoundException($e);
594
        }
595
596
        return new Channel($this->client, $response);
597
    }
598
599 6
    /**
600
     * @return string
601 6
     */
602
    public function getType()
603
    {
604
        return 'channels';
605
    }
606
}
607