| 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 |
|---|