Source for file FrontController.inc
Documentation is available at FrontController.inc
require_once $config->get('sysRoot'). 'alpha/util/AlphaErrorHandlers.inc';
require_once $config->get('sysRoot'). 'alpha/exceptions/AlphaException.inc';
require_once $config->get('sysRoot'). 'alpha/exceptions/SecurityException.inc';
require_once $config->get('sysRoot'). 'alpha/exceptions/ResourceNotFoundException.inc';
require_once $config->get('sysRoot'). 'alpha/exceptions/IllegalArguementException.inc';
require_once $config->get('sysRoot'). 'alpha/exceptions/LibraryNotInstalledException.inc';
require_once $config->get('sysRoot'). 'alpha/util/filters/AlphaFilterInterface.inc';
require_once $config->get('sysRoot'). 'alpha/model/BadRequestObject.inc';
require_once $config->get('sysRoot'). 'alpha/controller/AlphaController.inc';
* The front controller designed to optionally handle all requests
* @package alpha::controller::front
* @author John Collins <dev@alphaframework.org>
* @version $Id: FrontController.inc 1453 2011-12-04 15:12:54Z johnc $
* @license http://www.opensource.org/licenses/bsd-license.php The BSD License
* @copyright Copyright (c) 2011, John Collins (founder of Alpha Framework).
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
* * Neither the name of the Alpha Framework nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The name of the page controller we want to invoke
* Boolean to flag if the GET query string is encrypted or not
private $encryptedQuery = false;
* An array of controller alias
private $controllerAlias = array();
* An array of HTTP filters applied to each request to the front controller. Each
* member must implement AlphaFilterInterface!
private $filters = array();
* The name of the current alias
private static $logger = null;
* @throws ResourceNotFoundException
self::$logger = new Logger('FrontController');
self::$logger->debug('>>__construct()');
self::$logger->debug('Requested URL is ['. $_SERVER['REQUEST_URI']. ']');
// direct calls to the front controller
if (isset ($_GET['act'])) {
self::$logger->debug('Processing direct request to the front controller');
$this->pageController = $_GET['act'];
// calls to the front controller via mod_rewrite
}elseif($config->get('sysUseModRewrite') && !isset ($_GET['tk'])) {
self::$logger->debug('Processing a mod_rewrite request');
$this->handleModRewriteRequests();
// direct calls to the front controller with an encrypted query string
if (!isset ($_GET['tk'])) {
self::$logger->warn('No controller action set for the front controller, URL is ['. $_SERVER['REQUEST_URI']. ']');
throw new ResourceNotFoundException('The file that you have requested cannot be found!');
self::$logger->debug('Processing a direct request to the front controller with an encrypted token param');
$this->populateGetVars();
$this->pageController = $_GET['act'];
self::$logger->error('Error while attempting to decode a secure token in the FrontController: '. $e->getMessage());
throw new ResourceNotFoundException('The file that you have requested cannot be found!');
self::$logger->debug('<<__construct');
* Sets the encryption flag
* @param boolean $encryptedQuery
$this->encryptedQuery = $encryptedQuery;
* Method to populate the global _GET and _REQUEST arrays with the decoded
private function populateGetVars() {
$pairs = explode('&', $this->queryString);
foreach($pairs as $pair) {
if(count($keyValue) == 2) {
$_GET[$keyValue[0]] = $keyValue[1];
$_REQUEST[$keyValue[0]] = $keyValue[1];
* Static method for generating an absolute, secure URL for a page controller
if($config->get('sysUseModRewrite'))
* Static method for encoding a query string
* @param string $queryString
$td = mcrypt_module_open ('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
mcrypt_generic_init ($td, $config->get('sysQSKey'), $iv);
$encryptedData = mcrypt_generic ($td, $queryString);
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
// remove any characters that are likely to cause trouble on a URL
$return = strtr($return, '+/', '-_');
* Method to decode the current query string
* @throws SecurityException
private function decodeQuery() {
if (!isset ($_GET['tk'])) {
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
// replace any troublesome characters from the URL with the original values
$token = strtr($_GET['tk'], '-_', '+/');
$this->queryString = trim(mcrypt_decrypt('tripledes', $config->get('sysQSKey'), $token, 'ecb', $iv));
* Static method to return the decoded GET paramters from an encrytpted tk value
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
// replace any troublesome characters from the URL with the original values
$token = strtr($tk, '-_', '+/');
$params = trim(mcrypt_decrypt('tripledes', $config->get('sysQSKey'), $token, 'ecb', $iv));
* Static method to return the decoded GET paramters from an encrytpted tk value as an array of key/value pairs.
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
// replace any troublesome characters from the URL with the original values
$token = strtr($tk, '-_', '+/');
$params = trim(mcrypt_decrypt('tripledes', $config->get('sysQSKey'), $token, 'ecb', $iv));
foreach($pairs as $pair) {
$parameters[$split[0]] = $split[1];
* Method to load the page controller
* @param boolean $allowRedirects Defaults to true, set to false if you want to prevent the front controller from redirecting the request
* @throws ResourceNotFoundException
if($allowRedirects && $config->get('sysCheckInstalled') && $this->pageController != 'Install' && $this->pageController != 'Login') {
self::$logger->info('Invoking the Install controller as the system DB is not installed...');
$url = FrontController::generateSecureURL('act=Install');
self::$logger->info('Redirecting to ['. $url. ']');
header('Location: '. $url);
// first process any attached filters
foreach ($this->filters as $filter)
// if there is an alias configured for the above page controller, redirect there
if($config->get('sysForceFC') && $this->hasAlias($this->pageController)) {
// make sure that it is not already an alias-based request to prevent re-direct loop
if(empty($this->currentAlias)) {
// set the correct HTTP header for the response
header('HTTP/1.1 301 Moved Permanently');
// see if there are any other GET params appart from the controller name
$param = $_GET[$keys[1]];
// if its a title then replace spaces with underscores in the URL
$pageController = new $this->pageController();
$pageController->doPOST($_REQUEST);
$pageController->doGET($_GET);
self::$logger->warn($e->getMessage(). "\nStacktrace:\n". $e->getTraceAsString(). "\nRequest params:\n". var_export($_REQUEST, true). "\nRequested resource:\n". $_SERVER['REQUEST_URI']);
self::$logger->warn($e->getMessage(). "\nStacktrace:\n". $e->getTraceAsString(). "\nRequest params:\n". var_export($_REQUEST, true). "\nRequested resource:\n". $_SERVER['REQUEST_URI']);
self::$logger->warn($e->getMessage(). "\nStacktrace:\n". $e->getTraceAsString(). "\nRequest params:\n". var_export($_REQUEST, true). "\nRequested resource:\n". $_SERVER['REQUEST_URI']);
self::$logger->warn($e->getMessage(). "\nStacktrace:\n". $e->getTraceAsString(). "\nRequest params:\n". var_export($_REQUEST, true). "\nRequested resource:\n". $_SERVER['REQUEST_URI']);
if($config->get('sysEnableClientTempBlacklistFiler')) {
if(isset ($_SERVER['HTTP_USER_AGENT']) && isset ($_SERVER['REMOTE_ADDR']) && isset ($_SERVER['REQUEST_URI'])) {
$request->set('client', $_SERVER['HTTP_USER_AGENT']);
$request->set('IP', $_SERVER['REMOTE_ADDR']);
$request->set('requestedResource', $_SERVER['REQUEST_URI']);
self::$logger->warn($e->getMessage(). "\nStacktrace:\n". $e->getTraceAsString(). "\nRequest params:\n". var_export($_REQUEST, true). "\nRequested resource:\n". $_SERVER['REQUEST_URI']);
if($config->get('sysEnableClientTempBlacklistFiler')) {
if(isset ($_SERVER['HTTP_USER_AGENT']) && isset ($_SERVER['REMOTE_ADDR']) && isset ($_SERVER['REQUEST_URI'])) {
$request->set('client', $_SERVER['HTTP_USER_AGENT']);
$request->set('IP', $_SERVER['REMOTE_ADDR']);
$request->set('requestedResource', $_SERVER['REQUEST_URI']);
* Used to register a controller alias to enable shorter URLs with mod_rewrite support enabled. Note that
* only controllers with a single parameter are supported.
* @param string $controller The name of the page controller class
* @param string $alias The URL alias for the page controller
* @param string $param The name of the GET parameter on the alias URL request
public function registerAlias($controller, $alias, $param= null) {
$this->controllerAlias[$alias] = $controller;
$this->controllerAlias[$alias. '_param'] = $param;
// set up the page controller
$this->handleModRewriteRequests();
* Check to see if an alias exists for the given alias name
* Check to see if an alias exists for the given controller name
* @param string $controller
if(in_array($controller, $this->controllerAlias))
* Gets the full name of the controller for the given alias
return $this->controllerAlias[$alias];
* Gets the name of the alias for the given controller
* @param string $controller
if(in_array($controller, $this->controllerAlias)) {
$keys = array_keys($this->controllerAlias, $controller);
// there should only ever be one key per controller
* Gets the parameter name expected in requests to the controller with the given alias
return $this->controllerAlias[$alias. '_param'];
* Gets the parameter name expected in requests to the controller with the given controller name
* @param string $controller
return $this->controllerAlias[$alias. '_param'];
* Handles all of the rules for mod_rewrite style URL parsing
private function handleModRewriteRequests() {
self::$logger->debug('>>handleModRewriteRequests');
// strip off the system URL from the request URL
$request = str_replace($config->get('sysURL'), '', 'http://'. $_SERVER['HTTP_HOST']. $_SERVER['REQUEST_URI']);
self::$logger->debug('$request is ['. $request. ']');
$params = explode('/', $request);
self::$logger->debug('$params are ['. var_export($params, true). ']');
// first param will always be the controller alias
if(empty($this->currentAlias) && !empty($params[0]))
$this->currentAlias = $params[0];
// check to see if we can load the page controller without an alias
self::$logger->debug('Page controller name set on the request URL is ['. $params[0]. ']');
$this->pageController = $params[0];
}catch (IllegalArguementException $iae) {
// handle request with alias
self::$logger->debug('The supplied controller alias is ['. $this->currentAlias. ']');
// check to see if the controller is an alias for something
self::$logger->debug('Page controller name obtained from the URL alias is ['. $this->pageController. ']');
$_REQUEST[$this->getAliasParam($this->currentAlias)] = $params[1];
self::$logger->debug('$params are ['. var_export($params, true). ']');
self::$logger->debug('currentAlias is ['. $this->currentAlias. ']');
// now populate the _GET vars
if($this->currentAlias == 'tk') {
self::$logger->debug('Setting the GET vars for a mod_rewrite request with a tk param');
$_GET['tk'] = $params[1];
$this->populateGetVars();
$this->pageController = $_GET['act'];
for($i = 1; $i < $count; $i+= 2) {
if(isset ($params[$i+ 1])) {
$_REQUEST[$params[$i]] = $params[$i+ 1];
$_GET[$params[$i]] = $params[$i+ 1];
self::$logger->debug('$_GET is ['. var_export($_GET, true). ']');
self::$logger->debug('<<handleModRewriteRequests');
* Getter for the page controller
return $this->pageController;
* Add the supplied filter object to the list of filters ran on each request to the front controller
* @param AlphaFilterInterface $filterObject
* @throws IllegalArguementException
if($filterObject instanceof AlphaFilterInterface)
* Returns the array of filters currently attached to this FrontController
|