diff options
author | Wave <wave72@users.noreply.github.com> | 2016-07-22 10:55:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-22 10:55:02 +0200 |
commit | 744ad84714fe0f7a3d90250a4ff02dc4327b9061 (patch) | |
tree | 595fb74ec9ea0bc7130d18bd7993d719a222d343 /Zotlabs/Web | |
parent | c38c79d71c8ef70ef649f83e322f1984b75ee2dd (diff) | |
parent | 7d897a3f03bd57ed556433eb84a41963ba44e02e (diff) | |
download | volse-hubzilla-744ad84714fe0f7a3d90250a4ff02dc4327b9061.tar.gz volse-hubzilla-744ad84714fe0f7a3d90250a4ff02dc4327b9061.tar.bz2 volse-hubzilla-744ad84714fe0f7a3d90250a4ff02dc4327b9061.zip |
Merge pull request #6 from redmatrix/dev
Dev
Diffstat (limited to 'Zotlabs/Web')
-rw-r--r-- | Zotlabs/Web/CheckJS.php | 16 | ||||
-rw-r--r-- | Zotlabs/Web/Controller.php | 13 | ||||
-rw-r--r-- | Zotlabs/Web/Router.php | 125 | ||||
-rw-r--r-- | Zotlabs/Web/Session.php | 53 | ||||
-rw-r--r-- | Zotlabs/Web/SessionHandler.php | 9 | ||||
-rw-r--r-- | Zotlabs/Web/WebServer.php | 137 |
6 files changed, 294 insertions, 59 deletions
diff --git a/Zotlabs/Web/CheckJS.php b/Zotlabs/Web/CheckJS.php index 3ad5fc1ed..109790fa5 100644 --- a/Zotlabs/Web/CheckJS.php +++ b/Zotlabs/Web/CheckJS.php @@ -10,14 +10,28 @@ class CheckJS { function __construct($test = 0) { if(intval($_REQUEST['jsdisabled'])) $this->jsdisabled = 1; + else + $this->jsdisabled = 0; if(intval($_COOKIE['jsdisabled'])) $this->jsdisabled = 1; + else + $this->jsdisabled = 0; if(! $this->jsdisabled) { $page = urlencode(\App::$query_string); if($test) { - \App::$page['htmlhead'] .= "\r\n" . '<meta http-equiv="refresh" content="0; url=' . z_root() . '/nojs?f=&redir=' . $page . '">' . "\r\n"; + self::$jsdisabled = 1; + if(array_key_exists('jsdisabled',$_COOKIE)) + self::$jsdisabled = $_COOKIE['jsdisabled']; + + if(! array_key_exists('jsdisabled',$_COOKIE)) { + \App::$page['htmlhead'] .= "\r\n" . '<script>document.cookie="jsdisabled=0; path=/"; var jsMatch = /\&jsdisabled=0/; if (!jsMatch.exec(location.href)) { location.href = "' . z_root() . '/nojs/0?f=&redir=' . $page . '" ; }</script>' . "\r\n"; + /* emulate JS cookie if cookies are not accepted */ + if (array_key_exists('jsdisabled',$_GET)) { + $_COOKIE['jsdisabled'] = $_GET['jsdisabled']; + } + } } else { \App::$page['htmlhead'] .= "\r\n" . '<noscript><meta http-equiv="refresh" content="0; url=' . z_root() . '/nojs?f=&redir=' . $page . '"></noscript>' . "\r\n"; diff --git a/Zotlabs/Web/Controller.php b/Zotlabs/Web/Controller.php new file mode 100644 index 000000000..2d0f58891 --- /dev/null +++ b/Zotlabs/Web/Controller.php @@ -0,0 +1,13 @@ +<?php + +namespace Zotlabs\Web; + + +class Controller { + + function init() {} + function post() {} + function get() {} + +} + diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index 29f2b5206..f9290ac30 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -5,20 +5,32 @@ namespace Zotlabs\Web; class Router { + private $modname = ''; + private $controller = null; + function __construct(&$a) { /** * * We have already parsed the server path into App::$argc and App::$argv * - * App::$argv[0] is our module name. We will load the file mod/{App::$argv[0]}.php - * and use it for handling our URL request. + * App::$argv[0] is our module name. Let's call it 'foo'. We will load the + * Zotlabs/Module/Foo.php (object) or file mod/foo.php (procedural) + * and use it for handling our URL request to 'https://ourgreatwebsite.something/foo' . * The module file contains a few functions that we call in various circumstances * and in the following order: * - * "module"_init - * "module"_post (only called if there are $_POST variables) - * "module"_content - the string return of this function contains our page body + * Object: + * class Foo extends Zotlabs\Web\Controller { + * function init() { init function } + * function post() { post function } + * function get() { normal page function } + * } + * + * Procedual interface: + * foo_init() + * foo_post() (only called if there are $_POST variables) + * foo_content() - the string return of this function contains our page body * * Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do * so within the module init and/or post functions and then invoke killme() to terminate @@ -26,6 +38,7 @@ class Router { */ $module = \App::$module; + $modname = "Zotlabs\\Module\\" . ucfirst($module); if(strlen($module)) { @@ -38,8 +51,13 @@ class Router { if(is_array(\App::$plugins) && in_array($module,\App::$plugins) && file_exists("addon/{$module}/{$module}.php")) { include_once("addon/{$module}/{$module}.php"); - if(function_exists($module . '_module')) + if(class_exists($modname)) { + $this->controller = new $modname; \App::$module_loaded = true; + } + elseif(function_exists($module . '_module')) { + \App::$module_loaded = true; + } } if((strpos($module,'admin') === 0) && (! is_site_admin())) { @@ -50,33 +68,54 @@ class Router { /** * If the site has a custom module to over-ride the standard module, use it. - * Otherwise, look for the standard program module in the 'mod' directory + * Otherwise, look for the standard program module */ if(! (\App::$module_loaded)) { - if(file_exists("mod/site/{$module}.php")) { - include_once("mod/site/{$module}.php"); - \App::$module_loaded = true; + try { + $filename = 'Zotlabs/SiteModule/'. ucfirst($module). '.php'; + if(file_exists($filename)) { + // This won't be picked up by the autoloader, so load it explicitly + require_once($filename); + $this->controller = new $modname; + \App::$module_loaded = true; + } + else { + $filename = 'Zotlabs/Module/'. ucfirst($module). '.php'; + if(file_exists($filename)) { + $this->controller = new $modname; + \App::$module_loaded = true; + } + } + if(! \App::$module_loaded) + throw new \Exception('Module not found'); } - elseif(file_exists("mod/{$module}.php")) { - include_once("mod/{$module}.php"); - \App::$module_loaded = true; + catch(\Exception $e) { + if(file_exists("mod/site/{$module}.php")) { + include_once("mod/site/{$module}.php"); + \App::$module_loaded = true; + } + elseif(file_exists("mod/{$module}.php")) { + include_once("mod/{$module}.php"); + \App::$module_loaded = true; + } } - else logger("mod/{$module}.php not found."); } - - + /** - * This provides a place for plugins to register module handlers which don't otherwise exist on the system. + * This provides a place for plugins to register module handlers which don't otherwise exist + * on the system, or to completely over-ride an existing module. * If the plugin sets 'installed' to true we won't throw a 404 error for the specified module even if * there is no specific module file or matching plugin name. * The plugin should catch at least one of the module hooks for this URL. */ - $x = array('module' => $module, 'installed' => false); + $x = array('module' => $module, 'installed' => \App::$module_loaded, 'controller' => $this->controller); call_hooks('module_loaded', $x); - if($x['installed']) + if($x['installed']) { \App::$module_loaded = true; + $this->controller = $x['controller']; + } /** * The URL provided does not resolve to a valid module. @@ -96,6 +135,8 @@ class Router { killme(); } + logger("Module {$module} not found.", LOGGER_DEBUG, LOG_WARNING); + if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && \App::$config['system']['dreamhost_error_hack']) { logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); goaway(z_root() . $_SERVER['REQUEST_URI']); @@ -133,17 +174,20 @@ class Router { * to over-ride them. */ - if(function_exists(\App::$module . '_init')) { - $arr = array('init' => true, 'replace' => false); - call_hooks(\App::$module . '_mod_init', $arr); - if(! $arr['replace']) { + $arr = array('init' => true, 'replace' => false); + call_hooks(\App::$module . '_mod_init', $arr); + if(! $arr['replace']) { + if($this->controller && method_exists($this->controller,'init')) { + $this->controller->init(); + } + elseif(function_exists(\App::$module . '_init')) { $func = \App::$module . '_init'; $func($a); } } /** - * Do all theme initialiasion here before calling any additional module functions. + * Do all theme initialisation here before calling any additional module functions. * The module_init function may have changed the theme. * Additionally any page with a Comanche template may alter the theme. * So we'll check for those now. @@ -162,13 +206,15 @@ class Router { * load current theme info */ - $theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php'; + $current_theme = \Zotlabs\Render\Theme::current(); + + $theme_info_file = 'view/theme/' . $current_theme[0] . '/php/theme.php'; if (file_exists($theme_info_file)){ require_once($theme_info_file); } - if(function_exists(str_replace('-', '_', current_theme()) . '_init')) { - $func = str_replace('-', '_', current_theme()) . '_init'; + if(function_exists(str_replace('-', '_', $current_theme[0]) . '_init')) { + $func = str_replace('-', '_', $current_theme[0]) . '_init'; $func($a); } elseif (x(\App::$theme_info, 'extends') && file_exists('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php')) { @@ -179,21 +225,30 @@ class Router { } } - if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! \App::$error) - && (function_exists(\App::$module . '_post')) - && (! x($_POST, 'auth-params'))) { + if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! \App::$error) && (! x($_POST, 'auth-params'))) { call_hooks(\App::$module . '_mod_post', $_POST); - $func = \App::$module . '_post'; - $func($a); + + if($this->controller && method_exists($this->controller,'post')) { + $this->controller->post(); + } + elseif(function_exists(\App::$module . '_post')) { + $func = \App::$module . '_post'; + $func($a); + } } - if((! \App::$error) && (function_exists(\App::$module . '_content'))) { + if(! \App::$error) { $arr = array('content' => \App::$page['content'], 'replace' => false); call_hooks(\App::$module . '_mod_content', $arr); \App::$page['content'] = $arr['content']; if(! $arr['replace']) { - $func = \App::$module . '_content'; - $arr = array('content' => $func($a)); + if($this->controller && method_exists($this->controller,'get')) { + $arr = array('content' => $this->controller->get()); + } + elseif(function_exists(\App::$module . '_content')) { + $func = \App::$module . '_content'; + $arr = array('content' => $func($a)); + } } call_hooks(\App::$module . '_mod_aftercontent', $arr); \App::$page['content'] .= $arr['content']; diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index f998df396..4f2a3f1f7 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -13,10 +13,10 @@ namespace Zotlabs\Web; class Session { - private static $handler = null; - private static $session_started = false; + private $handler = null; + private $session_started = false; - function init() { + public function init() { $gc_probability = 50; @@ -29,28 +29,38 @@ class Session { */ $handler = new \Zotlabs\Web\SessionHandler(); - self::$handler = $handler; - $x = session_set_save_handler($handler,true); + $this->handler = $handler; + + $x = session_set_save_handler($handler,false); if(! $x) logger('Session save handler initialisation failed.',LOGGER_NORMAL,LOG_ERR); // Force cookies to be secure (https only) if this site is SSL enabled. // Must be done before session_start(). + $arr = session_get_cookie_params(); + + // Note when setting cookies: set the domain to false which creates a single domain + // cookie. If you use a hostname it will create a .domain.com wildcard which will + // have some nasty side effects if you have any other subdomains running hubzilla. + session_set_cookie_params( ((isset($arr['lifetime'])) ? $arr['lifetime'] : 0), ((isset($arr['path'])) ? $arr['path'] : '/'), - ((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()), + (($arr['domain']) ? $arr['domain'] : false), ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false), ((isset($arr['httponly'])) ? $arr['httponly'] : true) ); + + register_shutdown_function('session_write_close'); + } - function start() { + public function start() { session_start(); - self::$session_started = true; + $this->session_started = true; } /** @@ -59,8 +69,8 @@ class Session { * @return void */ - function nuke() { - self::new_cookie(0); // 0 means delete on browser exit + public function nuke() { + $this->new_cookie(0); // 0 means delete on browser exit if($_SESSION && count($_SESSION)) { foreach($_SESSION as $k => $v) { unset($_SESSION[$k]); @@ -68,48 +78,53 @@ class Session { } } - function new_cookie($xtime) { + public function new_cookie($xtime) { $newxtime = (($xtime> 0) ? (time() + $xtime) : 0); $old_sid = session_id(); - if(self::$handler && self::$session_started) { + $arr = session_get_cookie_params(); + + if($this->handler && $this->session_started) { + session_regenerate_id(true); // force SessionHandler record creation with the new session_id // which occurs as a side effect of read() - self::$handler->read(session_id()); + $this->handler->read(session_id()); } else logger('no session handler'); if (x($_COOKIE, 'jsdisabled')) { - setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime); + setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime, '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true)); } - setcookie(session_name(),session_id(),$newxtime); + setcookie(session_name(),session_id(),$newxtime, '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true)); $arr = array('expire' => $xtime); call_hooks('new_cookie', $arr); } - function extend_cookie() { + public function extend_cookie() { + + $arr = session_get_cookie_params(); // if there's a long-term cookie, extend it $xtime = (($_SESSION['remember_me']) ? (60 * 60 * 24 * 365) : 0 ); if($xtime) - setcookie(session_name(),session_id(),(time() + $xtime)); + setcookie(session_name(),session_id(),(time() + $xtime), '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true)); $arr = array('expire' => $xtime); call_hooks('extend_cookie', $arr); } - function return_check() { + public function return_check() { // check a returning visitor against IP changes. // If the change results in being blocked from re-entry with the current cookie @@ -149,7 +164,7 @@ class Session { // check any difference at all logger('Session address changed. Paranoid setting in effect, blocking session. ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']); - self::nuke(); + $this->nuke(); goaway(z_root()); break; } diff --git a/Zotlabs/Web/SessionHandler.php b/Zotlabs/Web/SessionHandler.php index 6980a6408..93b27a7e8 100644 --- a/Zotlabs/Web/SessionHandler.php +++ b/Zotlabs/Web/SessionHandler.php @@ -18,13 +18,14 @@ class SessionHandler implements \SessionHandlerInterface { function read ($id) { if($id) { - $r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id)); + $r = q("SELECT `sess_data` FROM `session` WHERE `sid`= '%s'", dbesc($id)); if($r) { - return $r[0]['data']; + return $r[0]['sess_data']; } else { - q("INSERT INTO `session` (sid, expire) values ('%s', '%s')", + q("INSERT INTO `session` (sess_data, sid, expire) values ('%s', '%s', '%s')", + dbesc(''), dbesc($id), dbesc(time() + 300) ); @@ -59,7 +60,7 @@ class SessionHandler implements \SessionHandlerInterface { } q("UPDATE `session` - SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'", + SET `sess_data` = '%s', `expire` = '%s' WHERE `sid` = '%s'", dbesc($data), dbesc($expire), dbesc($id) diff --git a/Zotlabs/Web/WebServer.php b/Zotlabs/Web/WebServer.php new file mode 100644 index 000000000..d4f3cb9ea --- /dev/null +++ b/Zotlabs/Web/WebServer.php @@ -0,0 +1,137 @@ +<?php /** @file */ + +namespace Zotlabs\Web; + +class WebServer { + + public function run() { + + + /* + * Bootstrap the application, load configuration, load modules, load theme, etc. + */ + + require_once('boot.php'); + + sys_boot(); + + + \App::$language = get_best_language(); + load_translation_table(\App::$language,\App::$install); + + + /** + * + * Important stuff we always need to do. + * + * The order of these may be important so use caution if you think they're all + * intertwingled with no logical order and decide to sort it out. Some of the + * dependencies have changed, but at least at one time in the recent past - the + * order was critical to everything working properly + * + */ + + if(\App::$session) { + \App::$session->start(); + } + else { + session_start(); + register_shutdown_function('session_write_close'); + } + + /** + * Language was set earlier, but we can over-ride it in the session. + * We have to do it here because the session was just now opened. + */ + + if(array_key_exists('system_language',$_POST)) { + if(strlen($_POST['system_language'])) + $_SESSION['language'] = $_POST['system_language']; + else + unset($_SESSION['language']); + } + if((x($_SESSION, 'language')) && ($_SESSION['language'] !== $lang)) { + \App::$language = $_SESSION['language']; + load_translation_table(\App::$language); + } + + if((x($_GET,'zid')) && (! \App::$install)) { + \App::$query_string = strip_zids(\App::$query_string); + if(! local_channel()) { + $_SESSION['my_address'] = $_GET['zid']; + zid_init(); + } + } + + if((x($_GET,'zat')) && (! \App::$install)) { + \App::$query_string = strip_zats(\App::$query_string); + if(! local_channel()) { + zat_init(); + } + } + + if((x($_SESSION, 'authenticated')) || (x($_POST, 'auth-params')) || (\App::$module === 'login')) + require('include/auth.php'); + + if(! x($_SESSION, 'sysmsg')) + $_SESSION['sysmsg'] = array(); + + if(! x($_SESSION, 'sysmsg_info')) + $_SESSION['sysmsg_info'] = array(); + + /* + * check_config() is responsible for running update scripts. These automatically + * update the DB schema whenever we push a new one out. It also checks to see if + * any plugins have been added or removed and reacts accordingly. + */ + + + if(\App::$install) { + /* Allow an exception for the view module so that pcss will be interpreted during installation */ + if(\App::$module != 'view') + \App::$module = 'setup'; + } + else + check_config($a); + + nav_set_selected('nothing'); + + $Router = new Router($a); + + /* initialise content region */ + + if(! x(\App::$page, 'content')) + \App::$page['content'] = ''; + + call_hooks('page_content_top', \App::$page['content']); + + + $Router->Dispatch($a); + + + // If you're just visiting, let javascript take you home + + if(x($_SESSION, 'visitor_home')) { + $homebase = $_SESSION['visitor_home']; + } elseif(local_channel()) { + $homebase = z_root() . '/channel/' . \App::$channel['channel_address']; + } + + if(isset($homebase)) { + \App::$page['content'] .= '<script>var homebase = "' . $homebase . '";</script>'; + } + + // now that we've been through the module content, see if the page reported + // a permission problem and if so, a 403 response would seem to be in order. + + if(stristr(implode("", $_SESSION['sysmsg']), t('Permission denied'))) { + header($_SERVER['SERVER_PROTOCOL'] . ' 403 ' . t('Permission denied.')); + } + + call_hooks('page_end', \App::$page['content']); + + construct_page($a); + + killme(); + } +}
\ No newline at end of file |