* * @license http://opensource.org/licenses/gpl-license.php GPL * */ /** * * Application Front Controller * * @category Abovo * * @package Abovo * */ class Abovo_Controller_Front extends Solar_Base { /** * * Config keys * * `classes`: * (array) Class stack * * `default`: * (string) Default app class name * * @var array * */ protected $_Abovo_Controller_Front = array( 'classes' => array('Abovo_App'), 'default' => 'Abovo_App_System_User', ); /** * * The default page name when none is specified. * * @var array * */ protected $_default; /** * * 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']; // set up a class stack for finding apps $this->_stack = Solar::factory('Solar_Class_Stack'); $this->_stack->add($this->_config['classes']); } /** * * Fetches the output of a module/app/action/info specification URI. * * If module/app is not found redirect to default app. * * @param Solar_Uri_Action|string $spec An action URI for the front * controller. E.g., 'module/app/action/pmjones/php+blog?page=2'. * * @return string The output of the page action. * */ public function fetch($spec = null) { // default to current URI $uri = Solar::factory('Solar_Uri_Action'); // override current URI with user spec if (is_string($spec)) { $uri->set($spec); } 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. $class = false; // path needs to have at least 2 elements; module and page if (count($uri->path) >= 2) { // take module and page name (app) $module = array_shift($uri->path); $page = array_shift($uri->path); // is this combination in the class stack if (! $class = $this->_getPageClass($module, $page)) { // ...no, so put them back array_unshift($uri->path, $page); array_unshift($uri->path, $module); } } // did we get a class? if (! $class) { // ...no, use default $file = str_replace('_', DIRECTORY_SEPARATOR, $this->_default) . '.php'; // is it valid? if (Solar::fileExists($file)) { $class = $this->_default; } } // last chance: do we have a class yet? if (! $class) { return $this->_notFound(); } // instantiate the controller class and fetch its content $obj = Solar::factory($class); // @todo this waits for 0.29 //$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 $module Abovo module name * * @param string $page 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($module, $page) { // try to find a matching class $module = str_replace('-',' ', $module); $module = str_replace(' ', '', ucwords(trim($module))); // try to find a matching class $page = str_replace('-',' ', $page); $page = str_replace(' ', '', ucwords(trim($page))); // complete app name $app = $module . '_' . $page; // try to find it $class = $this->_stack->load($app, 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. * * @return string * */ protected function _notFound() { $content = "Not Found" . "

404 Not Found

" . htmlspecialchars("Page not found.") . "

"; $response = Solar::factory('Solar_Http_Response'); $response->setStatusCode(404); $response->content = $content; return $response; } }