root/freepbx/branches/experimental/amp_conf/htdocs/users/functions.inc.php

Revision 2213, 32.0 kB (checked in by gregmac, 2 years ago)

Beginnings of UserPortal interface (NOT AT ALL FINISHED)

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
Line 
1 <?php /* $id$ */
2 //Copyright (C) 2004 Coalescent Systems Inc. (info@coalescentsystems.ca)
3 //
4 //This program is free software; you can redistribute it and/or
5 //modify it under the terms of the GNU General Public License
6 //as published by the Free Software Foundation; either version 2
7 //of the License, or (at your option) any later version.
8 //
9 //This program is distributed in the hope that it will be useful,
10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //GNU General Public License for more details.
13
14 require_once('../admin/featurecodes.class.php');
15 require_once('../admin/components.class.php');
16
17 function parse_amportal_conf($filename) {
18         $file = file($filename);
19         if (is_array($file)) {
20                 foreach ($file as $line) {
21                         if (preg_match("/^\s*([a-zA-Z0-9]+)=([a-zA-Z0-9 .&-@=_<>\"\']+)\s*$/",$line,$matches)) {
22                                 $conf[ $matches[1] ] = $matches[2];
23                         }
24                 }
25         } else {
26                 die("<h1>Missing or unreadable config file ($filename)...cannot continue</h1>");
27         }
28        
29         if ( !isset($conf["AMPDBENGINE"]) || ($conf["AMPDBENGINE"] == "")) {
30                 $conf["AMPDBENGINE"] = "mysql";
31         }
32        
33         if ( !isset($conf["AMPDBNAME"]) || ($conf["AMPDBNAME"] == "")) {
34                 $conf["AMPDBNAME"] = "asterisk";
35         }
36
37 /*                     
38         if (($amp_conf["AMPDBENGINE"] == "sqlite") && (!isset($amp_conf["AMPDBENGINE"])))
39                 $amp_conf["AMPDBFILE"] = "/var/lib/freepbx/freepbx.sqlite";
40 */
41        
42         return $conf;
43 }
44
45 function parse_asterisk_conf($filename) {
46         $file = file($filename);
47         foreach ($file as $line) {
48                 if (preg_match("/^\s*([a-zA-Z0-9]+)\s* => \s*(.*)\s*([;#].*)?/",$line,$matches)) {
49                         $conf[ $matches[1] ] = $matches[2];
50                 }
51         }
52         return $conf;
53 }
54
55 function getAmpAdminUsers() {
56         global $db;
57
58         $sql = "SELECT username FROM ampusers WHERE sections='*'";
59         $results = $db->getAll($sql);
60         if(DB::IsError($results)) {
61            die($results->getMessage());
62         }
63         return $results;
64 }
65
66 function getAmpUser($username) {
67         global $db;
68        
69         $sql = "SELECT username, password, extension_low, extension_high, deptname, sections FROM ampusers WHERE username = '".addslashes($username)."'";
70         $results = $db->getAll($sql);
71         if(DB::IsError($results)) {
72            die($results->getMessage());
73         }
74        
75         if (count($results) > 0) {
76                 $user = array();
77                 $user["username"] = $results[0][0];
78                 $user["password"] = $results[0][1];
79                 $user["extension_low"] = $results[0][2];
80                 $user["extension_high"] = $results[0][3];
81                 $user["deptname"] = $results[0][4];
82                 $user["sections"] = explode(";",$results[0][5]);
83                 return $user;
84         } else {
85                 return false;
86         }
87 }
88
89 function getEndUser($extension) {
90         global $db;
91
92         $sql = 'SELECT extension, password, voicemail, name FROM users WHERE extension = \''.addslashes($extension).'\'';
93        
94 }
95
96 class ampuser {
97         var $username;
98         var $_password;
99         var $_extension_high;
100         var $_extension_low;
101         var $_deptname;
102         var $_sections;
103        
104         function ampuser($username) {
105                 $this->username = $username;
106                 if ($user = getAmpUser($username)) {
107                         $this->_password = $user["password"];
108                         $this->_extension_high = $user["extension_high"];
109                         $this->_extension_low = $user["extension_low"];
110                         $this->_deptname = $user["deptname"];
111                         $this->_sections = $user["sections"];
112                 } else {
113                         // user doesn't exist
114                         $this->_password = false;
115                         $this->_extension_high = "";
116                         $this->_extension_low = "";
117                         $this->_deptname = "";
118                         $this->_sections = array();
119                 }
120         }
121        
122         /** Give this user full admin access
123         */
124         function setAdmin() {
125                 $this->_extension_high = "";
126                 $this->_extension_low = "";
127                 $this->_deptname = "";
128                 $this->_sections = array("*");
129         }
130        
131         function checkPassword($password) {
132                 // strict checking so false will never match
133                 return ($this->_password === $password);
134         }
135        
136         function checkSection($section) {
137                 // if they have * then it means all sections
138                 return in_array("*", $this->_sections) || in_array($section, $this->_sections);
139         }
140 }
141
142 class enduser extends ampuser {
143         function enduser($extension) {
144                 $conf = getVoicemail();
145                 var_dump($conf);
146                 die();
147         }
148 }
149
150 // returns true if extension is within allowed range
151 function checkRange($extension){
152         $low = isset($_SESSION["AMP_user"]->_extension_low)?$_SESSION["AMP_user"]->_extension_low:'';
153         $high = isset($_SESSION["AMP_user"]->_extension_high)?$_SESSION["AMP_user"]->_extension_high:'';
154        
155         if ((($extension >= $low) && ($extension <= $high)) || ($low == '' && $high == ''))
156                 return true;
157         else
158                 return false;
159 }
160
161 // returns true if department string matches dept for this user
162 function checkDept($dept){
163         $deptname = isset($_SESSION["AMP_user"])?$_SESSION["AMP_user"]:null;
164        
165         if ( ($dept == null) || ($dept == $deptname) )
166                 return true;
167         else
168                 return false;
169 }
170
171 /* look for all modules in modules dir.
172 ** returns array:
173 ** array['module']['displayName']
174 ** array['module']['version']
175 ** array['module']['type']
176 ** array['module']['status']
177 ** array['module']['items'][array(items)]
178 ** Use find_modules() to return only specific type or status
179 */
180 function find_allmodules() {
181         global $db;
182         global $amp_conf;
183        
184         if (!is_dir($amp_conf['AMPWEBROOT'].'/admin/modules'))
185         {
186             mkdir( $amp_conf['AMPWEBROOT'].'/admin/modules' );
187             return;
188         }
189        
190         $dir = opendir($amp_conf['AMPWEBROOT'].'/admin/modules');
191         $data = "<xml>";
192         //loop through each module directory, ensure there is a module.ini file
193         while ($file = readdir($dir)) {
194                 if (($file != ".") && ($file != "..") && ($file != "CVS") && ($file != ".svn") && is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$file) && is_file($amp_conf['AMPWEBROOT'].'/admin/modules/'.$file.'/module.xml')) {
195                         //open module.xml and read contents
196                         if(is_file($amp_conf['AMPWEBROOT'].'/admin/modules/'.$file.'/module.xml')){
197                                 $data .=file_get_contents($amp_conf['AMPWEBROOT'].'/admin/modules/'.$file.'/module.xml');
198                                
199                         }
200                 }
201         }
202         $data .= "</xml>";
203         $parser = new xml2ModuleArray($data);
204         $xmlarray = $parser->parseModulesXML($data);
205        
206         // determine details about this module from database
207         // modulename should match the directory name
208         $sql = "SELECT * FROM modules";
209         $results = $db->getAll($sql,DB_FETCHMODE_ASSOC);
210         if(DB::IsError($results)) {
211                 die($results->getMessage());
212         }
213        
214         if (is_array($results)) {
215                 foreach($results as $result) {
216                                 /*
217                                 set status key based on results
218                                 -1=broken (in table, not not on filesystem)
219                                 0 or null=not installed
220                                 1=disabled
221                                 2=enabled
222                                 3=enabled and needs upgrade
223                                 */
224                                 if(isset($xmlarray[ $result['modulename'] ] ) && is_array($xmlarray[ $result['modulename'] ])) {
225                                         if ($result['enabled'] != 0) {
226                                                 // check if file and registered versions are the same
227                                                 // version_compare returns 0 if no difference
228                                                 if (version_compare($result['version'],$xmlarray[ $result['modulename'] ]["version"]) === 0)
229                                                         $xmlarray[ $result['modulename'] ]["status"] = 2;
230                                                 else
231                                                         $xmlarray[ $result['modulename'] ]["status"] = 3;
232                                         } else {
233                                                 $xmlarray[ $result['modulename'] ]["status"] = 1;
234                                         }
235                                 } else {
236                                         $xmlarray[ $result['modulename'] ]["status"] = -1;
237                                 }
238                                        
239                 }
240         }
241
242         //echo "<pre>"; print_r($xmlarray); echo "</pre>";
243         return $xmlarray;
244 }
245
246 /* finds modules of the specified status and type
247 ** $status can be 0 (not installed), 1 (disabled), 2 (enabled)
248 ** $type can be 'setup' or 'tool'
249 **
250 ** returns array:
251 ** array['module']['displayName']
252 ** array['module']['version']
253 ** array['module']['type']
254 ** array['module']['status']
255 ** array['module']['items'][array(items)]
256 */
257 function find_modules($status) {
258         $modules = find_allmodules();
259         if (isset($modules) && is_array($modules)) {   
260                 foreach(array_keys($modules) as $key) {
261                         //remove modules not matching status
262                         if(isset($modules[$key]['status']) && $modules[$key]['status'] == $status ){
263                                 $return_modules[$key] = $modules[$key];
264                         }
265                 }
266                 return $return_modules;
267         } else {
268                 return false;
269         }
270 }
271
272
273 // This returns the version of a module
274 function modules_getversion($modname) {
275         global $db;
276
277         $sql = "SELECT version FROM modules WHERE modulename = '$modname'";
278         $results = $db->getRow($sql,DB_FETCHMODE_ASSOC);
279         if (isset($results['version']))
280                 return $results['version'];
281         else
282                 return null;
283 }
284
285 // I bet you can't guess what this one does.
286 function modules_setversion($modname, $vers) {
287         global $db;
288
289         return sql("UPDATE modules SET version='$vers' WHERE modulename = '$modname'");
290 }
291
292
293 /* queries database using PEAR.
294 *  $type can be query, getAll, getRow, getCol, getOne, etc
295 *  $fetchmode can be DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
296 *  returns array, unless using getOne
297 */
298 function sql($sql,$type="query",$fetchmode=null) {
299         global $db;
300         $results = $db->$type($sql,$fetchmode);
301         if(DB::IsError($results)) {
302                 die($results->getDebugInfo());
303         }
304         return $results;
305 }
306
307 // sql text formatting -- couldn't see that one was available already
308 function sql_formattext($txt) {
309         if (isset($txt)) {
310                 $fmt = str_replace("'", "''", $txt);
311                 $fmt = "'" . $fmt . "'";
312         } else {
313                 $fmt = 'null';
314         }
315
316         return $fmt;
317 }
318
319 //tell application we need to reload asterisk
320 function needreload() {
321         global $db;
322         $sql = "UPDATE admin SET value = 'true' WHERE variable = 'need_reload'";
323         $result = $db->query($sql);
324         if(DB::IsError($result)) {     
325                 die($result->getMessage());
326         }
327 }
328
329 //get the version number
330 function getversion() {
331         global $db;
332         $sql = "SELECT value FROM admin WHERE variable = 'version'";
333         $results = $db->getAll($sql);
334         if(DB::IsError($results)) {
335                 die($results->getMessage());
336         }
337         return $results;
338 }
339
340 // draw list for users and devices with paging
341 function drawListMenu($results, $skip, $dispnum, $extdisplay, $description) {
342         $perpage=20;
343        
344         $skipped = 0;
345         $index = 0;
346         if ($skip == "") $skip = 0;
347         echo "<li><a id=\"".($extdisplay=='' ? 'current':'')."\" href=\"config.php?display=".$dispnum."\">"._("Add")." ".$description."</a></li>";
348
349         if (isset($results)) {
350                 foreach ($results AS $key=>$result) {
351                         if ($index >= $perpage) {
352                                 $shownext= 1;
353                                 break;
354                         }
355                        
356                         if ($skipped<$skip && $skip!= 0) {
357                                 $skipped= $skipped + 1;
358                                 continue;
359                         }
360                        
361                         $index= $index + 1;     
362                         echo "<li><a id=\"".($extdisplay==$result[0] ? 'current':'')."\" href=\"config.php?display=".$dispnum."&extdisplay={$result[0]}&skip={$skip}\">{$result[1]} <{$result[0]}></a></li>";
363                 }
364         }
365          
366         if ($index >= $perpage) {
367                  print "<li><center>";
368         }
369          
370         if ($skip) {
371                  $prevskip= $skip - $perpage;
372                  if ($prevskip<0) $prevskip= 0;
373                  $prevtag_pre= "<a href='?display=".$dispnum."&skip=$prevskip'>[PREVIOUS]</a>";
374                  print "$prevtag_pre";
375         }
376        
377         if (isset($shownext)) {
378                 $nextskip= $skip + $index;
379                 if ($prevtag_pre) $prevtag .= " | ";
380                 print "$prevtag <a href='?display=".$dispnum."&skip=$nextskip'>[NEXT]</a>";
381         }
382         elseif ($skip) {
383                 print "$prevtag";
384         }
385          
386          print "</center></li>";
387 }
388
389 // this function simply makes a connection to the asterisk manager, and should be called by modules that require it (ie: dbput/dbget)
390 function checkAstMan() {
391         require_once('common/php-asmanager.php');
392         global $amp_conf;
393         $astman = new AGI_AsteriskManager();
394         if ($res = $astman->connect("127.0.0.1", $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
395                 return $astman->disconnect();
396         } else {
397                 echo "<h3>Cannot connect to Asterisk Manager with ".$amp_conf["AMPMGRUSER"]."/".$amp_conf["AMPMGRPASS"]."</h3>This module requires access to the Asterisk Manager.  Please ensure Asterisk is running and access to the manager is available.</div>";
398                 exit;
399         }
400 }
401
402
403 /** Recursively read voicemail.conf (and any included files)
404  * This function is called by getVoicemailConf()
405  */
406 function parse_voicemailconf($filename, &$vmconf, &$section) {
407         if (is_null($vmconf)) {
408                 $vmconf = array();
409         }
410         if (is_null($section)) {
411                 $section = "general";
412         }
413        
414         if (file_exists($filename)) {
415                 $fd = fopen($filename, "r");
416                 while ($line = fgets($fd, 1024)) {
417                         if (preg_match("/^\s*(\d+)\s*=>\s*(\d*),(.*),(.*),(.*),(.*)\s*([;#].*)?/",$line,$matches)) {
418                                 // "mailbox=>password,name,email,pager,options"
419                                 // this is a voicemail line     
420                                 $vmconf[$section][ $matches[1] ] = array("mailbox"=>$matches[1],
421                                                                         "pwd"=>$matches[2],
422                                                                         "name"=>$matches[3],
423                                                                         "email"=>$matches[4],
424                                                                         "pager"=>$matches[5],
425                                                                         "options"=>array(),
426                                                                         );
427                                                                
428                                 // parse options
429                                 //output($matches);
430                                 foreach (explode("|",$matches[6]) as $opt) {
431                                         $temp = explode("=",$opt);
432                                         //output($temp);
433                                         if (isset($temp[1])) {
434                                                 list($key,$value) = $temp;
435                                                 $vmconf[$section][ $matches[1] ]["options"][$key] = $value;
436                                         }
437                                 }
438                         } else if (preg_match("/^\s*(\d+)\s*=>\s*dup,(.*)\s*([;#].*)?/",$line,$matches)) {
439                                 // "mailbox=>dup,name"
440                                 // duplace name line
441                                 $vmconf[$section][ $matches[1] ]["dups"][] = $matches[2];
442                         } else if (preg_match("/^\s*#include\s+(.*)\s*([;#].*)?/",$line,$matches)) {
443                                 // include another file
444                                
445                                 if ($matches[1][0] == "/") {
446                                         // absolute path
447                                         $filename = $matches[1];
448                                 } else {
449                                         // relative path
450                                         $filename =  dirname($filename)."/".$matches[1];
451                                 }
452                                
453                                 parse_voicemailconf($filename, $vmconf, $section);
454                                
455                         } else if (preg_match("/^\s*\[(.+)\]/",$line,$matches)) {
456                                 // section name
457                                 $section = strtolower($matches[1]);
458                         } else if (preg_match("/^\s*([a-zA-Z0-9-_]+)\s*=\s*(.*?)\s*([;#].*)?$/",$line,$matches)) {
459                                 // name = value
460                                 // option line
461                                 $vmconf[$section][ $matches[1] ] = $matches[2];
462                         }
463                 }
464                 fclose($fd);
465         }
466 }
467
468 function getVoicemail() {
469         $vmconf = null;
470         $section = null;
471        
472         // yes, this is hardcoded.. is this a bad thing?
473         parse_voicemailconf("/etc/asterisk/voicemail.conf", $vmconf, $section);
474        
475         return $vmconf;
476 }
477
478 /** Write the voicemail.conf file
479  * This is called by saveVoicemail()
480  * It's important to make a copy of $vmconf before passing it. Since this is a recursive function, has to
481  * pass by reference. At the same time, it removes entries as it writes them to the file, so if you don't have
482  * a copy, by the time it's done $vmconf will be empty.
483 */
484 function write_voicemailconf($filename, &$vmconf, &$section, $iteration = 0) {
485         if ($iteration == 0) {
486                 $section = null;
487         }
488        
489         $output = array();
490        
491         if (file_exists($filename)) {
492                 $fd = fopen($filename, "r");
493                 while ($line = fgets($fd, 1024)) {
494                         if (preg_match("/^(\s*)(\d+)(\s*)=>(\s*)(\d*),(.*),(.*),(.*),(.*)(\s*[;#].*)?$/",$line,$matches)) {
495                                 // "mailbox=>password,name,email,pager,options"
496                                 // this is a voicemail line
497                                 //DEBUG echo "\nmailbox";
498                                
499                                 // make sure we have something as a comment
500                                 if (!isset($matches[10])) {
501                                         $matches[10] = "";
502                                 }
503                                
504                                 // $matches[1] [3] and [4] are to preserve indents/whitespace, we add these back in
505                                
506                                 if (isset($vmconf[$section][ $matches[2] ])) { 
507                                         // we have this one loaded
508                                         // repopulate from our version
509                                         $temp = & $vmconf[$section][ $matches[2] ];
510                                        
511                                         $options = array();
512                                         foreach ($temp["options"] as $key=>$value) {
513                                                 $options[] = $key."=".$value;
514                                         }
515                                        
516                                         $output[] = $matches[1].$temp["mailbox"].$matches[3]."=>".$matches[4].$temp["pwd"].",".$temp["name"].",".$temp["email"].",".$temp["pager"].",". implode("|",$options).$matches[10];
517                                        
518                                         // remove this one from $vmconf
519                                         unset($vmconf[$section][ $matches[2] ]);
520                                 } else {
521                                         // we don't know about this mailbox, so it must be deleted
522                                         // (and hopefully not JUST added since we did read_voiceamilconf)
523                                        
524                                         // do nothing
525                                 }
526                                
527                         } else if (preg_match("/^(\s*)(\d+)(\s*)=>(\s*)dup,(.*)(\s*[;#].*)?$/",$line,$matches)) {
528                                 // "mailbox=>dup,name"
529                                 // duplace name line
530                                 // leave it as-is (for now)
531                                 //DEBUG echo "\ndup mailbox";
532                                 $output[] = $line;
533                         } else if (preg_match("/^(\s*)#include(\s+)(.*)(\s*[;#].*)?$/",$line,$matches)) {
534                                 // include another file
535                                 //DEBUG echo "\ninclude ".$matches[3]."<blockquote>";
536                                
537                                 // make sure we have something as a comment
538                                 if (!isset($matches[4])) {
539                                         $matches[4] = "";
540                                 }
541                                
542                                 if ($matches[3][0] == "/") {
543                                         // absolute path
544                                         $include_filename = $matches[3];
545                                 } else {
546                                         // relative path
547                                         $include_filename =  dirname($filename)."/".$matches[3];
548                                 }
549                                
550                                 $output[] = $matches[1]."#include".$matches[2].$matches[3].$matches[4];
551                                 write_voicemailconf($include_filename, $vmconf, $section, $iteration+1);
552                                
553                                 //DEBUG echo "</blockquote>";
554                                
555                         } else if (preg_match("/^(\s*)\[(.+)\](\s*[;#].*)?$/",$line,$matches)) {
556                                 // section name
557                                 //DEBUG echo "\nsection";
558                                
559                                 // make sure we have something as a comment
560                                 if (!isset($matches[3])) {
561                                         $matches[3] = "";
562                                 }
563                                
564                                 // check if this is the first run (section is null)
565                                 if ($section !== null) {
566                                         // we need to add any new entries here, before the section changes
567                                         //DEBUG echo "<blockquote><i>";
568                                         //DEBUG var_dump($vmconf[$section]);
569                                         if (isset($vmconf[$section])){  //need this, or we get an error if we unset the last items in this section - should probably automatically remove the section/context from voicemail.conf
570                                                 foreach ($vmconf[$section] as $key=>$value) {
571                                                         if (is_array($value)) {
572                                                                 // mailbox line
573                                                                
574                                                                 $temp = & $vmconf[$section][ $key ];
575                                                                
576                                                                 $options = array();
577                                                                 foreach ($temp["options"] as $key1=>$value) {
578                                                                         $options[] = $key1."=".$value;
579                                                                 }
580                                                                
581                                                                 $output[] = $temp["mailbox"]." => ".$temp["pwd"].",".$temp["name"].",".$temp["email"].",".$temp["pager"].",". implode("|",$options);
582                                                                
583                                                                 // remove this one from $vmconf
584                                                                 unset($vmconf[$section][ $key ]);
585                                                                
586                                                         } else {
587                                                                 // option line
588                                                                
589                                                                 $output[] = $key."=".$vmconf[$section][ $key ];
590                                                                
591                                                                 // remove this one from $vmconf
592                                                                 unset($vmconf[$section][ $key ]);
593                                                         }
594                                                 }
595                                         }
596                                         //DEBUG echo "</i></blockquote>";
597                                 }
598                                
599                                 $section = strtolower($matches[2]);
600                                 $output[] = $matches[1]."[".$section."]".$matches[3];
601                                 $existing_sections[] = $section; //remember that this section exists
602
603                         } else if (preg_match("/^(\s*)([a-zA-Z0-9-_]+)(\s*)=(\s*)(.*?)(\s*[;#].*)?$/",$line,$matches)) {
604                                 // name = value
605                                 // option line
606                                 //DEBUG echo "\noption line";
607                                
608                                
609                                 // make sure we have something as a comment
610                                 if (!isset($matches[6])) {
611                                         $matches[6] = "";
612                                 }
613                                
614                                 if (isset($vmconf[$section][ $matches[2] ])) {
615                                         $output[] = $matches[1].$matches[2].$matches[3]."=".$matches[4].$vmconf[$section][ $matches[2] ].$matches[6];
616                                        
617                                         // remove this one from $vmconf
618                                         unset($vmconf[$section][ $matches[2] ]);
619                                 }
620                                 // else it's been deleted, so we don't write it in
621                                
622                         } else {
623                                 // unknown other line -- probably a comment or whitespace
624                                 //DEBUG echo "\nother: ".$line;
625                                
626                                 $output[] = str_replace(array("\n","\r"),"",$line); // str_replace so we don't double-space
627                         }
628                 }
629                
630                 if ($iteration == 0) {
631                         // we need to add any new entries here, since it's the end of the file
632                         //DEBUG echo "END OF FILE!! <blockquote><i>";
633                         //DEBUG var_dump($vmconf);
634                         foreach (array_keys($vmconf) as $section) {
635                                 if (!in_array($section,$existing_sections))  // If this is a new section, write the context label
636                                         $output[] = "[".$section."]";
637                                 foreach ($vmconf[$section] as $key=>$value) {
638                                         if (is_array($value)) {
639                                                 // mailbox line
640                                                
641                                                 $temp = & $vmconf[$section][ $key ];
642                                                
643                                                 $options = array();
644                                                 foreach ($temp["options"] as $key=>$value) {
645                                                         $options[] = $key."=".$value;
646                                                 }
647                                                
648                                                 $output[] = $temp["mailbox"]." => ".$temp["pwd"].",".$temp["name"].",".$temp["email"].",".$temp["pager"].",". implode("|",$options);
649                                                
650                                                 // remove this one from $vmconf
651                                                 unset($vmconf[$section][ $key ]);
652                                                
653                                         } else {
654                                                 // option line
655                                                
656                                                 $output[] = $key."=".$vmconf[$section][ $key ];
657                                                
658                                                 // remove this one from $vmconf
659                                                 unset($vmconf[$section][$key ]);
660                                         }
661                                 }
662                         }
663                         //DEBUG echo "</i></blockquote>";
664                 }
665                
666                 fclose($fd);
667                
668                 //DEBUG echo "\n\nwriting ".$filename;
669                 //DEBUG echo "\n-----------\n";
670                 //DEBUG echo implode("\n",$output);
671                 //DEBUG echo "\n-----------\n";
672                
673                 // write this file back out
674                
675                 if ($fd = fopen($filename, "w")) {
676                         fwrite($fd, implode("\n",$output)."\n");
677                         fclose($fd);
678                 }
679                
680         }
681 }
682
683 function saveVoicemail($vmconf) {
684         // yes, this is hardcoded.. is this a bad thing?
685         write_voicemailconf("/etc/asterisk/voicemail.conf", $vmconf, $section);
686 }
687
688
689 // $goto is the current goto destination setting
690 // $i is the destination set number (used when drawing multiple destination sets in a single form ie: digital receptionist)
691 // esnure that any form that includes this calls the setDestinations() javascript function on submit.
692 // ie: if the form name is "edit", and drawselects has been called with $i=2 then use onsubmit="setDestinations(edit,2)"
693 function drawselects($goto,$i) { 
694        
695         /* --- MODULES BEGIN --- */
696         global $active_modules;
697        
698         // This is purely to remove a warning.
699         if (!isset($selectHtml)) { $selectHtml=''; }
700         $selectHtml .= '<tr><td colspan=2>';
701        
702         //check for module-specific destination functions
703         foreach ($active_modules as $mod => $displayname) {
704                 $funct = strtolower($mod.'_destinations');
705        
706                 //if the modulename_destinations() function exits, run it and display selections for it
707                 if (function_exists($funct)) {
708                         $options = "";
709                         $destArray = $funct(); //returns an array with 'destination' and 'description'.
710                         $checked = false;
711                         if (isset($destArray)) {
712                                 //loop through each option returned by the module
713                                 foreach ($destArray as $dest) {
714                                         // check to see if the currently selected goto matches one these destinations
715                                         if ($dest['destination'] == $goto)
716                                                 $checked = true;  //there is a match, so we select the radio for this group
717
718                                         // create an select option for each destination
719                                         $options .= '<option value="'.$dest['destination'].'" '.(strpos($goto,$dest['destination']) === false ? '' : 'SELECTED').'>'.($dest['description'] ? $dest['description'] : $dest['destination']);
720                                 }
721                                
722                                 // make a unique id to be used for the HTML id
723                                 // This allows us to have multiple drawselect() sets on the page without
724                                 // conflicting with each other
725                                 $radioid = uniqid("drawselect");
726                                
727                                 $selectHtml .=  '<input type="radio" id="'.$radioid.'" name="goto_indicate'.$i.'" value="'.$mod.'" onclick="javascript:this.form.goto'.$i.'.value=\''.$mod.'\';" onkeypress="javascript:if (event.keyCode == 0 || (document.all && event.keyCode == 13)) this.form.goto'.$i.'.value=\''.$mod.'\';" '.($checked? 'CHECKED=CHECKED' : '').' /> '._($displayname['displayName']).': ';
728                                 if ($checked) { $goto = $mod; }
729                                 $selectHtml .=  '<select name="'.$mod.$i.'" onfocus="document.getElementById(\''.$radioid.'\').checked = true;">';
730                                 $selectHtml .= $options;       
731                                 $selectHtml .=  "</select><br>\n";
732                         }
733                        
734                 }
735         }
736         /* --- MODULES END --- */
737        
738         //display a custom goto field
739         $radioid = uniqid("drawselect");
740         $selectHtml .= '<input type="radio" id="'.$radioid.'" name="goto_indicate'.$i.'" value="custom" onclick="javascript:this.form.goto'.$i.'.value=\'custom\';" onkeypress="javascript:if (event.keyCode == 0 || (document.all && event.keyCode == 13)) this.form.goto'.$i.'.value=\'custom\';" '.(strpos($goto,'custom') === false ? '' : 'CHECKED=CHECKED').' />';
741         $selectHtml .= '<a href="#" class="info"> '._("Custom A