root/modules/branches/2.3/pbdirectory/agi-bin/pbdirectory

Revision 4985, 10.0 kB (checked in by p_lindheimer, 6 years ago)

#2343 pbdirectory script errors, thanks robert for the patch

  • Property svn:executable set to *
Line 
1 #!/usr/bin/env php
2 <?php
3
4 /**
5 // AGI directory Copyright (C) 2005 Greg MacLellan (greg@mtechsolutions.ca)
6 //
7 //This program is free software; you can redistribute it and/or
8 //modify it under the terms of the GNU General Public License
9 //as published by the Free Software Foundation; either version 2
10 //of the License, or (at your option) any later version.
11 //
12 //This program is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //GNU General Public License for more details.
16
17
18 */
19
20 /* --------WARNING---------
21  *
22  * This script is auto-copied from an included module and will get overwritten.
23  * If you modify it, you must change it to read only, in the agi-bin directory,
24  * to keep it from getting changed.
25  */
26
27 // set to 1 to say "zed" instead of "zee"
28 define("SAY_ZED",0);
29
30 /******************************************************************************/
31
32 define("DEBUG", 1);
33
34 define("DIR_LAST", 0);
35 define("DIR_FIRST", 1);
36 define("DIR_ANY", 2);
37
38 define("NUM_DIGITS", 3);
39 define("MAX_REPEAT", 2); // how many times can we repeat the menu before hanging up?
40
41 // ordinal values of digits
42 define("D_0",48);
43 define("D_1",49);
44 define("D_2",50);
45 define("D_3",51);
46 define("D_4",52);
47 define("D_5",53);
48 define("D_6",54);
49 define("D_7",55);
50 define("D_8",56);
51 define("D_9",57);
52 define("D_POUND",35);
53 define("D_STAR",42);
54
55 include("phpagi.php");
56
57 function get_var( $agi, $value)
58 {
59   $r = $agi->get_variable( $value );
60  
61   if ($r['result'] == 1)
62   {
63     $result = $r['data'];
64     return $result;
65   }
66   else
67     return '';
68 }
69
70 function output(&$var) {
71   if (DEBUG) {
72     global $logfile;
73    
74     if (!isset($logfile)) return false;
75    
76     ob_start();
77     var_dump($var);
78     $output = ob_get_contents();
79     ob_end_clean();
80     fwrite($logfile, $output);
81   }
82 }
83
84 function phonebook_list() {
85
86   global $ampmgruser, $ampmgrpass;
87
88   $numbers = array();
89   $astman = new AGI_AsteriskManager();
90   if ($res = $astman->connect("127.0.0.1", $ampmgruser , $ampmgrpass)) {
91     $list = $astman->database_show();
92     foreach ($list as $k => $v) {
93       if (substr($k, 1, 7) == 'cidname')
94         $numbers[substr($k, 9)] = $v ;
95     }
96
97     if (is_array($numbers))
98       natcasesort($numbers);
99
100     return $numbers;
101   } else {
102     fatal("Cannot connect to Asterisk Manager with ".$ampmgruser."/".$ampmgrpass);
103   }
104
105 }
106
107 /** Play a bunch of files, optionally accepting input and looping
108  * @param $files    The file/files to play (for multiple files, pass array)
109  * @param $escape_digits  The DTMF tones that can be pressed & returned, ie, "123*"
110  * @param $timeout    The timeout waiting for a digit, or 0 to not wait at all.
111  * @param $max_digits   Maximum number of digits to get. **NOT IMPLEMENTED YET.. 1 only**
112  * @param $loop     False for no loop, or an integer >0 being the number of times to loop.
113  * @param $loopreturn   Value to return when the loop expires
114 */
115 function stream_multiple($files, $escape_digits = "", $timeout = 0, $max_digits = 1, $loop = false, $loopreturn = 0) {
116   global $agi;
117  
118   if (!is_array($files)) {
119     $files = array($files);
120   }
121  
122   $i = 0;
123   do {
124     foreach ($files as $file) {
125       $agi->verbose("-- Playing '".$file."' (language 'en')");
126       $r = $agi->stream_file($file, $escape_digits);
127       $agi->conlog("stream_multiple: $file returned ".$r["result"]);
128       switch ($r["result"]) {
129         case 0: // they did nothing
130         break;
131         case -1: // they hungup
132           $agi->verbose("remote user hungup");
133           return -1;
134         break;
135         default: // they pressed a key
136           return $r["result"];
137         break;
138       }
139     }
140    
141     if ($timeout > 0) {
142       $r = $agi->wait_for_digit($timeout);
143       if (($r["result"] != 0) || (!$loop)) {
144         // return only if the reult is not 0 (timeout)
145         // or we're not doing a loop
146         return $r["result"];
147       }
148     }
149    
150     if ($loop && (++$i > $loop)) {
151       return $loopreturn;
152     }
153   } while ($loop);
154  
155   return 0;
156 }
157
158 /** If $file.(wav|WAV|gsm|GSM) exists
159  */
160 function sound_file_exists($file) {
161   global $agi;
162  
163   foreach (array("gsm","GSM","wav","WAV") as $ext) {
164     if (file_exists($file.".".$ext)) {
165       $agi->verbose("Found ".$file.".".$ext, 2);
166       return true;
167     }
168   }
169   return false;
170 }
171
172 function string_to_digits($string) {
173   $out = "";
174  
175   for($i=0; $i<strlen($string); $i++) {
176     switch (strtoupper($string[$i])) {
177       case '1':
178         $out .= '1';
179       break;
180       case '2': case 'A': case 'B': case 'C':
181         $out .= '2';
182       break;
183       case '3': case 'D': case 'E': case 'F':
184         $out .= '3';
185       break;
186       case '4': case 'G': case 'H': case 'I':
187         $out .= '4';
188       break;
189       case '5': case 'J': case 'K': case 'L':
190         $out .= '5';
191       break;
192       case '6': case 'M': case 'N': case 'O':
193         $out .= '6';
194       break;
195       case '7': case 'P': case 'Q': case 'R': case 'S':
196         $out .= '7';
197       break;
198       case '8': case 'T': case 'U': case 'V':
199         $out .= '8';
200       break;
201       case '9': case 'W': case 'X': case 'Y': case 'Z':
202         $out .= '9';
203       break;
204     }
205    
206     if ($i+1 == NUM_DIGITS) break;
207   }
208  
209   return $out;
210 }
211
212 function say_alpha($string,$escape_digits) {
213   $string = strtolower($string);
214   $files = array();
215  
216   for($i=0; $i<strlen($string); $i++) {
217     if (('a' <= $string[$i]) && ($string[$i] <= 'z')) {
218    
219       if (($string[$i] == 'z') && SAY_ZED) {
220         $files[] = "letters/zed";
221       } else {
222         $files[] = "letters/".$string[$i];
223       }
224      
225     } else if (('1' <= $string[$i]) && ($string[$i] <= '0')) {
226       $files[] = "digits/".$string[$i];
227      
228     } else {
229       switch ($string[$i]) {
230         case "@": $files[] = "letters/at"; break;
231         case "-": $files[] = "letters/dash"; break;
232         case "$": $files[] = "letters/dollar"; break;
233         case ".": $files[] = "letters/dot"; break;
234         case "=": $files[] = "letters/equals"; break;
235         case "!": $files[] = "letters/exclaimation-point"; break;
236         case "+": $files[] = "letters/plus"; break;
237         case "/": case "\\": $files[] = "letters/slash"; break;
238         case " ": $files[] = "letters/space"; break;
239       }
240     }
241   }
242  
243   return stream_multiple($files,$escape_digits);
244 }
245
246 function do_directory($type, &$directory, $say_exten, $operator) {
247   global $agi;
248
249   $agi->conlog('starting directory');
250  
251   $escape_digits = "1*";
252   if ($operator) $escape_digits .= "0";
253
254   $agi->stream_file("pbdirectory/welcome-to-phonebook");
255  
256   switch ($type) {
257     case DIR_FIRST: $intro = "pbdirectory/first-three-letters-entry"; break;
258     case DIR_ANY: $intro = "pbdirectory/first-three-letters-entry"; break;
259   }
260
261   if (DEBUG) $agi->verbose("start loop");
262  
263   $loop = 0;
264   while ($loop < MAX_REPEAT) {
265     if (DEBUG) $agi->verbose("loop = ".$loop);
266     $r = $agi->get_data($intro, 4000, NUM_DIGITS);
267    
268     if (($r["result"] == "0") && $operator) {
269       // operator
270       $agi->verbose("Dropping to operator");
271       // switch to o,1 in the current context
272       $agi->set_extension("o");
273       $agi->set_priority("1");
274       // exiting application immediately!
275       exit(0);
276     }
277     $digits = $r["result"];
278    
279     usleep(500); // pause a bit, so digit presses get cleared
280    
281     if ($digits !== "") {
282       // they entered SOMETHING, reset our loop
283       $loop = 0;
284     }
285    
286     $i = 0;
287     $digit = false;
288     if (isset($directory[$digits]) && isset($directory[$digits][$i])) {
289       $loop = 0; // reset loop counter
290       do {
291         $match = & $directory[$digits][$i];
292        
293         sleep(1);
294         //TODO: check if festival is available, say the name that way
295         $digit = say_alpha($match["name"],$escape_digits);
296        
297         if (!$digit) {
298           $digit = stream_multiple(array("pbdirectory/if-correct-press","digits/1","pbdirectory/if-incorrect-press","digits/star"), $escape_digits, 3000);
299         }
300        
301         switch ($digit) {
302           case D_1: // dial this
303             if ($say_exten) {
304               $agi->stream_file("try-extension");
305               $agi->say_digits($match["number"]);
306             }
307             $agi->conlog("Dial ".$match["number"]);
308            
309             $agi->set_variable('dialnumber', $match['number']);
310             exit(0);
311           break;
312           case D_STAR: // not correct
313             $i += 1;
314           break;
315           case D_0: // operator
316             if ($operator) {
317               $agi->verbose("Dropping to operator");
318               // switch to o,1 in the current context
319               $agi->set_extension("o");
320               $agi->set_priority("1");
321               // exiting application immediately!
322               exit(0);
323             }
324           break;
325           case -1: // hungup
326             $agi->conlog("User hungup");
327             exit(1);
328           break;
329           case 0: // no response
330             $loop++;
331           break;
332           case -2: // loop timed out
333             $agi->stream_file("goodbye");
334             $agi->hangup();
335             exit(0);
336           break;
337         }
338        
339         if ($digit !== 0) {
340           $loop = 0;
341         }
342         $digit = false;
343       } while (isset($directory[$digits][$i]) && ($loop < MAX_REPEAT));
344      
345       if (!isset($directory[$digits][$i])) {
346         $agi->stream_file("dir-nomore");
347         $loop = 0; // reset our loop counter so it doesn't hangup
348       }
349     } else if (!empty($digits) || ($digits === "0")) {
350       // strict type checking as they may have entered "0" (string) which is empty()
351       $agi->stream_file("dir-nomatch");
352     } // else, we timed out
353    
354     $loop++;
355   }
356 }
357
358 /******************************************************************************/
359 $agi = new AGI;
360
361 $ampmgruser  = get_var( $agi, "AMPMGRUSER" );
362 $ampmgrpass  = get_var( $agi, "AMPMGRPASS" );
363
364 if (DEBUG) $logfile = fopen("/tmp/pbdirectory.log","w");
365
366 $phonebook = phonebook_list();
367
368 $operator = false;
369 $dir_type = DIR_FIRST;
370 $say_exten = false;
371
372 if (isset($argv[1])) {
373   for($i=0; $i<strlen($argv[1]); $i++) {
374     switch ($argv[1][$i]) {
375       case "f": case "F":
376         $dir_type = DIR_FIRST;
377       break;
378       case "a": case "a":
379         $dir_type = DIR_ANY;
380       break;
381       case "o": case "O":
382         $operator = true;
383       break;
384       case "e": case "E":
385         $say_exten = true;
386       break;
387     }
388   }
389 }
390
391 $directory = array();
392 foreach ($phonebook as $number=>$name) {
393   $names = explode(' ',$name);
394    
395   switch ($dir_type) {
396     case DIR_FIRST: // first name only
397       $digits = string_to_digits($names[0]);
398       $directory[$digits][] = array("number"=>$number, "name"=>$name);
399     break;
400     case DIR_ANY: // all names
401       foreach ($names as $temp) {
402         $digits = string_to_digits($temp);
403         $directory[$digits][] = array("number"=>$number, "name"=>$name);
404       }
405     break;
406   }
407 }
408
409 if (DEBUG) {
410   output($argv);
411   output($dir_type);
412   output($directory);
413 }
414
415 $agi->verbose('test');
416 do_directory($dir_type, $directory, $say_exten, $operator);
417  
418 ?>
Note: See TracBrowser for help on using the browser.