| 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 |
/* benchmark */ |
|---|
| 15 |
function microtime_float() { list($usec,$sec) = explode(' ',microtime()); return ((float)$usec+(float)$sec); } |
|---|
| 16 |
$benchmark_starttime = microtime_float(); |
|---|
| 17 |
/*************/ |
|---|
| 18 |
|
|---|
| 19 |
$type = isset($_REQUEST['type'])?$_REQUEST['type']:'setup'; |
|---|
| 20 |
$display = isset($_REQUEST['display'])?$_REQUEST['display']:''; |
|---|
| 21 |
$extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null; |
|---|
| 22 |
$skip = isset($_REQUEST['skip'])?$_REQUEST['skip']:0; |
|---|
| 23 |
$action = isset($_REQUEST['action'])?$_REQUEST['action']:null; |
|---|
| 24 |
$quietmode = isset($_REQUEST['quietmode'])?$_REQUEST['quietmode']:''; |
|---|
| 25 |
|
|---|
| 26 |
// determine module type to show, default to 'setup' |
|---|
| 27 |
$type_names = array( |
|---|
| 28 |
'tool'=>'Tools', |
|---|
| 29 |
'setup'=>'Setup', |
|---|
| 30 |
'cdrcost'=>'Call Cost', |
|---|
| 31 |
); |
|---|
| 32 |
|
|---|
| 33 |
include('header.php'); |
|---|
| 34 |
|
|---|
| 35 |
// handle special requests |
|---|
| 36 |
if (isset($_REQUEST['handler'])) { |
|---|
| 37 |
switch ($_REQUEST['handler']) { |
|---|
| 38 |
case 'reload': |
|---|
| 39 |
/** AJAX handler for reload event |
|---|
| 40 |
*/ |
|---|
| 41 |
include_once('common/json.inc.php'); |
|---|
| 42 |
$response = do_reload(); |
|---|
| 43 |
$json = new Services_JSON(); |
|---|
| 44 |
echo $json->encode($response); |
|---|
| 45 |
break; |
|---|
| 46 |
case 'file': |
|---|
| 47 |
/** Handler to pass-through file requests |
|---|
| 48 |
* Looks for "module" and "file" variables, strips .. and only allows normal filename characters. |
|---|
| 49 |
* Accepts only files of the type listed in $allowed_exts below, and sends the corresponding mime-type, |
|---|
| 50 |
* and always interprets files through the PHP interpreter. (Most of?) the freepbx environment is available, |
|---|
| 51 |
* including $db and $astman, and the user is authenticated. |
|---|
| 52 |
*/ |
|---|
| 53 |
if (!isset($_REQUEST['module']) || !isset($_REQUEST['file'])) { |
|---|
| 54 |
die_freepbx("unknown"); |
|---|
| 55 |
} |
|---|
| 56 |
//TODO: this could probably be more efficient |
|---|
| 57 |
$module = str_replace('..','.', preg_replace('/[^a-zA-Z0-9-\_\.]/','',$_REQUEST['module'])); |
|---|
| 58 |
$file = str_replace('..','.', preg_replace('/[^a-zA-Z0-9-\_\.]/','',$_REQUEST['file'])); |
|---|
| 59 |
|
|---|
| 60 |
$allowed_exts = array( |
|---|
| 61 |
'.js' => 'text/javascript', |
|---|
| 62 |
'.js.php' => 'text/javascript', |
|---|
| 63 |
'.css' => 'text/css', |
|---|
| 64 |
'.css.php' => 'text/css', |
|---|
| 65 |
'.html.php' => 'text/html', |
|---|
| 66 |
'.jpg.php' => 'image/jpeg', |
|---|
| 67 |
'.jpeg.php' => 'image/jpeg', |
|---|
| 68 |
'.png.php' => 'image/png', |
|---|
| 69 |
'.gif.php' => 'image/gif', |
|---|
| 70 |
); |
|---|
| 71 |
foreach ($allowed_exts as $ext=>$mimetype) { |
|---|
| 72 |
if (substr($file, -1*strlen($ext)) == $ext) { |
|---|
| 73 |
$fullpath = 'modules/'.$module.'/'.$file; |
|---|
| 74 |
if (file_exists($fullpath)) { |
|---|
| 75 |
// file exists, and is allowed extension |
|---|
| 76 |
|
|---|
| 77 |
// image, css, js types - set Expires to an hour in advance so the client does |
|---|
| 78 |
// not keep checking for them. Replace from header.php |
|---|
| 79 |
if (!$amp_conf['DEVEL']) { |
|---|
| 80 |
@header('Expires: '.gmdate('D, d M Y H:i:s', time()+3600).' GMT', true); |
|---|
| 81 |
@header('Cache-Control: ',true); |
|---|
| 82 |
@header('Pragma: ', true); |
|---|
| 83 |
} |
|---|
| 84 |
@header("Content-type: ".$mimetype); |
|---|
| 85 |
include($fullpath); |
|---|
| 86 |
exit(); |
|---|
| 87 |
} |
|---|
| 88 |
break; |
|---|
| 89 |
} |
|---|
| 90 |
} |
|---|
| 91 |
die_freepbx("not allowed"); |
|---|
| 92 |
break; |
|---|
| 93 |
} |
|---|
| 94 |
exit(); |
|---|
| 95 |
} |
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 |
module_run_notification_checks(); |
|---|
| 99 |
|
|---|
| 100 |
$framework_asterisk_running = checkAstMan(); |
|---|
| 101 |
|
|---|
| 102 |
// get all enabled modules |
|---|
| 103 |
// active_modules array used below and in drawselects function and genConf function |
|---|
| 104 |
$active_modules = module_getinfo(false, MODULE_STATUS_ENABLED); |
|---|
| 105 |
|
|---|
| 106 |
$fpbx_menu = array(); |
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 |
// pointer to current item in $fpbx_menu, if applicable |
|---|
| 110 |
$cur_menuitem = null; |
|---|
| 111 |
|
|---|
| 112 |
// add module sections to $fpbx_menu |
|---|
| 113 |
$types = array(); |
|---|
| 114 |
if(is_array($active_modules)){ |
|---|
| 115 |
foreach($active_modules as $key => $module) { |
|---|
| 116 |
//include module functions |
|---|
| 117 |
if (is_file("modules/{$key}/functions.inc.php")) { |
|---|
| 118 |
require_once("modules/{$key}/functions.inc.php"); |
|---|
| 119 |
} |
|---|
| 120 |
|
|---|
| 121 |
//create an array of module sections to display |
|---|
| 122 |
// stored as [items][$type][$category][$name] = $displayvalue |
|---|
| 123 |
if (isset($module['items']) && is_array($module['items'])) { |
|---|
| 124 |
// loop through the types |
|---|
| 125 |
foreach($module['items'] as $itemKey => $item) { |
|---|
| 126 |
|
|---|
| 127 |
// check access, unless module.xml defines all have access |
|---|
| 128 |
if (!isset($item['access']) || strtolower($item['access']) != 'all') { |
|---|
| 129 |
if (!$_SESSION["AMP_user"]->checkSection($itemKey)) { |
|---|
| 130 |
// no access, skip to the next |
|---|
| 131 |
continue; |
|---|
| 132 |
} |
|---|
| 133 |
} |
|---|
| 134 |
|
|---|
| 135 |
if (!$framework_asterisk_running && |
|---|
| 136 |
((isset($item['needsenginedb']) && strtolower($item['needsenginedb'] == 'yes')) || |
|---|
| 137 |
(isset($item['needsenginerunning']) && strtolower($item['needsenginerunning'] == 'yes'))) |
|---|
| 138 |
) |
|---|
| 139 |
{ |
|---|
| 140 |
$item['disabled'] = true; |
|---|
| 141 |
} else { |
|---|
| 142 |
$item['disabled'] = false; |
|---|
| 143 |
} |
|---|
| 144 |
|
|---|
| 145 |
if (!in_array($item['type'], $types)) { |
|---|
| 146 |
$types[] = $item['type']; |
|---|
| 147 |
} |
|---|
| 148 |
|
|---|
| 149 |
if (!isset($item['display'])) { |
|---|
| 150 |
$item['display'] = $itemKey; |
|---|
| 151 |
} |
|---|
| 152 |
|
|---|
| 153 |
// reference to the actual module |
|---|
| 154 |
$item['module'] =& $active_modules[$key]; |
|---|
| 155 |
|
|---|
| 156 |
// item is an assoc array, with at least array(module=> name=>, category=>, type=>, display=>) |
|---|
| 157 |
$fpbx_menu[$itemKey] = $item; |
|---|
| 158 |
|
|---|
| 159 |
// allow a module to replace our main index page |
|---|
| 160 |
if (($item['display'] == 'index') && ($display == '')) { |
|---|
| 161 |
$display = 'index'; |
|---|
| 162 |
} |
|---|
| 163 |
|
|---|
| 164 |
// check current item |
|---|
| 165 |
if ($display == $item['display']) { |
|---|
| 166 |
// found current menuitem, make a reference to it |
|---|
| 167 |
$cur_menuitem =& $fpbx_menu[$itemKey]; |
|---|
| 168 |
} |
|---|
| 169 |
} |
|---|
| 170 |
} |
|---|
| 171 |
} |
|---|
| 172 |
} |
|---|
| 173 |
sort($types); |
|---|
| 174 |
|
|---|
| 175 |
// new gui hooks |
|---|
| 176 |
if(is_array($active_modules)){ |
|---|
| 177 |
foreach($active_modules as $key => $module) { |
|---|
| 178 |
if (isset($module['items']) && is_array($module['items'])) { |
|---|
| 179 |
foreach($module['items'] as $itemKey => $itemName) { |
|---|
| 180 |
//list of potential _configpageinit functions |
|---|
| 181 |
$initfuncname = $key . '_' . $itemKey . '_configpageinit'; |
|---|
| 182 |
if ( function_exists($initfuncname) ) { |
|---|
| 183 |
$configpageinits[] = $initfuncname; |
|---|
| 184 |
} |
|---|
| 185 |
} |
|---|
| 186 |
} |
|---|
| 187 |
//check for module level (rather than item as above) _configpageinit function |
|---|
| 188 |
$initfuncname = $key . '_configpageinit'; |
|---|
| 189 |
if ( function_exists($initfuncname) ) { |
|---|
| 190 |
$configpageinits[] = $initfuncname; |
|---|
| 191 |
} |
|---|
| 192 |
} |
|---|
| 193 |
} |
|---|
| 194 |
|
|---|
| 195 |
// extensions vs device/users ... this is a bad design, but hey, it works |
|---|
| 196 |
if (isset($amp_conf["AMPEXTENSIONS"]) && ($amp_conf["AMPEXTENSIONS"] == "deviceanduser")) { |
|---|
| 197 |
unset($fpbx_menu["extensions"]); |
|---|
| 198 |
} else { |
|---|
| 199 |
unset($fpbx_menu["devices"]); |
|---|
| 200 |
unset($fpbx_menu["users"]); |
|---|
| 201 |
} |
|---|
| 202 |
|
|---|
| 203 |
// check access |
|---|
| 204 |
if (!is_array($cur_menuitem) && $display != "") { |
|---|
| 205 |
showview("noaccess"); |
|---|
| 206 |
exit; |
|---|
| 207 |
} |
|---|
| 208 |
|
|---|
| 209 |
// load the component from the loaded modules |
|---|
| 210 |
if ( $display != '' && isset($configpageinits) && is_array($configpageinits) ) { |
|---|
| 211 |
|
|---|
| 212 |
$currentcomponent = new component($display,$type); |
|---|
| 213 |
|
|---|
| 214 |
// call every modules _configpageinit function which should just |
|---|
| 215 |
// register the gui and process functions for each module, if relevent |
|---|
| 216 |
// for this $display |
|---|
| 217 |
foreach ($configpageinits as $func) { |
|---|
| 218 |
$func($display); |
|---|
| 219 |
} |
|---|
| 220 |
|
|---|
| 221 |
// now run each 'process' function and 'gui' function |
|---|
| 222 |
$currentcomponent->processconfigpage(); |
|---|
| 223 |
$currentcomponent->buildconfigpage(); |
|---|
| 224 |
} |
|---|
| 225 |
|
|---|
| 226 |
// note: we buffer all the output from the 'page' being loaded.. |
|---|
| 227 |
// This may change in the future, with proper returns, but for now, it's a simple |
|---|
| 228 |
// way to support the old page.item.php include module format. |
|---|
| 229 |
|
|---|
| 230 |
ob_start(); |
|---|
| 231 |
|
|---|
| 232 |
$module_name = ""; |
|---|
| 233 |
$module_page = ""; |
|---|
| 234 |
$module_file = ""; |
|---|
| 235 |
|
|---|
| 236 |
|
|---|
| 237 |
|
|---|
| 238 |
// hack to have our default display handler show the "welcome" view |
|---|
| 239 |
// Note: this probably isn't REALLY needed if there is no menu item for "Welcome".. |
|---|
| 240 |
// but it doesn't really hurt, and it provides a handler in case some page links |
|---|
| 241 |
// to "?display=index" |
|---|
| 242 |
if (($display == 'index') && ($cur_menuitem['module']['rawname'] == 'builtin')) { |
|---|
| 243 |
$display = ''; |
|---|
| 244 |
} |
|---|
| 245 |
|
|---|
| 246 |
|
|---|
| 247 |
|
|---|
| 248 |
// show the appropriate page |
|---|
| 249 |
switch($display) { |
|---|
| 250 |
default: |
|---|
| 251 |
//display the appropriate module page |
|---|
| 252 |
$module_name = $cur_menuitem['module']['rawname']; |
|---|
| 253 |
$module_page = $cur_menuitem['display']; |
|---|
| 254 |
$module_file = 'modules/'.$module_name.'/page.'.$module_page.'.php'; |
|---|
| 255 |
|
|---|
| 256 |
//TODO Determine which item is this module displaying. Currently this is over the place, we should standarize on a "itemid" request var for now, we'll just cover all possibilities :-( |
|---|
| 257 |
$possibilites = array( |
|---|
| 258 |
'userdisplay', |
|---|
| 259 |
'extdisplay', |
|---|
| 260 |
'id', |
|---|
| 261 |
'itemid', |
|---|
| 262 |
'category', |
|---|
| 263 |
'selection' |
|---|
| 264 |
); |
|---|
| 265 |
$itemid = ''; |
|---|
| 266 |
foreach($possibilites as $possibility) { |
|---|
| 267 |
if ( isset($_REQUEST[$possibility]) && $_REQUEST[$possibility] != '' ) |
|---|
| 268 |
$itemid = $_REQUEST[$possibility]; |
|---|
| 269 |
} |
|---|
| 270 |
|
|---|
| 271 |
// create a module_hook object for this module's page |
|---|
| 272 |
$module_hook = new moduleHook; |
|---|
| 273 |
|
|---|
| 274 |
// populate object variables |
|---|
| 275 |
$module_hook->install_hooks($module_page,$module_name,$itemid); |
|---|
| 276 |
|
|---|
| 277 |
// let hooking modules process the $_REQUEST |
|---|
| 278 |
$module_hook->process_hooks($itemid, $module_name, $module_page, $_REQUEST); |
|---|
| 279 |
|
|---|
| 280 |
|
|---|
| 281 |
// include the module page |
|---|
| 282 |
if (isset($cur_menuitem['disabled']) && $cur_menuitem['disabled']) { |
|---|
| 283 |
showview("menuitem_disabled",$cur_menuitem); |
|---|
| 284 |
break; // we break here to avoid the generateconfigpage() below |
|---|
| 285 |
} else if (file_exists($module_file)) { |
|---|
| 286 |
// load language info if available |
|---|
| 287 |
if (extension_loaded('gettext')) { |
|---|
| 288 |
if (is_dir("modules/{$module_name}/i18n")) { |
|---|
| 289 |
bindtextdomain($module_name,"modules/{$module_name}/i18n"); |
|---|
| 290 |
bind_textdomain_codeset($module_name, 'utf8'); |
|---|
| 291 |
textdomain($module_name); |
|---|
| 292 |
} |
|---|
| 293 |
} |
|---|
| 294 |
include($module_file); |
|---|
| 295 |
} else { |
|---|
| 296 |
// TODO: make this a showview() |
|---|
| 297 |
echo "404 Not found"; |
|---|
| 298 |
} |
|---|
| 299 |
|
|---|
| 300 |
// global component |
|---|
| 301 |
if ( isset($currentcomponent) ) { |
|---|
| 302 |
echo $currentcomponent->generateconfigpage(); |
|---|
| 303 |
} |
|---|
| 304 |
|
|---|
| 305 |
break; |
|---|
| 306 |
case 'modules': |
|---|
| 307 |
// set these to avoide undefined variable warnings later |
|---|
| 308 |
// |
|---|
| 309 |
$module_name = 'modules'; |
|---|
| 310 |
$module_page = $cur_menuitem['display']; |
|---|
| 311 |
include 'page.modules.php'; |
|---|
| 312 |
break; |
|---|
| 313 |
case '': |
|---|
| 314 |
if ($astman) { |
|---|
| 315 |
showview('welcome', array('AMP_CONF' => &$amp_conf)); |
|---|
| 316 |
} else { |
|---|
| 317 |
// no manager, no connection to asterisk |
|---|
| 318 |
showview('welcome_nomanager', array('mgruser' => $amp_conf["AMPMGRUSER"])); |
|---|
| 319 |
} |
|---|
| 320 |
break; |
|---|
| 321 |
} |
|---|
| 322 |
|
|---|
| 323 |
if ($quietmode) { |
|---|
| 324 |
// send the output buffer |
|---|
| 325 |
@ob_end_flush(); |
|---|
| 326 |
} else { |
|---|
| 327 |
$admin_template = $template = array(); |
|---|
| 328 |
$admin_template['content'] = ob_get_contents(); |
|---|
| 329 |
@ob_end_clean(); |
|---|
| 330 |
|
|---|
| 331 |
// build the admin interface (with menu) |
|---|
| 332 |
$admin_template['fpbx_types'] = $types; |
|---|
| 333 |
$admin_template['fpbx_type_names'] = $type_names; |
|---|
| 334 |
$admin_template['fpbx_menu'] = $fpbx_menu; |
|---|
| 335 |
$admin_template['fpbx_usecategories'] = $amp_conf['USECATEGORIES']; |
|---|
| 336 |
$admin_template['fpbx_type'] = $type; |
|---|
| 337 |
$admin_template['display'] = $display; |
|---|
| 338 |
|
|---|
| 339 |
// set the language so local module languages take |
|---|
| 340 |
set_language(); |
|---|
| 341 |
|
|---|
| 342 |
// then load it and put it into the main freepbx interface |
|---|
| 343 |
$template['content'] = loadview('freepbx_admin', $admin_template); |
|---|
| 344 |
$template['use_nav_background'] = true; |
|---|
| 345 |
|
|---|
| 346 |
// setup main template |
|---|
| 347 |
$template['module_name'] = $module_name; |
|---|
| 348 |
$template['module_page'] = $module_page; |
|---|
| 349 |
if ($amp_conf['SERVERINTITLE']) { |
|---|
| 350 |
$template['title'] = $_SERVER['SERVER_NAME']." FreePBX administration"; |
|---|
| 351 |
} else { |
|---|
| 352 |
$template['title'] = "FreePBX administration"; |
|---|
| 353 |
} |
|---|
| 354 |
$template['amp_conf'] = &$amp_conf; |
|---|
| 355 |
$template['reload_needed'] = check_reload_needed(); |
|---|
| 356 |
$template['benchmark_starttime'] = $benchmark_starttime; |
|---|
| 357 |
|
|---|
| 358 |
showview('freepbx', $template); |
|---|
| 359 |
} |
|---|
| 360 |
|
|---|
| 361 |
?> |
|---|