Passed
Push — develop ( 5a77ad...a33561 )
by Портнов
04:54
created

AGI::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 5
c 2
b 0
f 0
dl 0
loc 9
rs 10
cc 3
nc 4
nop 0
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright (C) 2017-2020 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
namespace MikoPBX\Core\Asterisk;
21
22
/**
23
 * AGI class
24
 *
25
 * @package phpAGI
26
 * @link    http://www.voip-info.org/wiki-Asterisk+agi
27
 * @example examples/dtmf.php Get DTMF tones from the user and say the digits
28
 * @example examples/input.php Get text input from the user and say it back
29
 * @example examples/ping.php Ping an IP address
30
 */
31
class AGI extends AGIBase
32
{
33
    /**
34
     * Sends $message to the Asterisk console via the 'verbose' message system.
35
     *
36
     * If the Asterisk verbosity level is $level or greater, send $message to the console.
37
     *
38
     * The Asterisk verbosity system works as follows. The Asterisk user gets to set the desired verbosity at startup
39
     * time or later using the console 'set verbose' command. Messages are displayed on the console if their verbose
40
     * level is less than or equal to desired verbosity set by the user. More important messages should have a low
41
     * verbose level; less important messages should have a high verbose level.
42
     *
43
     * @link http://www.voip-info.org/wiki-verbose
44
     *
45
     * @param string $message
46
     * @param int    $level from 1 to 4
47
     *
48
     * @return array, see evaluate for return information.
49
     */
50
    public function verbose($message, $level = 1)
51
    {
52
        $ret = ['code' => 500, 'result' => -1, 'data' => ''];
53
        foreach (explode("\n", str_replace("\r\n", "\n", print_r($message, true))) as $msg) {
54
            $ret = $this->evaluate("VERBOSE \"$msg\" $level");
55
        }
56
57
        return $ret;
58
    }
59
60
61
    /**
62
     * Answer channel if not already in answer state.
63
     *
64
     * @link    http://www.voip-info.org/wiki-answer
65
     * @example examples/dtmf.php Get DTMF tones from the user and say the digits
66
     * @example examples/input.php Get text input from the user and say it back
67
     * @example examples/ping.php Ping an IP address
68
     *
69
     * @return array, see evaluate for return information.  ['result'] is 0 on success, -1 on failure.
70
     */
71
    public function answer()
72
    {
73
        return $this->evaluate('ANSWER');
74
    }
75
76
    /**
77
     * Deletes an entry in the Asterisk database for a given family and key.
78
     *
79
     * @link http://www.voip-info.org/wiki-database+del
80
     *
81
     * @param string $family
82
     * @param string $key
83
     *
84
     * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
85
     */
86
    public function database_del($family, $key)
87
    {
88
        return $this->evaluate("DATABASE DEL \"$family\" \"$key\"");
89
    }
90
91
    /**
92
     * Deletes a family or specific keytree within a family in the Asterisk database.
93
     *
94
     * @link http://www.voip-info.org/wiki-database+deltree
95
     *
96
     * @param string $family
97
     * @param string $keytree
98
     *
99
     * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
100
     */
101
    public function database_deltree(string $family, string $keytree = '')
102
    {
103
        $cmd = "DATABASE DELTREE \"$family\"";
104
        if (!empty($keytree)) {
105
            $cmd .= " \"$keytree\"";
106
        }
107
108
        return $this->evaluate($cmd);
109
    }
110
111
    /**
112
     * Retrieves an entry in the Asterisk database for a given family and key.
113
     *
114
     * @link http://www.voip-info.org/wiki-database+get
115
     *
116
     * @param string $family
117
     * @param string $key
118
     *
119
     * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 failure. ['data'] holds the
120
     *                value
121
     */
122
    public function database_get($family, $key)
123
    {
124
        return $this->evaluate("DATABASE GET \"$family\" \"$key\"");
125
    }
126
127
    /**
128
     * Adds or updates an entry in the Asterisk database for a given family, key, and value.
129
     *
130
     * @param string $family
131
     * @param string $key
132
     * @param string $value
133
     *
134
     * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise
135
     */
136
    public function databasePut($family, $key, $value)
137
    {
138
        $value = str_replace("\n", '\n', addslashes($value));
139
140
        return $this->evaluate("DATABASE PUT \"$family\" \"$key\" \"$value\"");
141
    }
142
143
    /**
144
     * Sets a variable, using Asterisk 1.6 syntax.
145
     *
146
     * @link http://www.voip-info.org/wiki/view/Asterisk+cmd+Set
147
     *
148
     * @param string           $pVariable
149
     * @param string|int|float $pValue
150
     *
151
     * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise
152
     */
153
    public function set_var($pVariable, $pValue)
154
    {
155
        if (is_numeric($pValue)) {
156
            return $this->evaluate("Set({$pVariable}={$pValue});");
157
        } else {
158
            return $this->evaluate("Set({$pVariable}=\"{$pValue}\");");
159
        }
160
    }
161
162
    /**
163
     * Fetch the value of a variable.
164
     *
165
     * Does not work with global variables. Does not work with some variables that are generated by modules.
166
     *
167
     * @link http://www.voip-info.org/wiki-get+variable
168
     * @link http://www.voip-info.org/wiki-Asterisk+variables
169
     *
170
     * @param string $variable name
171
     * @param bool   $getvalue return the value only
172
     *
173
     * @return array | string, see evaluate for return information. ['result'] is 0 if variable hasn't been set, 1 if
174
     *               it has. ['data'] holds the value. returns value if $getvalue is TRUE
175
     */
176
    public function get_variable($variable, $getvalue = false)
177
    {
178
        $res = $this->evaluate("GET VARIABLE $variable");
179
        if ($getvalue === false) {
180
            return ($res);
181
        }
182
183
        return trim($res['data']);
184
    }
185
186
    /**
187
     * Hangup the specified channel. If no channel name is given, hang up the current channel.
188
     *
189
     * With power comes responsibility. Hanging up channels other than your own isn't something
190
     * that is done routinely. If you are not sure why you are doing so, then don't.
191
     *
192
     * @link    http://www.voip-info.org/wiki-hangup
193
     * @example examples/dtmf.php Get DTMF tones from the user and say the digits
194
     * @example examples/input.php Get text input from the user and say it back
195
     * @example examples/ping.php Ping an IP address
196
     *
197
     * @param string $channel
198
     *
199
     * @return array, see evaluate for return information. ['result'] is 1 on success, -1 on failure.
200
     */
201
    public function hangup($channel = '')
202
    {
203
        return $this->evaluate("HANGUP $channel");
204
    }
205
206
    /**
207
     * Does nothing.
208
     *
209
     * @link http://www.voip-info.org/wiki-noop
210
     *
211
     * @param string $string
212
     *
213
     * @return array, see evaluate for return information.
214
     */
215
    public function noop($string = "")
216
    {
217
        return $this->evaluate("NOOP \"$string\"");
218
    }
219
220
    /**
221
     * Send the specified image on a channel.
222
     *
223
     * Most channels do not support the transmission of images.
224
     *
225
     * @link http://www.voip-info.org/wiki-send+image
226
     *
227
     * @param string $image without extension, often in /var/lib/asterisk/images
228
     *
229
     * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the image is sent
230
     *                or channel does not support image transmission.
231
     */
232
    public function send_image($image)
233
    {
234
        return $this->evaluate("SEND IMAGE $image");
235
    }
236
237
    /**
238
     * Send the given text to the connected channel.
239
     *
240
     * Most channels do not support transmission of text.
241
     *
242
     * @link http://www.voip-info.org/wiki-send+text
243
     *
244
     * @param $text
245
     *
246
     * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the text is sent or
247
     * channel does not support text transmission.
248
     */
249
    public function send_text($text)
250
    {
251
        return $this->evaluate("SEND TEXT \"$text\"");
252
    }
253
254
    /**
255
     * Cause the channel to automatically hangup at $time seconds in the future.
256
     * If $time is 0 then the autohangup feature is disabled on this channel.
257
     *
258
     * If the channel is hungup prior to $time seconds, this setting has no effect.
259
     *
260
     * @link http://www.voip-info.org/wiki-set+autohangup
261
     *
262
     * @param int $time until automatic hangup
263
     *
264
     * @return array, see evaluate for return information.
265
     */
266
    public function set_autohangup($time = 0)
267
    {
268
        return $this->evaluate("SET AUTOHANGUP $time");
269
    }
270
271
    /**
272
     * Changes the caller ID of the current channel.
273
     *
274
     * @link http://www.voip-info.org/wiki-set+callerid
275
     *
276
     * @param string $cid example: "John Smith"<1234567>
277
     *                    This command will let you take liberties with the <caller ID specification> but the format
278
     *                    shown in the example above works well: the name enclosed in double quotes followed
279
     *                    immediately by the number inside angle brackets. If there is no name then you can omit it. If
280
     *                    the name contains no spaces you can omit the double quotes around it. The number must follow
281
     *                    the name immediately; don't put a space between them. The angle brackets around the number
282
     *                    are necessary; if you omit them the number will be considered to be part of the name.
283
     *
284
     * @return array, see evaluate for return information.
285
     */
286
    public function set_callerid($cid)
287
    {
288
        return $this->evaluate("SET CALLERID $cid");
289
    }
290
291
    /**
292
     * Enable/Disable Music on hold generator.
293
     *
294
     * @link http://www.voip-info.org/wiki-set+music
295
     *
296
     * @param bool   $enabled
297
     * @param string $class
298
     *
299
     * @return array, see evaluate for return information.
300
     */
301
    public function set_music($enabled = true, $class = '')
302
    {
303
        $enabled = ($enabled) ? 'ON' : 'OFF';
304
305
        return $this->evaluate("SET MUSIC $enabled $class");
306
    }
307
308
    /**
309
     * Sets a variable to the specified value. The variables so created can later be used by later using
310
     * ${<variablename>} in the dialplan.
311
     *
312
     * These variables live in the channel Asterisk creates when you pickup a phone and as such they are both local and
313
     * temporary. Variables created in one channel can not be accessed by another channel. When you hang up the phone,
314
     * the channel is deleted and any variables in that channel are deleted as well.
315
     *
316
     * @link http://www.voip-info.org/wiki-set+variable
317
     *
318
     * @param string $variable is case sensitive
319
     * @param string $value
320
     *
321
     * @return array, see evaluate for return information.
322
     */
323
    public function set_variable($variable, $value)
324
    {
325
        $value = str_replace("\n", '\n', addslashes($value));
326
327
        return $this->evaluate("SET VARIABLE $variable \"$value\"");
328
    }
329
330
    /**
331
     * Set absolute maximum time of call.
332
     *
333
     * Note that the timeout is set from the current time forward, not counting the number of seconds the call has
334
     * already been up. Each time you call AbsoluteTimeout(), all previous absolute timeouts are cancelled. Will return
335
     * the call to the T extension so that you can playback an explanatory note to the calling party (the called party
336
     * will not hear that)
337
     *
338
     * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
339
     * @link http://www.dynx.net/ASTERISK/AGI/ccard/agi-ccard.agi
340
     *
341
     * @param $seconds
342
     * allowed, 0 disables timeout
343
     *
344
     * @return array, see evaluate for return information.
345
     */
346
    public function exec_absolutetimeout($seconds = 0)
347
    {
348
        return $this->exec('AbsoluteTimeout', $seconds);
349
    }
350
351
    /**
352
     * Executes the specified Asterisk application with given options.
353
     *
354
     * @link http://www.voip-info.org/wiki-exec
355
     * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
356
     *
357
     * @param string $application
358
     * @param mixed  $options
359
     *
360
     * @return array, see evaluate for return information. ['result'] is whatever the application returns, or -2 on
361
     *                failure to find application
362
     */
363
    public function exec($application, $options)
364
    {
365
        if (is_array($options)) {
366
            $options = join(',', $options);
367
        }
368
369
        return $this->evaluate("EXEC $application $options");
370
    }
371
372
    /**
373
     * Dial.
374
     *
375
     * Dial takes input from ${VXML_URL} to send XML Url to Cisco 7960
376
     * Dial takes input from ${ALERT_INFO} to set ring cadence for Cisco phones
377
     * Dial returns ${CAUSECODE}: If the dial failed, this is the errormessage.
378
     * Dial returns ${DIALSTATUS}: Text code returning status of last dial attempt.
379
     *
380
     * @link http://www.voip-info.org/wiki-Asterisk+cmd+Dial
381
     *
382
     * @param string $type
383
     * @param string $identifier
384
     * @param int    $timeout
385
     * @param string $options
386
     * @param string $url
387
     *
388
     * @return array, see evaluate for return information.
389
     */
390
    public function exec_dial($type, $identifier, $timeout = null, $options = null, $url = null)
391
    {
392
        return $this->exec(
393
            'Dial',
394
            trim(
395
                "$type/$identifier" . $this->option_delim . $timeout . $this->option_delim . $options . $this->option_delim . $url,
396
                $this->option_delim
397
            )
398
        );
399
    }
400
401
    /**
402
     * Goto.
403
     *
404
     * This function takes three arguments: context,extension, and priority, but the leading arguments
405
     * are optional, not the trailing arguments.  Thuse goto($z) sets the priority to $z.
406
     *
407
     * @param string $a
408
     * @param string $b ;
409
     * @param string $c ;
410
     *
411
     * @return array, see evaluate for return information.
412
     */
413
    public function exec_goto($a, $b = null, $c = null)
414
    {
415
        return $this->exec('Goto', trim($a . $this->option_delim . $b . $this->option_delim . $c, $this->option_delim));
416
    }
417
418
419
    // *********************************************************************************************************
420
    // **                             APPLICATIONS                                                                                        **
421
    // *********************************************************************************************************
422
423
    /**
424
     * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the
425
     * GET DATA command but this command returns after the first DTMF digit has been pressed while GET DATA can
426
     * accumulated any number of digits before returning.
427
     *
428
     * @param string $filename without extension, often in /var/lib/asterisk/sounds
429
     * @param string $escape_digits
430
     * @param int    $offset
431
     *
432
     * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes
433
     *                with no digit received, otherwise a decimal value of the DTMF tone.  Use chr() to convert to
434
     *                ASCII.
435
     * @example examples/ping.php Ping an IP address
436
     *
437
     * @link    http://www.voip-info.org/wiki-stream+file
438
     */
439
    public function stream_file($filename, $escape_digits = '', $offset = 0)
440
    {
441
        return $this->evaluate("STREAM FILE $filename \"$escape_digits\" $offset");
442
    }
443
444
    // *********************************************************************************************************
445
    // **                             DERIVED                                                                                             **
446
    // *********************************************************************************************************
447
448
    /**
449
     * Plays the given file and receives DTMF data.
450
     *
451
     * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
452
     * while STREAM FILE returns immediately after the first DTMF digit is detected.
453
     *
454
     * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
455
     *
456
     * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
457
     * of silence then the command ends.
458
     *
459
     * The user has the opportunity to press a key at any time during the message or the
460
     * post-message silence. If the user presses a key while the message is playing, the
461
     * message stops playing. When the first key is pressed a timer starts counting for
462
     * $timeout milliseconds. Every time the user presses another key the timer is restarted.
463
     * The command ends when the counter goes to zero or the maximum number of digits is entered,
464
     * whichever happens first.
465
     *
466
     * If you don't specify a time out then a default timeout of 2000 is used following a pressed
467
     * digit. If no digits are pressed then 6 seconds of silence follow the message.
468
     *
469
     * If you don't specify $max_digits then the user can enter as many digits as they want.
470
     *
471
     * Pressing the # key has the same effect as the timer running out: the command ends and
472
     * any previously keyed digits are returned. A side effect of this is that there is no
473
     * way to read a # key using this command.
474
     *
475
     * @param string $filename file to play. Do not include file extension.
476
     * @param ?int    $timeout  milliseconds
477
     * @param ?int    $max_digits
478
     *
479
     * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout
480
     *                if present.
481
     *
482
     * This differs from other commands with return DTMF as numbers representing ASCII characters.
483
     * @example examples/ping.php Ping an IP address
484
     *
485
     * @link    http://www.voip-info.org/wiki-get+data
486
     */
487
    public function getData($filename, $timeout = null, $max_digits = null)
488
    {
489
        return $this->evaluate(rtrim("GET DATA $filename $timeout $max_digits"));
490
    }
491
492
    /**
493
     * Waits up to $timeout milliseconds for channel to receive a DTMF digit.
494
     *
495
     * @link http://www.voip-info.org/wiki-wait+for+digit
496
     *
497
     * @param int $timeout in millisecons. Use -1 for the timeout value if you want the call to wait indefinitely.
498
     *
499
     * @return array, see evaluate for return information. ['result'] is 0 if wait completes with no
500
     * digit received, otherwise a decimal value of the DTMF tone.  Use chr() to convert to ASCII.
501
     */
502
    public function wait_for_digit($timeout = -1)
503
    {
504
        return $this->evaluate("WAIT FOR DIGIT $timeout");
505
    }
506
}
507