root/modules/branches/2.4/ivr/functions.inc.php

Revision 5824, 15.2 kB (checked in by p_lindheimer, 4 years ago)

#2858 Better handing of i and t options, added loop count and ability to loop before going to user defined i, t options

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2  /* $Id$ */
3
4
5 function ivr_init() {
6     global $db;
7
8     // Check to make sure that install.sql has been run
9     $sql = "SELECT deptname from ivr where displayname='__install_done' LIMIT 1";
10
11     $results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
12
13     if (DB::IsError($results)) {
14             // It couldn't locate the table. This is bad. Lets try to re-create it, just
15             // in case the user has had the brilliant idea to delete it.
16             // runModuleSQL taken from page.module.php. It's inclusion here is probably
17             // A bad thing. It should be, I think, globally available.
18             localrunModuleSQL('ivr', 'uninstall');
19             if (localrunModuleSQL('ivr', 'install')==false) {
20                     echo _("There is a problem with install.sql, cannot re-create databases. Contact support\n");
21                     die;
22             } else {
23                     $results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
24             }
25     }
26    
27     if (!isset($results[0])) {
28         // Note: There's an invalid entry created, __invalid, after this is run,
29         // so as long as this has been run _once_, there will always be a result.
30
31     // Read old IVR format, part of xtns..
32     $sql = "SELECT context,descr FROM extensions WHERE extension = 's' AND application LIKE 'DigitTimeout' AND context LIKE '".$dept."aa_%' ORDER BY context,priority";
33     $unique_aas = $db->getAll($sql);
34     if (isset($unique_aas)) {
35       foreach($unique_aas as $aa){
36         // This gets all the menu options
37         $id = ivr_get_ivr_id($aa[1]);
38         // Save the old name, with a link to the new name, for upgrading
39         $ivr_newname[$aa[0]] = "ivr-$id";
40         // Get the old config
41         $sql = "SELECT extension,args from extensions where application='Goto' and context='{$aa[0]}'";
42         $cmds = $db->getAll($sql, DB_FETCHMODE_ASSOC);
43         if (isset($cmds)) {
44           // There were some actions, so loop through them
45           foreach ($cmds as $cmd) {
46             $arr=explode(',', $cmd['args']);
47             // s == old stuff. We don't care.
48             if ($arr[0] != 's')
49               ivr_add_command($id,$cmd['extension'],$cmd['args'],0);
50           }
51         }
52       }
53       // Now. Upgrade all the links inside the old IVR's
54       if (isset($ivr_newname)) {
55         // Some IVR's were upgraded
56         $sql = "SELECT * FROM ivr_dests WHERE dest LIKE '%aa_%'";
57         $dests = $db->getAll($sql, DB_FETCHMODE_ASSOC);
58         if (isset($dests)) {
59           foreach ($dests as $dest) {
60             $arr=explode(',', $dest['dest']);
61             sql("UPDATE ivr_dests set dest='".$ivr_newname[$arr[0]].",s,1' where ivr_id='".$dest['ivr_id']."' and selection='".$dest['selection']."'");
62           }
63         }
64       }
65  
66       // Upgrade everything using IVR as a destination. Ick.
67  
68       // Are queue's using an ivr failover?
69       // ***FIXME*** if upgrading queues away from legacy cruft.
70       $queues = $db->getAll("select extensions,args from extensions where args LIKE '%aa_%' and context='ext-queues' and priority='6'");
71       if (count($res) != 0) {
72         foreach ($queues as $q) {
73           $arr=explode(',', $q['args']);
74           sql("UPDATE extensions set args='".$ivr_newname[$arr[0]].",s,1' where context='ext-queues' and priority='6' and extension='".$q['extension']."'");
75                               }
76       }
77  
78       // Now process everything else - if there's anything to process.
79       if (isset($ivr_newname) && is_array($ivr_newname)) {
80         foreach (array_keys($ivr_newname) as $old) {
81           // Timeconditions
82           sql("UPDATE timeconditions set truegoto='".$ivr_newname[$arr[0]].",s,1' where truegoto='$old,s,1'");
83           sql("UPDATE timeconditions set falsegoto='".$ivr_newname[$arr[0]].",s,1' where falsegoto='$old,s,1'");
84           // Inbound Routes
85           sql("UPDATE incoming set destination='".$ivr_newname[$arr[0]].",s,1' where destination='$old,s,1'");
86           // Ring Groups
87           sql("UPDATE ringgroups set postdest='".$ivr_newname[$arr[0]].",s,1' where postdest='$old,s,1'");
88         }
89       }
90     }
91     // Note, the __install_done line is for internal version checking - the second field
92     // should be incremented and checked if the database ever changes.
93     $result = sql("INSERT INTO ivr (displayname, deptname) VALUES ('__install_done', '1')");
94     needreload();
95     }
96 }
97
98 // The destinations this module provides
99 // returns a associative arrays with keys 'destination' and 'description'
100 function ivr_destinations() {
101   //get the list of IVR's
102   $results = ivr_list();
103
104   // return an associative array with destination and description
105   if (isset($results)) {
106     foreach($results as $result){
107       $extens[] = array('destination' => 'ivr-'.$result['ivr_id'].',s,1', 'description' => $result['displayname']);
108     }
109   }
110   if (isset($extens))
111     return $extens;
112   else
113     return null;
114 }
115
116 function ivr_getdest($exten) {
117   return array('ivr-'.$exten.',s,1');
118 }
119
120 function ivr_getdestinfo($dest) {
121   global $active_modules;
122
123   if (substr(trim($dest),0,4) == 'ivr-') {
124     $exten = explode(',',$dest);
125     $exten = substr($exten[0],4);
126
127     $thisexten = ivr_get_details($exten);
128     if (empty($thisexten)) {
129       return array();
130     } else {
131       //$type = isset($active_modules['announcement']['type'])?$active_modules['announcement']['type']:'setup';
132       return array('description' => 'IVR : '.$thisexten['displayname'],
133                    'edit_url' => 'config.php?display=ivr&action=edit&id='.urlencode($exten),
134                   );
135     }
136   } else {
137     return false;
138   }
139 }
140
141 function ivr_get_config($engine) {
142         global $ext;
143         global $conferences_conf;
144
145   switch($engine) {
146     case "asterisk":
147       $ivrlist = ivr_list();
148       if(is_array($ivrlist)) {
149         foreach($ivrlist as $item) {
150           $id = "ivr-".$item['ivr_id'];
151           $details = ivr_get_details($item['ivr_id']);
152
153           $announcement = (isset($details['announcement']) ? $details['announcement'] : '');
154           $loops = (isset($details['loops']) ? $details['loops'] : '2');
155
156           if (!empty($details['enable_directdial'])) {
157             // MODIFIED (PL)
158             // always include ext-findmefollow whether or not the module is currenlty
159             // enabled since subsequent activations should work without regenerating the
160             // ivr. (and no harm done if context does not exist.
161             //
162             $ext->addInclude($id,'from-did-direct-ivr');
163           }
164           // I'm not sure I like the ability of people to send voicemail from the IVR.
165           // Make it a config option, possibly?
166                                         // $ext->addInclude($item[0],'app-messagecenter');
167           if (!empty($details['enable_directory'])) {
168             $ext->addInclude($id,'app-directory');
169             $dir = featurecodes_getFeatureCode('infoservices', 'directory');
170             $ext->add($id, '#' ,'', new ext_dbdel('${BLKVM_OVERRIDE}'));
171             $ext->add($id, '#' ,'', new ext_setvar('__NODEST', ''));
172             $ext->add($id, '#', '', new ext_goto("app-directory,$dir,1"));
173           }
174
175           $ext->add($id, 'h', '', new ext_hangup(''));
176           $ext->add($id, 's', '', new ext_setvar('LOOPCOUNT', 0));
177           $ext->add($id, 's', '', new ext_setvar('__DIR-CONTEXT', $details['dircontext']));
178           $ext->add($id, 's', '', new ext_setvar('_IVR_CONTEXT_${CONTEXT}', '${IVR_CONTEXT}'));
179           $ext->add($id, 's', '', new ext_setvar('_IVR_CONTEXT', '${CONTEXT}'));
180           $ext->add($id, 's', '', new ext_gotoif('$["${CDR(disposition)}" = "ANSWERED"]','begin'));
181           $ext->add($id, 's', '', new ext_answer(''));
182           $ext->add($id, 's', '', new ext_wait('1'));
183           $ext->add($id, 's', 'begin', new ext_digittimeout(3));
184           $ext->add($id, 's', '', new ext_responsetimeout($details['timeout']));
185           if ($announcement != '') {
186             $ext->add($id, 's', '', new ext_background($announcement));
187           }
188           $ext->add($id, 's', '', new ext_waitexten());
189           $ext->add($id, 'hang', '', new ext_playback('vm-goodbye'));
190           $ext->add($id, 'hang', '', new ext_hangup(''));
191
192           $default_t=true;
193
194           // Actually add the IVR commands now.
195           $dests = ivr_get_dests($item['ivr_id']);
196           $timeout=false;
197           $invalid=false;
198           $addloop=false;
199           if (!empty($dests)) {
200             foreach($dests as $dest) {
201               if ($dest['selection'] == 't' && empty($details['alt_timeout'])) {
202                 $timeout=true;
203               } elseif ($dest['selection'] == 'i' && empty($details['alt_invalid'])) {
204                 $invalid=true;
205               } elseif (($dest['selection'] == 't' && !empty($details['alt_timeout']))) {
206                 $timeout=true;
207                 $ext->add($id, $dest['selection'], '', new ext_setvar('LOOPCOUNT','$[${LOOPCOUNT} + 1]')); 
208                 $ext->add($id, $dest['selection'], '', new ext_gotoif('$[${LOOPCOUNT} <= '.$loops.']','s,begin'));
209               } elseif (($dest['selection'] == 'i' && !empty($details['alt_invalid']))) {
210                 $invalid=true;
211                 $ext->add($id, $dest['selection'], '', new ext_setvar('LOOPCOUNT','$[${LOOPCOUNT} + 1]')); 
212                 //$ext->add($id, $dest['selection'], '', new ext_playback('invalid'));
213                 $ext->add($id, $dest['selection'], '', new ext_execif('$[${LOOPCOUNT} <= '.$loops.']','Playback','invalid'));
214                 $ext->add($id, $dest['selection'], '', new ext_gotoif('$[${LOOPCOUNT} <= '.$loops.']','s,begin'));
215               }
216               $ext->add($id, $dest['selection'],'', new ext_dbdel('${BLKVM_OVERRIDE}'));
217               $ext->add($id, $dest['selection'],'', new ext_setvar('__NODEST', ''));
218
219               // if the goto goes loops back to this ivr, then don't go to the begining or it will break the return to previous ivr info
220               //
221               $dest_context = trim(strtok($dest['dest'],",|"));
222               if ($dest_context == $id) {
223                 $dest['dest'] = $id.',s,begin';
224               }
225
226               if ($dest['ivr_ret']) {
227                 $ext->add($id, $dest['selection'],'', new ext_gotoif('$["x${IVR_CONTEXT_${CONTEXT}}" = "x"]', $dest['dest'].':${IVR_CONTEXT_${CONTEXT}},return,1'));
228               } else {
229                 $ext->add($id, $dest['selection'],'', new ext_goto($dest['dest']));
230               }
231             }
232           }
233           // Apply invalid if required
234           if (!$invalid) {
235             //$ext->add($id, 'i', '', new ext_noop('default i dest'));
236             $ext->add($id, 'i', '', new ext_playback('invalid'));
237             $ext->add($id, 'i', '', new ext_goto('loop,1'));
238             $addloop=true;
239           }
240           if (!$timeout) {
241             //$ext->add($id, 't', '', new ext_noop('default t dest'));
242             $ext->add($id, 't', '', new ext_goto('loop,1'));
243             $addloop=true;
244           }
245           if ($addloop) {
246             $ext->add($id, 'loop', '', new ext_setvar('LOOPCOUNT','$[${LOOPCOUNT} + 1]')); 
247             $ext->add($id, 'loop', '', new ext_gotoif('$[${LOOPCOUNT} > '.$loops.']','hang,1'));
248             $ext->add($id, 'loop', '', new ext_goto($id.',s,begin'));
249
250             // these need to be reset or inheritance problems makes them go away in some conditions and infinite inheritance creates other problems
251             //
252             $ext->add($id, 'return', '', new ext_setvar('_IVR_CONTEXT', '${CONTEXT}'));
253             $ext->add($id, 'return', '', new ext_setvar('_IVR_CONTEXT_${CONTEXT}', '${IVR_CONTEXT_${CONTEXT}}'));
254             $ext->add($id, 'return', '', new ext_goto($id.',s,begin'));
255           }
256           $ext->add($id, 'fax', '', new ext_goto('ext-fax,in_fax,1'));
257         }
258       }
259     break;
260   }
261 }
262
263
264
265 function ivr_get_ivr_id($name) {
266   global $db;
267   $res = $db->getRow("SELECT ivr_id from ivr where displayname='$name'");
268   if (count($res) == 0) {
269     // It's not there. Create it and return the ID
270     sql("INSERT INTO ivr (displayname, enable_directory, enable_directdial, timeout, alt_timeout, alt_invalid, `loops`)  values('$name', 'CHECKED', 'CHECKED', 10, '', '', 2)");
271     $res = $db->getRow("SELECT ivr_id from ivr where displayname='$name'");
272     needreload();
273   }
274   return ($res[0]);
275  
276 }
277
278 function ivr_add_command($id, $cmd, $dest, $ivr_ret) {
279   global $db;
280   // Does it already exist?
281   $res = $db->getRow("SELECT * from ivr_dests where ivr_id='$id' and selection='$cmd'");
282   $ivr_ret = $ivr_ret ? 1 : 0;
283   if (count($res) == 0) {
284     // Just add it.
285     sql("INSERT INTO ivr_dests VALUES('$id', '$cmd', '$dest', '$ivr_ret')");
286   } else {
287     // Update it.
288     sql("UPDATE ivr_dests SET dest='$dest', ivr_ret='$ivr_ret' where ivr_id='$id' and selection='$cmd'");
289   }
290   needreload();
291 }
292 function ivr_do_edit($id, $post) {
293
294   $displayname = isset($post['displayname'])?$post['displayname']:'';
295   $timeout = isset($post['timeout'])?$post['timeout']:'';
296   $ena_directory = isset($post['ena_directory'])?$post['ena_directory']:'';
297   $ena_directdial = isset($post['ena_directdial'])?$post['ena_directdial']:'';
298   $annmsg = isset($post['annmsg'])?$post['annmsg']:'';
299   $dircontext = isset($post['dircontext'])?$post['dircontext']:'';
300
301   $loops = isset($post['loops'])?$post['loops']:'2';
302   $alt_timeout = isset($post['alt_timeout'])?$post['alt_timeout']:'';
303   $alt_invalid = isset($post['alt_invalid'])?$post['alt_invalid']:'';
304
305   if (!empty($ena_directory)) {
306     $ena_directory='CHECKED';
307   }
308   if (!empty($ena_directdial)) {
309     $ena_directdial='CHECKED';
310   }
311   if (!empty($alt_timeout)) {
312     $alt_timeout='CHECKED';
313   }
314   if (!empty($alt_invalid)) {
315     $alt_invalid='CHECKED';
316   }
317  
318   sql("UPDATE ivr SET displayname='$displayname', enable_directory='$ena_directory', enable_directdial='$ena_directdial', timeout='$timeout', announcement='$annmsg', dircontext='$dircontext', alt_timeout='$alt_timeout', alt_invalid='$alt_invalid', `loops`='$loops' WHERE ivr_id='$id'");
319
320   // Delete all the old dests
321   sql("DELETE FROM ivr_dests where ivr_id='$id'");
322   // Now, lets find all the goto's in the post. Destinations return gotoN => foo and get fooN for the dest.
323   // Is that right, or am I missing something?
324   foreach(array_keys($post) as $var) {
325     if (preg_match('/goto(\d+)/', $var, $match)) {
326       // This is a really horrible line of code. take N, and get value of fooN. See above. Note we
327       // get match[1] from the preg_match above
328       $dest = $post[$post[$var].$match[1]];
329       $cmd = $post['option'.$match[1]];
330       $ivr_ret = $post['ivr_ret'.$match[1]];
331       // Debugging if it all goes pear shaped.
332       // print "I think pushing $cmd does $dest<br>\n";
333       if (strlen($cmd))
334         ivr_add_command($id, $cmd, $dest, $ivr_ret);
335     }
336   }
337   needreload();
338 }
339
340
341 function ivr_list() {
342   global $db;
343
344   $sql = "SELECT * FROM ivr where displayname <> '__install_done' ORDER BY displayname";
345         $res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
346         if(DB::IsError($res)) {
347     return null;
348         }
349         return $res;
350 }
351
352 function ivr_get_details($id) {
353   global $db;
354
355   $sql = "SELECT * FROM ivr where ivr_id='$id'";
356         $res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
357         if(DB::IsError($res)) {
358     return null;
359         }
360         return $res[0];
361 }
362
363 function ivr_get_dests($id) {
364   global $db;
365
366   $sql = "SELECT selection, dest, ivr_ret FROM ivr_dests where ivr_id='$id' ORDER BY selection";
367         $res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
368         if(DB::IsError($res)) {
369                 return null;
370         }
371         return $res;
372 }
373  
374 function ivr_get_name($id) {
375   $res = ivr_get_details($id);
376   if (isset($res['displayname'])) {
377     return $res['displayname'];
378   } else {
379     return null;
380   }
381 }
382
383 function ivr_check_destinations($dest=true) {
384   global $active_modules;
385
386   $destlist = array();
387   if (is_array($dest) && empty($dest)) {
388     return $destlist;
389   }
390   $sql = "SELECT dest, displayname, selection, a.ivr_id ivr_id FROM ivr a INNER JOIN ivr_dests d ON a.ivr_id = d.ivr_id  ";
391   if ($dest !== true) {
392     $sql .= "WHERE dest in ('".implode("','",$dest)."')";
393   }
394   $sql .= "ORDER BY displayname";
395   $results = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
396
397   //$type = isset($active_modules['ivr']['type'])?$active_modules['ivr']['type']:'setup';
398
399   foreach ($results as $result) {
400     $thisdest = $result['dest'];
401     $thisid   = $result['ivr_id'];
402     $destlist[] = array(
403       'dest' => $thisdest,
404       'description' => 'IVR: '.$result['displayname'].' / Option: '.$result['selection'],
405       'edit_url' => 'config.php?display=ivr&action=edit&id='.urlencode($thisid),
406     );
407   }
408   return $destlist;
409 }
410 ?>
Note: See TracBrowser for help on using the browser.