pics/models/Dispatcher.php

141 lines
4.0 KiB
PHP

<?php
/*****************************************************************************
* Dispatcher.php
* Contains key class Dispatcher.
*
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
*****************************************************************************/
class Dispatcher
{
public static function route()
{
$possibleActions = [
'albums' => 'ViewPhotoAlbums',
'editasset' => 'EditAsset',
'edituser' => 'EditUser',
'login' => 'Login',
'logout' => 'Logout',
'managecomments' => 'ManageComments',
'manageerrors' => 'ManageErrors',
'managetags' => 'ManageTags',
'manageusers' => 'ManageUsers',
'people' => 'ViewPeople',
'suggest' => 'ProvideAutoSuggest',
'timeline' => 'ViewTimeline',
'uploadmedia' => 'UploadMedia',
];
// Work around PHP's FPM not always providing PATH_INFO.
if (empty($_SERVER['PATH_INFO']) && isset($_SERVER['REQUEST_URI']))
{
if (strpos($_SERVER['REQUEST_URI'], '?') === false)
$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
else
$_SERVER['PATH_INFO'] = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?'));
}
// Nothing in particular? Just show the root of the album list.
if (empty($_SERVER['PATH_INFO']) || $_SERVER['PATH_INFO'] == '/')
{
return new ViewPhotoAlbum();
}
// An album, person, or any other tag?
elseif (preg_match('~^/(?<tag>.+?)(?:/page/(?<page>\d+))?/?$~', $_SERVER['PATH_INFO'], $path) && Tag::matchSlug($path['tag']))
{
$_GET = array_merge($_GET, $path);
return new ViewPhotoAlbum();
}
// Look for an action...
elseif (preg_match('~^/(?<action>[a-z]+)(?:/page/(?<page>\d+))?/?~', $_SERVER['PATH_INFO'], $path) && isset($possibleActions[$path['action']]))
{
$_GET = array_merge($_GET, $path);
return new $possibleActions[$path['action']]();
}
else
throw new NotFoundException();
}
public static function dispatch()
{
// Let's try to find our bearings!
try
{
$page = self::route();
$page->showContent();
}
// Something wasn't found?
catch (NotFoundException $e)
{
self::trigger404();
}
// Or are they just sneaking into areas they don't belong?
catch (NotAllowedException $e)
{
if (Registry::get('user')->isGuest())
self::kickGuest();
else
self::trigger403();
}
catch (Exception $e)
{
ErrorHandler::handleError(E_USER_ERROR, 'Unspecified exception: ' . $e->getMessage(), $e->getFile(), $e->getLine());
}
catch (Error $e)
{
ErrorHandler::handleError(E_USER_ERROR, 'Fatal error: ' . $e->getMessage(), $e->getFile(), $e->getLine());
}
}
/**
* Kicks a guest to a login form, redirecting them back to this page upon login.
*/
public static function kickGuest()
{
$form = new LogInForm('Log in');
$form->setErrorMessage('Admin access required. Please log in.');
$form->setRedirectUrl($_SERVER['REQUEST_URI']);
$page = new MainTemplate('Login required');
$page->appendStylesheet(BASEURL . '/css/admin.css');
$page->adopt($form);
$page->html_main();
exit;
}
public static function trigger400()
{
header('HTTP/1.1 400 Bad Request');
$page = new MainTemplate('Bad request');
$page->adopt(new DummyBox('Bad request', '<p>The server does not understand your request.</p>'));
$page->html_main();
exit;
}
public static function trigger403()
{
header('HTTP/1.1 403 Forbidden');
$page = new MainTemplate('Access denied');
$page->adopt(new DummyBox('Forbidden', '<p>You do not have access to the page you requested.</p>'));
$page->html_main();
exit;
}
public static function trigger404()
{
header('HTTP/1.1 404 Not Found');
$page = new MainTemplate('Page not found');
if (Registry::has('user') && Registry::get('user')->isAdmin())
{
$page->appendStylesheet(BASEURL . '/css/admin.css');
$page->adopt(new AdminBar());
}
$page->adopt(new DummyBox('Well, this is a bit embarrassing!', '<p>The page you requested could not be found. Don\'t worry, it\'s probably not your fault. You\'re welcome to browse the website, though!</p>', 'errormsg'));
$page->addClass('errorpage');
$page->html_main();
exit;
}
}