| 1 |
<?php /* $Id$ */ |
|---|
| 2 |
//Copyright (C) 2004 Coalescent Systems Inc. (info@coalescentsystems.ca) |
|---|
| 3 |
//Copyright (C) 2006-2010 Philippe Lindheimer |
|---|
| 4 |
/* |
|---|
| 5 |
* |
|---|
| 6 |
* This program is free software; you can redistribute it and/or |
|---|
| 7 |
* modify it under the terms of the GNU General Public License |
|---|
| 8 |
* as published by the Free Software Foundation; either version 2 |
|---|
| 9 |
* of the License, or (at your option) any later version. |
|---|
| 10 |
* |
|---|
| 11 |
* This program is distributed in the hope that it will be useful, |
|---|
| 12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 |
* GNU General Public License for more details. |
|---|
| 15 |
*/ |
|---|
| 16 |
|
|---|
| 17 |
//set variables |
|---|
| 18 |
$vars = array( |
|---|
| 19 |
'action' => null, |
|---|
| 20 |
'display' => '', |
|---|
| 21 |
'extdisplay' => null, |
|---|
| 22 |
'logout' => false, |
|---|
| 23 |
'password' => '', |
|---|
| 24 |
'quietmode' => '', |
|---|
| 25 |
'restrictmods' => false, |
|---|
| 26 |
'skip' => 0, |
|---|
| 27 |
'skip_astman' => false, |
|---|
| 28 |
'username' => '', |
|---|
| 29 |
'type' => '' |
|---|
| 30 |
); |
|---|
| 31 |
|
|---|
| 32 |
foreach ($vars as $k => $v) { |
|---|
| 33 |
$$k = isset($_REQUEST[$k]) ? $_REQUEST[$k] : $v; |
|---|
| 34 |
|
|---|
| 35 |
//special handeling |
|---|
| 36 |
switch ($$k) { |
|---|
| 37 |
case 'extdisplay': |
|---|
| 38 |
$extdisplay = $extdisplay |
|---|
| 39 |
? htmlspecialchars($extdisplay, ENT_QUOTES) |
|---|
| 40 |
: false; |
|---|
| 41 |
$_REQUEST['extdisplay'] = $extdisplay; |
|---|
| 42 |
break; |
|---|
| 43 |
|
|---|
| 44 |
case 'restrict_mods': |
|---|
| 45 |
$restrict_mods = $restrict_mods |
|---|
| 46 |
? array_flip(explode('/', $restrict_mods)) |
|---|
| 47 |
: false; |
|---|
| 48 |
break; |
|---|
| 49 |
|
|---|
| 50 |
case 'skip_astman': |
|---|
| 51 |
$bootstrap_settings['skip_astman'] = $skip_astman; |
|---|
| 52 |
break; |
|---|
| 53 |
} |
|---|
| 54 |
} |
|---|
| 55 |
|
|---|
| 56 |
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); |
|---|
| 57 |
header('Expires: Sat, 01 Jan 2000 00:00:00 GMT'); |
|---|
| 58 |
header('Cache-Control: post-check=0, pre-check=0',false); |
|---|
| 59 |
header('Pragma: no-cache'); |
|---|
| 60 |
header('Content-Type: text/html; charset=utf-8'); |
|---|
| 61 |
|
|---|
| 62 |
require_once(dirname(__FILE__) . '/libraries/ampuser.class.php'); |
|---|
| 63 |
//start a session if we need one |
|---|
| 64 |
if (!isset($_SESSION)) { |
|---|
| 65 |
session_start(); |
|---|
| 66 |
} |
|---|
| 67 |
|
|---|
| 68 |
//unset the ampuser if the user logged out |
|---|
| 69 |
if ($logout == 'true') { |
|---|
| 70 |
unset($_SESSION['AMP_user']); |
|---|
| 71 |
exit(); |
|---|
| 72 |
} |
|---|
| 73 |
|
|---|
| 74 |
//session_cache_limiter('public, no-store'); |
|---|
| 75 |
if (isset($_REQUEST['handler'])) { |
|---|
| 76 |
$restrict_mods = true; |
|---|
| 77 |
// I think reload is the only handler that requires astman, so skip it for others |
|---|
| 78 |
switch ($_REQUEST['handler']) { |
|---|
| 79 |
case 'api': |
|---|
| 80 |
$restrict_mods = false; |
|---|
| 81 |
break; |
|---|
| 82 |
case 'reload'; |
|---|
| 83 |
break; |
|---|
| 84 |
default: |
|---|
| 85 |
$bootstrap_settings['skip_astman'] = true; |
|---|
| 86 |
break; |
|---|
| 87 |
} |
|---|
| 88 |
} |
|---|
| 89 |
|
|---|
| 90 |
require('bootstrap.php'); |
|---|
| 91 |
|
|---|
| 92 |
/* If there is an action request then some sort of update is usually being done. |
|---|
| 93 |
This will protect from cross site request forgeries unless disabled. |
|---|
| 94 |
*/ |
|---|
| 95 |
if (!isset($no_auth) && $action != '' && $amp_conf['CHECKREFERER']) { |
|---|
| 96 |
if (isset($_SERVER['HTTP_REFERER'])) { |
|---|
| 97 |
$referer = parse_url($_SERVER['HTTP_REFERER']); |
|---|
| 98 |
$refererok = (trim($referer['host']) == trim($_SERVER['SERVER_NAME'])) ? true : false; |
|---|
| 99 |
} else { |
|---|
| 100 |
$refererok = false; |
|---|
| 101 |
} |
|---|
| 102 |
|
|---|
| 103 |
if (!$refererok) { |
|---|
| 104 |
show_view($amp_conf['VIEW_BAD_REFFERER'], array('amp_conf'=>&$amp_conf)); |
|---|
| 105 |
exit; |
|---|
| 106 |
} |
|---|
| 107 |
} |
|---|
| 108 |
|
|---|
| 109 |
// handle special requests |
|---|
| 110 |
if (!isset($no_auth) && isset($_REQUEST['handler'])) { |
|---|
| 111 |
$module = isset($_REQUEST['module']) ? $_REQUEST['module'] : ''; |
|---|
| 112 |
$file = isset($_REQUEST['file']) ? $_REQUEST['file'] : ''; |
|---|
| 113 |
fileRequestHandler($_REQUEST['handler'], $module, $file); |
|---|
| 114 |
exit(); |
|---|
| 115 |
} |
|---|
| 116 |
|
|---|
| 117 |
$fw_gui_html = ''; |
|---|
| 118 |
//buffer & compress our responce |
|---|
| 119 |
ob_start($amp_conf['buffering_callback']); |
|---|
| 120 |
|
|---|
| 121 |
if (!$quietmode) { |
|---|
| 122 |
//send header |
|---|
| 123 |
$header['title'] = framework_server_name(); |
|---|
| 124 |
$header['amp_conf'] = $amp_conf; |
|---|
| 125 |
$fw_gui_html .= load_view(dirname(__FILE__) . '/views/header.php', $header); |
|---|
| 126 |
|
|---|
| 127 |
if (isset($no_auth)) { |
|---|
| 128 |
$fw_gui_html .= load_view(dirname(__FILE__) . '/views/menu.php', $header); |
|---|
| 129 |
$fw_gui_html .= $no_auth; |
|---|
| 130 |
$fw_gui_html .= load_view($amp_conf['VIEW_FOOTER'], array('no_auth' => $no_auth)); |
|---|
| 131 |
echo $fw_gui_html; |
|---|
| 132 |
exit(); |
|---|
| 133 |
} |
|---|
| 134 |
module_run_notification_checks(); |
|---|
| 135 |
} |
|---|
| 136 |
$fw_gui_html .= ob_get_contents(); |
|---|
| 137 |
ob_end_clean(); |
|---|
| 138 |
|
|---|
| 139 |
//draw up freepbx menu |
|---|
| 140 |
$fpbx_menu = array(); |
|---|
| 141 |
|
|---|
| 142 |
// pointer to current item in $fpbx_menu, if applicable |
|---|
| 143 |
$cur_menuitem = null; |
|---|
| 144 |
|
|---|
| 145 |
// add module sections to $fpbx_menu |
|---|
| 146 |
|
|---|
| 147 |
if(is_array($active_modules)){ |
|---|
| 148 |
foreach($active_modules as $key => $module) { |
|---|
| 149 |
|
|---|
| 150 |
//create an array of module sections to display |
|---|
| 151 |
// stored as [items][$type][$category][$name] = $displayvalue |
|---|
| 152 |
if (isset($module['items']) && is_array($module['items'])) { |
|---|
| 153 |
// loop through the types |
|---|
| 154 |
foreach($module['items'] as $itemKey => $item) { |
|---|
| 155 |
|
|---|
| 156 |
// check access, unless module.xml defines all have access |
|---|
| 157 |
//TODO: move this to bootstrap and make it work |
|---|
| 158 |
if (!isset($item['access']) || strtolower($item['access']) != 'all') { |
|---|
| 159 |
if (is_object($_SESSION["AMP_user"]) && !$_SESSION["AMP_user"]->checkSection($itemKey)) { |
|---|
| 160 |
// no access, skip to the next |
|---|
| 161 |
continue; |
|---|
| 162 |
} |
|---|
| 163 |
} |
|---|
| 164 |
|
|---|
| 165 |
if (!isset($item['display'])) { |
|---|
| 166 |
$item['display'] = $itemKey; |
|---|
| 167 |
} |
|---|
| 168 |
|
|---|
| 169 |
// reference to the actual module |
|---|
| 170 |
$item['module'] =& $active_modules[$key]; |
|---|
| 171 |
|
|---|
| 172 |
// item is an assoc array, with at least array(module=> name=>, category=>, type=>, display=>) |
|---|
| 173 |
$fpbx_menu[$itemKey] = $item; |
|---|
| 174 |
|
|---|
| 175 |
// allow a module to replace our main index page |
|---|
| 176 |
if (($item['display'] == 'index') && ($display == '')) { |
|---|
| 177 |
$display = 'index'; |
|---|
| 178 |
} |
|---|
| 179 |
|
|---|
| 180 |
// check current item |
|---|
| 181 |
if ($display == $item['display']) { |
|---|
| 182 |
// found current menuitem, make a reference to it |
|---|
| 183 |
$cur_menuitem =& $fpbx_menu[$itemKey]; |
|---|
| 184 |
} |
|---|
| 185 |
} |
|---|
| 186 |
} |
|---|
| 187 |
} |
|---|
| 188 |
} |
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 |
// new gui hooks |
|---|
| 192 |
if(!$quietmode && is_array($active_modules)){ |
|---|
| 193 |
foreach($active_modules as $key => $module) { |
|---|
| 194 |
|
|---|
| 195 |
if (isset($module['items']) && is_array($module['items'])) { |
|---|
| 196 |
foreach($module['items'] as $itemKey => $itemName) { |
|---|
| 197 |
//list of potential _configpageinit functions |
|---|
| 198 |
$initfuncname = $key . '_' . $itemKey . '_configpageinit'; |
|---|
| 199 |
if ( function_exists($initfuncname) ) { |
|---|
| 200 |
$configpageinits[] = $initfuncname; |
|---|
| 201 |
} |
|---|
| 202 |
} |
|---|
| 203 |
} |
|---|
| 204 |
//check for module level (rather than item as above) _configpageinit function |
|---|
| 205 |
$initfuncname = $key . '_configpageinit'; |
|---|
| 206 |
if ( function_exists($initfuncname) ) { |
|---|
| 207 |
$configpageinits[] = $initfuncname; |
|---|
| 208 |
} |
|---|
| 209 |
} |
|---|
| 210 |
} |
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 |
// extensions vs device/users ... this is a bad design, but hey, it works |
|---|
| 214 |
if (!$quietmode) { |
|---|
| 215 |
if (isset($amp_conf["AMPEXTENSIONS"]) && ($amp_conf["AMPEXTENSIONS"] == "deviceanduser")) { |
|---|
| 216 |
unset($fpbx_menu["extensions"]); |
|---|
| 217 |
} else { |
|---|
| 218 |
unset($fpbx_menu["devices"]); |
|---|
| 219 |
unset($fpbx_menu["users"]); |
|---|
| 220 |
} |
|---|
| 221 |
} |
|---|
| 222 |
|
|---|
| 223 |
// check access |
|---|
| 224 |
if (!is_array($cur_menuitem) && $display != "") { |
|---|
| 225 |
show_view($amp_conf['VIEW_NOACCESS'], array('amp_conf'=>&$amp_conf)); |
|---|
| 226 |
exit; |
|---|
| 227 |
} |
|---|
| 228 |
|
|---|
| 229 |
// load the component from the loaded modules |
|---|
| 230 |
if ($display != '' && isset($configpageinits) && is_array($configpageinits) ) { |
|---|
| 231 |
|
|---|
| 232 |
$currentcomponent = new component($display,$type); |
|---|
| 233 |
|
|---|
| 234 |
// call every modules _configpageinit function which should just |
|---|
| 235 |
// register the gui and process functions for each module, if relevant |
|---|
| 236 |
// for this $display |
|---|
| 237 |
foreach ($configpageinits as $func) { |
|---|
| 238 |
$func($display); |
|---|
| 239 |
} |
|---|
| 240 |
|
|---|
| 241 |
// now run each 'process' function and 'gui' function |
|---|
| 242 |
$currentcomponent->processconfigpage(); |
|---|
| 243 |
$currentcomponent->buildconfigpage(); |
|---|
| 244 |
} |
|---|
| 245 |
ob_start($amp_conf['buffering_callback']); |
|---|
| 246 |
$module_name = ""; |
|---|
| 247 |
$module_page = ""; |
|---|
| 248 |
$module_file = ""; |
|---|
| 249 |
|
|---|
| 250 |
|
|---|
| 251 |
|
|---|
| 252 |
// hack to have our default display handler show the "welcome" view |
|---|
| 253 |
// Note: this probably isn't REALLY needed if there is no menu item for "Welcome".. |
|---|
| 254 |
// but it doesn't really hurt, and it provides a handler in case some page links |
|---|
| 255 |
// to "?display=index" |
|---|
| 256 |
if ($display == 'index' && ($cur_menuitem['module']['rawname'] == 'builtin')) { |
|---|
| 257 |
$display = ''; |
|---|
| 258 |
} |
|---|
| 259 |
|
|---|
| 260 |
// show the appropriate page |
|---|
| 261 |
switch($display) { |
|---|
| 262 |
default: |
|---|
| 263 |
//display the appropriate module page |
|---|
| 264 |
$module_name = $cur_menuitem['module']['rawname']; |
|---|
| 265 |
$module_page = $cur_menuitem['display']; |
|---|
| 266 |
$module_file = 'modules/'.$module_name.'/page.'.$module_page.'.php'; |
|---|
| 267 |
|
|---|
| 268 |
//TODO Determine which item is this module displaying. |
|---|
| 269 |
//Currently this is over the place, we should standardize on a "itemid" request var |
|---|
| 270 |
//for now, we'll just cover all possibilities :-( |
|---|
| 271 |
$possibilites = array( |
|---|
| 272 |
'userdisplay', |
|---|
| 273 |
'extdisplay', |
|---|
| 274 |
'id', |
|---|
| 275 |
'itemid', |
|---|
| 276 |
'selection' |
|---|
| 277 |
); |
|---|
| 278 |
$itemid = ''; |
|---|
| 279 |
foreach($possibilites as $possibility) { |
|---|
| 280 |
if ( isset($_REQUEST[$possibility]) && $_REQUEST[$possibility] != '' ) { |
|---|
| 281 |
$itemid = htmlspecialchars($_REQUEST[$possibility], ENT_QUOTES); |
|---|
| 282 |
$_REQUEST[$possibility] = $itemid; |
|---|
| 283 |
} |
|---|
| 284 |
} |
|---|
| 285 |
|
|---|
| 286 |
// create a module_hook object for this module's page |
|---|
| 287 |
$module_hook = new moduleHook; |
|---|
| 288 |
|
|---|
| 289 |
// populate object variables |
|---|
| 290 |
$module_hook->install_hooks($module_page,$module_name,$itemid); |
|---|
| 291 |
|
|---|
| 292 |
// let hooking modules process the $_REQUEST |
|---|
| 293 |
$module_hook->process_hooks($itemid, $module_name, $module_page, $_REQUEST); |
|---|
| 294 |
|
|---|
| 295 |
|
|---|
| 296 |
// include the module page |
|---|
| 297 |
if (isset($cur_menuitem['disabled']) && $cur_menuitem['disabled']) { |
|---|
| 298 |
show_view($amp_conf['VIEW_MENUITEM_DISABLED'], $cur_menuitem); |
|---|
| 299 |
break; // we break here to avoid the generateconfigpage() below |
|---|
| 300 |
} else if (file_exists($module_file)) { |
|---|
| 301 |
// load language info if available |
|---|
| 302 |
if (extension_loaded('gettext')) { |
|---|
| 303 |
if (is_dir("modules/{$module_name}/i18n")) { |
|---|
| 304 |
bindtextdomain($module_name,"modules/{$module_name}/i18n"); |
|---|
| 305 |
bind_textdomain_codeset($module_name, 'utf8'); |
|---|
| 306 |
textdomain($module_name); |
|---|
| 307 |
} |
|---|
| 308 |
} |
|---|
| 309 |
include($module_file); |
|---|
| 310 |
} else { |
|---|
| 311 |
echo "404 Not found (" . $module_file . ')'; |
|---|
| 312 |
} |
|---|
| 313 |
|
|---|
| 314 |
// global component |
|---|
| 315 |
if ( isset($currentcomponent) ) { |
|---|
| 316 |
echo $currentcomponent->generateconfigpage(); |
|---|
| 317 |
} |
|---|
| 318 |
|
|---|
| 319 |
break; |
|---|
| 320 |
case 'modules': |
|---|
| 321 |
// set these to avoid undefined variable warnings later |
|---|
| 322 |
// |
|---|
| 323 |
$module_name = 'modules'; |
|---|
| 324 |
$module_page = $cur_menuitem['display']; |
|---|
| 325 |
include 'page.modules.php'; |
|---|
| 326 |
break; |
|---|
| 327 |
case '': |
|---|
| 328 |
if ($astman) { |
|---|
| 329 |
show_view($amp_conf['VIEW_WELCOME'], array('AMP_CONF' => &$amp_conf)); |
|---|
| 330 |
} else { |
|---|
| 331 |
// no manager, no connection to asterisk |
|---|
| 332 |
show_view($amp_conf['VIEW_WELCOME_NOMANAGER'], array('mgruser' => $amp_conf["AMPMGRUSER"])); |
|---|
| 333 |
} |
|---|
| 334 |
break; |
|---|
| 335 |
} |
|---|
| 336 |
|
|---|
| 337 |
if ($quietmode) { |
|---|
| 338 |
// send the output buffer |
|---|
| 339 |
ob_end_flush(); |
|---|
| 340 |
} else { |
|---|
| 341 |
$admin_template = $template = array(); |
|---|
| 342 |
$content = ob_get_contents(); |
|---|
| 343 |
ob_end_clean(); |
|---|
| 344 |
//now restart buffering so that our data is compressed again |
|---|
| 345 |
ob_start($amp_conf['buffering_callback']); |
|---|
| 346 |
|
|---|
| 347 |
//if we have a module loaded, load its css |
|---|
| 348 |
if (isset($module_name)) { |
|---|
| 349 |
$fw_gui_html .= framework_include_css(); |
|---|
| 350 |
} |
|---|
| 351 |
|
|---|
| 352 |
// send menu |
|---|
| 353 |
$menu['fpbx_menu'] = $fpbx_menu; //array of modules & settings |
|---|
| 354 |
$menu['display'] = $display; //currently displayed item |
|---|
| 355 |
$menu['authtype'] = $amp_conf['AUTHTYPE']; |
|---|
| 356 |
$menu['reload_confirm'] = $amp_conf['RELOADCONFIRM']; |
|---|
| 357 |
|
|---|
| 358 |
// set the language so local module languages take |
|---|
| 359 |
set_language(); |
|---|
| 360 |
|
|---|
| 361 |
// menu + page content + footer |
|---|
| 362 |
|
|---|
| 363 |
$fw_gui_html .= load_view($amp_conf['VIEW_MENU'], $menu); |
|---|
| 364 |
|
|---|
| 365 |
//send actual page content |
|---|
| 366 |
$fw_gui_html .= $content; |
|---|
| 367 |
|
|---|
| 368 |
//send footer |
|---|
| 369 |
$footer['module_name'] = $module_name; |
|---|
| 370 |
$footer['module_page'] = $module_page; |
|---|
| 371 |
$footer['benchmark_starttime'] = $benchmark_starttime; |
|---|
| 372 |
$footer['reload_needed'] = check_reload_needed(); |
|---|
| 373 |
$fw_gui_html .= load_view($amp_conf['VIEW_FOOTER'], $footer); |
|---|
| 374 |
|
|---|
| 375 |
|
|---|
| 376 |
//$template['benchmark_starttime'] = $benchmark_starttime; |
|---|
| 377 |
|
|---|
| 378 |
} |
|---|
| 379 |
|
|---|
| 380 |
echo $fw_gui_html; |
|---|
| 381 |
?> |
|---|