All pastes #675162 Raw Edit

Someone

public php v1 · immutable
#675162 ·published 2007-08-29 21:20 UTC
rendered paste body
<?php/** *  * Front-controller class to find and invoke a page-controller. *  * @category Solar *  * @package Solar_Controller *  * @author Paul M. Jones <pmjones@solarphp.com> *  * @license http://opensource.org/licenses/bsd-license.php BSD *  * @version $Id: Front.php 2601 2007-07-21 18:14:49Z pmjones $ *  *//** *  * Front-controller class to find and invoke a page-controller. *  * An example bootstrap "index.php" for your web root using the front * controller ... *  * {{code: php *     require 'Solar.php'; *     Solar::start(); *     $front = Solar::factory('Solar_Controller_Front'); *     $front->display(); *     Solar::stop(); * }} *  * @category Solar *  * @package Solar_Controller *  */class Solar_Controller_Front extends Solar_Base {    /**     *      * User-defined configuration array.     *      * Keys are ...     *      * `classes`     * : (array) Base class names for page controllers.     *      * `default`     * : (string) The default page-name.     *      * `routing`     * : (array) Key-value pairs explicitly mapping a page-name to a     *   controller class.     *      * @var array     *      */    protected $_Solar_Controller_Front = array(        'classes' => array('Solar_App'),        'default' => 'hello',        'not_found' => 'hello',        'routing' => array(            'bookmarks'  => 'Solar_App_Bookmarks',            'hello'      => 'Solar_App_Hello',            'hello-ajax' => 'Solar_App_HelloAjax',            'hello-mini' => 'Solar_App_HelloMini',        ),    );        /**     *      * The default page name when none is specified.     *      * @var array     *      */    protected $_default;        /**     *      * The page name when invalid page is specified.     *      * @var array     *      */    protected $_not_found;        /**     *      * Explicit page-name to class-name mappings.     *      * @var array     *      */    protected $_routing;        /**     *      * Stack of page-controller class prefixes.     *      * @var Solar_Class_Stack     *      */    protected $_stack;        /**     *      * Constructor.     *      * @param array $config User-provided configuration values.     *      */    public function __construct($config)    {        // do the "real" construction        parent::__construct($config);                 // set convenience vars from config        $this->_default = $this->_config['default'];        $this->_not_found = $this->_config['not_found'];        $this->_routing = $this->_config['routing'];                // set up a class stack for finding apps        $this->_stack = Solar::factory('Solar_Class_Stack');        $this->_stack->add($this->_config['classes']);                // extended setup        $this->_setup();    }        /**     *      * Sets up the environment for all pages.     *      * Registers a Solar_Request object as 'request'.     *      * @return void     *      */    protected function _setup()    {        if (! Solar::isRegistered('request')) {            Solar::register('request', 'Solar_Request');        }    }        /**     *      * Fetches the output of a page/action/info specification URI.     *      * @param Solar_Uri_Action|string $spec An action URI for the front     * controller.  E.g., 'bookmarks/user/pmjones/php+blog?page=2'. When     * empty (the default) uses the current URI.     *      * @return string The output of the page action.     *      */    public function fetch($spec = null)    {        if ($spec instanceof Solar_Uri_Action) {            // a URI was passed directly            $uri = $spec;        } else {            // user spec is a URI string; if empty, is the current URI            $uri = Solar::factory('Solar_Uri_Action', array(                'uri' => (string) $spec,            ));        }                // take the page name off the top of the path and try to get a        // controller class from it.        $page = array_shift($uri->path);                if (empty($page)) {            array_unshift($uri->path, $page);            $class = $this->_getPageClass($this->_default);        } else {            $class = $this->_getPageClass($page);        }		        // did we get a class from it?        /*        if (! $class) {            // put the original segment back on top.            array_unshift($uri->path, $page);            // try to get a controller class from the default page name            $class = $this->_getPageClass($this->_default);        }        */                // last chance: do we have a class yet?        if (! $class) {        	array_unshift($uri->path, $page);            return $this->_notFound($page, $uri);        }                // instantiate the controller class and fetch its content        $obj = Solar::factory($class);        $obj->setFrontController($this);        return $obj->fetch($uri);    }        /**     *      * Displays the output of an page/action/info specification URI.     *      * @param string $spec A page/action/info spec for the front     * controller. E.g., 'bookmarks/user/pmjones/php+blog?page=2'.     *      * @return string The output of the page action.     *      */    public function display($spec = null)    {        echo $this->fetch($spec);    }        /**     *      * Finds the page-controller class name from a page name.     *      * @param string $page The page name.     *      * @return string The related page-controller class picked from     * the routing, or from the list of available classes.  If not found,     * returns false.     *      */    protected function _getPageClass($page)    {        if (! empty($this->_routing[$page])) {            // found an explicit route            $class = $this->_routing[$page];        } else {            // no explicit route, try to find a matching class            $page = str_replace('-',' ', $page);            $page = str_replace(' ', '', ucwords(trim($page)));            $class = $this->_stack->load($page, false);        }        return $class;    }        /**     *      * Executes when fetch() cannot find a related page-controller class.     *      * Generates an "HTTP 1.1/404 Not Found" status header and returns a     * short HTML page describing the error.     *      * @param string $page The name of the page not found.     *      * @return string     *      */    protected function _notFound($page, $uri)    {        if ($class = $this->_getPageClass($this->_not_found)) {            $obj = Solar::factory($class);            $obj->setFrontController($this);            $response = $obj->fetch($uri);        } else {            $content = "<html><head><title>Not Found</title>"                     . "<body><h1>404 Not Found</h1><p>"                     . htmlspecialchars("Page controller for '$page' not found.")                     . "</p></body></html>";            $response = Solar::factory('Solar_Http_Response');            $response->content = $content;        }                $response->setStatusCode(404);                return $response;    }}