<?php
/**
* @package Habari
*
*/
/**
* Class which handles incoming requests and drives the
* MVC strategy for building the model and assigning to
* a view.
*
*/
class Controller extends Singleton
{
public $base_url = ''; // base url for site
private $stub = ''; // stub supplied by rewriter
private $action = ''; // action name (string)
private $handler = null; // the action handler object
/**
* Enables singleton working properly
*
* @see singleton.php
*/
protected static function instance()
{
return self::getInstanceOf( get_class() );
}
/**
* Returns the base URL
*
* @return string base URL
*/
public static function get_base_url()
{
return Controller::instance()->base_url;
}
/**
* Returns the stub in its entirety
*
* @return string the URL incoming stub
*/
public static function get_stub()
{
return Controller::instance()->stub;
}
/**
* Returns the full requested URL
*
* @return string The full requested URL
*/
public static function get_full_url()
{
return self::get_base_url() . self::get_stub();
}
/**
* Returns the action
*
* @return string name of action
*/
public static function get_action()
{
return Controller::instance()->action;
}
/**
* Returns the action handler
*
* @return object handler object
*/
public static function get_handler()
{
return Controller::instance()->handler;
}
/**
* Returns the action handler's variables
*
* @return array variables used by handler
*/
public static function get_handler_vars()
{
return Controller::instance()->handler->handler_vars;
}
/**
* A convenience method for returning a handler variable (handler_var).
* This includes parameters set on the url, and fields submitted by POST.
* The alternative to this, while possible to write, is just too long.
* @param string $name The name of the variable to return.
* @param mixed $default A default value to return if the variable is not set.
* @return mixed The value of that variable in the handler
*/
public static function get_var( $name, $default = null )
{
return isset( Controller::instance()->handler->handler_vars[ $name ] ) ? Controller::instance()->handler->handler_vars[ $name ] : $default;
}
/**
* Parses the requested URL. Automatically
* translates URLs coming in from mod_rewrite and parses
* out any action and parameters in the slug.
*/
public static function parse_request()
{
/* Local scope variable caching */
$controller = Controller::instance();
/* Grab the base URL from the Site class */
$controller->base_url = Site::get_path( 'base', true );
/* Start with the entire URL coming from web server... */
$start_url = '';
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
$start_url = $_SERVER['REQUEST_URI'];
}
else {
$start_url = $_SERVER['SCRIPT_NAME'];
if ( isset( $_SERVER['PATH_INFO'] ) ) {
$start_url .= $_SERVER['PATH_INFO'];
}
// the query string is included in REQUEST_URI, we only need to append it if we're building the URI ourselves
if ( isset( $_SERVER['QUERY_STRING'] ) && ( $_SERVER['QUERY_STRING'] != '' ) ) {
$start_url .= '?' . $_SERVER['QUERY_STRING'];
}
}
/* Strip out the base URL from the requested URL */
/* but only if the base URL isn't / */
if ( '/' != $controller->base_url ) {
$start_url = str_replace( $controller->base_url, '', $start_url );
}
// undo &s
$start_url = str_replace( '&', '&', $start_url );
/* Trim off any leading or trailing slashes */
$start_url = trim( $start_url, '/' );
/* Allow plugins to rewrite the stub before it's passed through the rules */
$start_url = Plugins::filter( 'rewrite_request', $start_url );
$controller->stub = $start_url;
/* Grab the URL filtering rules from DB */
$matched_rule = URL::parse( $controller->stub );
if ( $matched_rule === false ) {
$matched_rule = URL::set_404();
}
/* OK, we have a matching rule. Set the action and create a handler */
$controller->action = $matched_rule->action;
$controller->handler = new $matched_rule->handler();
/* Insert the regexed submatches as the named parameters */
$controller->handler->handler_vars['entire_match'] = $matched_rule->entire_match; // The entire matched string is returned at index 0
foreach ( $matched_rule->named_arg_values as $named_arg_key=>$named_arg_value ) {
$controller->handler->handler_vars[$named_arg_key] = $named_arg_value;
}
/* Also, we musn't forget to add the GET and POST vars into the action's settings array */
$handler_vars = new SuperGlobal( $controller->handler->handler_vars );
$handler_vars = $handler_vars->merge( $_GET, $_POST );
$controller->handler->handler_vars = $handler_vars;
return true;
}
/**
* Handle the requested action by firing off the matched handler action(s)
*/
public static function dispatch_request()
{
/* OK, set the wheels in motion... */
Plugins::act( 'handler_' . Controller::instance()->action, Controller::get_handler_vars() );
if ( method_exists( Controller::instance()->handler, 'act' ) ) {
Controller::instance()->handler->act( Controller::instance()->action );
}
}
}
?>