root/trunk/AMP/amp_conf/htdocs/admin/modules/core/functions.inc.php

Revision 842, 53.3 kB (checked in by rcourtna, 7 years ago)

yeehaa, a working amp module. Conferences creates simple meetme rooms, and is a good demonstration of how an AMP module should look.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2
3 // The destinations this module provides
4 // returns a associative arrays with keys 'destination' and 'description'
5 function core_destinations() {
6     //get the list of meetmes
7     $results = core_users_list();
8     
9     if (isset($results)) {
10         //get voicemail
11         $uservm = getVoicemail();
12         $vmcontexts = array_keys($uservm);
13         foreach ($results as $thisext) {
14             $extnum = $thisext[0];
15             // search vm contexts for this extensions mailbox
16             foreach ($vmcontexts as $vmcontext) {
17                 if(isset($uservm[$vmcontext][$extnum])){
18                 //    $vmname = $uservm[$vmcontext][$extnum]['name'];
19                 //    $vmboxes[$extnum] = array($extnum, '"' . $vmname . '" <' . $extnum . '>');
20                 $vmboxes[$extnum] = true;
21                 }
22             }
23         }
24     }
25     
26     // return an associative array with destination and description
27     // core provides both users and voicemail boxes as destinations
28     if (isset($results)) {
29         foreach($results as $result){
30                 $extens[] = array('destination' => 'ext-local,'.$result['0'].',1', 'description' => $result['1'].' <'.$result['0'].'>');
31                 if($vmboxes[$result['0']]) {
32                     $extens[] = array('destination' => 'ext-local,${VM_PREFIX}'.$result['0'].',1', 'description' => 'voicemail box '.$result['0']);
33                 }
34         }
35     }
36     
37     return $extens;
38 }
39
40 /*     Generates dialplan for "core" components (extensions & inbound routing)
41     We call this with retrieve_conf
42 */
43 function core_get_config($engine) {
44     global $ext// is this the best way to pass this?
45     switch($engine) {
46         case "asterisk":
47             /* inbound routing extensions */
48             foreach(core_did_list() as $item) {
49                 $did = core_did_get($item['extension'],$item['cidnum']);
50                 $exten = $did['extension'];
51                 $cidnum = $did['cidnum'];
52                 
53                 // destination field in 'incoming' database is backwards from what ext_goto expects
54                 $goto_context = strtok($did['destination'],',');
55                 $goto_exten = strtok(',');
56                 $goto_pri = strtok(',');
57                 
58                 //sub a blank extension with 's'
59                 $exten = (empty($exten)?"s":$exten);
60                 $exten = $exten.(empty($cidnum)?"":"/".$cidnum); //if a CID num is defined, add it
61                 $ext->add('ext-did', $exten, '', new ext_setvar('FROM_DID',$exten));
62                 //$ext->add('ext-did', $exten, '', new ext_goto($goto_pri,$goto_exten,$goto_context));
63                 
64                 if ($exten == "s") {  //if the exten is s, then also make a catchall for undefined DIDs
65                     $catchaccount = "_X.".(empty($cidnum)?"":"/".$cidnum);
66                     $ext->add('ext-did', $catchaccount, '', new ext_setvar('FROM_DID',$catchaccount));
67                     $ext->add('ext-did', $catchaccount, '', new ext_goto($goto_pri,$goto_exten,$goto_context));
68                 }
69                 
70                 if ($item['faxexten'] != "default") {
71                     $ext->add('ext-did', $exten, '', new ext_setvar('FAX_RX',$item['faxexten']));
72                 }
73                 if (!empty($item['faxemail'])) {
74                     $ext->add('ext-did', $exten, '', new ext_setvar('FAX_RX_EMAIL',$item['faxexten']));
75                 }
76                 if ($item['answer'] == "1") {
77                     $ext->add('ext-did', $exten, '', new ext_answer(''));
78                     $ext->add('ext-did', $exten, '', new ext_wait($item['wait']));
79                 }
80                 if ($item['privacyman'] == "1") {
81                     $ext->add('ext-did', $exten, '', new ext_privacymanager(''));
82                 }
83                 
84                 //temporary use of 'incoming calls' until a time of day module is created
85                 if (empty($item['destination'])) {
86                     $ext->add('ext-did', $exten, '', new ext_goto('1','s','from-pstn'));
87                 } else {
88                     $ext->add('ext-did', $exten, '', new ext_goto($goto_pri,$goto_exten,$goto_context));
89                 }
90                 
91             }
92             
93             /* user extensions */
94             foreach(core_users_list() as $item) {
95                 $exten = core_users_get($item[0]);
96                 $vm = ($exten['voicemail'] == "enabled" ? $exten['extension'] : "novm");
97                 
98                 $ext->add('ext-local', $exten['extension'], '', new ext_macro('exten-vm',$vm.",".$exten['extension']));
99                 
100                 if($vm != "novm")
101                     $ext->add('ext-local', '${VM_PREFIX}'.$exten['extension'], '', new ext_macro('vm',$vm));
102                     
103                 $hint = core_hint_get($exten['extension']);
104                 if (!empty($hint))
105                     $ext->addHint('ext-local', $exten['extension'], $hint);
106             }
107             
108             /* dialplan globals */
109             // modules should NOT use the globals table to store anything!
110             // modules should use $ext->addGlobal("testvar","testval"); in their module_get_config() function instead
111             // I'm cheating for core functionality - do as I say, not as I do ;-)       
112             $sql = "SELECT * FROM globals";
113             $globals = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
114             foreach($globals as $global) {
115                 $ext->addGlobal($global['variable'],$global['value']);
116             }
117             
118             /* outbound routes */
119             // modules should use their own table for storage (and module_get_config() to add dialplan)
120             // modules should NOT use the extension table to store anything!
121             $sql = "SELECT application FROM extensions where context = 'outbound-allroutes'";
122             $outrts = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
123             $ext->add('outbound-allroutes', 'foo', '', new ext_noop('bar'));
124             foreach($outrts as $outrt) {
125                 $ext->addInclude('outbound-allroutes',$outrt['application']);
126                 $sql = "SELECT * FROM extensions where context = '".$outrt['application']."' ORDER BY priority ASC";
127                 $thisrt = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
128                 $ext->add($outrt['application'], $thisrt[0]['extension'], '', new ext_macro($thisrt[0]['args']));
129                 $ext->add($outrt['application'], $thisrt[1]['extension'], '', new ext_macro($thisrt[1]['args']));
130             }
131         break;
132     }
133 }
134
135
136
137
138
139
140
141
142
143
144
145 /* begin page.ampusers.php functions */
146
147 function core_ampusers_add($username, $password, $extension_low, $extension_high, $deptname, $sections) {
148     $sql = "INSERT INTO ampusers (username, password, extension_low, extension_high, deptname, sections) VALUES (";
149     $sql .= "'".$username."',";
150     $sql .= "'".$password."',";
151     $sql .= "'".$extension_low."',";
152     $sql .= "'".$extension_high."',";
153     $sql .= "'".$deptname."',";
154     $sql .= "'".implode(";",$sections)."');";
155     
156     sql($sql,"query");
157 }
158
159 function core_ampusers_del($username) {
160     $sql = "DELETE FROM ampusers WHERE username = '".$username."'";
161     sql($sql,"query");
162 }
163
164 function core_ampusers_list() {
165     $sql = "SELECT username FROM ampusers ORDER BY username";
166     return sql($sql,"getAll");
167 }
168
169 /* end page.ampusers.php functions */
170
171
172
173
174
175
176
177
178
179 /* begin page.did.php functions */
180
181 function core_did_list(){
182     $sql = "SELECT * FROM incoming";
183     return sql($sql,"getAll",DB_FETCHMODE_ASSOC);
184 }
185
186 function core_did_get($extension="",$cidnum=""){
187     $sql = "SELECT * FROM incoming WHERE cidnum = \"$cidnum\" AND extension = \"$extension\"";
188     return sql($sql,"getRow",DB_FETCHMODE_ASSOC);
189 }
190
191 function core_did_del($extension,$cidnum){
192     $sql="DELETE FROM incoming WHERE cidnum = \"$cidnum\" AND extension = \"$extension\"";
193     sql($sql);
194 }
195
196 function core_did_add($incoming){
197     extract($incoming); // create variables from request
198     $existing=core_did_get($extension,$cidnum);
199     if (empty($existing)) {
200         $destination=${$goto_indicate0.'0'};
201         $sql="INSERT INTO incoming (cidnum,extension,destination,faxexten,faxemail,answer,wait,privacyman) values (\"$cidnum\",\"$extension\",\"$destination\",\"$faxexten\",\"$faxemail\",\"$answer\",\"$wait\",\"$privacyman\")";
202         sql($sql);
203     } else {
204         echo "<script>javascript:alert('"._("A route for this DID/CID already exists!")."')</script>";
205     }
206 }
207
208 /* end page.did.php functions */
209
210
211
212
213
214
215
216 /* begin page.devices.php functions */
217
218 //get the existing devices
219 function core_devices_list() {
220     $sql = "SELECT id,description FROM devices";
221     $results = sql($sql,"getAll");
222
223     foreach($results as $result){
224         if (checkRange($result[0])){
225             $extens[] = array($result[0],$result[1]);
226         }
227     }
228     if (isset($extens)) sort($extens);
229     return $extens;
230 }
231
232
233 function core_devices_add($id,$tech,$dial,$devicetype,$user,$description){
234     global $amp_conf;
235     global $currentFile;
236     
237     //ensure this id is not already in use
238     $devices = core_devices_list();
239     if (is_array($devices)) {
240         foreach($devices as $device) {
241             if ($device[0]==$id) {
242                 echo "<script>javascript:alert('"._("This device id is already in use")."');</script>";
243                 return false;
244             }
245         }
246     }
247     //unless defined, $dial is TECH/id
248     //zap is an exception
249     if (empty($dial) && strtolower($tech) == "zap")
250         $dial = "ZAP/".$_REQUEST['channel'];
251     if (empty($dial))
252         $dial = strtoupper($tech)."/".$id;
253     
254     //check to see if we are requesting a new user
255     if ($user == "new") {
256         $user = $id;
257         $jump = true;
258     }
259     
260     //insert into devices table
261     $sql="INSERT INTO devices (id,tech,dial,devicetype,user,description) values (\"$id\",\"$tech\",\"$dial\",\"$devicetype\",\"$user\",\"$description\")";
262     sql($sql);
263     
264     //add details to astdb
265     $astman = new AGI_AsteriskManager();
266     if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
267         $astman->database_put("DEVICE",$id."/dial",$dial);
268         $astman->database_put("DEVICE",$id."/type",$devicetype);
269         $astman->database_put("DEVICE",$id."/user",$user);
270         if($user != "none") {
271             $existingdevices = $astman->database_get("AMPUSER",$user."/device");
272             if (!empty($existingdevices)) {
273                     $existingdevices .= "&";
274             }
275             $astman->database_put("AMPUSER",$user."/device",$existingdevices.$id);
276         }
277         $astman->disconnect();
278     } else {
279         fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
280     }
281     
282     //voicemail symlink
283     exec("rm -f /var/spool/asterisk/voicemail/device/".$id);
284     exec("/bin/ln -s /var/spool/asterisk/voicemail/default/".$user."/ /var/spool/asterisk/voicemail/device/".$id);
285         
286     //take care of sip/iax/zap config
287     $funct = "core_devices_add".strtolower($tech);
288     if(function_exists($funct)){
289         $funct($id);
290     }
291     
292     //script to write op_server.cfg file from mysql
293     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
294     exec($wOpScript);
295     
296 /*    if($user != "none") {
297         core_hint_add($user);
298     }*/
299     
300     //if we are requesting a new user, let's jump to users.php
301     if ($jump) {
302         echo("<script language=\"JavaScript\">window.location=\"config.php?display=users&extdisplay={$id}&name={$description}\";</script>");
303     }
304 }
305
306 function core_devices_del($account){
307     global $amp_conf;
308     global $currentFile;
309     
310     //get all info about device
311     $devinfo = core_devices_get($account);
312     
313     //delete from devices table
314     $sql="DELETE FROM devices WHERE id = \"$account\"";
315     sql($sql);
316     
317     //delete details to astdb
318     $astman = new AGI_AsteriskManager();
319     if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
320         // If a user was selected, remove this device from the user
321         $deviceuser = $astman->database_get("DEVICE",$account."/user");
322         if ($user != "none") {
323                 // Remove the device record from the user's device list
324                 $userdevices = $astman->database_get("AMPUSER",$deviceuser."/device");
325                 $userdevices = str_replace($account."&", "", $userdevices."&");
326                 // If there was more than one device, remove the extra "&" at the end.
327                 if (substr($userdevices, -1, 1) == "&") {
328                     $userdevices = substr($userdevices, 0, -1);
329                 }
330                 if (empty($userdevices)) {
331                         $astman->database_del("AMPUSER",$deviceuser."/device");
332                 } else {
333                         $astman->database_put("AMPUSER",$deviceuser."/device",$userdevices);
334                 }
335         }
336         $astman->database_del("DEVICE",$account."/dial");
337         $astman->database_del("DEVICE",$account."/type");
338         $astman->database_del("DEVICE",$account."/user");
339         $astman->disconnect();
340     } else {
341         fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
342     }
343     
344     //voicemail symlink
345     exec("rm -f /var/spool/asterisk/voicemail/device/".$account);
346     
347     //take care of sip/iax/zap config
348     $funct = "core_devices_del".strtolower($devinfo['tech']);
349     if(function_exists($funct)){
350         $funct($account);
351     }
352     
353     //script to write op_server.cfg file from mysql
354     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
355     exec($wOpScript);
356     
357     //take care of any hint priority
358     /*core_hint_add($devinfo['user']);*/
359 }
360
361 function core_devices_get($account){
362     //get all the variables for the meetme
363     $sql = "SELECT * FROM devices WHERE id = '$account'";
364     $results = sql($sql,"getRow",DB_FETCHMODE_ASSOC);
365     
366     //take care of sip/iax/zap config
367     $funct = "get".strtolower($results['tech']);
368     if(function_exists($funct)){
369         $devtech = $funct($account);
370         if (is_array($devtech)){
371             $results = array_merge($results,$devtech);
372         }
373     }
374     
375     return $results;
376 }
377
378 /*
379 //TODO it is current not possible to use ${variables} for a HINT extensions (ie: for adhoc devices).
380 //Because of this limitation, the only way to update HINTs for adhoc devices, is to make the change
381 //via the amp admin, so that a dialplan rewrite $ reload can be performed.
382 function core_hint_add($account){
383     global $currentFile;   
384     //delete any existing hint for this extension
385     core_hint_del($account);
386     
387     //determine what devices this user is associated with
388     $sql = "SELECT dial from devices where user = '{$account}'";
389     $results = sql($sql,"getOne");
390     
391     //create a string
392     if (isset($results)){
393         if (strpos($results,"&"))
394             $hint = implode($results,"&");
395         else
396             $hint = $results;
397     }
398
399     //Add 'hint' priority if passed
400     if (isset($hint)) {
401         $sql = "INSERT INTO extensions (context, extension, priority, application) VALUES ('ext-local', '".$account."', 'hint', '".$hint."')";
402         sql($sql);
403     }
404     $wScript1 = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_extensions_from_mysql.pl';
405     exec($wScript1);
406 }
407
408 function core_hint_del($user) {
409     global $currentFile;
410     //delete from devices table
411     $sql="DELETE FROM extensions WHERE extension = \"{$user}\" AND priority = \"hint\"";
412     sql($sql);
413     $wScript1 = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_extensions_from_mysql.pl';
414     exec($wScript1);
415 }
416
417 */
418
419 // this function rebuilds the astdb based on device table contents
420 // used on devices.php if action=resetall
421 function core_devices2astdb(){
422     require_once('common/php-asmanager.php');
423     checkAstMan();
424     global $amp_conf;
425     $sql = "SELECT * FROM devices";
426     $devresults = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
427
428     //add details to astdb
429     $astman = new AGI_AsteriskManager();
430     if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {   
431         $astman->database_deltree("DEVICE");
432         foreach($devresults as $dev) {
433             extract($dev);   
434             $astman->database_put("DEVICE",$id."/dial",$dial);
435             $astman->database_put("DEVICE",$id."/type",$devicetype);
436             $astman->database_put("DEVICE",$id."/user",$user);       
437             // If a user is selected, add this device to the user
438             if($user != "none") {
439                     $existingdevices = $astman->database_get("AMPUSER",$user."/device");
440                     if (!empty($existingdevices)) {
441                             $existingdevices .= "&";
442                     }
443                     $astman->database_put("AMPUSER",$user."/device",$existingdevices.$id);
444             }
445             
446             //voicemail symlink
447             exec("rm -f /var/spool/asterisk/voicemail/device/".$id);
448             exec("/bin/ln -s /var/spool/asterisk/voicemail/default/".$user."/ /var/spool/asterisk/voicemail/device/".$id);
449         }
450     } else {
451         echo "Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"];
452     }
453     return $astman->disconnect();
454 }
455
456 // this function rebuilds the astdb based on users table contents
457 // used on devices.php if action=resetall
458 function core_users2astdb(){
459     require_once('common/php-asmanager.php');
460     checkAstMan();
461     global $amp_conf;
462     $sql = "SELECT * FROM users";
463     $userresults = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
464     
465     //add details to astdb
466     $astman = new AGI_AsteriskManager();
467     if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
468         $astman->database_deltree("AMPUSER");
469         foreach($userresults as $usr) {
470             extract($usr);
471             $astman->database_put("AMPUSER",$extension."/password",$password);
472             $astman->database_put("AMPUSER",$extension."/ringtimer",$ringtimer);
473             $astman->database_put("AMPUSER",$extension."/noanswer",$noasnwer);
474             $astman->database_put("AMPUSER",$extension."/recording",$recording);
475             $astman->database_put("AMPUSER",$extension."/outboundcid","\"".$outboundcid."\"");
476             $astman->database_put("AMPUSER",$extension."/cidname","\"".$name."\"");
477         }   
478     } else {
479         echo "Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"];
480     }
481     return $astman->disconnect();
482 }
483
484 //add to sip table
485 function core_devices_addsip($account) {
486     sipexists();
487     global $db;
488     global $currentFile;
489     $sipfields = array(array($account,'account',$account),
490     array($account,'accountcode',($_REQUEST['accountcode'])?$_REQUEST['accountcode']:''),
491     array($account,'secret',($_REQUEST['secret'])?$_REQUEST['secret']:''),
492     array($account,'canreinvite',($_REQUEST['canreinvite'])?$_REQUEST['canreinvite']:'no'),
493     array($account,'context',($_REQUEST['context'])?$_REQUEST['context']:'from-internal'),
494     array($account,'dtmfmode',($_REQUEST['dtmfmode'])?$_REQUEST['dtmfmode']:''),
495     array($account,'host',($_REQUEST['host'])?$_REQUEST['host']:'dynamic'),
496     array($account,'type',($_REQUEST['type'])?$_REQUEST['type']:'friend'),
497     array($account,'mailbox',($_REQUEST['mailbox'])?$_REQUEST['mailbox']:$account.'@device'),
498     array($account,'username',($_REQUEST['username'])?$_REQUEST['username']:$account),
499     array($account,'nat',($_REQUEST['nat'])?$_REQUEST['nat']:'never'),
500     array($account,'port',($_REQUEST['port'])?$_REQUEST['port']:'5060'),
501     array($account,'qualify',($_REQUEST['qualify'])?$_REQUEST['qualify']:'no'),
502     array($account,'callgroup',($_REQUEST['callgroup'])?$_REQUEST['callgroup']:''),
503     array($account,'pickupgroup',($_REQUEST['pickupgroup'])?$_REQUEST['pickupgroup']:''),
504     array($account,'disallow',($_REQUEST['disallow'])?$_REQUEST['disallow']:''),
505     array($account,'allow',($_REQUEST['allow'])?$_REQUEST['allow']:''),
506     array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand'),
507     array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand'),
508     array($account,'callerid',($_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>'));
509
510     $compiled = $db->prepare('INSERT INTO sip (id, keyword, data) values (?,?,?)');
511     $result = $db->executeMultiple($compiled,$sipfields);
512     if(DB::IsError($result)) {
513         die($result->getDebugInfo()."<br><br>".'error adding to SIP table');   
514     }
515           
516
517     //script to write sip conf file from mysql
518     $wScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_sip_conf_from_mysql.pl';
519     exec($wScript);
520
521 }
522
523 function core_devices_delsip($account) {
524     global $db;
525     global $currentFile;
526     $sql = "DELETE FROM sip WHERE id = '$account'";
527     $result = $db->query($sql);
528     if(DB::IsError($result)) {
529         die($result->getMessage().$sql);
530     }
531
532     //script to write sip conf file from mysql
533     $wScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_sip_conf_from_mysql.pl';
534     exec($wScript);
535     //script to write op_server.cfg file from mysql
536     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
537     exec($wOpScript);
538 }
539
540 function core_devices_getsip($account) {
541     global $db;
542     $sql = "SELECT keyword,data FROM sip WHERE id = '$account'";
543     $results = $db->getAssoc($sql);
544     if(DB::IsError($results)) {
545         $results = null;
546     }
547     return $results;
548 }
549
550 //add to iax table
551 function core_devices_addiax2($account) {
552     global $db;
553     global $currentFile;
554     $iaxfields = array(array($account,'account',$account),
555     array($account,'secret',($_REQUEST['secret'])?$_REQUEST['secret']:''),
556     array($account,'notransfer',($_REQUEST['notransfer'])?$_REQUEST['notransfer']:'yes'),
557     array($account,'context',($_REQUEST['context'])?$_REQUEST['context']:'from-internal'),
558     array($account,'host',($_REQUEST['host'])?$_REQUEST['host']:'dynamic'),
559     array($account,'type',($_REQUEST['type'])?$_REQUEST['type']:'friend'),
560     array($account,'mailbox',($_REQUEST['mailbox'])?$_REQUEST['mailbox']:$account.'@device'),
561     array($account,'username',($_REQUEST['username'])?$_REQUEST['username']:$account),
562     array($account,'port',($_REQUEST['iaxport'])?$_REQUEST['iaxport']:'4569'),
563     array($account,'qualify',($_REQUEST['qualify'])?$_REQUEST['qualify']:'no'),
564     array($account,'disallow',($_REQUEST['disallow'])?$_REQUEST['disallow']:''),
565     array($account,'allow',($_REQUEST['allow'])?$_REQUEST['allow']:''),
566     array($account,'accountcode',($_REQUEST['accountcode'])?$_REQUEST['accountcode']:''),
567     array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand'),
568     array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand'),
569     array($account,'callerid',($_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>'));
570
571     $compiled = $db->prepare('INSERT INTO iax (id, keyword, data) values (?,?,?)');
572     $result = $db->executeMultiple($compiled,$iaxfields);
573     if(DB::IsError($result)) {
574         die($result->getMessage()."<br><br>error adding to IAX table");   
575     }   
576
577
578     //script to write iax2 conf file from mysql
579     $wScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_iax_conf_from_mysql.pl';
580     exec($wScript);
581     //script to write op_server.cfg file from mysql
582     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
583     exec($wOpScript);
584 }
585
586 function core_devices_deliax2($account) {
587     global $db;
588     global $currentFile;
589     $sql = "DELETE FROM iax WHERE id = '$account'";
590     $result = $db->query($sql);
591     if(DB::IsError($result)) {
592         die($result->getMessage().$sql);
593     }
594     
595     //script to write iax2 conf file from mysql
596     $wScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_iax_conf_from_mysql.pl';
597     exec($wScript);
598     //script to write op_server.cfg file from mysql
599     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
600     exec($wOpScript);
601 }
602
603 function core_devices_getiax2($account) {
604     global $db;
605     $sql = "SELECT keyword,data FROM iax WHERE id = '$account'";
606     $results = $db->getAssoc($sql);
607     if(DB::IsError($results)) {
608         $results = null;
609     }
610     return $results;
611 }
612
613 function core_devices_addzap($account) {
614     zapexists();
615     global $db;
616     global $currentFile;
617     $zapfields = array(
618     array($account,'account',$account),
619     array($account,'context',($_REQUEST['context'])?$_REQUEST['context']:'from-internal'),
620     array($account,'mailbox',($_REQUEST['mailbox'])?$_REQUEST['mailbox']:$account.'@device'),
621     array($account,'callerid',($_REQUEST['description'])?$_REQUEST['description']." <".$account.'>':'device'." <".$account.'>'),
622     array($account,'signalling',($_REQUEST['signalling'])?$_REQUEST['signalling']:'fxo_ks'),
623     array($account,'echocancel',($_REQUEST['echocancel'])?$_REQUEST['echocancel']:'yes'),
624     array($account,'echocancelwhenbridged',($_REQUEST['echocancelwhenbridged'])?$_REQUEST['echocancelwhenbridged']:'no'),
625     array($account,'echotraining',($_REQUEST['echotraining'])?$_REQUEST['echotraining']:'800'),
626     array($account,'busydetect',($_REQUEST['busydetect'])?$_REQUEST['busydetect']:'no'),
627     array($account,'busycount',($_REQUEST['busycount'])?$_REQUEST['busycount']:'7'),
628     array($account,'callprogress',($_REQUEST['callprogress'])?$_REQUEST['callprogress']:'no'),
629     array($account,'record_in',($_REQUEST['record_in'])?$_REQUEST['record_in']:'On-Demand'),
630     array($account,'record_out',($_REQUEST['record_out'])?$_REQUEST['record_out']:'On-Demand'),
631     array($account,'channel',($_REQUEST['channel'])?$_REQUEST['channel']:''));
632
633     $compiled = $db->prepare('INSERT INTO zap (id, keyword, data) values (?,?,?)');
634     $result = $db->executeMultiple($compiled,$zapfields);
635     if(DB::IsError($result)) {
636         die($result->getMessage()."<br><br>error adding to ZAP table");   
637     }   
638
639
640     //script to write zap conf file from mysql
641     $wScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_zap_conf_from_mysql.pl';
642     exec($wScript);
643     //script to write op_server.cfg file from mysql
644     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
645     exec($wOpScript);
646 }
647
648 function core_devices_delzap($account) {
649     global $db;
650     global $currentFile;
651     $sql = "DELETE FROM zap WHERE id = '$account'";
652     $result = $db->query($sql);
653     if(DB::IsError($result)) {
654         die($result->getMessage().$sql);
655     }
656     
657     //script to write zap conf file from mysql
658     $wScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_zap_conf_from_mysql.pl';
659     exec($wScript);
660     //script to write op_server.cfg file from mysql
661     $wOpScript = rtrim($_SERVER['SCRIPT_FILENAME'],$currentFile).'retrieve_op_conf_from_mysql.pl';
662     exec($wOpScript);
663 }
664
665 function core_devices_getzap($account) {
666     global $db;
667     $sql = "SELECT keyword,data FROM zap WHERE id = '$account'";
668     $results = $db->getAssoc($sql);
669     if(DB::IsError($results)) {
670         $results = null;
671     }
672     return $results;
673 }
674 /* end page.devices.php functions */
675
676
677
678
679 function core_hint_get($account){
680     //determine what devices this user is associated with
681     $sql = "SELECT dial from devices where user = '{$account}'";
682     $results = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
683     //print_r($results);
684     
685     //create an array of strings
686     if (is_array($results)){
687         foreach ($results as $result) {
688             $dial[] = $result['dial'];
689         }
690     }
691     
692     //create a string with & delimiter
693     if (is_array($dial)){
694         $hint = implode($dial,"&");
695     } else {
696         $hint = $results[0]['dial'];
697     }
698     
699     return $hint;
700 }
701
702
703
704 /* begin page.users.php functions */
705
706 // get the existing extensions
707 // the returned arrays contain [0]:extension [1]:name
708 function core_users_list() {
709     $results = sql("SELECT extension,name,voicemail FROM users ORDER BY extension","getAll");
710
711     //only allow extensions that are within administrator's allowed range
712     foreach($results as $result){
713         if (checkRange($result[0])){
714             $extens[] = array($result[0],$result[1]);
715         }
716     }
717     if (isset($extens)) sort($extens);
718     return $extens;
719 }
720
721 function core_users_add($vars,$vmcontext) {
722     extract($vars);
723     
724     global $db;
725     global $amp_conf;
726     //ensure this id is not already in use
727     $extens = getextens();
728     if(is_array($extens)) {
729         foreach($extens as $exten) {
730             if ($exten[0]==$extension) {
731                 echo "<script>javascript:alert('"._("This user extension is already in use")."');</script>";
732                 return false;
733             }
734         }
735     }
736     
737     //build the recording variable
738     $recording = "out=".$record_out."|in=".$record_in;
739     
740     //insert into users table
741     $sql="INSERT INTO users (extension,password,name,voicemail,ringtimer,noanswer,recording,outboundcid) values (\"$extension\",\"$password\",\"$name\",\"$vm\",\"$ringtimer\",\"$noanswer\",\"$recording\",'$outboundcid')";
742     $results = $db->query($sql);
743     if(DB::IsError($results)) {
744         die($results->getMessage().$sql);
745     }
746     
747     //write to astdb
748     $astman = new AGI_AsteriskManager();
749     if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {   
750         $astman->database_put("AMPUSER",$extension."/password",$password);
751         $astman->database_put("AMPUSER",$extension."/ringtimer",$ringtimer);
752         $astman->database_put("AMPUSER",$extension."/noanswer",$noasnwer);
753         $astman->database_put("AMPUSER",$extension."/recording",$recording);
754         $astman->database_put("AMPUSER",$extension."/outboundcid","\"".$outboundcid."\"");
755         $astman->database_put("AMPUSER",$extension."/cidname","\"".$name."\"");
756         $astman->disconnect();
757     } else {
758         fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
759     }
760     
761 /*    //write to extensions table - AMP2 will not do this
762     //update ext-local context in extensions.conf
763     
764     //warning: as of 009 we aren't allowing a user to use any mailbox but their own
765     //This may affect some upgraders as it is possible in previous versions!
766     //$mailb = ($vm == 'disabled' || $mailbox == '') ? 'novm' : $mailbox;
767     $mailb = ($vm == 'disabled') ? 'novm' : $extension;
768     
769     addaccount($extension,$mailb);*/
770     
771     /*core_hint_add($extension);*/
772     
773     
774     //take care of voicemail.conf if using voicemail
775     $uservm = getVoicemail();
776     unset($uservm[$incontext][$account]);
777     
778     if ($vm != 'disabled')
779     {
780         // need to check if there are any options entered in the text field
781         if ($_REQUEST['options']!=''){
782             $options = explode("|",$_REQUEST['options']);
783             foreach($options as $option) {
784                 $vmoption = explode("=",$option);
785                 $vmoptions[$vmoption[0]] = $vmoption[1];
786             }
787         }
788         $vmoption = explode("=",$attach);
789             $vmoptions[$vmoption[0]] = $vmoption[1];
790         $vmoption = explode("=",$saycid);
791             $vmoptions[$vmoption[0]] = $vmoption[1];
792         $vmoption = explode("=",$envelope);
793             $vmoptions[$vmoption[0]] = $vmoption[1];
794         $vmoption = explode("=",$delete);
795             $vmoptions[$vmoption[0]] = $vmoption[1];
796         $uservm[$vmcontext][$extension] = array(
797                                     'mailbox' => $extension,
798                                     'pwd' => $vmpwd,
799                                     'name' => $name,
800                                     'email' => $email,
801                                     'pager' => $pager,
802                                     'options' => $vmoptions);
803     }
804     saveVoicemail($uservm);
805 }
806
807 function core_users_get($extension){
808     global $db;
809     //get all the variables for the meetme
810     $sql = "SELECT * FROM users WHERE extension = '$extension'";
811     $results = $db->getRow($sql,DB_FETCHMODE_ASSOC);
812     if(DB::IsError($results)) {
813         die($results->getMessage().$sql);
814     }
815     //explode recording vars
816     $recording = explode("|",$results['recording']);
817     $recout = substr($recording[0],4);
818     $recin = substr($recording[1],3);
819     $results['record_in']=$recin;
820     $results['record_out']=$recout;
821
822     return $results;
823 }
824
825 function core_users_del($extension,$incontext,$uservm){
826     global $db;
827     global $amp_conf;
828     
829     //delete from devices table
830     $sql="DELETE FROM users WHERE extension = \"$extension\"";
831     $results = $db->query($sql);
832     if(DB::IsError($results)) {
833         die($results->getMessage().$sql);
834     }
835
836     //delete details to astdb
837     $astman = new AGI_AsteriskManager();
838     if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {   
839         $astman->database_del("AMPUSER",$extension."/password",$password);
840         $astman->database_del("AMPUSER",$extension."/ringtimer",$ringtimer);
841         $astman->database_del("AMPUSER",$extension."/noanswer",$noasnwer);
842         $astman->database_del("AMPUSER",$extension."/recording",$recording);
843         $astman->database_del("AMPUSER",$extension."/outboundcid","\"".$outboundcid."\"");
844         $astman->database_del("AMPUSER",$extension."/cidname","\"".$name."\"");
845         $astman->disconnect();
846     } else {
847         fatal("Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]);
848     }
849     
850     //take care of voicemail.conf
851     unset($uservm[$incontext][$extension]);
852     saveVoicemail($uservm);
853     /*   
854     //delete the extension info from extensions table
855     delextensions('ext-local',$extension);
856     */
857     /*//delete hint
858     core_hint_del($extension);*/
859 }
860
861 /* end page.users.php functions */
862
863
864
865
866
867 /* begin page.trunks.php functions */
868
869 // we're adding ,don't require a $trunknum
870 function core_trunks_add($tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register) {
871     global $db;
872     
873     // find the next available ID
874     $trunknum = 1;
875     foreach(core_trunks_list() as $trunk) {
876         if ($trunknum == ltrim($trunk[0],"OUT_")) {
877             $trunknum++;
878         }
879     }
880     
881     core_trunks_backendAdd($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register);
882     
883     return $trunknum;
884 }
885
886 function core_trunks_del($trunknum, $tech = null) {
887     global $db;
888     
889     if ($tech === null) { // in EditTrunk, we get this info anyways
890         $tech = core_trunks_getTrunkTech($trunknum);
891     }
892
893     //delete from globals table
894     sql("DELETE FROM globals WHERE variable LIKE '%OUT_$trunknum' OR variable IN ('OUTCID_$trunknum','OUTMAXCHANS_$trunknum','OUTPREFIX_$trunknum')");
895     
896     //write outids
897     core_trunks_writeoutids();
898
899     // conditionally, delete from iax or sip
900     switch (strtolower($tech)) {
901         case "iax":
902         case "iax2":
903             sql("DELETE FROM iax WHERE id = '9999$trunknum' OR id = '99999$trunknum' OR id = '9999999$trunknum'");
904         break;
905         case "sip":
906             sql("DELETE FROM sip WHERE id = '9999$trunknum' OR id = '99999$trunknum' OR id = '9999999$trunknum'");
907         break;
908     }
909 }
910
911 function core_trunks_edit($trunknum, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register) {
912     //echo "editTrunk($trunknum, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register)";
913     $tech = core_trunks_getTrunkTech($trunknum);
914     core_trunks_del($trunknum, $tech);
915     core_trunks_backendAdd($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register);
916 }
917
918 // just used internally by addTrunk() and editTrunk()
919 //obsolete
920 function core_trunks_backendAdd($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register) {
921     global $db;
922     
923     if  (is_null($dialoutprefix)) $dialoutprefix = ""; // can't be NULL
924     
925     //echo  "backendAddTrunk($trunknum, $tech, $channelid, $dialoutprefix, $maxchans, $outcid, $peerdetails, $usercontext, $userconfig, $register)";
926     
927     // change iax to "iax2" (only spot we actually store iax2, since its used by Dial()..)
928     $techtemp = ((strtolower($tech) == "iax") ? "iax2" : $tech);
929     $outval = (($techtemp == "custom") ? "AMP:".$channelid : strtoupper($techtemp).'/'.$channelid);
930     
931     $glofields = array(
932             array('OUT_'.$trunknum, $outval),
933             array('OUTPREFIX_'.$trunknum, $dialoutprefix),
934             array('OUTMAXCHANS_'.$trunknum, $maxchans),
935             array('OUTCID_'.$trunknum, $outcid),
936             );
937             
938     unset($techtemp);
939     
940     $compiled = $db->prepare('INSERT INTO globals (variable, value) values (?,?)');
941     $result = $db->executeMultiple($compiled,$glofields);
942     if(DB::IsError($result)) {
943         die($result->getMessage()."<br><br>".$sql);
944     }
945     
946     core_trunks_writeoutids();
947     
948     switch (strtolower($tech)) {
949         case "iax":
950         case "iax2":
951             core_trunks_addSipOrIax($peerdetails,'iax',$channelid,$trunknum);
952             if ($usercontext != ""){
953                 core_trunks_addSipOrIax($userconfig,'iax',$usercontext,'9'.$trunknum);
954             }
955             if ($register != ""){
956                 core_trunks_addRegister($trunknum,'iax',$register);
957             }
958         break;
959         case "sip":
960             core_trunks_addSipOrIax($peerdetails,'sip',$channelid,$trunknum);
961             if ($usercontext != ""){
962                 core_trunks_addSipOrIax($userconfig,'sip',$usercontext,'9'.$trunknum);
963             }
964             if ($register != ""){
965                 core_trunks_addRegister($trunknum,'sip',$register);
966             }
967         break;
968     }   
969 }
970
971 function core_trunks_getTrunkTech($trunknum) {
972
973     $results = sql("SELECT value FROM globals WHERE variable = 'OUT_".$trunknum."'","getAll");
974     if (!$results) {
975         return false;
976     }
977     if(strpos($results[0][0],"AMP:") === 0) {  //custom trunks begin with AMP:
978         $tech = "custom";
979     } else {
980         $tech = strtolower( strtok($results[0][0],'/') ); // the technology.  ie: ZAP/g0 is ZAP
981         
982         if ($tech == "iax2") $tech = "iax"; // same thing, here
983     }
984     return $tech;
985 }
986
987 //add trunk info to sip or iax table
988 function core_trunks_addSipOrIax($config,$table,$channelid,$trunknum) {
989     global $db;
990     
991     $confitem['account'] = $channelid;
992     $gimmieabreak = nl2br($config);
993     $lines = split('<br />',$gimmieabreak);
994     foreach ($lines as $line) {
995         $line = trim($line);
996         if (count(split('=',$line)) > 1) {
997             $tmp = split('=',$line);
998             $key=trim($tmp[0]);
999             $value=trim($tmp[1]);
1000             if (isset($confitem[$key]) && !empty($confitem[$key]))
1001                 $confitem[$key].="&".$value;
1002             else
1003                 $confitem[$key]=$value;
1004         }
1005     }
1006     foreach($confitem as $k=>$v) {
1007         $dbconfitem[]=array($k,$v);
1008     }
1009     $compiled = $db->prepare("INSERT INTO $table (id, keyword, data) values ('9999$trunknum',?,?)");
1010     $result = $db->executeMultiple($compiled,$dbconfitem);
1011     if(DB::IsError($result)) {
1012         die($result->getMessage()."<br><br>INSERT INTO $table (id, keyword, data) values ('9999$trunknum',?,?)");   
1013     }
1014 }
1015
1016 //get unique trunks
1017 function core_trunks_list() {
1018     global $db;
1019     
1020     // we have to escape _ for mysql: normally a wildcard
1021     $unique_trunks = sql("SELECT * FROM globals WHERE variable LIKE 'OUT\\\_%' ORDER BY RIGHT( variable, LENGTH( variable ) - 4 )+0","getAll");
1022
1023     //if no trunks have ever been defined, then create the proper variables with the default zap trunk
1024     if (count($unique_trunks) == 0) {
1025         //If all trunks have been deleted from admin, dialoutids might still exist
1026         sql("DELETE FROM globals WHERE variable = 'DIALOUTIDS'");
1027     
1028         $glofields = array(array('OUT_1','ZAP/g0'),
1029                             array('DIAL_OUT_1','9'),
1030                             array('DIALOUTIDS','1'));
1031         $compiled = $db->prepare('INSERT INTO globals (variable, value) values (?,?)');
1032         $result = $db->executeMultiple($compiled,$glofields);
1033         if(DB::IsError($result)) {
1034             die($result->getMessage()."<br><br>".$sql);   
1035         }
1036         $unique_trunks[] = array('OUT_1','ZAP/g0');
1037     }
1038     // asort($unique_trunks);
1039     return $unique_trunks;
1040 }
1041
1042 //write the OUTIDS global variable (used in dialparties.agi)
1043 function core_trunks_writeoutids() {
1044     // we have to escape _ for mysql: normally a wildcard
1045     $unique_trunks = sql("SELECT variable FROM globals WHERE variable LIKE 'OUT\\\_%'","getAll");
1046
1047     foreach ($unique_trunks as $unique_trunk) {
1048         $outid = strtok($unique_trunk[0],"_");
1049         $outid = strtok("_");
1050         $outids .= $outid ."/";
1051     }
1052     
1053     sql("UPDATE globals SET value = '$outids' WHERE variable = 'DIALOUTIDS'");
1054 }
1055
1056 function core_trunks_addTrunkRegister($trunknum,$tech,$reg) {
1057     sql("INSERT INTO $tech (id, keyword, data) values ('9999999$trunknum','register','$reg')");
1058 }
1059
1060
1061 function core_trunks_addDialRules($trunknum, $dialrules) {
1062     $values = array();
1063     $i = 1;
1064     foreach ($dialrules as $rule) {
1065         $values["rule".$i++] = $rule;
1066     }
1067     
1068     $conf = core_trunks_readDialRulesFile();
1069     
1070     // rewrite for this trunk
1071     $conf["trunk-".$trunknum] = $values;
1072     
1073     core_trunks_writeDialRulesFile($conf);
1074 }
1075
1076 function core_trunks_readDialRulesFile() {
1077     global $localPrefixFile; // probably not the best way
1078     
1079     core_trunks_parse_conf($localPrefixFile, &$conf, &$section);
1080     
1081     return $conf;
1082 }
1083
1084 function core_trunks_writeDialRulesFile($conf) {
1085     global $localPrefixFile; // probably not the best way
1086     
1087     $fd = fopen($localPrefixFile,"w");
1088     foreach ($conf as $section=>$values) {
1089         fwrite($fd, "[".$section."]\n");
1090         foreach ($values as $key=>$value) {
1091             fwrite($fd, $key."=".$value."\n");
1092         }
1093         fwrite($fd, "\n");
1094     }
1095     fclose($fd);
1096 }
1097
1098 function core_trunks_parse_conf($filename, &$conf, &$section) {
1099     if (is_null($conf)) {
1100         $conf = array();
1101     }
1102     if (is_null($section)) {
1103         $section = "general";
1104     }
1105     
1106     if (file_exists($filename)) {
1107         $fd = fopen($filename, "r");
1108         while ($line = fgets($fd, 1024)) {
1109             if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {
1110                 // name = value
1111                 // option line
1112                 $conf[$section][ $matches[1] ] = $matches[2];
1113             } else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {
1114                 // section name
1115                 $section = strtolower($matches[1]);
1116             } else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {
1117                 // include another file
1118                 
1119                 if ($matches[1][0] == "/") {
1120                     // absolute path
1121                     $filename = $matches[1];
1122                 } else {
1123                     // relative path
1124                     $filename dirname($filename)."/".$matches[1];
1125                 }
1126                 
1127                 core_trunks_parse_conf($filename, $conf, $section);
1128             }
1129         }
1130     }
1131 }
1132
1133 function core_trunks_getTrunkTrunkName($trunknum) {
1134     $results = sql("SELECT value FROM globals WHERE variable = 'OUT_".$trunknum."'","getAll");
1135     if (!$results) {
1136         return false;
1137     }
1138     
1139     if(strpos($results[0][0],"AMP:") === 0) {  //custom trunks begin with AMP:
1140         $tname = ltrim($results[0][0],"AMP:");
1141     } else {
1142     strtok($results[0][0],'/');
1143         $tname = strtok('/'); // the text _after_ technology.  ie: ZAP/g0 is g0
1144     }
1145     return $tname;
1146 }
1147
1148 //get and print peer details (prefixed with 4 9's)
1149 function core_trunks_getTrunkPeerDetails($trunknum) {
1150     global $db;
1151     
1152     $tech = core_trunks_getTrunkTech($trunknum);
1153     
1154     if ($tech == "zap") return ""; // zap has no details
1155     
1156     $results = sql("SELECT keyword,data FROM $tech WHERE id = '9999$trunknum' ORDER BY id","getAll");
1157     
1158     foreach ($results as $result) {
1159         if ($result[0] != 'account') {
1160             $confdetail .= $result[0] .'='. $result[1] . "\n";
1161         }
1162     }
1163     return $confdetail;
1164 }
1165
1166 //get trunk user context (prefixed with 5 9's)
1167 function core_trunks_getTrunkUserContext($trunknum) {
1168     $tech = core_trunks_getTrunkTech($trunknum);
1169     if ($tech == "zap") return ""; // zap has no account
1170     
1171     $results = sql("SELECT keyword,data FROM $tech WHERE id = '99999$trunknum' ORDER BY id","getAll");
1172
1173     foreach ($results as $result) {
1174         if ($result[0] == 'account') {
1175             $account = $result[1];
1176         }
1177     }
1178     return $account;
1179 }
1180
1181 //get and print user config (prefixed with 5 9's)
1182 function core_trunks_getTrunkUserConfig($trunknum) {
1183     global $db;
1184     
1185     $tech = core_trunks_getTrunkTech($trunknum);
1186     
1187     if ($tech == "zap") return ""; // zap has no details
1188     
1189     $results = sql("SELECT keyword,data FROM $tech WHERE id = '99999$trunknum' ORDER BY id","getAll");
1190
1191     foreach ($results as $result) {
1192         if ($result[0] != 'account') {
1193             $confdetail .= $result[0] .'='. $result[1] . "\n";
1194         }
1195     }
1196     return $confdetail;
1197 }
1198
1199 //get trunk account register string
1200 function core_trunks_getTrunkRegister($trunknum) {
1201     $tech = core_trunks_getTrunkTech($trunknum);
1202     
1203     if ($tech == "zap") return ""; // zap has no register
1204     
1205     $results = sql("SELECT keyword,data FROM $tech WHERE id = '9999999$trunknum'","getAll");
1206
1207     foreach ($results as $result) {
1208             $register = $result[1];
1209     }
1210     return $register;
1211 }
1212
1213 function core_trunks_getDialRules($trunknum) {
1214     $conf = core_trunks_readDialRulesFile();
1215     if (isset($conf["trunk-".$trunknum])) {
1216         return $conf["trunk-".$trunknum];
1217     }
1218     return false;
1219 }
1220
1221 //get outbound routes for a given trunk
1222 function core_trunks_gettrunkroutes($trunknum) {
1223     $results = sql("SELECT DISTINCT SUBSTRING(context,7), priority FROM extensions WHERE context LIKE 'outrt-%' AND (args LIKE 'dialout-trunk,".$trunknum.",%' OR args LIKE 'dialout-enum,".$trunknum.",%')ORDER BY context ","getAll");
1224     
1225     $routes = array();
1226     foreach ($results as $row) {
1227         $routes[$row[0]] = $row[1];
1228     }
1229     
1230     // array(routename=>priority)
1231     return $routes;
1232 }
1233
1234 function core_trunks_deleteDialRules($trunknum) {
1235     $conf = core_trunks_readDialRulesFile();
1236     
1237     // remove rules for this trunk
1238     unset($conf["trunk-".$trunknum]);
1239     
1240     core_trunks_writeDialRulesFile($conf);
1241 }
1242
1243 /* end page.trunks.php functions */
1244
1245
1246
1247
1248
1249
1250 /* begin page.routing.php functions */
1251
1252 //get unique outbound route names
1253 function core_routing_getroutenames() {
1254     $results = sql("SELECT DISTINCT SUBSTRING(context,7) FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ","getAll");
1255     // we SUBSTRING() to remove "outrt-"
1256
1257     if (count($results) == 0) {
1258         // see if they're still using the old dialprefix method
1259         $results = sql("SELECT variable,value FROM globals WHERE variable LIKE 'DIAL\\\_OUT\\\_%'","getAll");
1260         // we SUBSTRING() to remove "outrt-"
1261         
1262         if (count($results) > 0) {
1263             // yes, they are using old method, let's update
1264             
1265             // get the default trunk
1266             $results_def = sql("SELECT value FROM globals WHERE variable = 'OUT'","getAll");
1267             
1268             if (preg_match("/{OUT_(\d+)}/", $results_def[0][0], $matches)) {
1269                 $def_trunk = $matches[1];
1270             } else {
1271                 $def_trunk = "";
1272             }
1273             
1274             $default_patterns = array(    // default patterns that used to be in extensions.conf
1275                         "NXXXXXX",
1276                         "NXXNXXXXXX",
1277                         "1800NXXXXXX",
1278                         "1888NXXXXXX",
1279                         "1877NXXXXXX",
1280                         "1866NXXXXXX",
1281                         "1NXXNXXXXXX",
1282                         "011.",
1283                         "911",
1284                         "411",
1285                         "311",
1286                         );
1287             
1288             foreach ($results as $temp) {
1289                 // temp[0] is "DIAL_OUT_1"
1290                 // temp[1] is the dial prefix
1291                 
1292                 $trunknum = substr($temp[0],9);
1293                 
1294                 $name = "route".$trunknum;
1295                 
1296                 $trunks = array(1=>"OUT_".$trunknum); // only one trunk to use
1297                 
1298                 $patterns = array();
1299                 foreach ($default_patterns as $pattern) {
1300                     $patterns[] = $temp[1]."|".$pattern;
1301                 }
1302                 
1303                 if ($trunknum == $def_trunk) {
1304                     // this is the default trunk, add the patterns with no prefix
1305                     $patterns = array_merge($patterns, $default_patterns);
1306                 }
1307                 
1308                 // add this as a new route
1309                 core_routes_add($name, $patterns, $trunks,"new");
1310             }
1311             
1312             
1313             // delete old values
1314             sql("DELETE FROM globals WHERE (variable LIKE 'DIAL\\\_OUT\\\_%') OR (variable = 'OUT') ");
1315
1316             // we need to re-generate extensions_additional.conf
1317             // i'm not sure how to do this from here
1318             
1319             // re-run our query
1320             $results = sql("SELECT DISTINCT SUBSTRING(context,7) FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ","getAll");
1321             // we SUBSTRING() to remove "outrt-"
1322         }
1323         
1324     } // else, it just means they have no routes.
1325     
1326     return $results;
1327 }
1328
1329 function core_routing_setroutepriority($routepriority, $reporoutedirection, $reporoutekey)
1330 {
1331     global $db;
1332     $counter=-1;
1333     foreach ($routepriority as $tresult)
1334     {
1335         $counter++;
1336         if (($counter==($reporoutekey-1)) && ($reporoutedirection=="up")) {
1337             // swap this one with the one before (move up)
1338             $temproute = $routepriority[$counter];
1339             $routepriority[ $counter ] = $routepriority[ $counter+1 ];
1340             $routepriority[ $counter+1 ] = $temproute;
1341             
1342         } else if (($counter==($reporoutekey)) && ($reporoutedirection=="down")) {
1343             // swap this one with the one after (move down)
1344             $temproute = $routepriority[ $counter+1 ];
1345             $routepriority[ $counter+1 ] = $routepriority[ $counter ];
1346             $routepriority[ $counter ] = $temproute;
1347         }
1348     }
1349     unset($temptrunk);
1350     $routepriority = array_values($routepriority); // resequence our numbers
1351     $counter=0;
1352     foreach ($routepriority as $tresult)
1353     {
1354         $order=core_routing_setroutepriorityvalue($counter++);
1355         $sql = sprintf("Update extensions set context='outrt-%s-%s' WHERE context='outrt-%s'",$order,substr($tresult[0],4), $tresult[0]);
1356         $result = $db->query($sql);
1357         if(DB::IsError($result)) {     
1358             die($result->getMessage());
1359         }
1360     }
1361     // Delete and readd the outbound-allroutes entries
1362     $sql = "delete from  extensions WHERE context='outbound-allroutes'";
1363     $result = $db->query($sql);
1364     if(DB::IsError($result)) {
1365             die($result->getMessage().$sql);
1366     }
1367     $sql = "SELECT DISTINCT context FROM extensions WHERE context like 'outrt-%' ORDER BY context";
1368     $results = $db->getAll($sql);
1369     if(DB::IsError($results)) {
1370         die($results->getMessage());
1371     }
1372
1373     $priority_loops=1;   
1374     foreach ($results as $row) {
1375         $sql = "INSERT INTO extensions (context, extension, priority, application, args, descr, flags) VALUES ";
1376         $sql .= "('outbound-allroutes', ";
1377         $sql .= "'include', ";
1378         $sql .= "'".$priority_loops++."', ";
1379         $sql .= "'".$row[0]."', ";
1380         $sql .= "'', ";
1381         $sql .= "'', ";
1382         $sql .= "'2')";
1383     
1384         //$sql = sprintf("Update extensions set application='outrt-%s-%s' WHERE context='outbound-allroutes' and  application='outrt-%s'",$order,substr($tresult[0],4), $tresult[0]);
1385         $result = $db->query($sql);
1386         if(DB::IsError($result)) {     
1387             die($result->getMessage(). $sql);
1388          }
1389     }
1390     $sql = "SELECT DISTINCT SUBSTRING(context,7) FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context ";
1391         // we SUBSTRING() to remove "outrt-"
1392         $routepriority = $db->getAll($sql);
1393         if(DB::IsError($routepriority))
1394         {
1395                 die($routepriority->getMessage());
1396         }
1397         return ($routepriority);
1398     
1399 }
1400
1401 function core_routing_setroutepriorityvalue($key)
1402 {
1403     $key=$key+1;
1404     if ($key<10)
1405         $prefix = sprintf("00%d",$key);
1406     else if ((9<$key)&&($key<100))
1407         $prefix = sprintf("0%d",$key);
1408     else if ($key>100)
1409         $prefix = sprintf("%d",$key);
1410     return ($prefix);
1411 }
1412
1413
1414 function core_routing_add($name, $patterns, $trunks, $method, $pass) {
1415     global $db;
1416
1417     $trunktech=array();
1418
1419     //Retrieve each trunk tech for later lookup
1420     $sql="select * from globals WHERE variable LIKE 'OUT\\_%'";
1421         $result = $db->getAll($sql);
1422         if(DB::IsError($result)) {
1423         die($result->getMessage());
1424     }
1425     foreach($result as $tr) {
1426         $tech = strtok($tr[1], "/");
1427         $trunktech[$tr[0]]=$tech;
1428     }
1429     
1430      if ($method=="new")
1431     {   
1432             $sql="select DISTINCT context FROM extensions WHERE context LIKE 'outrt-%' ORDER BY context";
1433             $routepriority = $db->getAll($sql);
1434             if(DB::IsError($result)) {
1435                     die($result->getMessage());
1436             }
1437             $order=core_routing_setroutepriorityvalue(count($routepriority));
1438          $name = sprintf ("%s-%s",$order,$name);
1439     }
1440     $trunks = array_values($trunks); // probably already done, but it's important for our dialplan
1441
1442     
1443     foreach ($patterns as $pattern) {
1444         
1445         if (false !== ($pos = strpos($pattern,"|"))) {
1446             // we have a | meaning to not pass the digits on
1447             // (ie, 9|NXXXXXX should use the pattern _9NXXXXXX but only pass NXXXXXX, not the leading 9)
1448             
1449             $pattern = str_replace("|","",$pattern); // remove all |'s
1450             $exten = "EXTEN:".$pos; // chop off leading digit
1451         } else {
1452             // we pass the full dialed number as-is
1453             $exten = "EXTEN";
1454         }
1455         
1456         if (!preg_match("/^[0-9*]+$/",$pattern)) {
1457             // note # is not here, as asterisk doesn't recoginize it as a normal digit, thus it requires _ pattern matching
1458             
1459             // it's not strictly digits, so it must have patterns, so prepend a _
1460             $pattern = "_".$pattern;
1461         }
1462         
1463         foreach ($trunks as $priority => $trunk) {
1464             $priority += 1; // since arrays are 0-based, but we want priorities to start at 1
1465             
1466             $sql = "INSERT INTO extensions (context, extension, priority, application, args) VALUES ";
1467             $sql .= "('outrt-".$name."', ";
1468             $sql .= "'".$pattern."', ";
1469             $sql .= "'".$priority."', ";
1470             $sql .= "'Macro', ";
1471             if ($trunktech[$trunk] == "ENUM")
1472                 $sql .= "'dialout-enum,".substr($trunk,4).",\${".$exten."},".$pass."'"; // cut off OUT_ from $trunk
1473             else
1474                 $sql .= "'dialout-trunk,".substr($trunk,4).",\${".$exten."},".$pass."'"; // cut off OUT_ from $trunk
1475             $sql .= ")";
1476             
1477             $result = $db->query($sql);
1478             if(DB::IsError($result)) {
1479                 die($result->getMessage());
1480             }
1481             //blank pass so that it isn't added for additional trunks
1482             $pass = "";
1483         }
1484         
1485         $priority += 1;
1486         $sql = "INSERT INTO extensions (context, extension, priority, application, args, descr) VALUES ";
1487         $sql .= "('outrt-".$name."', ";
1488         $sql .= "'".$pattern."', ";
1489         $sql .= "'".$priority."', ";
1490         $sql .= "'Macro', ";
1491         $sql .= "'outisbusy', ";
1492         $sql .= "'No available circuits')";
1493         
1494         $result = $db->query($sql);
1495         if(DB::IsError($result)) {
1496             die($result->getMessage());
1497         }
1498     }
1499
1500     
1501     // add an include=>outrt-$name  to [outbound-allroutes]:
1502     
1503     // we have to find the first available priority.. priority doesn't really matter for the include, but
1504     // there is a unique index on (context,extension,priority) so if we don't do this we can't put more than
1505     // one route in the outbound-allroutes context.
1506     $sql = "SELECT priority FROM extensions WHERE context = 'outbound-allroutes' AND extension = 'include'";
1507     $results = $db->getAll($sql);
1508     if(DB::IsError($results)) {
1509         die($results->getMessage());
1510     }
1511     $priorities = array();
1512     foreach ($results as $row) {
1513         $priorities[] = $row[0];
1514     }
1515     for ($priority = 1; in_array($priority, $priorities); $priority++);
1516     
1517     // $priority should now be the lowest available number
1518     
1519     $sql = "INSERT INTO extensions (context, extension, priority, application, args, descr, flags) VALUES ";
1520     $sql .= "('outbound-allroutes', ";
1521     $sql .= "'include', ";
1522     $sql .= "'".$priority."', ";
1523     $sql .= "'outrt-".$name."', ";
1524     $sql .= "'', ";
1525     $sql .= "'', ";
1526     $sql .= "'2')";
1527     
1528     $result = $db->query($sql);
1529     if(DB::IsError($result)) {
1530         die($priority.$result->getMessage());
1531     }
1532     
1533 }
1534
1535 function core_routing_edit($name, $patterns, $trunks, $pass) {
1536     core_routing_del($name);
1537     core_routing_add($name, $patterns, $trunks,"edit", $pass);
1538 }
1539
1540 function core_routing_del($name) {
1541     global $db;
1542     $sql = "DELETE FROM extensions WHERE context = 'outrt-".$name."'";
1543     $result = $db->query($sql);
1544     if(DB::IsError($result)) {
1545         die($result->getMessage());
1546     }
1547     
1548     $sql = "DELETE FROM extensions WHERE context = 'outbound-allroutes' AND application = 'outrt-".$name."' ";
1549     $result = $db->query($sql);
1550     if(DB::IsError($result)) {
1551         die($result->getMessage());
1552     }
1553     
1554     return $result;
1555 }
1556
1557 function core_routing_rename($oldname, $newname) {
1558     global $db;
1559
1560     $route_prefix=substr($oldname,0,4);
1561     $newname=$route_prefix.$newname;
1562     $sql = "SELECT context FROM extensions WHERE context = 'outrt-".$newname."'";
1563     $results = $db->getAll($sql);
1564     if (count($results) > 0) {
1565         // there's already a route with this name
1566         return false;
1567     }
1568     
1569     $sql = "UPDATE extensions SET context = 'outrt-".$newname."' WHERE context = 'outrt-".$oldname."'";
1570     $result = $db->query($sql);
1571     if(DB::IsError($result)) {
1572         die($result->getMessage());
1573     }
1574         $mypriority=sprintf("%d",$route_prefix);   
1575     $sql = "UPDATE extensions SET application = 'outrt-".$newname."', priority = '$mypriority' WHERE context = 'outbound-allroutes' AND application = 'outrt-".$oldname."' ";
1576     $result = $db->query($sql);
1577     if(DB::IsError($result)) {
1578         die($result->getMessage());
1579     }
1580     
1581     return true;
1582 }
1583
1584 //get unique outbound route patterns for a given context
1585 function core_routing_getroutepatterns($route) {
1586     global $db;
1587     $sql = "SELECT extension, args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'dialout-trunk%' OR args LIKE'dialout-enum%') ORDER BY extension ";
1588     $results = $db->getAll($sql);
1589     if(DB::IsError($results)) {
1590         die($results->getMessage());
1591     }
1592     
1593     $patterns = array();
1594     foreach ($results as $row) {
1595         if ($row[0][0] == "_") {
1596             // remove leading _
1597             $pattern = substr($row[0],1);
1598         } else {
1599             $pattern = $row[0];
1600         }
1601         
1602         if (preg_match("/{EXTEN:(\d+)}/", $row[1], $matches)) {
1603             // this has a digit offset, we need to insert a |
1604             $pattern = substr($pattern,0,$matches[1])."|".substr($pattern,$matches[1]);
1605         }
1606         
1607         $patterns[] = $pattern;
1608     }
1609     return array_unique($patterns);
1610 }
1611
1612 //get unique outbound route trunks for a given context
1613 function core_routing_getroutetrunks($route) {
1614     global $db;
1615     $sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'dialout-trunk,%' OR args LIKE 'dialout-enum,%') ORDER BY priority ";
1616     $results = $db->getAll($sql);
1617     if(DB::IsError($results)) {
1618         die($results->getMessage());
1619     }
1620     
1621     $trunks = array();
1622     foreach ($results as $row) {
1623         if (preg_match('/^dialout-trunk,(\d+)/', $row[0], $matches)) {
1624             // check in_array -- even though we did distinct
1625             // we still might get ${EXTEN} and ${EXTEN:1} if they used | to split a pattern
1626             if (!in_array("OUT_".$matches[1], $trunks)) {
1627                 $trunks[] = "OUT_".$matches[1];
1628             }
1629         } else if (preg_match('/^dialout-enum,(\d+)/', $row[0], $matches)) {
1630             if (!in_array("OUT_".$matches[1], $trunks)) {
1631                 $trunks[] = "OUT_".$matches[1];
1632             }
1633         }
1634     }
1635     return $trunks;
1636 }
1637
1638
1639 //get password for this route
1640 function core_routing_getroutepassword($route) {
1641     global $db;
1642     $sql = "SELECT DISTINCT args FROM extensions WHERE context = 'outrt-".$route."' AND (args LIKE 'dialout-trunk,%' OR args LIKE 'dialout-enum,%') ORDER BY priority ";
1643     $results = $db->getOne($sql);
1644     if(DB::IsError($results)) {
1645         die($results->getMessage());
1646     }
1647     if (preg_match('/^.*,.*,.*,(\d+)/', $results, $matches)) {
1648         $password = $matches[1];
1649     } else {
1650         $password = "";
1651     }
1652     return $password;
1653     
1654 }
1655
1656 /* end page.routing.php functions */
1657
1658 ?>
Note: See TracBrowser for help on using the browser.