Open Source Training Seminar FreePBX Paid Support

root/freepbx/trunk/amp_conf/htdocs/admin/extensions.class.php

Revision 6314, 26.7 kB (checked in by p_lindheimer, 3 weeks ago)

closes #2992 move include for globals to end of auto-generated globals to allow an auto-generated global to be overridden if desired

  • Property svn:mime-type set to text/html
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2
3 class extensions {
4         /** The config
5          * array(section=>array(extension=>array( array('basetag'=>basetag,'tag'=>tag,'addpri'=>addpri,'cmd'=>cmd) )))
6          * ( $_exts[$section][$extension][$priority] )
7          */
8         var $_exts;
9        
10         /** Hints
11          * special cases of priorities
12          */
13         var $_hints;
14        
15         var $_sorted;
16        
17         /** The filename to write this configuration to
18         */
19         function get_filename() {
20                 return "extensions_additional.conf";
21         }
22        
23         /** Add an entry to the extensions file
24         * @param $section    The section to be added to
25         * @param $extension  The extension used
26         * @param $tag        A tag to use (to reference with basetag), use false or '' if none
27         * @param $command    The command to execute
28         * @param $basetag    The tag to base this on. Only used in conjunction with $addpriority
29         *                    priority. Defaults to false.
30         * @param $addpriority  Finds the priority of the tag called $basetag, and adds this
31         *                       value to it to use as the priority for this command.
32         * @return
33         */
34         function add($section, $extension, $tag, $command, $basetag = false, $addpriority = false) {
35                
36                 if ($basetag || $addpriority) {
37                         if (!is_int($addpriority) || ($addpriority < 1)) {
38                                 trigger_error("\$addpriority must be an integer >= 1 in extensions::add()");
39                                 return false;
40                         }
41                         if (empty($basetag)) {
42                                 trigger_error("\$basetag is required with \$addpriority in extensions::add()");
43                                 return false;
44                         }
45                 }
46                
47                 if (empty($basetag)) {
48                         // no basetag, we need to make one
49                        
50                         if (!isset($this->_exts[$section][$extension])) {
51                                 // first entry, use 1
52                                 $basetag = '1';
53                         } else {
54                                 // anything else just n
55                                 $basetag = 'n';
56                         }
57                 }
58                
59                 $new = array(
60                         'basetag' => $basetag,
61                         'tag' => $tag,
62                         'addpri' => $addpriority,
63                         'cmd' => $command,
64                 );
65                
66                 $this->_exts[$section][$extension][] = $new;
67         }
68        
69         /** Sort sections, extensions and priorities alphabetically
70          */
71         function sort() {
72                 foreach (array_keys($this->_exts) as $section) {
73                         foreach (array_keys($this->_exts[$section]) as $extension) {
74                                 // sort priorities
75                                 ksort($this->_exts[$section][$extension]);
76                         }
77                         // sort extensions
78                         ksort($this->_exts[$section]);
79                 }
80                 // sort sections
81                 ksort($this->_exts);
82                
83                 $this->_sorted = true;
84         }
85        
86         function addHint($section, $extension, $hintvalue) {
87                 $this->_hints[$section][$extension][] = $hintvalue;
88         }
89        
90         function addGlobal($globvar, $globval) {
91                 $this->_globals[$globvar] = $globval;
92         }
93        
94         function addInclude($section, $incsection) {
95                 $this->_includes[$section][] = $incsection;
96         }
97
98         function addSwitch($section, $incsection) {
99                 $this->_switches[$section][] = $incsection;
100         }
101
102         function addExec($section, $incsection) {
103                 $this->_exec[$section][] = $incsection;
104         }
105        
106         /* This function allows new priorities to be injected into already generated dialplan
107         *  usage: $ext->splice($context, $exten, $priority_number, new ext_goto('1','s','ext-did'));
108         *         if $priority is not numeric, it will interpret it as a tag and try to inject
109         *         the command just prior to  the first instruction it finds with the specified tag
110         *         if it can't find the tag, it will inject it after the last instruction
111         */
112         function splice($section, $extension, $priority, $command) {
113
114                 // if the priority is a tag, then we look for the real priority to insert it before that
115                 // tag. If the tag does not exists, then we put it at the very end which may not be
116                 // desired but it puts it somewhere
117                 //
118                 if (!ctype_digit(trim($priority))) {
119                         $new_priority = false;
120                         $count = 0;
121                         if (isset($this->_exts[$section][$extension])) {
122                                 foreach($this->_exts[$section][$extension] as $pri => $curr_command) {
123                                         if ($curr_command['tag'] == $priority) {
124                                                 $new_priority = $count;
125                                                 break;
126                                         }
127                                         $count++;
128                                 }
129                         }
130                         $priority = ($new_priority === false) ? $count : $new_priority;
131                 }
132                 if($priority == 0) {
133                         $basetag = '1';
134                         // we'll be defining a new pri "1", so change existing "1" to "n"
135                         $this->_exts[$section][$extension][0]['basetag'] = 'n';
136                 } else {
137                         $basetag = 'n';
138                 }
139                 $newcommand = array(
140                         'basetag' => $basetag,
141                         'tag' => '',
142                         'addpri' => '',
143                         'cmd' => $command
144                 );
145
146                 /* This little routine from http://ca.php.net/array_splice overcomes
147                 *  problems that array_splice has with multidmentional arrays
148                 */
149                 $array = isset($this->_exts[$section][$extension]) ? $this->_exts[$section][$extension] : array();
150                 $ky = $priority;
151                 $val = $newcommand;
152                 $n = $ky;
153                 foreach($array as $key => $value) {
154                         $backup_array[$key] = $array[$key];
155                 }
156                 $upper_limit = count($array);
157                 while($n <= $upper_limit) {
158                         if($n == $ky) {
159                                 $array[$n] = $val;
160                                 // echo $n;
161                         } else {
162                                 $i = $n - "1";
163                                 $array[$n] = $backup_array[$i];
164                         }
165                         $n++;
166                 }
167
168                 // apply our newly modified array
169                 //echo "Splicing [$section] $extension\n";
170                 $this->_exts[$section][$extension] = $array;           
171
172                 //print_r($this->_exts[$section][$extension]);
173         }
174        
175         /** Generate the file
176         * @return A string containing the extensions.conf file
177         */
178         function generateConf() {
179                 $output = "";
180                
181                 /* sorting is not necessary anymore
182                 if (!$this->_sorted) {
183                         $this->sort();
184                 }
185                 */
186                
187                 //var_dump($this->_exts);
188                
189                 //take care of globals first
190                 if(isset($this->_globals) && is_array($this->_globals)){
191                         $output .= "[globals]\n";
192                         foreach (array_keys($this->_globals) as $global) {
193                                 $output .= $global." = ".$this->_globals[$global]."\n";
194                         }
195                         $output .= "#include globals_custom.conf\n";
196                         $output .= "\n;end of [globals]\n\n";
197                 }
198                
199                 //now the rest of the contexts
200                 if(is_array($this->_exts)){
201                         foreach (array_keys($this->_exts) as $section) {
202                                 $output .= "[".$section."]\n";
203                                
204                                 //automatically include a -custom context
205                                 $output .= "include => {$section}-custom\n";
206                                 //add requested includes for this context
207                                 if (isset($this->_includes[$section])) {
208                                         foreach ($this->_includes[$section] as $include) {
209                                                 $output .= "include => ".$include."\n";
210                                         }
211                                 }
212                                 if (isset($this->_switches[$section])) {
213                                         foreach ($this->_switches[$section] as $include) {
214                                                 $output .= "switch => ".$include."\n";
215                                         }
216                                 }
217
218                                 //add requested #exec scripts for this context
219                                 if (isset($this->_exec[$section])) {
220                                         foreach ($this->_exec[$section] as $include) {
221                                                 $output .= "#exec ".$include."\n";
222                                         }
223                                 }
224                                
225                                 foreach (array_keys($this->_exts[$section]) as $extension) {
226                                         foreach (array_keys($this->_exts[$section][$extension]) as $idx) {
227                                        
228                                                 $ext = $this->_exts[$section][$extension][$idx];
229                                                
230                                                 //echo "[$section] $extension $idx\n";
231                                                 //var_dump($ext);
232                                                        
233                                                 $output .= "exten => ".$extension.",".
234                                                         $ext['basetag'].
235                                                         ($ext['addpri'] ? '+'.$ext['addpri'] : '').
236                                                         ($ext['tag'] ? '('.$ext['tag'].')' : '').
237                                                         ",".$ext['cmd']->output()."\n";
238                                         }
239                                         if (isset($this->_hints[$section][$extension])) {
240                                                 foreach ($this->_hints[$section][$extension] as $hint) {
241                                                         $output .= "exten => ".$extension.",hint,".$hint."\n";
242                                                 }
243                                         }
244                                 }
245                                
246                                 $output .= "\n; end of [".$section."]\n\n\n";
247                         }
248                 }
249                
250                 return $output;
251         }
252
253         /** Generate the file
254         * @return A string containing the extensions.conf file
255         */
256         function generateOldConf() {
257                 $output = "";
258                
259                 /* sorting is not necessary anymore
260                 if (!$this->_sorted) {
261                         $this->sort();
262                 }
263                 */
264                
265                 var_dump($this->_exts);
266                
267                 foreach (array_keys($this->_exts) as $section) {
268                         $output .= "[".$section."]\n";
269                        
270                         foreach (array_keys($this->_exts[$section]) as $extension) {
271                                 $priority = 0;
272                                 $prioritytable = array();
273                                
274                                 foreach (array_keys($this->_exts[$section][$extension]) as $idx) {
275                                
276                                         $ext = $this->_exts[$section][$extension][$idx];
277                                        
278                                         //var_dump($ext);
279                                         switch ($ext['basetag']) {
280                                                 case '1': $priority = 1; break;
281                                                 case 'n': $priority += 1; break;
282                                                 default:
283                                                         if (isset($prioritytable[$ext['basetag']])) {
284                                                                 $priority = $prioritytable[$ext['basetag']];
285                                                         } else {
286                                                                 $priority = 'unknown!!!';
287                                                         }
288                                                 break;
289                                         }
290                                        
291                                         if ($ext['addpri']) {
292                                                 $priority += $ext['addpri'];
293                                         }
294                                        
295                                         if ($ext['tag']) {
296                                                 $prioritytable[$ext['tag']] = $priority;
297                                         }
298                                        
299                                         $output .= "exten => ".$extension.",".$priority.
300                                                 ",".$ext['cmd']->output()."\n";
301                                        
302                                 }
303                                
304                                 if (isset($this->_hints[$section][$extension])) {
305                                         foreach ($this->_hints[$section][$extension] as $hint) {
306                                                 $output .= "exten => ".$extension.",hint,".$hint;
307                                         }
308                                 }
309                         }
310                        
311                         $output .= "\n; end of [".$section."]\n\n\n";
312                 }
313                
314                 return $output;
315         }
316
317         /** Checks if a value used for a goto is empty
318          * Basically the same as php's empty() function, except considers 0 to be
319          * non-empty.
320          *
321          * This function can be called statically
322          */
323         function gotoEmpty($value) {
324                 return ($value === "" || $value === null || $value === false);
325         }
326 }
327
328 class extension {
329         var $data;
330        
331         function extension($data = '') {
332                 $this->data = $data;
333         }
334        
335         function incrementContents($value) {
336                 return true;
337         }
338        
339         function output() {
340                 return $this->data;
341         }
342 }
343
344 class ext_gosub extends extension {
345         var $pri;
346         var $ext;
347         var $context;
348        
349         function ext_gosub($pri, $ext = false, $context = false) {
350                 if ($context !== false && $ext === false) {
351                         trigger_error("\$ext is required when passing \$context in ext_gosub::ext_gosub()");
352                 }
353                
354                 $this->pri = $pri;
355                 $this->ext = $ext;
356                 $this->context = $context;
357         }
358        
359         function incrementContents($value) {
360                 $this->pri += $value;
361         }
362        
363         function output() {
364                 return 'Gosub('.($this->context ? $this->context.',' : '').($this->ext ? $this->ext.',' : '').$this->pri.')' ;
365         }
366 }
367
368 class ext_return extends extension {
369         function output() {
370                 return "Return()";
371         }
372 }
373
374 class ext_gosubif extends extension {
375         var $true_priority;
376         var $false_priority;
377         var $condition;
378         function ext_gosubif($condition, $true_priority, $false_priority = false) {
379                 $this->true_priority = $true_priority;
380                 $this->false_priority = $false_priority;
381                 $this->condition = $condition;
382         }
383         function output() {
384                 return 'GosubIf(' .$this->condition. '?' .$this->true_priority.($this->false_priority ? ':' .$this->false_priority : '' ). ')' ;
385         }
386         function incrementContents($value) {
387                 $this->true_priority += $value;
388                 $this->false_priority += $value;
389         }
390 }
391
392 class ext_goto extends extension {
393         var $pri;
394         var $ext;
395         var $context;
396        
397         function ext_goto($pri, $ext = false, $context = false) {
398                 if ($context !== false && $ext === false) {
399                         trigger_error("\$ext is required when passing \$context in ext_goto::ext_goto()");
400                 }
401                
402                 $this->pri = $pri;
403                 $this->ext = $ext;
404                 $this->context = $context;
405         }
406        
407         function incrementContents($value) {
408                 $this->pri += $value;
409         }
410        
411         function output() {
412                 return 'Goto('.(!extensions::gotoEmpty($this->context) ? $this->context.',' : '').(!extensions::gotoEmpty($this->ext) ? $this->ext.',' : '').$this->pri.')' ;
413         }
414 }
415
416 class ext_gotoif extends extension {
417         var $true_priority;
418         var $false_priority;
419         var $condition;
420         function ext_gotoif($condition, $true_priority, $false_priority = false) {
421                 $this->true_priority = $true_priority;
422                 $this->false_priority = $false_priority;
423                 $this->condition = $condition;
424         }
425         function output() {
426                 return 'GotoIf(' .$this->condition. '?' .$this->true_priority.($this->false_priority ? ':' .$this->false_priority : '' ). ')' ;
427         }
428         function incrementContents($value) {
429                 $this->true_priority += $value;
430                 $this->false_priority += $value;
431         }
432 }
433
434 class ext_gotoiftime extends extension {
435         var $true_priority;
436         var $condition;
437         function ext_gotoiftime($condition, $true_priority) {
438                 $this->true_priority = $true_priority;
439                 $this->condition = $condition;
440         }
441         function output() {
442                 return 'GotoIfTime(' .$this->condition. '?' .$this->true_priority. ')' ;
443         }
444         function incrementContents($value) {
445                 $this->true_priority += $value;
446         }
447 }
448
449 class ext_noop extends extension {
450         function output() {
451                 return "Noop(".$this->data.")";
452         }
453 }
454
455 class ext_dial extends extension {
456         var $number;
457         var $options;
458        
459         function ext_dial($number, $options = "tr") {
460                 $this->number = $number;
461                 $this->options = $options;
462         }
463        
464         function output() {
465                 return "Dial(".$this->number.",".$this->options.")";
466         }
467 }
468
469 class ext_setvar {
470         var $var;
471         var $value;
472        
473         function ext_setvar($var, $value) {
474                 $this->var = $var;
475                 $this->value = $value;
476         }
477        
478         function output() {
479                 return "Set(".$this->var."=".$this->value.")";
480         }
481 }
482 class ext_set extends ext_setvar {} // alias, SetVar was renamed to Set in ast 1.2
483
484 class ext_setglobalvar {
485         var $var;
486         var $value;
487        
488         function ext_setglobalvar($var, $value) {
489                 $this->var = $var;
490                 $this->value = $value;
491         }
492        
493         function output() {
494                 return "Set(".$this->var."=".$this->value.",g)";
495         }
496 }
497
498 class ext_sipaddheader {
499         var $header;
500         var $value;
501        
502         function ext_sipaddheader($header, $value) {
503                 $this->header = $header;
504                 $this->value = $value;
505         }
506        
507         function output() {
508                 return "SIPAddHeader(".$this->header.": ".$this->value.")";
509         }
510 }
511
512 class ext_sipgetheader {
513         var $header;
514         var $value;
515        
516         function ext_sipgetheader($value, $header) {
517                 $this->value = $value;
518                 $this->header = $header;
519         }
520        
521         function output() {
522                 return "SIPGetHeader(".$this->value."=".$this->header.")";
523         }
524 }
525
526 class ext_alertinfo {
527         var $value;
528        
529         function ext_alertinfo($value) {
530                 $this->value = $value;
531         }
532        
533         function output() {
534                 return "SIPAddHeader(Alert-Info: ".$this->value.")";
535         }
536 }
537
538 class ext_wait extends extension {
539         function output() {
540                 return "Wait(".$this->data.")";
541         }
542 }
543
544 class ext_parkedcall extends extension {
545         function output() {
546                 return "ParkedCall(".$this->data.")";
547         }
548 }
549
550
551 class ext_resetcdr extends extension {
552         function output() {
553                 return "ResetCDR(".$this->data.")";
554         }
555 }
556
557 class ext_nocdr extends extension {
558         function output() {
559                 return "NoCDR()";
560         }
561 }
562
563 class ext_forkcdr extends extension {
564         function output() {
565                 return "ForkCDR()";
566         }
567 }
568
569 class ext_waitexten extends extension {
570         var $seconds;
571         var $options;
572        
573         function ext_waitexten($seconds = "", $options = "") {
574                 $this->seconds = $seconds;
575                 $this->options = $options;
576         }
577        
578         function output() {
579                 return "WaitExten(".$this->seconds.",".$this->options.")";
580         }
581 }
582
583 class ext_answer extends extension {
584         function output() {
585                 return "Answer";
586         }
587 }
588
589 class ext_privacymanager extends extension {
590         function output() {
591                 return "PrivacyManager(".$this->data.")";
592         }
593 }
594
595 class ext_macro {
596         var $macro;
597         var $args;
598        
599         function ext_macro($macro, $args='') {
600                 $this->macro = $macro;
601                 $this->args = $args;
602         }
603        
604         function output() {
605                 return "Macro(".$this->macro.",".$this->args.")";
606         }
607 }
608
609 //      The app_false argument only works with asterisk 1.6
610 //
611 class ext_execif {
612         var $expr;
613         var $app_true;
614         var $data_true;
615         var $app_false;
616         var $data_false;
617        
618         function ext_execif($expr, $app_true, $data_true='', $app_false = '', $data_false = '') {
619                 $this->expr = $expr;
620                 $this->app_true = $app_true;
621                 $this->data_true = $data_true;
622                 $this->app_false = $app_false;
623                 $this->data_false = $data_false;
624         }
625        
626         function output() {
627                 global $version;
628
629                 if (version_compare($version, "1.6", "ge")) {
630                         if ($app_false != '')
631                                 return "ExecIf({$this->expr}?{$this->app_true}({$this->data_true}):{$this->app_false}({$this->data_false}))";
632                         else
633                                 return "ExecIf({$this->expr}?{$this->app_true}({$this->data_true}))";
634                 } else {
635                         return "ExecIf({$this->expr},{$this->app_true},{$this->data_true})";
636                 }
637         }
638 }
639
640 class ext_setcidname extends extension {
641         function output() {
642                 return "Set(CALLERID(name)=".$this->data.")";
643         }
644 }
645
646 class ext_setcallerpres extends extension {
647         function output() {
648                 global $version;
649
650                 if (version_compare($version, "1.6", "lt")) {
651                         return "SetCallerPres({$this->data})";
652                 } else {
653                         return "Set(CALLERPRES()={$this->data})";
654                 }
655         }
656 }
657
658 class ext_record extends extension {
659         function output() {
660                 return "Record(".$this->data.")";
661         }
662 }
663
664 class ext_playback extends extension {
665         function output() {
666                 return "Playback(".$this->data.")";
667         }
668 }
669
670 class ext_queue {
671         var $var;
672         var $value;
673        
674         function ext_queue($queuename, $options, $optionalurl, $announceoverride, $timeout) {
675                 $this->queuename = $queuename;
676                 $this->options = $options;
677                 $this->optionalurl = $optionalurl;
678                 $this->announceoverride = $announceoverride;
679                 $this->timeout = $timeout;
680         }
681        
682         function output() {
683                 // for some reason the Queue cmd takes an empty last param (timeout) as being 0
684                 // when really we want unlimited
685                 if ($this->timeout != "")
686                         return "Queue(".$this->queuename.",".$this->options.",".$this->optionalurl.",".$this->announceoverride.",".$this->timeout.")";
687                 else
688                         return "Queue(".$this->queuename.",".$this->options.",".$this->optionalurl.",".$this->announceoverride.")";
689         }
690 }
691
692 class ext_addqueuemember extends extension {
693         var $queue;
694         var $channel;
695        
696         function ext_addqueuemember($queue, $channel){
697                 $this->queue = $queue;
698                 $this->channel = $channel;
699         }
700        
701         function output() {
702                 return "AddQueueMember({$this->queue},{$this->channel})";
703         }
704 }
705
706 class ext_removequeuemember extends extension {
707         var $queue;
708         var $channel;
709        
710         function ext_removequeuemember($queue, $channel){
711                 $this->queue = $queue;
712                 $this->channel = $channel;
713         }
714        
715         function output() {
716                 return "RemoveQueueMember({$this->queue},{$this->channel})";
717         }
718 }
719
720 class ext_userevent extends extension {
721         var $eventname;
722         var $body;
723        
724         function ext_userevent($eventname, $body=""){
725                 $this->eventname = $eventname;
726                 $this->body = $body;
727         }
728        
729         function output() {
730                 if ($this->body == '')
731                         return "UserEvent({$this->eventname})";
732                 else
733                         return "UserEvent({$this->eventname},{$this->body})";
734         }
735 }
736
737 class ext_macroexit extends extension {
738         function output() {
739                 return "MacroExit()";
740         }
741 }
742
743 class ext_hangup extends extension {
744         function output() {
745                 return "Hangup";
746         }
747 }
748
749 class ext_digittimeout extends extension {
750         function output() {
751                 return "Set(TIMEOUT(digit)=".$this->data.")";
752         }
753 }
754
755 class ext_responsetimeout extends extension {
756         function output() {
757                 return "Set(TIMEOUT(response)=".$this->data.")";
758         }
759 }
760
761 class ext_background extends extension {
762         function output() {
763                 return "Background(".$this->data.")";
764         }
765 }
766
767 class ext_read {
768         var $astvar;
769         var $filename;
770         var $maxdigits;
771         var $option;
772         var $attempts; // added in ast 1.2
773         var $timeout;  // added in ast 1.2
774        
775         function ext_read($astvar, $filename='', $maxdigits='', $option='', $attempts ='', $timeout ='') {
776                 $this->astvar = $astvar;
777                 $this->filename = $filename;
778                 $this->maxdigits = $maxdigits;
779                 $this->option = $option;
780                 $this->attempts = $attempts;
781                 $this->timeout = $timeout;
782         }
783        
784         function output() {
785                 return "Read(".$this->astvar.",".$this->filename.",".$this->maxdigits.",".$this->option.",".$this->attempts.",".$this->timeout.")";
786         }
787 }
788
789 class ext_meetme {
790         var $confno;
791         var $options;
792         var $pin;
793        
794         function ext_meetme($confno, $options='', $pin='') {
795                 $this->confno = $confno;
796                 $this->options = $options;
797                 $this->pin = $pin;
798         }
799        
800         function output() {
801                 return "MeetMe(".$this->confno.",".$this->options.",".$this->pin.")";
802         }
803 }
804
805 class ext_authenticate {
806         var $pass;
807         var $options;
808        
809         function ext_authenticate($pass, $options='') {
810                 $this->pass = $pass;
811                 $this->options = $options;
812         }
813         function output() {
814                 return "Authenticate(".$this->pass.",".$this->options.")";
815         }
816 }
817
818 class ext_vmauthenticate {
819         var $mailbox;
820         var $options;
821
822         function ext_vmauthenticate($mailbox='', $options='') {
823                 $this->mailbox = $mailbox;
824                 $this->options = $options;
825         }
826         function output() {
827                 return "VMAuthenticate(" .$this->mailbox . (($this->options != '') ? ','.$this->options : '' ) .")";
828         }
829 }
830
831 class ext_page extends extension {
832         function output() {
833                 return "Page(".$this->data.")";
834         }
835 }
836
837 class ext_disa extends extension {
838         function output() {
839                 return "DISA(".$this->data.")";
840         }
841 }
842 class ext_agi extends extension {
843         function output() {
844                 return "AGI(".$this->data.")";
845         }
846 }
847 class ext_deadagi extends extension {
848         function output() {
849                 return "DeadAGI(".$this->data.")";
850         }
851 }
852 class ext_dbdel extends extension {
853         function output() {
854                 return "dbDel(".$this->data.")";
855         }
856 }
857 class ext_dbdeltree extends extension {
858         function output() {
859                 return "dbDeltree(".$this->data.")";
860         }
861 }
862 class ext_dbget extends extension {
863         var $varname;
864         var $key;
865         function ext_dbget($varname, $key) {
866                 $this->varname = $varname;
867                 $this->key = $key;
868         }
869         function output() {
870                 return 'Set('.$this->varname.'=${DB('.$this->key.')})';
871         }
872 }
873 class ext_dbput extends extension {
874         var $key;
875         function ext_dbput($key, $data) {
876                 $this->key = $key;
877                 $this->data = $data;
878         }
879         function output() {
880                 return 'Set(DB('.$this->key.')='.$this->data.')';
881         }
882 }
883 class ext_vmmain extends extension {
884         function output() {
885                 return "VoiceMailMain(".$this->data.")";
886         }
887 }
888 class ext_vm extends extension {
889         function output() {
890                 return "VoiceMail(".$this->data.")";
891         }
892 }
893 class ext_vmexists extends extension {
894         function output() {
895                 return "MailBoxExists(".$this->data.")";
896         }
897 }
898 class ext_saydigits extends extension {
899         function output() {
900                 return "SayDigits(".$this->data.")";
901         }
902 }
903 class ext_sayunixtime extends extension {
904         function output() {
905                 return "SayUnixTime(".$this->data.")";
906         }
907 }
908 class ext_echo extends extension {
909         function output() {
910                 return "Echo(".$this->data.")";
911         }
912 }
913 // Thanks to agillis for the suggestion of the nvfaxdetect option
914 class ext_nvfaxdetect extends extension {
915         function output() {
916                 return "NVFaxDetect(".$this->data.")";
917         }
918 }
919 class ext_playtones extends extension {
920         function output() {
921                 return "Playtones(".$this->data.")";
922         }
923 }
924 class ext_stopplaytones extends extension {
925         function output() {
926                 return "StopPlaytones";
927         }
928 }
929 class ext_zapbarge extends extension {
930         function output() {
931                 return "ZapBarge(".$this->data.")";
932         }
933 }
934 class ext_sayalpha extends extension {
935         function output() {
936                 return "SayAlpha(".$this->data.")";
937         }
938 }
939 class ext_saynumber extends extension {
940         var $gender;
941         function ext_saynumber($data, $gender = 'f') {
942                 parent::extension($data);
943                 $this->gender = $gender;
944         }
945         function output() {
946                 return "SayNumber(".$this->data.",".$this->gender.")";
947         }
948 }
949 class ext_sayphonetic extends extension {
950         function output() {
951                 return "SayPhonetic(".$this->data.")";
952         }
953 }
954 class ext_system extends extension {
955         function output() {
956