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

Revision 11305, 18.9 kB (checked in by p_lindheimer, 2 years ago)

change from BLKVM_OVERRIDE to macro-blkvm- functions re #4799

  • 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     global $amp_conf;
8
9     // Check to make sure that install.sql has been run
10     $sql = "SELECT deptname from ivr where displayname='__install_done' LIMIT 1";
11
12     $results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
13
14     if (DB::IsError($results)) {
15             // It couldn't locate the table. This is bad. Lets try to re-create it, just
16             // in case the user has had the brilliant idea to delete it.
17             // runModuleSQL taken from page.module.php. It's inclusion here is probably
18             // A bad thing. It should be, I think, globally available.
19             localrunModuleSQL('ivr', 'uninstall');
20             if (localrunModuleSQL('ivr', 'install')==false) {
21                     echo _("There is a problem with install.sql, cannot re-create databases. Contact support\n");
22                     die;
23             } else {
24                     $results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
25             }
26     }
27     
28     if (!isset($results[0])) {
29         // Note: There's an invalid entry created, __invalid, after this is run,
30         // so as long as this has been run _once_, there will always be a result.
31
32         // Read old IVR format, part of xtns..
33         // In old IVR format, we had different dept as part of the context name, but since this is run once at install time, we need to read
34         // all of them. Hopefully a wildcard will be adequate, changing it to that.
35         //
36         if ($amp_conf["AMPDBENGINE"] == "sqlite3")  {
37             $sql = "SELECT context,descr FROM extensions WHERE extension = 's' AND application LIKE 'DigitTimeout' AND context LIKE '%aa\_%' ESCAPE '\' ORDER BY context,priority";
38         }
39         else  {
40             $sql = "SELECT context,descr FROM extensions WHERE extension = 's' AND application LIKE 'DigitTimeout' AND context LIKE '%aa_%' ORDER BY context,priority";
41         }
42         $unique_aas = $db->getAll($sql);
43         if (isset($unique_aas)) {
44             foreach($unique_aas as $aa){
45                 // This gets all the menu options
46                 $id = ivr_get_ivr_id($aa[1]);
47                 // Save the old name, with a link to the new name, for upgrading
48                 $ivr_newname[$aa[0]] = "ivr-$id";
49                 // Get the old config
50                 $sql = "SELECT extension,args from extensions where application='Goto' and context='{$aa[0]}'";
51                 $cmds = $db->getAll($sql, DB_FETCHMODE_ASSOC);
52                 if (isset($cmds)) {
53                     // There were some actions, so loop through them
54                     foreach ($cmds as $cmd) {
55                         $arr=explode(',', $cmd['args']);
56                         // s == old stuff. We don't care.
57                         if ($arr[0] != 's')
58                             ivr_add_command($id,$cmd['extension'],$cmd['args'],0);
59                     }
60                 }
61             }
62             // Now. Upgrade all the links inside the old IVR's
63             if (isset($ivr_newname)) {
64                 // Some IVR's were upgraded
65                 $sql = "SELECT * FROM ivr_dests WHERE dest LIKE '%aa_%'";
66                 $dests = $db->getAll($sql, DB_FETCHMODE_ASSOC);
67                 if (isset($dests)) {
68                     foreach ($dests as $dest) {
69                         $arr=explode(',', $dest['dest']);
70                         sql("UPDATE ivr_dests set dest='".$ivr_newname[$arr[0]].",s,1' where ivr_id='".$dest['ivr_id']."' and selection='".$dest['selection']."'");
71                     }
72                 }
73             }
74     
75             // Upgrade everything using IVR as a destination. Ick.
76     
77             // Are queue's using an ivr failover?
78             // ***FIXME*** if upgrading queues away from legacy cruft.
79             $queues = $db->getAll("select extensions,args from extensions where args LIKE '%aa_%' and context='ext-queues' and priority='6'");
80             if (is_array($queues)) {
81                 foreach ($queues as $q) {
82                     $arr=explode(',', $q['args']);
83                     sql("UPDATE extensions set args='".$ivr_newname[$arr[0]].",s,1' where context='ext-queues' and priority='6' and extension='".$q['extension']."'");
84                                 }
85             }
86     
87             // Now process everything else - if there's anything to process.
88             if (isset($ivr_newname) && is_array($ivr_newname)) {
89                 foreach (array_keys($ivr_newname) as $old) {
90                     // Timeconditions
91                     sql("UPDATE timeconditions set truegoto='".$ivr_newname[$arr[0]].",s,1' where truegoto='$old,s,1'");
92                     sql("UPDATE timeconditions set falsegoto='".$ivr_newname[$arr[0]].",s,1' where falsegoto='$old,s,1'");
93                     // Inbound Routes
94                     sql("UPDATE incoming set destination='".$ivr_newname[$arr[0]].",s,1' where destination='$old,s,1'");
95                     // Ring Groups
96                     sql("UPDATE ringgroups set postdest='".$ivr_newname[$arr[0]].",s,1' where postdest='$old,s,1'");
97                 }
98             }
99         }
100         // Note, the __install_done line is for internal version checking - the second field
101         // should be incremented and checked if the database ever changes.
102         $result = sql("INSERT INTO ivr (displayname, deptname) VALUES ('__install_done', '1')");
103         needreload();
104     }
105 }
106
107 // The destinations this module provides
108 // returns a associative arrays with keys 'destination' and 'description'
109 function ivr_destinations() {
110     //get the list of IVR's
111     $results = ivr_list();
112
113     // return an associative array with destination and description
114     if (isset($results)) {
115         foreach($results as $result){
116             $extens[] = array('destination' => 'ivr-'.$result['ivr_id'].',s,1', 'description' => $result['displayname']);
117         }
118     }
119     if (isset($extens))
120         return $extens;
121     else
122         return null;
123 }
124
125 function ivr_getdest($exten) {
126     return array('ivr-'.$exten.',s,1');
127 }
128
129 function ivr_getdestinfo($dest) {
130     global $active_modules;
131
132     if (substr(trim($dest),0,4) == 'ivr-') {
133         $exten = explode(',',$dest);
134         $exten = substr($exten[0],4);
135
136         $thisexten = ivr_get_details($exten);
137         if (empty($thisexten)) {
138             return array();
139         } else {
140             //$type = isset($active_modules['ivr']['type'])?$active_modules['ivr']['type']:'setup';
141             return array('description' => sprintf(_("IVR: %s"),$thisexten['displayname']),
142                          'edit_url' => 'config.php?display=ivr&action=edit&id='.urlencode($exten),
143                                   );
144         }
145     } else {
146         return false;
147     }
148 }
149
150 function ivr_recordings_usage($recording_id) {
151     global $active_modules;
152
153     $results = sql("SELECT `ivr_id`, `displayname` FROM `ivr` WHERE `announcement_id` = '$recording_id' || `timeout_id` = '$recording_id' || `invalid_id` = '$recording_id'","getAll",DB_FETCHMODE_ASSOC);
154     if (empty($results)) {
155         return array();
156     } else {
157         //$type = isset($active_modules['ivr']['type'])?$active_modules['ivr']['type']:'setup';
158         foreach ($results as $result) {
159             $usage_arr[] = array(
160                 'url_query' => 'config.php?display=ivr&action=edit&id='.urlencode($result['ivr_id']),
161                 'description' => sprintf(_("IVR: %s"),$result['displayname']),
162             );
163         }
164         return $usage_arr;
165     }
166 }
167
168 function ivr_get_config($engine) {
169     global $ext;
170
171     switch($engine) {
172         case "asterisk":
173             $ddial_contexts = array();
174             $ivrlist = ivr_list();
175             if(is_array($ivrlist)) {
176                 foreach($ivrlist as $item) {
177                     $id = "ivr-".$item['ivr_id'];
178                     $details = ivr_get_details($item['ivr_id']);
179
180                     $announcement_id = (isset($details['announcement_id']) ? $details['announcement_id'] : '');
181                     $timeout_id = (isset($details['timeout_id']) ? $details['timeout_id'] : '');
182                     $invalid_id = (isset($details['invalid_id']) ? $details['invalid_id'] : '');
183                     $loops = (isset($details['loops']) ? $details['loops'] : '2');
184                     $retvm = (isset($details['retvm']) ? $details['retvm'] : '');
185
186                     if (!empty($details['enable_directdial'])) {
187                         if ($details['enable_directdial'] == 'CHECKED') {
188                             $ext->addInclude($id,'from-did-direct-ivr'); //generated in core module
189                         } else {
190                             $ext->addInclude($id,'from-ivr-directory-'.$details['enable_directdial']);
191                             $ddial_contexts[$details['enable_directdial']] = true;
192                         }
193                     }
194                     // I'm not sure I like the ability of people to send voicemail from the IVR.
195                     // Make it a config option, possibly?
196                                         // $ext->addInclude($item[0],'app-messagecenter');
197                     if (!empty($details['enable_directory'])) {
198                         $ext->addInclude($id,'app-directory');
199                         $dir = featurecodes_getFeatureCode('infoservices', 'directory');
200                         $ext->add($id, '#' ,'', new ext_macro('blkvm-clr'));
201                         $ext->add($id, '#' ,'', new ext_setvar('__NODEST', ''));
202                         $ext->add($id, '#', '', new ext_goto("app-directory,$dir,1"));
203                     }
204
205                     $ext->add($id, 'h', '', new ext_hangup(''));
206                     if ($announcement_id) {
207                         $announcement_msg = recordings_get_file($announcement_id);
208                         $ext->add($id, 's', '', new ext_setvar('MSG', "$announcement_msg"));
209                     } else {
210                         $ext->add($id, 's', '', new ext_setvar('MSG', ""));
211                     }
212                     $ext->add($id, 's', '', new ext_setvar('LOOPCOUNT', 0));
213                     $ext->add($id, 's', '', new ext_setvar('__DIR-CONTEXT', $details['dircontext']));
214                     $ext->add($id, 's', '', new ext_setvar('_IVR_CONTEXT_${CONTEXT}', '${IVR_CONTEXT}'));
215                     $ext->add($id, 's', '', new ext_setvar('_IVR_CONTEXT', '${CONTEXT}'));
216                     $ext->add($id, 's', '', new ext_gotoif('$["${CDR(disposition)}" = "ANSWERED"]','begin'));
217                     $ext->add($id, 's', '', new ext_answer(''));
218                     $ext->add($id, 's', '', new ext_wait('1'));
219                     $ext->add($id, 's', 'begin', new ext_digittimeout(3));
220                     $ext->add($id, 's', '', new ext_responsetimeout($details['timeout']));
221
222                     if ($retvm) {
223                         $ext->add($id, 's', '', new ext_setvar('__IVR_RETVM', 'RETURN'));
224                     } else {
225                         $ext->add($id, 's', '', new ext_setvar('__IVR_RETVM', ''));
226                     }
227
228                     $ext->add($id, 's', '', new ext_execif('$["${MSG}" != ""]','Background','${MSG}'));
229                     $ext->add($id, 's', '', new ext_waitexten());
230                     $ext->add($id, 'hang', '', new ext_playback('vm-goodbye'));
231                     $ext->add($id, 'hang', '', new ext_hangup(''));
232
233                     $default_t=true;
234
235                     // Actually add the IVR commands now.
236                     $dests = ivr_get_dests($item['ivr_id']);
237                     $timeout=false;
238                     $invalid=false;
239                     $addloop=false;
240                     if (!empty($dests)) {
241                         foreach($dests as $dest) {
242                             if ($dest['selection'] == 't' && empty($details['alt_timeout'])) {
243                                  $timeout=true;
244                             } elseif ($dest['selection'] == 'i' && empty($details['alt_invalid'])) {
245                                  $invalid=true;
246                             } elseif (($dest['selection'] == 't' && !empty($details['alt_timeout']))) {
247                                  $timeout=true;
248                                 if ($timeout_id) {
249                                     $timeout_msg = recordings_get_file($timeout_id);
250                                     $ext->add($id, $dest['selection'], '', new ext_setvar('MSG',"$timeout_msg"));   
251                                 }
252                                 $ext->add($id, $dest['selection'], '', new ext_setvar('LOOPCOUNT','$[${LOOPCOUNT} + 1]'));   
253                                 $ext->add($id, $dest['selection'], '', new ext_gotoif('$[${LOOPCOUNT} <= '.$loops.']','s,begin'));
254                             } elseif (($dest['selection'] == 'i' && !empty($details['alt_invalid']))) {
255                                  $invalid=true;
256                                 $ext->add($id, $dest['selection'], '', new ext_setvar('LOOPCOUNT','$[${LOOPCOUNT} + 1]'));   
257
258
259                                 if ($invalid_id) {
260                                     $invalid_msg = recordings_get_file($invalid_id);
261                                     $ext->add($id, $dest['selection'], '', new ext_setvar('MSG',"$invalid_msg"));   
262                                 } else {
263                                     $ext->add($id, $dest['selection'], '', new ext_execif('$[${LOOPCOUNT} <= '.$loops.']','Playback','invalid'));
264                                 }
265                                 $ext->add($id, $dest['selection'], '', new ext_gotoif('$[${LOOPCOUNT} <= '.$loops.']','s,begin'));
266                             }
267                             $ext->add($id, $dest['selection'],'', new ext_macro('blkvm-clr'));
268                             $ext->add($id, $dest['selection'],'', new ext_setvar('__NODEST', ''));
269
270                             // 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
271                             //
272                             $dest_context = trim(strtok($dest['dest'],",|"));
273                             if ($dest_context == $id) {
274                                 $dest['dest'] = $id.',s,begin';
275                             }
276
277                             if ($dest['ivr_ret']) {
278                                 $ext->add($id, $dest['selection'],'', new ext_gotoif('$["x${IVR_CONTEXT_${CONTEXT}}" = "x"]', $dest['dest'].':${IVR_CONTEXT_${CONTEXT}},return,1'));
279                             } else {
280                                 $ext->add($id, $dest['selection'],'', new ext_goto($dest['dest']));
281                             }
282                         }
283                     }
284                     // Apply invalid if required
285                     if (!$invalid) {
286                         if ($invalid_id) {
287                             $invalid_msg = recordings_get_file($invalid_id);
288                             $ext->add($id, 'i', '', new ext_setvar('MSG',"$invalid_msg"));   
289                         } else {
290                             $ext->add($id, 'i', '', new ext_playback('invalid'));
291                         }
292                         $ext->add($id, 'i', '', new ext_goto('loop,1'));
293                         $addloop=true;
294                     }
295                     if (!$timeout) {
296                         if ($timeout_id) {
297                             $timeout_msg = recordings_get_file($timeout_id);
298                             $ext->add($id, 't', '', new ext_setvar('MSG',"$timeout_msg"));   
299                         }
300                         $ext->add($id, 't', '', new ext_goto('loop,1'));
301                         $addloop=true;
302                     }
303                     if ($addloop) {
304                         $ext->add($id, 'loop', '', new ext_setvar('LOOPCOUNT','$[${LOOPCOUNT} + 1]'));   
305                         $ext->add($id, 'loop', '', new ext_gotoif('$[${LOOPCOUNT} > '.$loops.']','hang,1'));
306                         $ext->add($id, 'loop', '', new ext_goto($id.',s,begin'));
307
308                         // these need to be reset or inheritance problems makes them go away in some conditions and infinite inheritance creates other problems
309                         // reset the message including blanking it if set by a sub-ivr
310                         $announcement_msg = ($announcement_id) ? $announcement_msg : '';
311                         $ext->add($id, 'return', '', new ext_setvar('MSG', "$announcement_msg"));
312                         $ext->add($id, 'return', '', new ext_setvar('_IVR_CONTEXT', '${CONTEXT}'));
313                         $ext->add($id, 'return', '', new ext_setvar('_IVR_CONTEXT_${CONTEXT}', '${IVR_CONTEXT_${CONTEXT}}'));
314                         $ext->add($id, 'return', '', new ext_goto($id.',s,begin'));
315                     }
316                 }
317
318                 if (!empty($ddial_contexts)) {
319                     global $version;
320                     $ast_lt_14 = version_compare($version, '1.4', 'lt');
321
322                     foreach(array_keys($ddial_contexts) as $dir_id) {
323                         $context = 'from-ivr-directory-'.$dir_id;
324                         $entries = function_exists('directory_get_dir_entries') ? directory_get_dir_entries($dir_id) : array();
325                         foreach ($entries as $dstring) {
326                             $exten = $dstring['dial'] == '' ? $dstring['foreign_id'] : $dstring['dial'];
327                             if ($exten == '' || $exten == 'custom') {
328                                 continue;
329                             }
330                           $ext->add($context, $exten,'', new ext_macro('blkvm-clr'));
331                             $ext->add($context, $exten,'', new ext_setvar('__NODEST', ''));
332                             $ext->add($context, $exten,'', new ext_goto('1',$exten,'from-internal'));
333                         }
334                     }
335                 }
336             }
337         break;
338     }
339 }
340
341 function ivr_get_ivr_id($name) {
342     global $db;
343     $res = $db->getRow("SELECT ivr_id from ivr where displayname='$name'");
344     if (count($res) == 0) {
345         // It's not there. Create it and return the ID
346         sql("INSERT INTO ivr (displayname, enable_directory, enable_directdial, timeout, alt_timeout, alt_invalid, `loops`, `retvm`)  values('$name', '', '', 10, '', '', 2, '')");
347         $res = $db->getRow("SELECT ivr_id from ivr where displayname='$name'");
348     }
349     return ($res[0]);
350     
351 }
352
353 function ivr_add_command($id, $cmd, $dest, $ivr_ret) {
354     global $db;
355     // Does it already exist?
356     $res = $db->getRow("SELECT * from ivr_dests where ivr_id='$id' and selection='$cmd'");
357     $ivr_ret = $ivr_ret ? 1 : 0;
358     if (count($res) == 0) {
359         // Just add it.
360         sql("INSERT INTO ivr_dests VALUES('$id', '$cmd', '$dest', '$ivr_ret')");
361     } else {
362         // Update it.
363         sql("UPDATE ivr_dests SET dest='$dest', ivr_ret='$ivr_ret' where ivr_id='$id' and selection='$cmd'");
364     }
365 }
366 function ivr_do_edit($id, $post) {
367
368     $displayname = isset($post['displayname'])?$post['displayname']:'';
369     $timeout = isset($post['timeout'])?$post['timeout']:'';
370     $ena_directory = isset($post['ena_directory'])?$post['ena_directory']:'';
371     $ena_directdial = isset($post['ena_directdial'])?$post['ena_directdial']:'';
372     $annmsg_id = isset($post['annmsg_id'])?$post['annmsg_id']:'';
373     $dircontext = isset($post['dircontext'])?$post['dircontext']:'';
374     $timeout_id = isset($post['timeout_id'])?$post['timeout_id']:'';
375     $invalid_id = isset($post['invalid_id'])?$post['invalid_id']:'';
376
377     $loops = isset($post['loops'])?$post['loops']:'2';
378     $alt_timeout = isset($post['alt_timeout'])?$post['alt_timeout']:'';
379     $alt_invalid = isset($post['alt_invalid'])?$post['alt_invalid']:'';
380     $retvm = isset($post['retvm'])?$post['retvm']:'';
381
382     if (!empty($ena_directdial) && !is_numeric($ena_directdial)) {
383         $ena_directdial='CHECKED';
384     }
385     if (!empty($alt_timeout)) {
386         $alt_timeout='CHECKED';
387     }
388     if (!empty($alt_invalid)) {
389         $alt_invalid='CHECKED';
390     }
391     if (!empty($retvm)) {
392         $retvm='CHECKED';
393     }
394     
395     $sql = "
396     UPDATE ivr
397     SET
398         displayname='$displayname',
399         enable_directory='$ena_directory',
400         enable_directdial='$ena_directdial',
401         timeout='$timeout',
402         announcement_id='$annmsg_id',
403         timeout_id='$timeout_id',
404         invalid_id='$invalid_id',
405         dircontext='$dircontext',
406         alt_timeout='$alt_timeout',
407         alt_invalid='$alt_invalid',
408         retvm='$retvm',
409         `loops`='$loops'
410     WHERE ivr_id='$id'
411     ";
412     sql($sql);
413
414     // Delete all the old dests
415     sql("DELETE FROM ivr_dests where ivr_id='$id'");
416     // Now, lets find all the goto's in the post. Destinations return gotoN => foo and get fooN for the dest.
417     // Is that right, or am I missing something?
418     foreach(array_keys($post) as $var) {
419         if (preg_match('/goto(\d+)/', $var, $match)) {
420             // This is a really horrible line of code. take N, and get value of fooN. See above. Note we
421             // get match[1] from the preg_match above
422             $dest = $post[$post[$var].$match[1]];
423             $cmd = $post['option'.$match[1]];
424             $ivr_ret = isset($post['ivr_ret'.$match[1]]) ? $post['ivr_ret'.$match[1]] : '';
425             // Debugging if it all goes pear shaped.
426             // print "I think pushing $cmd does $dest<br>\n";
427             if (strlen($cmd))
428                 ivr_add_command($id, $cmd, $dest, $ivr_ret);
429         }
430     }
431 }
432
433
434 function ivr_list() {
435     global $db;
436
437     $sql = "SELECT * FROM ivr where displayname <> '__install_done' ORDER BY displayname";
438         $res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
439         if(DB::IsError($res)) {
440         return null;
441         }
442         return $res;
443 }
444
445 function ivr_get_details($id) {
446     global $db;
447
448     $sql = "SELECT * FROM ivr where ivr_id='$id'";
449         $res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
450         if(DB::IsError($res)) {
451         return null;
452         }
453         return $res[0];
454 }
455
456 function ivr_get_dests($id) {
457     global $db;
458
459     $sql = "SELECT selection, dest, ivr_ret FROM ivr_dests where ivr_id='$id' ORDER BY selection";
460         $res = $db->getAll($sql, DB_FETCHMODE_ASSOC);
461         if(DB::IsError($res)) {
462                 return null;
463         }
464         return $res;
465 }
466     
467 function ivr_get_name($id) {
468     $res = ivr_get_details($id);
469     if (isset($res['displayname'])) {
470         return $res['displayname'];
471     } else {
472         return null;
473     }
474 }
475
476 function ivr_check_destinations($dest=true) {
477     global $active_modules;
478
479     $destlist = array();
480     if (is_array($dest) && empty($dest)) {
481         return $destlist;
482     }
483     $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  ";
484     if ($dest !== true) {
485         $sql .= "WHERE dest in ('".implode("','",$dest)."')";
486     }
487     $sql .= "ORDER BY displayname";
488     $results = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
489
490     //$type = isset($active_modules['ivr']['type'])?$active_modules['ivr']['type']:'setup';
491
492     foreach ($results as $result) {
493         $thisdest = $result['dest'];
494         $thisid   = $result['ivr_id'];
495         $destlist[] = array(
496             'dest' => $thisdest,
497             'description' => sprintf(_("IVR: %s / Option: %s"),$result['displayname'],$result['selection']),
498             'edit_url' => 'config.php?display=ivr&action=edit&id='.urlencode($thisid),
499         );
500     }
501     return $destlist;
502 }
503
504 function ivr_change_destination($old_dest, $new_dest) {
505     global $db;
506      $sql = "UPDATE ivr_dests SET dest = '$new_dest' WHERE dest = '$old_dest'";
507      $db->query($sql);
508
509 }
510 ?>
511
Note: See TracBrowser for help on using the browser.