Changeset 11497
- Timestamp:
- 02/20/11 02:08:04 (2 years ago)
- Files:
-
- contributed_modules/modules/smartroutes/CHANGES (added)
- contributed_modules/modules/smartroutes/functions.inc.php (modified) (19 diffs)
- contributed_modules/modules/smartroutes/install.sql (modified) (2 diffs)
- contributed_modules/modules/smartroutes/module.xml (modified) (2 diffs)
- contributed_modules/modules/smartroutes/page.smartroutes.php (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
contributed_modules/modules/smartroutes/functions.inc.php
r11441 r11497 20 20 include '../fax/functions.inc.php'; // so we can include the same fax hook code that the standard inbound route includes (if available) 21 21 22 22 // return a list of smartroutes for menu/display 23 23 function smartroutes_list() { 24 24 global $db; … … 32 32 33 33 34 // return the asterisk dialplan goto destination for a specific smartroute 34 35 function smartroutes_getdest($id) { 35 36 return array('smartroute-'.$id.',s,1'); 36 37 } 37 38 38 39 40 // return the database record for a given smartroute 39 41 function smartroutes_get_route($id) { 40 42 global $db; … … 49 51 } 50 52 53 54 // return the queries for a given route 51 55 function smartroutes_get_queries($id) { 52 56 global $db; … … 58 62 } 59 63 64 65 // return the destinations for a given route 60 66 function smartroutes_get_dests($id) { 61 67 global $db; … … 68 74 69 75 76 // return the name of the smartroute marked as trunk default 77 function smartroutes_get_trunkdefault() { 78 global $db; 79 80 $route = $db->getRow("SELECT name FROM smartroute where trunkdefault=1"); 81 82 if(DB::IsError($route) || count($route) == 0) { 83 return null; 84 } 85 86 if(!empty($route[0]) && !DB::IsError($route) && isset($route[0])) return $route[0]; 87 88 return null; 89 } 90 91 92 // return the dialplan destination for the smartroute marked as trunk default 93 function smartroutes_get_trunkdefault_gotoroute() { 94 global $db; 95 96 $route = $db->getRow("SELECT id FROM smartroute where trunkdefault=1"); 97 98 if(DB::IsError($route) || count($route) == 0) { 99 return null; 100 } 101 102 if(!empty($route[0]) && !DB::IsError($route) && isset($route[0])) return smartroutes_getdest($route[0]); 103 104 return null; 105 } 106 107 108 // return a list of the Asterisk odbc resources defined 109 function smartroutes_get_dsns() { 110 $ret_dsns = array(); 111 112 $asterisk_dsns = smartroutes_read_config('/etc/asterisk/res_odbc.conf'); 113 if(count($asterisk_dsns)) { 114 $ret_dsns = array_keys($asterisk_dsns); 115 } 116 return $ret_dsns; 117 } 118 119 120 // add a smartroute entry 70 121 function smartroutes_add_route($name) { 71 122 global $db; … … 86 137 } 87 138 139 140 // delete a smartroute entry 88 141 function smartroutes_del($id) { 89 142 global $db; … … 96 149 } 97 150 151 152 // save a smartroute entry 98 153 function smartroutes_save($id) { 99 154 global $db; … … 113 168 114 169 foreach ($_POST as $key => $value) { 170 if($key == 'trunkdefault' && $value == '1') { 171 // only one smartroute can be the trunk default so disable all 172 sql("UPDATE `smartroute` SET `trunkdefault` = '0'"); 173 } 174 115 175 switch ($key) { 116 176 case 'faxenabled': … … 146 206 case 'faxdetection': 147 207 case 'legacy_email': 208 case 'trunkdefault': 148 209 case 'faxdetectionwait': 149 210 $sql_value = $db->escapeSimple($value); … … 293 354 294 355 356 // return an array of smartroute destinations 295 357 function smartroutes_destinations() { 296 358 $destinations = array(); 297 359 $smartroutes = smartroutes_list(); 298 360 361 // first destination is static inbound routes 362 // 363 // ** in case we translated a DID and want to process based on static inbound routes) 364 // ** or if a smartroute is set for default trunk call processing but we want to hand off to static inbound routes 365 $destinations[] = array('destination' => 'from-pstn,${EXTEN},1','description' => '* FreePBX Std Inbound Routes *'); 366 299 367 if(isset($smartroutes)) { 300 368 foreach($smartroutes as $route){ … … 315 383 } 316 384 385 386 // write the dialplan for smartroutes 317 387 function smartroutes_get_config($engine) { 318 388 global $ext; … … 344 414 // $ob_file = fopen('/tmp/smartroute.log','w'); 345 415 // ob_start('ob_file_callback'); 416 417 // do we need to configure smartroutes to handle all trunk calls (before static inbound routes) 418 $trunk_default_gotoroute = smartroutes_get_trunkdefault_gotoroute(); 419 if($trunk_default_gotoroute != null) { 420 // smartroutes are taking point on inbound trunk calls 421 // create a new from-trunk context 422 $ext->add('from-trunk', '_.', '', new ext_setvar('__FROM_DID','${EXTEN}')); 423 $ext->add('from-trunk', '_.', '', new ext_setvar('__CATCHALL_DID','${EXTEN}')); 424 $ext->add('from-trunk', '_.', '', new ext_goto($trunk_default_gotoroute[0])); 425 $ext->add('from-trunk', 'i', '', new ext_setvar('__CATCHALL_DID','${INVALID_EXTEN}')); 426 $ext->add('from-trunk', 'i', '', new ext_goto($trunk_default_gotoroute[0])); 427 428 // to get to the original static "inbound routes" we go to "from-pstn" (which is the sole inclusion of the existing from-trunk) 429 } 430 346 431 347 432 // *** FIRST FIX CATCHALL TO SET FROM_DID (we need this when the catch-all is routed to smartroutes for processing - that way we can search on FROM_DID) … … 726 811 $macrodestination = true; 727 812 } 813 814 // also exchange EXTEN for SR_OR_EXTVAR if set FOR ANY PRIMARY DESTINATION 815 // also set the actual context for any destination with an ,s, extension FOR ANY PRIMARY DESTINATION 816 $dest['extvar'] = trim($dest['extvar']); 817 if(!empty($dest['extvar'])) { 818 $dest['destination'] = str_replace('${EXTEN}',$dest['extvar'],$dest['destination']); 819 $dest_str_part_pos = strpos($dest['destination'], ',s,'); 820 if(is_numeric($dest_str_part_pos) ) { 821 $dest['destination'] = $dest['extvar'].substr($dest['destination'],$dest_str_part_pos); 822 } 823 } 728 824 729 825 // set processing vars … … 739 835 // clear these 740 836 $ext->add($context, $extension, '', new ext_setvar('SR_MACRO', "")); 741 $ext->add($context, $extension, '', new ext_setvar('SR_MACRO_TRUNK', "")); 837 $ext->add($context, $extension, '', new ext_setvar('SR_MACRO_TRUNK', "")); 742 838 } 743 839 $ext->add($context, $extension, '', new ext_goto("process_match_found")); … … 862 958 // fclose($ob_file); 863 959 } 864 865 866 960 961 962 // helper function for the dialplan generation code - process an individual odbc query 867 963 function smartroutes_create_odbc_query($smartroute, $query) { 868 964 $odbc_query = array(); … … 916 1012 917 1013 1014 // read an asterisk config file into an array 918 1015 function smartroutes_read_config($config_file) { 919 1016 $config = array(); … … 968 1065 969 1066 970 1067 // save the Asterisk odbc queries/funcs file /etc/asterisk/func_odbc.conf 971 1068 function smartroutes_save_odbc_funcs($odbc_queries) { 972 1069 global $version; … … 1026 1123 1027 1124 } 1028 1029 1030 1125 1126 1127 // when a smartroute is setup for default trunk call processing, provide notification on the static inbound route page 1128 function smartroutes_hook_core($viewing_itemid, $target_menuid) { 1129 $html = ''; 1130 1131 if ($target_menuid == 'did') { 1132 $trunk_default_route_name = smartroutes_get_trunkdefault(); 1133 1134 if($trunk_default_route_name != null) { 1135 $html = '<tr><td colspan="2"><h5><hr>'; 1136 $html .= '<p><span style="background-color: #CCFFFF; color: black; line-height: 125%; padding:2pt;"> <b style="color: red;">'._("Important:").'</b> '._("Inbound trunk calls first processed by SmartRoute:").' ['.$trunk_default_route_name.'] </span></p>'."\n"; 1137 $html .= '<hr></h5></td></tr>'; 1138 } 1139 } 1140 1141 return $html; 1142 } 1143 1144 1145 // from fax module - provide fax functions for smartroutes (like on the static inbound route pages) 1031 1146 function smartroutes_fax_hook_core($viewing_itemid, $target_menuid, $smartroute){ // ejr 2-31-11 modified to pass smartroute array 1032 1147 //hmm, not sure why engine_getinfo() isnt being called here?! should probobly read: $info=engine_getinfo(); … … 1148 1263 1149 1264 } 1150 1151 1152 1265 1153 1266 contributed_modules/modules/smartroutes/install.sql
r11417 r11497 13 13 `id` int unsigned NOT NULL PRIMARY KEY auto_increment, 14 14 `name` varchar(40) NOT NULL, 15 `destination` varchar(50) default NULL, 15 `trunkdefault` tinyint(1) default '0', 16 `destination` varchar(50) default NULL, 16 17 `faxenabled` tinyint(1) default NULL, 17 18 `faxdetection` varchar(20) default NULL, … … 39 40 `search-type` varchar(20) default 'EXACT' 40 41 ); 42 43 -- 44 -- Upgrade existing tables with a new field for version 1.1 45 -- 46 ALTER TABLE `smartroute` ADD `trunkdefault` TINYINT(1) default '0'; 41 47 42 48 -- contributed_modules/modules/smartroutes/module.xml
r11417 r11497 2 2 <rawname>smartroutes</rawname> 3 3 <name>SmartRoutes</name> 4 <description>Route inbound calls based on ANI, CID, or other variables using external databases.</description> 5 <version>1.0</version> 4 <description>SmartRoutes is a module that allows you to control inbound call routing based on external database values. Using SmartRoutes you can pre-process incoming DIDs, route incoming calls to the appropriate queue (skills based routing), you can automatically route calls from one trunk to another (sip->tdm gateway), you can set variables in the dial plan (like cdr, caller id name, etc), strip unnecessary caller-id and did prefixes from inbound calls, and much more based on the caller id, did called or other Asterisk call values. As an example, you can route customer calls differently based on how much money they do with your business.</description> 5 <version>1.1</version> 6 <publisher>VoiceNation Live</publisher> 7 <license>GPLv2</license> 6 8 <type>setup</type> 7 9 <category>Addons</category> … … 9 11 <smartroutes category="Inbound Call Control">SmartRoutes</smartroutes> 10 12 </menuitems> 11 <location> release/smartroutes-1.0.tgz</location>13 <location>contributed_modules/release/smartroutes-1.1.tgz</location> 12 14 <info>http://www.qualityansweringservice.com/anatomy-oscc/freepbx/smartroutes</info> 15 <changelog> 16 *1.1* added pulldown to select pre-configured odbc dsn's from Asterisk's res_odbc.conf, allow SmartRoutes to be primary processor for trunk calls, allow override extension/context for destinations other than trunks, allow standard FreePBX inbound routes as a SmartRoutes destination (with override extension), minor bug fixes, new database field value trunkdefault in table smartroute 17 *1.0* initial commit 18 </changelog> 19 <depends> 20 <version>2.7.0beta1</version> 21 <phpversion>5.1.0</phpversion> 22 </depends> 13 23 </module> contributed_modules/modules/smartroutes/page.smartroutes.php
r11440 r11497 97 97 <h2><?php echo _("SmartRoutes"); ?></h2> 98 98 <!-- Splash Screen / Instructions here --> 99 <p>SmartRoutes is a module that allows you to control inbound call routing based on external database values. Using SmartRoutes you can route incoming calls to the appropriate queue (skills based routing), you can automatically route calls from one trunk to another (sip->tdm gateway), you can set variables in the dial plan (like cdr, caller id name, etc), strip unnecessary caller-id and did prefixes from inbound calls, and much more based on the caller id, did called or other Asterisk call values. As an example, you can route customer calls differently based on how much money they do with your business.</p> 99 <p>SmartRoutes is a module that allows you to control inbound call routing based on external database values. Using SmartRoutes you can route incoming calls to the appropriate queue (skills based routing), you can automatically route calls from one trunk to another (sip->tdm gateway), you can set variables in the dial plan (like cdr, caller id name, etc), strip unnecessary caller-id and did prefixes from inbound calls, and much more based on the caller id, did called or other Asterisk call values. As an example, you can route customer calls differently based on how much money they do with your business.</p> 100 <?php 101 $trunk_default_route_name = smartroutes_get_trunkdefault(); 102 103 if($trunk_default_route_name != null) { 104 echo('<p><span style="background-color: #CCFFFF; color: black; line-height: 125%; padding:2pt;"> <b style="color: red;">'._("Important:").'</b> '._("Inbound trunk calls processed by SmartRoute:").' ['.$trunk_default_route_name.'] </span><br>'."\n"); 105 echo('<span style="color:gray;">To process standard inbound routes, choose destination "SmartRoutes" and specify "* FreePBX Std Inbound Routes *"</span></p>'); 106 } 107 ?> 108 100 109 <b>Notes:</b> 101 110 <ul> … … 111 120 <?php } ?> 112 121 113 <li>Digium has recommended that MySQL interaction use the more stable ODBC as opposed to Asterisk Addons MySQL commands (which have been deprecated). For emore info see: <a href="https://issues.asterisk.org/view.php?id=17964" target="_blank">this report</a> and <a href="http://forums.digium.com/viewtopic.php?f=13&t=76449" target="_blank">this post</a>.</li>122 <li>Digium has recommended that MySQL interaction use the more stable ODBC as opposed to Asterisk Addons MySQL commands (which have been deprecated). For more info see: <a href="https://issues.asterisk.org/view.php?id=17964" target="_blank">this report</a> and <a href="http://forums.digium.com/viewtopic.php?f=13&t=76449" target="_blank">this post</a>.</li> 114 123 <li>To access multiple databases, or for more advanced call routing you can have smartroutes that route to other smartroutes. Setting the variables in the dialplan will allow database lookup values to persist from one Smartroute to the next.</li> 115 124 <li>This module will set the FROM_DID variable in the catch-all section for inbound routes.</li> … … 171 180 172 181 echo('</table>'."\n"); 173 182 183 // ** setup the "default trunk route" row 184 // **************************** 185 echo('<table>'."\n"); 186 echo('<tr><td colspan="2"><h5><a href=# class="info">'._("Default Trunk Route")."\n".'<span>'); 187 echo _("Default Trunk Route"); 188 echo('<br /><br /></span></a><hr></h5></td></tr>'."\n"); 189 190 echo('<tr><td><a href="#" class="info">'._("Select this SmartRoute as the primary handler for trunk calls?").'<span>'._("Should this SmartRoute be the iniital route for processing trunk calls? (Note: Will bypass static routes - but can be sent to static routes as destination below).").'</span></a>:</td>'."\n"); 191 echo('<td><select name="trunkdefault" tabindex="'.$tabindex++.'"><option value="1" '.($smartroute_route['trunkdefault'] == "1"? 'SELECTED':'').' >Yes</option><option value="0" '.($smartroute_route['trunkdefault'] != "1"? 'SELECTED':'').' >No</option></select></td></tr>'."\n"); 192 193 if($smartroute_route['trunkdefault'] == "1") { 194 echo('<tr><td colspan="2"><br><span style="background-color: #CCFFFF; color: black; line-height: 125%; padding:2pt;"> <b style="color: red;">'._("Important:").'</b> '._("Inbound trunk calls processed by this SmartRoute").' </span><br>'."\n"); 195 echo('<span style="color:gray;">To process standard inbound routes, choose destination "SmartRoutes" and specify "* FreePBX Std Inbound Routes *"</span></td></tr>'."\n"); 196 } 197 198 echo('</table>'."\n"); 199 174 200 175 201 echo('<table>'."\n"); … … 258 284 259 285 echo('<tr><td colspan="2"><div class="smartroutes_dest"><table>'."\n"); 260 echo('<tr id="smartroutes_destlabels"><td style="padding-left: 18px;"><a href=# class="info">'._("Match Value").'<span><br>'._("The value returned from the main query that this route defines.").'<br></span></a></td><td><a href=# class="info">'._(" Trunk Extension").'<span><br>'._("(optional) When sending to a trunk, allow specifing new destination DID value or variable. This feature only works for the primary destination as a trunk and requires FreePBX version 2.8 or higher. To use this capability for failover, have failover go to another smartroute where the primary destination trunk is the failover trunk with an override extension.<br><br>Note that any Asterisk vars used here need to be indicated as they are in Asterisk with '\${asteriskvar}'.").'<br></span></a></td><td><a href=# class="info">'._("Destination").'<span><br>'._("Primary destination for this route.").'<br></span></a></td><td><a href=# class="info">'._("Failover").'<span><br>'._("When primary destination is a *trunk* that is unable to connect, use this destination.").'<br></span></a></td></tr>'."\n");286 echo('<tr id="smartroutes_destlabels"><td style="padding-left: 18px;"><a href=# class="info">'._("Match Value").'<span><br>'._("The value returned from the main query that this route defines.").'<br></span></a></td><td><a href=# class="info">'._("Override Primary<br>Extension/Context").'<span><br>'._("(optional) When destination normally passes '\${EXTEN}' in the Asterisk dialplan goto call, allow specifing new destination DID value or variable. If the destination normally passes the 's' extension then we will replace the primary context with this variable or value (the specific target of the type selected is irrelevant because we'll override it). This feature only applies to the primary destination. To use this capability for failover, have failover go to another smartroute where the primary destination is the failover destination with a primary override extension/context.<br><br>Note that any Asterisk vars used here need to be indicated in Asterisk value notation with '\${asteriskvar}'.<br><br>Example extension translation uses: Custom Contexts, Smartroutes, Trunks (FreePBX 2.8+), and the FreePBX Std Inbound Routes.<br><br>Example context translation uses: IVR, and Announcements.").'<br></span></a></td><td><a href=# class="info">'._("Destination").'<span><br>'._("Primary destination for this route.").'<br></span></a></td><td><a href=# class="info">'._("Failover").'<span><br>'._("When primary destination is a *trunk* that is unable to connect, use this destination. Note: This feature requires FreePBX version 2.8 or higher. ").'<br></span></a></td></tr>'."\n"); 261 287 262 288 // get freepbx version … … 344 370 345 371 echo('<tr><td><a href="#" class="info">'._("Database Type").'<span>'._("Select the database type to use.").'</span></a>:</td>'."\n"); 346 echo('<td><select name="dbengine" tabindex="'.$tabindex++.'"><option value="odbc" '.($smartroute_route['dbengine'] == "odbc"? 'SELECTED':'').' >ODBC (Recommended)</option><option value="mysql" '.($smartroute_route['dbengine'] != "odbc"? 'SELECTED':'').' >MySQL </option></select></td></tr>'."\n");347 348 echo('<tr><td><a href="#" class="info">'._("MySQL Host").'<span>'._("Enter the MySQL Host (if using MySQL) .").'</span></a></td>'."\n");372 echo('<td><select name="dbengine" tabindex="'.$tabindex++.'"><option value="odbc" '.($smartroute_route['dbengine'] == "odbc"? 'SELECTED':'').' >ODBC (Recommended)</option><option value="mysql" '.($smartroute_route['dbengine'] != "odbc"? 'SELECTED':'').' >MySQL (Deprecated)</option></select></td></tr>'."\n"); 373 374 echo('<tr><td><a href="#" class="info">'._("MySQL Host").'<span>'._("Enter the MySQL Host (if using MySQL) DEPRECATED.").'</span></a></td>'."\n"); 349 375 echo('<td><input type="text" name="mysql-host" value="'.$smartroute_route['mysql-host'].'" tabindex="'.$tabindex++.'"></td></tr>'."\n"); 350 376 … … 360 386 echo('<br>'."\n"); 361 387 362 echo('<tr><td><a href="#" class="info">'._("ODBC DSN").'<span>'._("Enter the ODBC DSN (if using ODBC) RECOMMENDED").'</span></a></td>'."\n"); 363 echo('<td><input type="text" name="odbc-dsn" value="'.$smartroute_route['odbc-dsn'].'" tabindex="'.$tabindex++.'"></td></tr>'."\n"); 388 // list dsn's configured in Asterisk (/etc/asterisk/res_odbc.conf 389 $dsn_list = smartroutes_get_dsns(); 390 if(is_array($dsn_list) && count($dsn_list)) { 391 echo('<tr><td><a href="#" class="info">'._("ODBC DSN").'<span>'._("Enter the ODBC DSN (if using ODBC) RECOMMENDED").'</span></a></td>'."\n"); 392 echo('<td><select name="odbc-dsn" tabindex="'.$tabindex++.'">."\n"'); 393 foreach($dsn_list as $dsn_name) { 394 echo('<option value="'.$dsn_name.'" '.($smartroute_route['odbc-dsn'] == $dsn_name? 'SELECTED':'').' >'.$dsn_name.'</option>'."\n"); 395 } 396 397 echo('</select></td></tr>'."\n"); 398 } 399 else { 400 // just provide an entry field (assume they will add the odbc source to asterisk later 401 echo('<tr><td><a href="#" class="info">'._("ODBC DSN (Note: None found configured in Asterisk)").'<span>'._("Enter the ODBC DSN (if using ODBC) RECOMMENDED").'</span></a></td>'."\n"); 402 echo('<td><input type="text" name="odbc-dsn" value="'.$smartroute_route['odbc-dsn'].'" tabindex="'.$tabindex++.'"></td></tr>'."\n"); 403 } 364 404 365 405 echo('</table>'."\n"); … … 649 689 // *** NOTE THAT WE USE THE SAME FORM FIELD LINES AS ABOVE EXCEPT THAT THE ++ IS REMOVED FROM tabindex AND WE ADJUST THE VAL BEFORE EACH LINE 650 690 // we also modified the $destSetNum value to support dynamic creation 691 692 // get freepbx version 693 $installed_ver = getversion(); 651 694 652 695 // fix for our .js here from loop above … … 670 713 $tabindex = "'+tabindex1+'"; 671 714 echo('<td><input type="text" class="smartroute_dest_extvar" id="smartroute_dest_extvar_'.$destRowsUsed.'" name="smartroute_dest_extvar['.$destRowsUsed.']" value="'.$dest['extvar'].'" tabindex="'.$tabindex.'" /></td>'); 672 673 // get freepbx version674 $installed_ver = getversion();675 715 676 716 //removed the ++ from $destSetNum and hard-coded the destSet numbers (from original code in form above)
