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

Revision 5824, 15.2 kB (checked in by p_lindheimer, 5 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 ?>
411
Note: See TracBrowser for help on using the browser.