Changeset 9240
- Timestamp:
- 03/16/10 20:07:40 (2 years ago)
- Files:
-
- modules/branches/2.8/core/agi-bin/fixlocalprefix (modified) (2 diffs)
- modules/branches/2.8/core/core.css (moved) (moved from modules/branches/2.8/core/routing.css)
- modules/branches/2.8/core/functions.inc.php (modified) (17 diffs)
- modules/branches/2.8/core/install.php (modified) (3 diffs)
- modules/branches/2.8/core/module.xml (modified) (1 diff)
- modules/branches/2.8/core/page.routing.php (modified) (10 diffs)
- modules/branches/2.8/core/page.trunks.php (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
modules/branches/2.8/core/agi-bin/fixlocalprefix
r7630 r9240 18 18 // Copyright (C) 2004 Coalescent Systems Inc. (info@coalescentsystems.ca) 19 19 // 20 20 21 /* --------WARNING--------- 21 22 * … … 24 25 * to keep it from getting changed. 25 26 26 27 This program takes a number, checks it against a list of patterns for a specific trunk, and modifies the number based 28 on the rules for that number. 29 30 Two variables are required: 31 32 DIAL_NUMBER - the number to be dialed (this will be modified, if necessary) 33 DIAL_TRUNK - the trunk number to use 34 35 The list of prefixes is contained in $localprefix_file (defined below, defaults to /etc/asterisk/localprefixes.conf). This 36 file has the format: 37 38 [trunk-1] 39 rule1=1613|NXXXXXX 40 rule2=1519|555XXXX 41 rule2=1519|54[0-9]XXXX 42 43 [trunk-2] 44 rule1=1613+NXXXXXX 45 rule2=1519+12XXXXX 46 47 48 The section read depends on the value of DIAL_TRUNK. 49 50 A | means to drop the number before the |. In this example, if DIAL_NUMBER is "16135551234" and DIAL_TRUNK is "1", 51 DIAL_NUMBER will become "5551234" (rule1). If DIAL_NUMBER is "15195551234", it will become "5551234" (rule2). 52 "15195435555" will become "5435555" (rule3). 53 54 A + means to prefix the beginning digits to the following pattern. In this example, if DIAL_NUMBER is 5551234, and 55 DIAL_TRUNK is "2", DIAL_NUMBER will become "16135551234". If DIAL_NUMBER is "1235555", it will match rule2 and 56 become "15191235555". 57 58 If no number is matched, DIAL_NUMBER is left untouched, and the script will exit with return value 0. If any errors 59 occur, DIAL_NUMBER is left untouched and the script will exit with return value 1. 60 61 There is no limit to the number of rules that may be defined. 62 63 You can also use #include filename.conf to include other files. Sections are preserved when including, which may 64 cause undesired behaviour if not planned for. For example: 65 66 localprefixes.conf: 67 [trunk-1] 68 #include t1.conf 69 rule1=1613|453XXXX 70 rule2=1613|384XXXX 71 72 t1.conf: 73 [trunk-2] 74 rule1=141|NXXXXXX 75 76 rule1 and rule2 defined in localprefixes.conf will actually belong to [trunk-2], and additionally, rule1 in 77 localprefixes.conf will override the rule1 defined in t1.conf. 78 27 ERROR: This script has been deprecated and no longer used, leaving to print out warnings 28 for a while in cae someone is using it out there. This has been replaced by 29 the creation of dialpan subroutines to perform the same operation. 79 30 */ 80 31 81 32 include("phpagi.php"); 82 33 83 function get_var( $agi, $value)84 {85 $r = $agi->get_variable( $value );86 87 if ($r['result'] == 1)88 {89 $result = $r['data'];90 return $result;91 }92 else93 return '';94 }95 96 function parse_conf($filename, &$conf, &$section) {97 if (is_null($conf)) {98 $conf = array();99 }100 if (is_null($section)) {101 $section = "general";102 }103 104 if (file_exists($filename)) {105 $fd = fopen($filename, "r");106 while ($line = fgets($fd, 1024)) {107 if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {108 // name = value109 // option line110 $conf[$section][ $matches[1] ] = $matches[2];111 } else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {112 // section name113 $section = strtolower($matches[1]);114 } else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {115 // include another file116 117 if ($matches[1][0] == "/") {118 // absolute path119 $filename = $matches[1];120 } else {121 // relative path122 $filename = dirname($filename)."/".$matches[1];123 }124 125 parse_conf($filename, $conf, $section);126 }127 }128 }129 }130 131 function sanitizeNumber($number) {132 global $agi;133 if (strpos($number,"-") !== false) {134 $agi->verbose("Stripping hyphens");135 $number = str_replace("-","",$number);136 }137 return $number;138 }139 140 function fixNumber($pattern, $number, &$agi) {141 // valid chars in a pattern are 0-9XNZwW#*\.\[\]\-\+\|142 $chars = '0-9XNZwW#*\.\[\]\-'; //escaped pcre-ready143 144 // convert x n and z to uppercase145 $regex = str_replace(array('x','n','z'), array('X','N','Z'), $pattern);146 // sanitize the pattern - remove any non-pattern chars147 $regex = preg_replace("/[^0-9XNZwW#*\.\[\]\-\+\|]/", "", $regex);148 // Also kill the '-' characters outside of groups149 $regex = preg_replace("/((?:\[[^\]]*\])*)([^\[\]\-]*)-?/", "$1$2", $regex);150 151 $agi->verbose('Using pattern '.$regex, 4);152 // attempt to grab the pieces of the pattern153 if (preg_match('/^(([0-9XNZwW#*\.\[\]\-]+)\|)?(([0-9XNZwW#*\.\[\]\-]+)\+)?([0-9XNZwW#*\.\[\]\-]*)$/', $regex, $matches)) {154 // one of NXXXXXX, 613|NXXXXXX 1+NXXXXXX 613|1+NXXXXXX,155 // matches[2] = drop (eg 613), matches[4] = prefix (eg 1), matches[5] = rest of number (eg NXXXXX)156 157 $drop = $matches[2];158 $prefix = $matches[4];159 $static = $matches[5];160 } else if (preg_match('/^(([0-9XNZwW#*\.\[\]\-]+)\+)?(([0-9XNZwW#*\.\[\]\-]+)\|)?([0-9XNZwW#*\.\[\]\-]*)$/', $regex, $matches)) {161 // one of NXXXXXX, 613|NXXXXXX 1+NXXXXXX 1+613|NXXXXXX162 // matches[2] = prefix (eg 1), matches[4] = drop (eg 613), matches[5] = rest of number (eg NXXXXX)163 164 $drop = $matches[4];165 $prefix = $matches[2];166 $static = $matches[5];167 } else {168 if (!is_null($agi)) {169 $agi->verbose('Could not understand pattern "'.$pattern.'" ('.$regex.')', 1);170 }171 return false;172 }173 174 // convert asterisk pattern matching into perl regular expression175 $regex = str_replace(176 array(177 "X",178 "Z",179 "N",180 ".",181 "*",182 ),183 array(184 "[0-9]",185 "[1-9]",186 "[2-9]",187 "[0-9#*]+",188 "\*",189 ),190 // note, we're doing a subpattern match on the static portion so it can be extracted later191 $drop.'('.$static.')');192 193 if (preg_match('/^'.$regex.'$/', $number, $matches)) {194 return $prefix.$matches[1];195 }196 return false;197 }198 199 34 /**********************************************************************************************************************/ 200 35 201 36 $agi = new AGI(); 202 203 $localprefix_file = get_var($agi, "ASTETCDIR")."/localprefixes.conf"; 204 205 if (file_exists($localprefix_file)) { 206 parse_conf($localprefix_file, $conf, $section); 207 if (count($conf) == 0) { 208 // $agi->verbose("Could not parse ".$localprefix_file); 209 exit(1); 210 } 211 } else { 212 $agi->verbose("Could not open ".$localprefix_file); 213 exit(1); 214 } 215 216 $r = $agi->get_variable("DIAL_NUMBER"); 217 if ($r["result"] == 0) { 218 $agi->verbose("DIAL_NUMBER not set -- nothing to do"); 219 exit(1); 220 } 221 $number = $r["data"]; 222 223 $number = sanitizeNumber($number); 224 225 $r = $agi->get_variable("DIAL_TRUNK"); 226 if ($r["result"] == 0) { 227 $agi->verbose("DIAL_TRUNK not set -- nothing to do"); 228 exit(1); 229 } 230 $trunk = $r["data"]; 231 232 233 if (isset($conf["trunk-$trunk"])) { 234 foreach ($conf["trunk-$trunk"] as $key=>$rule) { 235 // extract all ruleXX keys 236 //$agi->conlog("$key = $rule"); 237 if (preg_match("/^rule\d+$/",$key)) { 238 // $rule is a dial rule 239 240 if (($newnum = fixNumber($rule, $number, $agi)) !== false) { 241 $agi->verbose('Dialpattern '.$rule.' matched. '.$number.' -> '.$newnum, 2); 242 $agi->set_variable("DIAL_NUMBER", $newnum); 243 244 // reverted back form r2080 (r2081 on trac) so that any pattern match will end 245 // the loop. This needs to stay like this for backwards compatibility and often 246 // patterns are used to avoid matching substitution rules for exception cases. 247 exit(0); 248 } // else, it didn't match this rule 249 } // else, this isn't a rule 250 } 251 } // else, no config for this section 252 253 // we just exit with no changes to the variable. 37 $agi->verbose("ERROR: This the fixlocalprefix script has been deprecated and does nothing"); 254 38 exit(0); 255 39 modules/branches/2.8/core/functions.inc.php
r9226 r9240 90 90 case 'features_featuremap_additional.conf': 91 91 return $this->generate_featuremap_additional($version); 92 break;93 case 'localprefixes.conf':94 return $this->generate_localprefixes($version);95 92 break; 96 93 } … … 568 565 $output .= "channel=>$zapchannel\n"; 569 566 $output .= $additional."\n"; 570 }571 return $output;572 }573 function generate_localprefixes($ast_version) {574 $output = "";575 576 $conf = core_trunks_readDialRulesFile();577 foreach ($conf as $section=>$values) {578 $output .= "[".$section."]\n";579 foreach ($values as $key=>$value) {580 $output .= $key."=".$value."\n";581 }582 $output .= "\n";583 567 } 584 568 return $output; … … 1367 1351 continue; 1368 1352 } 1353 $trunkgroup = 'OUT_'.$trunkprops['trunkid']; 1369 1354 switch ($trunkprops['tech']) { 1370 1355 case 'dundi': … … 1373 1358 $ext->add($macro_name, 's', '', new ext_goto('1','${ARG1}')); 1374 1359 1375 $trunkgroup = 'OUT_'.$trunkprops['trunkid'];1376 1360 $trunkcontext = "from-trunk-".$trunkprops['tech']."-".$trunkprops['channelid']; 1377 1361 $ext->add($trunkcontext, '_.', '', new ext_set('GROUP()',$trunkgroup)); 1378 1362 $ext->add($trunkcontext, '_.', '', new ext_goto('1','${EXTEN}','from-trunk')); 1379 1363 1380 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_set('OUTBOUND_GROUP', 'OUT_${DIAL_TRUNK}'));1381 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_gotoif('$["${OUTMAXCHANS_ ${DIAL_TRUNK}}" = ""]', 'nomax'));1382 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_gotoif('$[${GROUP_COUNT( OUT_${DIAL_TRUNK})} >= ${OUTMAXCHANS_${DIAL_TRUNK}}]', 'hangit'));1364 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_set('OUTBOUND_GROUP', $trunkgroup)); 1365 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_gotoif('$["${OUTMAXCHANS_'.$trunkprops['trunkid'].'}" = ""]', 'nomax')); 1366 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_gotoif('$[${GROUP_COUNT('.$trunkgroup.')} >= ${OUTMAXCHANS_${DIAL_TRUNK}}]', 'hangit')); 1383 1367 if ($ast_lt_16) { 1384 1368 $ext->add($tcontext,$trunkprops['trunkid'],'nomax',new ext_execif('$["${CALLINGPRES_SV}" != ""]', 'SetCallerPres', '${CALLINGPRES_SV}')); … … 1387 1371 } 1388 1372 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_set('DIAL_NUMBER','${FROM_DID}')); 1389 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_ execif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','AGI','fixlocalprefix'));1373 $ext->add($tcontext,$trunkprops['trunkid'],'',new ext_gosubif('$["${PREFIX_TRUNK_'.$trunkprops['trunkid'].'}" != ""]','sub-flp-'.$trunkprops['trunkid'].',s,1')); 1390 1374 $ext->add($tcontext, $trunkprops['trunkid'], '', new ext_macro('dundi-${DIAL_TRUNK}','${OUTNUM}')); 1391 1375 $ext->add($tcontext,$trunkprops['trunkid'],'hangit',new ext_hangup()); … … 1397 1381 case 'iax2': 1398 1382 case 'sip': 1399 $trunkgroup = 'OUT_'.$trunkprops['trunkid'];1400 1383 $trunkcontext = "from-trunk-".$trunkprops['tech']."-".$trunkprops['channelid']; 1401 1384 $ext->add($trunkcontext, '_.', '', new ext_set('GROUP()',$trunkgroup)); … … 1436 1419 } 1437 1420 $ext->add($tcontext,$tcustom,'',new ext_set('DIAL_NUMBER','${FROM_DID}')); 1438 $ext->add($tcontext,$tcustom,'',new ext_ execif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','AGI','fixlocalprefix'));1421 $ext->add($tcontext,$tcustom,'',new ext_gosubif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','sub-flp-${DIAL_TRUNK},s,1')); 1439 1422 $ext->add($tcontext,$tcustom,'',new ext_dial('${EVAL(${TDIAL_STRING})}','300,${DIAL_TRUNK_OPTIONS}')); 1440 1423 $ext->add($tcontext,$tcustom,'hangit',new ext_hangup()); … … 1451 1434 } 1452 1435 $ext->add($tcontext,$texten,'',new ext_set('DIAL_NUMBER','${FROM_DID}')); 1453 $ext->add($tcontext,$texten,'',new ext_execif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','AGI','fixlocalprefix')); 1436 $ext->add($tcontext,$texten,'',new ext_gosubif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','sub-flp-${DIAL_TRUNK},s,1')); 1437 1454 1438 $ext->add($tcontext,$texten,'',new ext_dial('${TDIAL_STRING}/${OUTNUM}','300,${DIAL_TRUNK_OPTIONS}')); 1455 1439 $ext->add($tcontext,$texten,'hangit',new ext_hangup()); 1456 1440 } 1457 1441 } 1442 1443 $trunk_hash = core_trunks_list_dialrules(); 1444 if (is_array($trunk_hash) && count($trunk_hash)) { 1445 foreach ($trunk_hash as $trunkid => $patterns) { 1446 // First, generate the global referencing how many there are 1447 $ext->addGlobal("PREFIX_TRUNK_$trunkid",count($patterns)); 1448 1449 $context = 'sub-flp-'.$trunkid; 1450 $target = 'TARGET_FLP4'.$trunkid; 1451 $exten = 's'; 1452 foreach ($patterns as $pattern) { 1453 $prepend = $pattern['prepend_digits']; 1454 $offset = strlen(preg_replace('/(\[[^\]]*\])/','X',$pattern['match_pattern_prefix'])); 1455 1456 $regex_base = $pattern['match_pattern_prefix'].$pattern['match_pattern_pass']; 1457 1458 // convert asterisk pattern matching into perl regular expression 1459 // - two steps, use $ in place of + 1460 // - next replace $ with + 1461 // if you don't do this, the str_replace() walks over itself 1462 $regex_intermediate = str_replace( 1463 array( 1464 "X", 1465 "Z", 1466 "N", 1467 ".", 1468 "*", 1469 "+", 1470 ), 1471 array( 1472 "[0-9]", 1473 "[1-9]", 1474 "[2-9]", 1475 "[0-9#*\$]$", 1476 "\*", 1477 "\+", 1478 ), 1479 $pattern['match_pattern_prefix'].$pattern['match_pattern_pass'] 1480 ); 1481 $regex = strtr($regex_intermediate,"$","+"); 1482 1483 if ($pattern['prepend_digits'] == '' && $offset == 0) { 1484 $ext->add($context, $exten, '', new ext_execif('$[${REGEX("^'.$regex.'$" ${DIAL_NUMBER})} = 1]','Return')); 1485 } else { 1486 $offset = $offset?':'.$offset:''; 1487 $ext->add($context, $exten, '', new ext_execif('$[${REGEX("^'.$regex.'$" ${DIAL_NUMBER})} = 1]','Set',$target.'='.$pattern['prepend_digits'].'${DIAL_NUMBER'.$offset.'}')); 1488 $ext->add($context, $exten, '', new ext_gotoif('$[${LEN(${'.$target.'})} != 0]', 'match')); 1489 } 1490 1491 } 1492 $ext->add($context, $exten, '', new ext_return('')); 1493 $ext->add($context, $exten, 'match', new ext_set('DIAL_NUMBER','${'.$target.'}')); 1494 $ext->add($context, $exten, '', new ext_return('')); 1495 } 1496 } 1497 1498 1458 1499 /* dialplan globals */ 1459 1500 // modules should NOT use the globals table to store anything! … … 1551 1592 $has_extension_state = true; 1552 1593 } 1553 }1554 1555 // Let's create globals for each trunk to determine which one's have fixlocalprefix settings.1556 // this allows us to skip calling the agi script if there are no rules to process saving1557 // on performance1558 //1559 $conf = core_trunks_readDialRulesFile();1560 if (is_array($conf)) {1561 foreach ($conf as $trunknum => $entries) {1562 $trunkname = substr($trunknum,6);1563 $ext->addGlobal("PREFIX_TRUNK_$trunkname",count($entries));1564 }1565 1594 } 1566 1595 … … 1915 1944 $ext->add($context, $exten, '', new ext_set('DIAL_TRUNK_OPTIONS', '${TRUNK_OPTIONS}')); 1916 1945 $ext->add($context, $exten, '', new ext_macro('outbound-callerid', '${DIAL_TRUNK}')); 1917 $ext->add($context, $exten, 'skipoutcid', new ext_ execif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','AGI','fixlocalprefix')); // this sets DIAL_NUMBER to the proper dial string for this trunk1946 $ext->add($context, $exten, 'skipoutcid', new ext_gosubif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','sub-flp-${DIAL_TRUNK},s,1')); // this sets DIAL_NUMBER to the proper dial string for this trunk 1918 1947 $ext->add($context, $exten, '', new ext_set('OUTNUM', '${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}')); // OUTNUM is the final dial number 1919 1948 $ext->add($context, $exten, '', new ext_set('custom', '${CUT(OUT_${DIAL_TRUNK},:,1)}')); // Custom trunks are prefixed with "AMP:" … … 2048 2077 $ext->add($context, $exten, '', new ext_set('DIAL_TRUNK_OPTIONS', '${TRUNK_OPTIONS}')); 2049 2078 $ext->add($context, $exten, '', new ext_macro('outbound-callerid', '${DIAL_TRUNK}')); 2050 $ext->add($context, $exten, 'skipoutcid', new ext_ execif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','AGI','fixlocalprefix')); // this sets DIAL_NUMBER to the proper dial string for this trunk2079 $ext->add($context, $exten, 'skipoutcid', new ext_gosubif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','sub-flp-${DIAL_TRUNK},s,1')); // manipulate DIAL_NUMBER 2051 2080 $ext->add($context, $exten, '', new ext_set('OUTNUM', '${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}')); // OUTNUM is the final dial number 2052 2081 … … 2218 2247 $ext->add($context, $exten, 'nomax', new ext_set('DIAL_NUMBER', '${ARG2}')); 2219 2248 $ext->add($context, $exten, '', new ext_set('DIAL_TRUNK', '${ARG1}')); 2220 $ext->add($context, $exten, '', new ext_ execif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','AGI','fixlocalprefix')); // this sets DIAL_NUMBER to the proper dial string for this trunk2249 $ext->add($context, $exten, '', new ext_gosubif('$["${PREFIX_TRUNK_${DIAL_TRUNK}}" != ""]','sub-flp-${DIAL_TRUNK},s,1')); // manimpulate DIAL_NUMBER 2221 2250 // Replacement for asterisk's ENUMLOOKUP function 2222 2251 $ext->add($context, $exten, '', new ext_agi('enumlookup.agi')); … … 4491 4520 4492 4521 4493 4494 4495 4522 /* begin page.trunks.php functions */ 4496 4523 … … 4779 4806 4780 4807 4781 function core_trunks_addDialRules($trunknum, $dialrules) { 4782 global $db; 4783 4784 $rules_arr = array(); 4785 $i = 1; 4786 foreach ($dialrules as $rule) { 4787 $rules_arr[] = array($db->escapeSimple($rule),$i); 4788 $i++; 4789 } 4790 sql("DELETE FROM `trunks_dialpatterns` WHERE `trunkid` = $trunknum"); 4791 $compiled = $db->prepare("INSERT INTO `trunks_dialpatterns` (trunkid, rule, seq) VALUES ($trunknum,?,?)"); 4792 $result = $db->executeMultiple($compiled,$rules_arr); 4808 function core_trunks_update_dialrules($trunknum, &$patterns, $delete = false) { 4809 global $db; 4810 4811 $trunknum = $db->escapeSimple($trunknum); 4812 $filter_prepend = '/[^0-9+*#]/'; 4813 $filter_prefix = '/[^0-9.*#+xnzXNZ\-\[\]]/'; 4814 $filter_match = '/[^0-9*#+xnzXNZ\-\[\]]/'; 4815 4816 $insert_pattern = array(); 4817 $seq = 0; 4818 foreach ($patterns as $pattern) { 4819 $match_pattern_prefix = $db->escapeSimple(preg_replace($filter_prefix,'',strtoupper(trim($pattern['match_pattern_prefix'])))); 4820 $match_pattern_pass = $db->escapeSimple(preg_replace($filter_match,'',strtoupper(trim($pattern['match_pattern_pass'])))); 4821 $prepend_digits = $db->escapeSimple(preg_replace($filter_prepend,'',strtoupper(trim($pattern['prepend_digits'])))); 4822 if ($match_pattern_prefix.$match_pattern_pass == '') { 4823 continue; 4824 } 4825 // if duplicate prepend, get rid of subsequent since they will never be checked 4826 $hash_index = md5($match_pattern_prefix.$match_pattern_pass); 4827 if (!isset($insert_pattern[$hash_index])) { 4828 $insert_pattern[$hash_index] = array($match_pattern_prefix, $match_pattern_pass, $prepend_digits, $seq); 4829 $seq++; 4830 } 4831 } 4832 4833 if ($delete) { 4834 sql('DELETE FROM `trunk_dialpatterns` WHERE `trunkid`='.q($trunknum)); 4835 } 4836 $compiled = $db->prepare('INSERT INTO `trunk_dialpatterns` (`trunkid`, `match_pattern_prefix`, `match_pattern_pass`, `prepend_digits`, `seq`) VALUES ('.$trunknum.',?,?,?,?)'); 4837 $result = $db->executeMultiple($compiled,$insert_pattern); 4793 4838 if(DB::IsError($result)) { 4794 die_freepbx($result->getDebugInfo()."<br><br>".'error adding to trunks_dialpatterns table'); 4795 } 4796 } 4797 4798 function core_trunks_readDialRulesFile() { 4799 $rule_hash = array(); 4800 $sqlstr = "SELECT `trunkid`, `rule` FROM `trunks_dialpatterns` ORDER BY `trunkid`, `seq`"; 4801 $patterns = sql($sqlstr,"getAll",DB_FETCHMODE_ASSOC); 4802 $trunk_num = false; 4839 die_freepbx($result->getDebugInfo()."<br><br>".'error updating trunk_dialpatterns'); 4840 } 4841 } 4842 4843 function core_trunks_list_dialrules() { 4844 $rule_hash = array(); 4845 4846 $patterns = core_trunks_get_dialrules(); 4803 4847 foreach ($patterns as $pattern) { 4804 if ($pattern['trunkid'] != $trunk_num) { 4805 $rule_num = 1; 4806 $trunk_num = $pattern['trunkid']; 4807 } 4808 $rule_hash['trunk-'.$pattern['trunkid']]['rule'.$rule_num++] = $pattern['rule']; 4848 //$rule_hash[$pattern['trunkid']][] = $pattern['prepend_digits'].'^'.$pattern['match_pattern_prefix'].'|'.$pattern['match_pattern_pass']; 4849 $rule_hash[$pattern['trunkid']][] = $pattern; 4809 4850 } 4810 4851 return $rule_hash; … … 4911 4952 } 4912 4953 4913 function core_trunks_getDialRules($trunknum) { 4914 $conf = core_trunks_readDialRulesFile(); 4915 if (isset($conf["trunk-".$trunknum])) { 4916 return $conf["trunk-".$trunknum]; 4917 } 4918 return false; 4919 } 4954 function core_trunks_get_dialrules($trunknum = false) { 4955 global $db; 4956 if ($trunknum === false) { 4957 $sql = "SELECT * FROM `trunk_dialpatterns` ORDER BY `trunkid`, `seq`"; 4958 } else { 4959 $trunknum = q($db->escapeSimple($trunknum)); 4960 $sql = "SELECT * FROM `trunk_dialpatterns` WHERE `trunkid` = $trunknum ORDER BY `seq`"; 4961 } 4962 $patterns = sql($sql,"getAll",DB_FETCHMODE_ASSOC); 4963 return $patterns; 4964 } 4965 4920 4966 4921 4967 //get outbound routes for a given trunk … … 4931 4977 } 4932 4978 4979 function core_trunks_delete_dialrules($trunknum) { 4980 global $db; 4981 $trunknum = q($db->escapeSimple($trunknum)); 4982 sql("DELETE FROM `trunk_dialpatterns` WHERE `trunkid` = $trunknum"); 4983 } 4984 4985 4986 //----------------------------------------------------------------------------------------------------------------------------------------- 4987 // The following APIs have all been removed and will result in crashes with traceback to obtain calling tree information 4988 4989 function core_trunks_addDialRules($trunknum, $dialrules) { 4990 $trace = debug_backtrace(); 4991 $function = $trace[0]['function']; 4992 die_freepbx("function: $function has been deprecated and removed"); 4993 } 4994 4933 4995 function core_trunks_deleteDialRules($trunknum) { 4934 sql("DELETE FROM `trunks_dialpatterns` WHERE `trunkid` = $trunknum"); 4935 } 4996 $trace = debug_backtrace(); 4997 $function = $trace[0]['function']; 4998 die_freepbx("function: $function has been deprecated and removed"); 4999 } 5000 5001 function core_trunks_getDialRules($trunknum) { 5002 $trace = debug_backtrace(); 5003 $function = $trace[0]['function']; 5004 die_freepbx("function: $function has been deprecated and removed"); 5005 } 5006 5007 function core_trunks_readDialRulesFile() { 5008 $trace = debug_backtrace(); 5009 $function = $trace[0]['function']; 5010 die_freepbx("function: $function has been deprecated and removed"); 5011 } 5012 4936 5013 4937 5014 /* end page.trunks.php functions */ … … 5181 5258 5182 5259 $route_id = $db->escapeSimple($route_id); 5183 $filter = '/[^0-9\ -\.\[\]xXnNzZ]/';5260 $filter = '/[^0-9\*\#\+\-\.\[\]xXnNzZ]/'; 5184 5261 $insert_pattern = array(); 5185 5262 foreach ($patterns as $pattern) { 5186 $match_pattern_prefix = $db->escapeSimple(preg_replace($filter,'',strtoupper($pattern['match_pattern_prefix']))); 5187 $match_pattern_pass = $db->escapeSimple(preg_replace($filter,'',strtoupper($pattern['match_pattern_pass']))); 5188 $match_cid = $db->escapeSimple(preg_replace($filter,'',strtoupper($pattern['match_cid']))); 5189 $prepend_digits = $db->escapeSimple(preg_replace($filter,'',strtoupper($pattern['prepend_digits']))); 5263 $match_pattern_prefix = $db->escapeSimple(preg_replace($filter,'',strtoupper(trim($pattern['match_pattern_prefix'])))); 5264 $match_pattern_pass = $db->escapeSimple(preg_replace($filter,'',strtoupper(trim($pattern['match_pattern_pass'])))); 5265 $match_cid = $db->escapeSimple(preg_replace($filter,'',strtoupper(trim($pattern['match_cid'])))); 5266 $prepend_digits = $db->escapeSimple(preg_replace($filter,'',strtoupper(trim($pattern['prepend_digits'])))); 5267 5268 if ($match_pattern_pass.$match_pattern_pass.$match_cid == '') { 5269 continue; 5270 } 5190 5271 5191 5272 $hash_index = md5($match_pattern_prefix.$match_pattern_pass.$match_cid); 5192 $insert_pattern[$hash_index] = array($match_pattern_prefix, $match_pattern_pass, $match_cid, $prepend_digits); 5273 if (!isset($insert_pattern[$hash_index])) { 5274 $insert_pattern[$hash_index] = array($match_pattern_prefix, $match_pattern_pass, $match_cid, $prepend_digits); 5275 } 5193 5276 } 5194 5277 modules/branches/2.8/core/install.php
r8671 r9240 267 267 } 268 268 269 270 269 // This next set of functions and code are used to migrate from the old 271 270 // global variable storage of trunk data to the new trunk table and trunk … … 279 278 ereg("OUT_([0-9]+)",$unique_trunks[$b][0],$trunk_num2); 280 279 return ($trunk_num1[1] >= $trunk_num2[1]? 1:-1); 281 }282 283 // Get values from localprefix configuration file where values are stored284 // for fixlocalprefix macro285 //286 function __parse_DialRulesFile($filename, &$conf, &$section) {287 if (is_null($conf)) {288 $conf = array();289 }290 if (is_null($section)) {291 $section = "general";292 }293 294 if (file_exists($filename)) {295 $fd = fopen($filename, "r");296 while ($line = fgets($fd, 1024)) {297 if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {298 // name = value299 // option line300 $conf[$section][ $matches[1] ] = $matches[2];301 } else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {302 // section name303 $section = strtolower($matches[1]);304 } else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {305 // include another file306 307 if ($matches[1][0] == "/") {308 // absolute path309 $filename = $matches[1];310 } else {311 // relative path312 $filename = dirname($filename)."/".$matches[1];313 }314 __parse_DialRulesFile($filename, $conf, $section);315 }316 }317 }318 }319 320 function __order_DialRules($a, $b) {321 return substr($a,4) > substr($b,4);322 280 } 323 281 … … 519 477 } 520 478 521 $sql = "522 CREATE TABLE `trunks_dialpatterns`523 (524 `trunkid` INTEGER,525 `rule` VARCHAR( 255 ) NOT NULL,526 `seq` INTEGER,527 PRIMARY KEY (`trunkid`, `rule`, `seq`)528 )529 ";530 outn(_("Checking if trunks_dialpatterns table exists.."));531 $check = $db->query($sql);532 if(DB::IsError($check) && $check->getCode() != DB_ERROR_ALREADY_EXISTS) {533 die_freepbx("Can not create trunks_dialpatterns table");534 } else if(DB::IsError($check) && $check->getCode() == DB_ERROR_ALREADY_EXISTS) {535 out(_("already exists"));536 } else {537 out(_("created"));538 outn(_("loading table from localprefixes.conf.."));539 $localPrefixFile = $amp_conf['ASTETCDIR']."/localprefixes.conf";540 $conf == array();541 __parse_DialRulesFile($localPrefixFile, $conf, $section);542 543 $rules_arr = array();544 foreach ($conf as $tname => $rules) {545 $tid = ltrim($tname,'trunk-');546 uksort($rules,'__order_DialRules'); //make sure they are in order547 $seq = 1;548 foreach ($rules as $rule) {549 $rules_arr[] = array($tid,$rule,$seq);550 $seq++;551 }552 }553 $compiled = $db->prepare("INSERT INTO `trunks_dialpatterns` (trunkid, rule, seq) VALUES (?,?,?)");554 $result = $db->executeMultiple($compiled,$rules_arr);555 if(DB::IsError($result)) {556 die_freepbx($result->getDebugInfo().'error populating trunks_dialpatterns table');557 }558 out(_("loaded"));559 }560 561 479 outn(_("Checking if privacy manager options exists..")); 562 480 $check = $db->query('SELECT pmmaxretries FROM incoming'); modules/branches/2.8/core/module.xml
r9210 r9240 10 10 <canuninstall>no</canuninstall> 11 11 <changelog> 12 *2.8.0.0beta1.1* #4132, #2833 12 *2.8.0.0beta1.1* #4132, #2833, #4068, #4135, #4143, #4144 13 13 *2.8.0.0beta1.0* #4100, #4102, #4110 New Outbound Routing Schema and features 14 14 *2.7.0.2* really fix #4092 modules/branches/2.8/core/page.routing.php
r9229 r9240 234 234 if ($key > 0) { 235 235 echo "\t\t<img src=\"images/resultset_up.png\" onclick=\"repositionRoute('{$tresult['route_id']}','up')\" alt='" . _("Move Up") . 236 "' style=' float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n";236 "' style='cursor:pointer; float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; 237 237 } else { 238 238 echo "\t\t<img src='images/blank.gif' style='float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; … … 242 242 if ($key < ($positions-1)) { 243 243 echo "\t\t<img src='images/resultset_down.png' onclick=\"repositionRoute('{$tresult['route_id']}','down')\" alt='" . _("Move Down") . 244 "' style=' float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n";244 "' style='cursor:pointer; float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; 245 245 } else { 246 246 echo "\t\t<img src='images/blank.gif' style='float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; … … 250 250 if ($key > 0) { 251 251 echo "\t\t<img src=\"images/resultset_top.png\" onclick=\"repositionRoute('{$tresult['route_id']}','top')\" alt='" . _("First") . 252 "' style=' float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n";252 "' style='cursor:pointer; float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; 253 253 } else { 254 254 echo "\t\t<img src='images/blank.gif' style='float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; … … 258 258 if ($key < ($positions-1)) { 259 259 echo "\t\t<img src='images/resultset_bottom.png' onclick=\"repositionRoute('{$tresult['route_id']}','bottom')\" alt='" . _("Last") . 260 "' style=' float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n";260 "' style='cursor:pointer; float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; 261 261 } else { 262 262 echo "\t\t<img src='images/blank.gif' style='float:none; margin-left:0px; margin-bottom:0px;' width='12px' height='12px'>\n"; … … 421 421 <b>[1237-9]</b> <?php echo _("matches any digit in the brackets (example: 1,2,3,7,8,9)")?><br /> 422 422 <b>.</b> <?php echo _("wildcard, matches one or more dialed digits")?> <br /> 423 <b><?php echo _("prepend ")?></b> <?php echo _("Digits to prepend to a successful match. If the dialed number matches the patterns specified by the subsequent columns, then thisewill be prepended before sending to the trunks.")?><br />424 <b><?php echo _("prefix ")?></b> <?php echo _("Prefix to remove on a successful match. The dialed number is compared to this and the subsequent columns for a match. Upon a match, this prefix is removed from the dialed number before sending it to the trunks.")?><br />425 <b><?php echo _("match pattern ")?></b> <?php echo _("The dialed number will be compared against the prefix + this match pattern. Upon a match, the match pattern portion of the dialed number will be sent to the trunks")?><br />426 <b><?php echo _("CallerID ")?></b> <?php echo _("If CallerID is supplied, the dialed number will only match the prefix + match pattern if the CallerID being transmitted matches this. When extensions make outbound calls, the CallerID will be their extension number and NOT their Outbound CID. The above special matching sequences can be used for CallerID matching similar to other number matches.")?><br />423 <b><?php echo _("prepend:")?></b> <?php echo _("Digits to prepend to a successful match. If the dialed number matches the patterns specified by the subsequent columns, then this will be prepended before sending to the trunks.")?><br /> 424 <b><?php echo _("prefix:")?></b> <?php echo _("Prefix to remove on a successful match. The dialed number is compared to this and the subsequent columns for a match. Upon a match, this prefix is removed from the dialed number before sending it to the trunks.")?><br /> 425 <b><?php echo _("match pattern:")?></b> <?php echo _("The dialed number will be compared against the prefix + this match pattern. Upon a match, the match pattern portion of the dialed number will be sent to the trunks")?><br /> 426 <b><?php echo _("CallerID:")?></b> <?php echo _("If CallerID is supplied, the dialed number will only match the prefix + match pattern if the CallerID being transmitted matches this. When extensions make outbound calls, the CallerID will be their extension number and NOT their Outbound CID. The above special matching sequences can be used for CallerID matching similar to other number matches.")?><br /> 427 427 </span></a> 428 428 <hr></h5></td> … … 598 598 </select> 599 599 600 <img src="images/trash.png" style=" float:none; margin-left:0px; margin-bottom:-3px;" title="Click here to remove this trunk" onclick="deleteTrunk(<?php echo $key ?>)">600 <img src="images/trash.png" style="cursor:pointer; float:none; margin-left:0px; margin-bottom:-3px;" title="Click here to remove this trunk" onclick="deleteTrunk(<?php echo $key ?>)"> 601 601 <?php // move up 602 602 if ($key > 0) {?> … … 609 609 610 610 if ($key < ($positions-1)) {?> 611 <img src="images/resultset_down.png" onclick="repositionTrunk('<?php echo $key ?>','down')" alt="<?php echo _("Move Down")?>" style=" float:none; margin-left:0px; margin-bottom:0px;" width="12px" height="12px">611 <img src="images/resultset_down.png" onclick="repositionTrunk('<?php echo $key ?>','down')" alt="<?php echo _("Move Down")?>" style="cursor:pointer; float:none; margin-left:0px; margin-bottom:0px;" width="12px" height="12px"> 612 612 <?php } else { ?> 613 613 <img src="images/blank.gif" style="float:none; margin-left:0px; margin-bottom:0px;" width="9" height="11"> … … 681 681 682 682 function patternsRemove(idx) { 683 $("#prepend_digit_"+idx+",#pattern_prefix_"+idx+",#pattern_pass_"+idx+",#match_cid_"+idx).each(function(){ 684 this.value = ''; 685 }).parent().parent().hide(); 686 } 687 688 /* Insert a sip_setting/sip_value pair of text boxes */ 683 $("#prepend_digit_"+idx).parent().parent().remove(); 684 } 685 689 686 function addCustomField(prepend_digit, pattern_prefix, pattern_pass, match_cid) { 690 687 var idx = $(".dial-pattern").size(); … … 699 696 var dpt_match_cid = match_cid == '' ? 'dpt-title' : 'dpt-value'; 700 697 701 $("#last_row").before('\698 var new_insert = $("#last_row").before('\ 702 699 <tr>\ 703 700 <td colspan="2">\ … … 706 703 [<input title="<?php echo $mp_tit?>" type="text" size="16" id="pattern_pass_'+idx+'" name="pattern_pass['+idx+']" class="'+dpt_pattern_pass+'" value="'+pattern_pass+'" tabindex="'+tabindex2+'"> /\ 707 704 <input title="<?php echo $ci_tit?>" type="text" size="14" id="match_cid_'+idx+'" name="match_cid['+idx+']" class="'+dpt_match_cid+'" value="'+match_cid+'" tabindex="'+tabindex3+'">]\ 708 <img src="images/trash.png" style=" float:none; margin-left:0px; margin-bottom:-3px;" alt="<?php echo _("remove")?>" title="<?php echo _("Click here to remove this pattern")?>" onclick="patternsRemove('+idx+')">\705 <img src="images/trash.png" style="cursor:pointer; float:none; margin-left:0px; margin-bottom:-3px;" alt="<?php echo _("remove")?>" title="<?php echo _("Click here to remove this pattern")?>" onclick="patternsRemove('+idx+')">\ 709 706 </td>\ 710 707 </tr>\ 711 ') ;712 // There's almost always one blank field so make sure these are done 713 $(".dpt-title").toggleVal({708 ').prev(); 709 710 new_insert.find(".dpt-title").toggleVal({ 714 711 populateFrom: "title", 715 712 changedClass: "text-normal", 716 713 focusClass: "text-normal" 717 714 }); 718 // If any value were put in, handled those also719 715 if (pattern_pass != '' || pattern_prefix != '' || prepend_digit != '' || match_cid != '') { 720 $(".dpt-value").toggleVal({716 new_insert.find(".dpt-value").toggleVal({ 721 717 changedClass: "text-red" 722 718 }); modules/branches/2.8/core/page.trunks.php
r9217 r9240 42 42 $failtrunk_enable = ($failtrunk == "")?'':'CHECKED'; 43 43 44 if (isset($_REQUEST["dialrules"])) { 45 $dialrules = explode("\n",$_REQUEST["dialrules"]); 46 47 if (is_array($dialrules)) 48 foreach (array_keys($dialrules) as $key) { 49 //trim it 50 $dialrules[$key] = trim($dialrules[$key]); 51 52 // remove blanks 53 if ($dialrules[$key] == "") unset($dialrules[$key]); 54 55 // remove leading underscores (we do that on backend) 56 if ($dialrules[$key][0] == "_") $dialrules[$key] = substr($dialrules[$key],1); 57 } 58 59 // check for duplicates, and re-sequence 60 $dialrules = array_values(array_unique($dialrules)); 61 } else { 62 $dialrules = array(); 63 } 44 // 45 // Use a hash of the value inserted to get rid of duplicates 46 $dialpattern_insert = array(); 47 $p_idx = 0; 48 $n_idx = 0; 49 50 if (isset($_POST["prepend_digit"])) { 51 $prepend_digit = $_POST["prepend_digit"]; 52 $pattern_prefix = $_POST["pattern_prefix"]; 53 $pattern_pass = $_POST["pattern_pass"]; 54 55 foreach (array_keys($prepend_digit) as $key) { 56 if ($prepend_digit[$key]!='' || $pattern_prefix[$key]!='' || $pattern_pass[$key]!='') { 57 58 $dialpattern_insert[] = array( 59 'prepend_digits' => htmlspecialchars(trim($prepend_digit[$key])), 60 'match_pattern_prefix' => htmlspecialchars(trim($pattern_prefix[$key])), 61 'match_pattern_pass' => htmlspecialchars(trim($pattern_pass[$key])), 62 ); 63 } 64 } 65 } 66 64 67 65 68 //if submitting form, update database … … 68 71 $trunknum = core_trunks_add($tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register, $keepcid, trim($failtrunk), $disabletrunk, $trunk_name, $provider); 69 72 70 core_trunks_addDialRules($trunknum, $dialrules);73 core_trunks_update_dialrules($trunknum, $dialpattern_insert); 71 74 needreload(); 72 75 redirect_standard(); … … 76 79 77 80 // this can rewrite too, so edit is the same 78 core_trunks_addDialRules($trunknum, $dialrules);81 core_trunks_update_dialrules($trunknum, $dialpattern_insert, true); 79 82 needreload(); 80 83 redirect_standard('extdisplay'); … … 83 86 84 87 core_trunks_del($trunknum); 85 core_trunks_deleteDialRules($trunknum);88 core_trunks_delete_dialrules($trunknum); 86 89 core_routing_trunk_del($trunknum); 87 90 needreload(); … … 108 111 109 112 if (isset($xmldata['lca-data']['prefix'])) { 110 113 $hash_filter = array(); //avoid duplicates 111 114 if ($action == 'populatenpanxx10') { 112 115 // 10 digit dialing … … 114 117 // - match local 10 digits 115 118 // - add 1 to anything else 116 $dialrules[] = $matches[1].'NXXXXXX'; 119 $dialpattern_array[] = array( 120 'prepend_digits' => '', 121 'match_pattern_prefix' => '', 122 'match_pattern_pass' => htmlspecialchars($matches[1].'NXXXXXX'), 123 ); 117 124 // add NPA to 7-digits 118 125 foreach ($xmldata['lca-data']['prefix'] as $prefix) { 119 $dialrules[] = $prefix['npa'].'+'.$prefix['nxx'].'XXXX'; 126 if (isset($hash_filter[$prefix['npa'].'+'.$prefix['nxx']])) { 127 continue; 128 } else { 129 $hash_filter[$prefix['npa'].'+'.$prefix['nxx']] = true; 130 } 131 $dialpattern_array[] = array( 132 'prepend_digits' => htmlspecialchars($prefix['npa']), 133 'match_pattern_prefix' => '', 134 'match_pattern_pass' => htmlspecialchars($prefix['nxx'].'XXXX'), 135 ); 120 136 } 121 137 foreach ($xmldata['lca-data']['prefix'] as $prefix) { 122 $dialrules[] = $prefix['npa'].$prefix['nxx'].'XXXX'; 138 if (isset($hash_filter[$prefix['npa'].$prefix['nxx']])) { 139 continue; 140 } else { 141 $hash_filter[$prefix['npa'].$prefix['nxx']] = true; 142 } 143 $dialpattern_array[] = array( 144 'prepend_digits' => '', 145 'match_pattern_prefix' => '', 146 'match_pattern_pass' => htmlspecialchars($prefix['npa'].$prefix['nxx'].'XXXX'), 147 ); 123 148 } 124 149 // if a number was not matched as local, dial it with '1' prefix 125 $dialrules[] = '1+NXXNXXXXXX'; 150 $dialpattern_array[] = array( 151 'prepend_digits' => '', 152 'match_pattern_prefix' => '', 153 'match_pattern_pass' => '1+NXXNXXXXXX', 154 ); 126 155 } else { 127 156 // 7 digit dialing … … 130 159 // - add 1 to everything else 131 160 foreach ($xmldata['lca-data']['prefix'] as $prefix) { 132 $dialrules[] = $prefix['npa'].'|'.$prefix['nxx'].'XXXX'; 161 if (isset($hash_filter[$prefix['npa'].'|'.$prefix['nxx']])) { 162 continue; 163 } else { 164 $hash_filter[$prefix['npa'].'|'.$prefix['nxx']] = true; 165 } 166 $dialpattern_array[] = array( 167 'prepend_digits' => '', 168 'match_pattern_prefix' => htmlspecialchars( $prefix['npa']), 169 'match_pattern_pass' => htmlspecialchars($prefix['nxx'].'XXXX'), 170 ); 133 171 } 134 172 foreach ($xmldata['lca-data']['prefix'] as $prefix) { 135 $dialrules[] = $prefix['nxx'].'XXXX'; 173 if (isset($hash_filter[$prefix['nxx']])) { 174 continue; 175 } else { 176 $hash_filter[$prefix['nxx']] = true; 177 } 178 $dialpattern_array[] = array( 179 'prepend_digits' => '', 180 'match_pattern_prefix' => '', 181 'match_pattern_pass' => htmlspecialchars($prefix['nxx'].'XXXX'), 182 ); 136 183 } 137 $dialrules[] = '1+NXXNXXXXXX'; 138 $dialrules[] = '1'.$matches[1].'+NXXXXXX'; 184 $dialpattern_array[] = array( 185 'prepend_digits' => '1', 186 'match_pattern_prefix' => '', 187 'match_pattern_pass' => 'NXXNXXXXXX', 188 ); 189 $dialpattern_array[] = array( 190 'prepend_digits' => htmlspecialchars('1'.$matches[1]), 191 'match_pattern_prefix' => '', 192 'match_pattern_pass' => 'NXXXXXX', 193 ); 139 194 } 140 195 141 196 // check for duplicates, and re-sequence 142 $dialrules = array_values(array_unique($dialrules));197 unset($hash_filter); 143 198 } else { 144 199 $errormsg = _("Error fetching prefix list for: "). $_REQUEST["npanxx"]; … … 241 296 $provider = $trunk_details['provider']; 242 297 $trunk_name = htmlentities($trunk_details['name']); 243 298 244 299 if ($tech!="enum") { 245 300 … … 264 319 } 265 320 } 266 if (count($dialrules) == 0) { 267 if ($temp = core_trunks_getDialRules($trunknum)) { 268 foreach ($temp as $key=>$val) { 269 // extract all ruleXX keys 270 if (preg_match("/^rule\d+$/",$key)) { 271 $dialrules[] = $val; 272 } 273 } 274 } 275 unset($temp); 276 } 321 if (count($dialpattern_array) == 0) { 322 $dialpattern_array = core_trunks_get_dialrules($trunknum); 323 } 277 324 $upper_tech = strtoupper($tech); 278 325 if (trim($trunk_name) == '') { … … 333 380 echo "<h2>".sprintf(_("Add %s Trunk"),$upper_tech).($upper_tech == 'ZAP' && ast_with_dahdi()?" ("._("DAHDI compatibility mode").")":"")."</h2>"; 334 381 } 382 if (!isset($dialpattern_array)) { 383 $dialpattern_array = array(); 384 } 385 335 386 switch ($tech) { 336 387 case 'dundi': … … 360 411 <tr> 361 412 <td colspan="2"> 362 <h4><?php echo _("General Settings")?>< /h4>413 <h4><?php echo _("General Settings")?><hr></h4> 363 414 </td> 364 415 </tr> … … 431 482 </tr> 432 483 433 <tr> 434 <td colspan="2"> 435 <h4><?php echo _("Outgoing Dial Rules")?></h4> 436 </td> 437 </tr> 438 <tr> 439 <td valign="top"> 440 <a href=# class="info"><?php echo _("Dial Rules")?><span><?php echo _("A Dial Rule controls how calls will be dialed on this trunk. It can be used to add or remove prefixes. Numbers that don't match any patterns defined here will be dialed as-is. Note that a pattern without a + or | (to add or remove a prefix) will not make any changes but will create a match. Only the first matched rule will be executed and the remaining rules will not be acted on.")?><br /><br /><b><?php echo _("Rules:")?></b><br /> 441 <strong>X</strong> <?php echo _("matches any digit from 0-9")?><br /> 442 <strong>Z</strong> <?php echo _("matches any digit from 1-9")?><br /> 443 <strong>N</strong> <?php echo _("matches any digit from 2-9")?><br /> 444 <strong>[1237-9]</strong> <?php echo _("matches any digit or letter in the brackets (in this example, 1,2,3,7,8,9)")?><br /> 445 <strong>.</strong> <?php echo _("wildcard, matches one or more characters (not allowed before a | or +)")?><br /> 446 <strong>|</strong> <?php echo _("removes a dialing prefix from the number (for example, 613|NXXXXXX would match when some dialed \"6135551234\" but would only pass \"5551234\" to the trunk)")?> 447 <strong>+</strong> <?php echo _("adds a dialing prefix from the number (for example, 1613+NXXXXXX would match when some dialed \"5551234\" and would pass \"16135551234\" to the trunk)")?><br /><br /> 448 <?php echo _("You can also use both + and |, for example: 01+0|1ZXXXXXXXXX would match \"016065551234\" and dial it as \"0116065551234\" Note that the order does not matter, eg. 0|01+1ZXXXXXXXXX does the same thing."); ?> 449 </span></a>: 450 </td><td valign="top"> 451 <textarea id="dialrules" cols="20" tabindex="<?php echo ++$tabindex;?>" rows="<?php 452 if (is_array($dialrules)) { 453 $rows = count($dialrules)+1; 454 echo (($rows < 5) ? 5 : (($rows > 20) ? 20 : $rows) ); 455 } else { 456 echo "5"; 457 } ?>" name="dialrules"><?php if(is_array($dialrules)) { echo implode("\n",$dialrules); } ?></textarea><br> 458 459 <input type="submit" style="font-size:10px;" value="<?php echo _("Clean & Remove duplicates")?>" tabindex="<?php echo ++$tabindex;?>"/> 460 </td> 461 </tr> 484 <tr> 485 <td colspan="2"><h4> 486 <a href=# class="info"><?php echo _("Dialed Number Manipulation Rules")?><span> 487 <?php echo _("These rules can manipulate the dialed number before sending it out this trunk. If no rule applies, the number is not changed. The original dialed number is passed down from the route where some manipulation may have already occured. This trunk has the option to further manipulate the number. If the number matches the combined values in the <b>prefix</b> plus the <b>match pattern</b> boxes, the rule will be applied and all subsequent rules ignored.<b /> Upon a match, the <b>prefix</b>, if defined, will be stripped. Next the <b>prepend</b> will be inserted in front of the <b>match pattern</b> and the resulting number will be sent to the trunk. All fields are optional.")?><br /><br /><b><?php echo _("Rules:")?></b><br /> 488 <b>X</b> <?php echo _("matches any digit from 0-9")?><br /> 489 <b>Z</b> <?php echo _("matches any digit from 1-9")?><br /> 490 <b>N</b> <?php echo _("matches any digit from 2-9")?><br /> 491 <b>[1237-9]</b> <?php echo _("matches any digit in the brackets (example: 1,2,3,7,8,9)")?><br /> 492 <b>.</b> <?php echo _("wildcard, matches one or more dialed digits")?> <br /> 493 <b><?php echo _("prepend:")?></b> <?php echo _("Digits to prepend upon a successful match. If the dialed number matches the patterns in the <b>prefix</b> and <b>match pattern</b> boxes, this will be prepended before sending to the trunk.")?><br /> 494 <b><?php echo _("prefix:")?></b> <?php echo _("Prefix to remove upon a successful match. If the dialed number matches this plus the <b>match pattern</b> box, this prefix is removed before adding the optional <b>prepend</b> box and sending the results to the trunk.")?><br /> 495 <b><?php echo _("match pattern:")?></b> <?php echo _("The dialed number will be compared against the <b>prefix</b> plus this pattern. Upon a match, this portion of the number will be sent to the trunks after removing the <b>prefix</b> and appending the <b>prepend</b> digits")?><br /> 496 <?php echo _("You can completely replace a number by matching on the <b>prefix</b> only, replacing it with a <b>prepend</b> and leaving the <b>match pattern</b> blank."); ?> 497 </span></a> 498 <hr></h4></td> 499 </tr> 500 501 <tr><td colspan="2"> 502 <input type="button" id="dial-pattern-add" value="<?php echo _("Add More Dial Pattern Fields")?>" /> 503 <input type="button" id="dial-pattern-clear" value="<?php echo _("Clear all Fields")?>" /> 504 </td></tr> 505 <tr><td colspan="2"><div class="dialpatterns"><table> 506 <?php 507 $pp_tit = _("prepend"); 508 $pf_tit = _("prefix"); 509 $mp_tit = _("match pattern"); 510 foreach ($dialpattern_array as $idx => $pattern) { 511 $tabindex++; 512 $dpt_class = $pattern['prepend_digits'] == '' ? 'dpt-title' : 'dpt-value'; 513 echo <<< END 514 <tr> 515 <td colspan="2"> 516 (<input title="$pp_tit" type="text" size="5" id="prepend_digit_$idx" name="prepend_digit[$idx]" class="dial-pattern dp-prepend $dpt_class" value="{$pattern['prepend_digits']}" tabindex="$tabindex">) + 517 END; 518 $tabindex++; 519 $dpt_class = $pattern['match_pattern_prefix'] == '' ? 'dpt-title' : 'dpt-value'; 520 echo <<< END 521 <input title="$pf_tit" type="text" size="4" id="pattern_prefix_$idx" name="pattern_prefix[$idx]" class="dp-prefix $dpt_class" value="{$pattern['match_pattern_prefix']}" tabindex="$tabindex"> | 522 END; 523 $tabindex++; 524 $dpt_class = $pattern['match_pattern_pass'] == '' ? 'dpt-title' : 'dpt-value'; 525 echo <<< END 526 <input title="$mp_tit" type="text" size="16" id="pattern_pass_$idx" name="pattern_pass[$idx]" class="dp-match $dpt_class" value="{$pattern['match_pattern_pass']}" tabindex="$tabindex"> 527 END; 528 ?> 529 <img src="images/trash.png" style="cursor:pointer; float:none; margin-left:0px; margin-bottom:-3px;" alt="<?php echo _("remove")?>" title="<?php echo _('Click here to remove this pattern')?>" onclick="patternsRemove(<?php echo _("$idx") ?>)"> 530 </td> 531 </tr> 532 <?php 533 } 534 $next_idx = count($dialpattern_array); 535 ?> 536 <tr> 537 <td colspan="2"> 538 (<input title="<?php echo $pp_tit?>" type="text" size="5" id="prepend_digit_<?php echo $next_idx?>" name="prepend_digit[<?php echo $next_idx?>]" class="dp-prepend dial-pattern dpt-title" value="" tabindex="<?php echo ++$tabindex;?>">) + 539 <input title="<?php echo $pf_tit?>" type="text" size="4" id="pattern_prefix_<?php echo $next_idx?>" name="pattern_prefix[<?php echo $next_idx?>]" class="dp-prefix dpt-title" value="" tabindex="<?php echo ++$tabindex;?>"> | 540 <input title="<?php echo $mp_tit?>" type="text" size="16" id="pattern_pass_<?php echo $next_idx?>" name="pattern_pass[<?php echo $next_idx?>]" class="dp-match dpt-title" value="" tabindex="<?php echo ++$tabindex;?>"> 541 <img src="images/trash.png" style="cursor:pointer; float:none; margin-left:0px; margin-bottom:-3px;" alt="<?php echo _("remove")?>" title="<?php echo _("Click here to remove this pattern")?>" onclick="patternsRemove(<?php echo _("$next_idx") ?>)"> 542 543 </td> 544 </tr> 545 <tr id="last_row"></tr> 546 </table></div></tr></td> 547 <?php 548 $tabindex += 2000; // make room for dynamic insertion of new fields 549 ?> 462 550 <tr> 463 551 <td> … … 529 617 function populateAlwaysAdd() { 530 618 do { 531 var localpattern = <?php echo 'prompt("'._("What is the local dialing pattern?\\n\\n(ie. NXXNXXXXXX for US/CAN 10-digit dialing, NXXXXXX for 7-digit)").'"'?>,"NXXXXXX");619 var localpattern = <?php echo 'prompt("'._("What is the local dialing pattern?\\n\\n(ie. NXXNXXXXXX for US/CAN 10-digit dialing, NXXXXXX for 7-digit)").'"'?>,<?php echo _("NXXXXXX")?>); 532 620 if (localpattern == null) return; 533 621 } while (!localpattern.match('^[0-9#*ZXN\.]+$') && <?php echo '!alert("'._("Invalid pattern. Only 0-9, #, *, Z, N, X and . are allowed.").'")'?>); … … 538 626 } while (!localprefix.match('^[0-9#*]+$') && <?php echo '!alert("'._("Invalid prefix. Only dialable characters (0-9, #, and *) are allowed.").'")'?>); 539 627 540 dialrules = document.getElementById('dialrules'); 541 if (dialrules.value[dialrules.value.length-1] != '\n') { 542 dialrules.value = dialrules.value + '\n'; 543 } 544 dialrules.value = dialrules.value + localprefix + '+' + localpattern + '\n'; 628 addCustomField(localprefix,'',localpattern); 545 629 } 546 630 … … 552 636 553 637 do { 554 var localpattern = <?php echo 'prompt("'._("What is the dialing pattern for local numbers after")?> "+localprefix+"? \n\n<?php echo _("(ie. NXXNXXXXXX for US/CAN 10-digit dialing, NXXXXXX for 7-digit)").'"'?>,"NXXXXXX");638 var localpattern = <?php echo 'prompt("'._("What is the dialing pattern for local numbers after")?> "+localprefix+"? \n\n<?php echo _("(ie. NXXNXXXXXX for US/CAN 10-digit dialing, NXXXXXX for 7-digit)").'"'?>,<?php echo _("NXXXXXX")?>); 555 639 if (localpattern == null) return; 556 640 } while (!localpattern.match('^[0-9#*ZXN\.]+$') && <?php echo '!alert("'._("Invalid pattern. Only 0-9, #, *, Z, N, X and . are allowed.").'")'?>); 557 641 558 dialrules = document.getElementById('dialrules'); 559 if (dialrules.value[dialrules.value.length-1] != '\n') { 560 dialrules.value = dialrules.value + '\n'; 561 } 562 dialrules.value = dialrules.value + localprefix + '|' + localpattern + '\n'; 642 addCustomField('',localprefix,localpattern); 563 643 } 564 644 … … 581 661 } 582 662 </script> 583 <?php /* //DIALRULES 584 <tr> 585 <td> 586 <a href=# class="info">Dial rules<span>The area code this trunk is in.</span></a>: 587 </td><td> 588 <select id="dialrulestype" name="dialrulestype" onChange="changeRulesType();"> 589 <?php 590 $rules = array( "asis" => "Don't change number", 591 "always" => "Always dial prefix+areacode", 592 "local" => "Local 7-digit dialing", 593 "local10" => "Local 10-digit dialing"); 594 595 foreach ($rules as $value=>$display) { 596 echo "<option value=\"".$value."\" ".(($value == $dialrulestype) ? "SELECTED" : "").">".$display."</option>"; 597 } 598 ?> 599 </select> 600 601 </td> 602 </tr> 603 <tr> 604 <td> 605 <a href=# class="info"><?php echo _("Local dialing pattern<span>The dialing pattern to make a 'local' call.</span>")</a>: 606 </td><td> 607 <input id="localpattern" type="text" size="10" maxlength="20" name="localpattern" value="<?php echo $localpattern ?>"/> 608 609 </td> 610 </tr> 611 <tr> 612 <td> 613 <a href=# class="info"><?php echo _("Long-distance dial prefix<span>The prefix for dialing long-distance numbers. In north america, this should be \"1\".</span>")?></a>: 614 </td><td> 615 <input id="lddialprefix" type="text" size="3" maxlength="6" name="lddialprefix" value="<?php echo $lddialprefix ?>"/> 616 617 </td> 618 </tr> 619 <tr> 620 <td> 621 <a href=# class="info"><?php echo _("Local LD prefix<span>The area code this trunk is in. Any 7-digit numbers that don't match a number in the below list will have dialprefix+areacode added to them. </span>")?></a>: 622 </td><td> 623 <input id="areacode" type="text" size="3" maxlength="6" name="areacode" value="<?php echo $areacode ?>"/> 624 625 </td> 626 </tr> 627 <tr> 628 <td valign="top"> 629 <a href=# class="info"><?php echo _("Local prefixes<span>This should be a list of local areacodes + prefixes to use for local dialing.</span>")?></a>: 630 </td><td valign="top"> 631 <textarea id="localprefixes" cols="8" rows="<?php $rows = count($localprefixes)+1; echo (($rows < 5) ? 5 : (($rows > 20) ? 20 : $rows) ); ?>" name="localprefixes"><?php echo implode("\n",$localprefixes);?></textarea><br> 632 633 <input id="npanxx" name="npanxx" type="hidden" /><br> 634 <a href=# class="info"><?php echo _("Populate with local rules<span>Do a lookup from http://members.dandy.net/~czg/search.html to find all local-reachable area codes and phone numbers.</span>")?></a>: <input type="button" value="Go" onClick="checkPopulate();" /> 635 <br><br> 636 </td> 637 </tr> 638 <script language="javascript"> 639 640 function checkPopulate() { 641 //var npanxx = prompt("What is your areacode + prefix (NPA-NXX)?", document.getElementById('areacode').value); 642 var npanxx = <?php echo 'prompt("'._("What is your areacode + prefix (NPA-NXX)?").'")'?>; 643 644 if (npanxx.match("^[2-9][0-9][0-9][-]?[2-9][0-9][0-9]$")) { 645 document.getElementById('npanxx').value = npanxx; 646 trunkEdit.action.value = "populatenpanxx"; 647 trunkEdit.submit(); 648 } else if (npanxx != null) { 649 <?php echo 'alert("'._("Invalid format for NPA-NXX code (must be format: NXXNXX)").'")'?>; 650 } 651 } 652 653 function changeRulesType() { 654 switch(document.getElementById('dialrulestype').value) { 655 case "always": 656 document.getElementById('lddialprefix').disabled = false; 657 document.getElementById('areacode').disabled = false; 658 document.getElementById('localprefixes').disabled = true; 659 break; 660 case "local": 661 case "local10": 662 document.getElementById('lddialprefix').disabled = false; 663 document.getElementById('areacode').disabled = false; 664 document.getElementById('localprefixes').disabled = false; 665 break; 666 case "asis": 667 default: 668 document.getElementById('lddialprefix').disabled = true; 669 document.getElementById('areacode').disabled = true; 670 document.getElementById('localprefixes').disabled = true; 671 break; 672 } 673 } 674 changeRulesType(); 675 </script> 676 */?> 663 677 664 <tr> 678 665 <td> … … 685 672 <tr> 686 673 <td colspan="2"> 687 <h4><?php echo _("Outgoing Settings")?></h4>674 <h4><?php echo _("Outgoing Settings")?><hr></h4> 688 675 </td> 689 676 </tr> … … 814 801 <!-- 815 802 803 $(document).ready(function(){ 804 /* Add a Custom Var / Val textbox */ 805 $("#dial-pattern-add").click(function(){ 806 addCustomField('','','',''); 807 }); 808 $("#dial-pattern-clear").click(function(){ 809 clearAllPatterns(); 810 }); 811 $(".dpt-title").toggleVal({ 812 populateFrom: "title", 813 changedClass: "text-normal", 814 focusClass: "text-normal" 815 }); 816 $(".dpt-value").toggleVal({ 817 changedClass: "text-red" 818 }); 819 }); 820 821 function patternsRemove(idx) { 822 $("#prepend_digit_"+idx).parent().parent().remove(); 823 } 824 825 function addCustomField(prepend_digit, pattern_prefix, pattern_pass) { 826 var idx = $(".dial-pattern").size(); 827 var idxp = idx - 1; 828 var tabindex = parseInt($("#pattern_pass_"+idxp).attr('tabindex')) + 1; 829 var tabindex1 = tabindex + 2; 830 var tabindex2 = tabindex + 3; 831 var dpt_prepend_digit = prepend_digit == '' ? 'dpt-title' : 'dpt-value'; 832 var dpt_pattern_prefix = pattern_prefix == '' ? 'dpt-title' : 'dpt-value'; 833 var dpt_pattern_pass = pattern_pass == '' ? 'dpt-title' : 'dpt-value'; 834 835 var new_insert = $("#last_row").before('\ 836 <tr>\ 837 <td colspan="2">\ 838 (<input title="<?php echo $pp_tit?>" type="text" size="5" id="prepend_digit_'+idx+'" name="prepend_digit['+idx+']" class="dp-prepend dial-pattern '+dpt_prepend_digit+'" value="'+prepend_digit+'" tabindex="'+tabindex+'">) +\ 839 <input title="<?php echo $pf_tit?>" type="text" size="4" id="pattern_prefix_'+idx+'" name="pattern_prefix['+idx+']" class="dp-prefix '+dpt_pattern_prefix+'" value="'+pattern_prefix+'" tabindex="'+tabindex1+'"> |\ 840 <input title="<?php echo $mp_tit?>" type="text" size="16" id="pattern_pass_'+idx+'" name="pattern_pass['+idx+']" class="dp-match '+dpt_pattern_pass+'" value="'+pattern_pass+'" tabindex="'+tabindex2+'">\ 841 <img src="images/trash.png" style="cursor:pointer; float:none; margin-left:0px; margin-bottom:-3px;" alt="<?php echo _("remove")?>" title="<?php echo _("Click here to remove this pattern")?>" onclick="patternsRemove('+idx+')">\ 842 </td>\ 843 </tr>\ 844 ').prev(); 845 846 new_insert.find(".dpt-title").toggleVal({ 847 populateFrom: "title", 848 changedClass: "text-normal", 849 focusClass: "text-normal" 850 }); 851 if (pattern_pass != '' || pattern_prefix != '' || prepend_digit != '') { 852 new_insert.find(".dpt-value").toggleVal({ 853 changedClass: "text-red" 854 }); 855 } 856 857 return idx; 858 } 859 860 function clearPatterns() { 861 $(".dpt-title").each(function() { 862 if($(this).val() == $(this).data("defText")) { 863 $(this).val(""); 864 } 865 }); 866 return true; 867 } 868 869 function clearAllPatterns() { 870 $(".dpt-value").addClass('dpt-title').removeClass('dpt-value'); 871 $(".toggleval").each(function() { 872 $(this).val(""); 873 }); 874 $(".dpt-title").toggleVal({ 875 populateFrom: "title", 876 changedClass: "text-normal", 877 focusClass: "text-normal" 878 }); 879 return true; 880 } 881 882 // all blanks are ok 883 function validatePatterns() { 884 var culprit; 885 var msgInvalidDialPattern; 886 defaultEmptyOK = true; 887 888 // TODO: need to validate differently for prepend, prefix and match fields. The prepend 889 // must be a dialable digit. The prefix can be any pattern but not contain "." and 890 // the pattern can contain a "." also 891 //$filter_prepend = '/[^0-9\+\*\#/'; 892 //$filter_match = '/[^0-9\-\+\*\#\.\[\]xXnNzZ]/'; 893 //$filter_prefix = '/[^0-9\-\+\*\#\[\]xXnNzZ]/'; 894 //defaultEmptyOK = false; 895 /* TODO: get some sort of check in for dialpatterns 896 if (!isDialpattern(theForm.dialpattern.value)) 897 return warnInvalid(theForm.dialpattern, msgInvalidDialPattern); 898 */ 899 900 $(".dp-prepend").each(function() { 901 if ($.trim(this.value) == '') { 902 } else if (this.value.search('[^0-9*#+\s]+') >= 0) { 903 culprit = this; 904 return false; 905 } 906 }); 907 if (!culprit) { 908 $(".dp-prefix").each(function() { 909 if ($.trim($(this).val()) == '') { 910 } else if (!isDialpattern(this.value) || this.value.search('[._]+') >= 0) { 911 culprit = this; 912 return false; 913 } 914 }); 915 } 916 if (!culprit) { 917 $(".dp-match").each(function() { 918 if ($.trim(this.value) == '') { 919 } else if (!isDialpattern(this.value) || this.value.search('[_]+') >= 0) { 920 culprit = this; 921 return false; 922 } 923 }); 924 } 925 926 if (culprit != undefined) { 927 msgInvalidDialPattern = "<?php echo _('Dial pattern is invalid'); ?>"; 928 // now we have to put it back... 929 // do I have to turn it off first though? 930 $(".dpt-title").each(function() { 931 if ($.trim($(this).val()) == '') { 932 $(this).toggleVal({ 933 populateFrom: "title", 934 changedClass: "text-normal", 935 focusClass: "text-normal" 936 }); 937 } 938 }); 939 return warnInvalid(culprit, msgInvalidDialPattern); 940 } else { 941 return true; 942 } 943 } 944 816 945 var theForm = document.trunkEdit; 817 946 … … 839 968 if (!isInteger(theForm.maxchans.value)) 840 969 return warnInvalid(theForm.maxchans, msgInvalidMaxChans); 841 842 if (!isDialrule(theForm.dialrules.value))843 return warnInvalid(theForm.dialrules, msgInvalidDialRules);844 970 845 971 if (!isDialIdentifierSpecial(theForm.dialoutprefix.value)) … … 870 996 <?php } ?> 871 997 872 theForm.action.value = act; 873 return true; 998 clearPatterns(); 999 if (validatePatterns()) { 1000 theForm.action.value = act; 1001 return true; 1002 } else { 1003 return false; 1004 } 874 1005 } 875 1006
