Refactor CMS Controller, can now have ::render() called from the outside
This commit is contained in:
parent
66508a2771
commit
682dbe4b95
|
|
@ -1,5 +1,6 @@
|
|||
* **Build 21x** (2015-03-xx)
|
||||
- Form fields can now use a simpler interface for using the Input preset converter (see Backend > Forms docs).
|
||||
- The event `cms.page.init` no longer passes the URL as the third parameter, `$controller->getRouter()->getUrl()` should be used instead.
|
||||
|
||||
* **Build 217** (2015-03-06)
|
||||
- Improvements made to the user menu in the back-end: clicking your avatar will display a popover with settings links from the `mysettings` context.
|
||||
|
|
|
|||
|
|
@ -130,16 +130,6 @@ class Controller
|
|||
self::$instance = $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing instance of the controller.
|
||||
* If the controller doesn't exists, returns null.
|
||||
* @return mixed Returns the controller object or null;
|
||||
*/
|
||||
public static function getController()
|
||||
{
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and serves the requested page.
|
||||
* If the page cannot be found, returns the page with the URL /404.
|
||||
|
|
@ -210,6 +200,54 @@ class Controller
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the page
|
||||
*/
|
||||
$result = $this->runPage($page, $this->router->getParameters());
|
||||
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('page.display', [$url, $page, $result], true)) ||
|
||||
($event = Event::fire('cms.page.display', [$this, $url, $page, $result], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
if (!is_string($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return Response::make($result, $this->statusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a page in its entirety, including component initialization.
|
||||
* AJAX will be disabled for this process.
|
||||
* @param string $pageFile Specifies the CMS page file name to run.
|
||||
* @param array $params Routing parameters.
|
||||
* @param \Cms\Classes\Theme $theme Theme object
|
||||
*/
|
||||
public static function render($pageFile, $params = [], $theme = null)
|
||||
{
|
||||
if (!$theme && (!$theme = Theme::getActiveTheme())) {
|
||||
throw new CmsException(Lang::get('cms::lang.theme.active.not_found'));
|
||||
}
|
||||
|
||||
$controller = new static($theme);
|
||||
$page = Page::load($theme, $pageFile);
|
||||
return $controller->runPage($page, $params, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a page directly from its object and supplied parameters.
|
||||
* @param \Cms\Classes\Page $page Specifies the CMS page to run.
|
||||
* @param array $params Routing parameters.
|
||||
* @return string
|
||||
*/
|
||||
public function runPage($page, $params = [], $useAjax = true)
|
||||
{
|
||||
$this->page = $page;
|
||||
|
||||
/*
|
||||
|
|
@ -232,7 +270,7 @@ class Controller
|
|||
'page' => $this->page,
|
||||
'layout' => $this->layout,
|
||||
'theme' => $this->theme,
|
||||
'param' => $this->router->getParameters(),
|
||||
'param' => $params,
|
||||
'controller' => $this,
|
||||
'environment' => App::environment(),
|
||||
'session' => App::make('session'),
|
||||
|
|
@ -270,8 +308,8 @@ class Controller
|
|||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('page.init', [$url, $page], true)) ||
|
||||
($event = Event::fire('cms.page.init', [$this, $url, $page], true))
|
||||
($event = $this->fireEvent('page.init', [$page], true)) ||
|
||||
($event = Event::fire('cms.page.init', [$this, $page], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
|
@ -279,7 +317,7 @@ class Controller
|
|||
/*
|
||||
* Execute AJAX event
|
||||
*/
|
||||
if ($ajaxResponse = $this->execAjaxHandlers()) {
|
||||
if ($useAjax && $ajaxResponse = $this->execAjaxHandlers()) {
|
||||
return $ajaxResponse;
|
||||
}
|
||||
|
||||
|
|
@ -287,6 +325,7 @@ class Controller
|
|||
* Execute postback handler
|
||||
*/
|
||||
if (
|
||||
$useAjax &&
|
||||
($handler = post('_handler')) &&
|
||||
($handlerResponse = $this->runAjaxHandler($handler)) &&
|
||||
$handlerResponse !== true
|
||||
|
|
@ -330,23 +369,89 @@ class Controller
|
|||
$result = $template->render($this->vars);
|
||||
CmsException::unmask();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the current page cycle without rendering the page,
|
||||
* used by AJAX handler that may rely on the logic inside the action.
|
||||
*/
|
||||
public function pageCycle()
|
||||
{
|
||||
return $this->execPageCycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the page life cycle.
|
||||
* Creates an object from the PHP sections of the page and
|
||||
* it's layout, then executes their life cycle functions.
|
||||
*/
|
||||
protected function execPageCycle()
|
||||
{
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('page.display', [$url, $page, $result], true)) ||
|
||||
($event = Event::fire('cms.page.display', [$this, $url, $page, $result], true))
|
||||
($event = $this->fireEvent('page.start', [], true)) ||
|
||||
($event = Event::fire('cms.page.start', [$this], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
if (!is_string($result)) {
|
||||
return $result;
|
||||
/*
|
||||
* Run layout functions
|
||||
*/
|
||||
if ($this->layoutObj) {
|
||||
CmsException::mask($this->layout, 300);
|
||||
$response = (($result = $this->layoutObj->onStart()) ||
|
||||
($result = $this->layout->runComponents()) ||
|
||||
($result = $this->layoutObj->onBeforePageStart())) ? $result: null;
|
||||
CmsException::unmask();
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
return Response::make($result, $this->statusCode);
|
||||
/*
|
||||
* Run page functions
|
||||
*/
|
||||
CmsException::mask($this->page, 300);
|
||||
$response = (($result = $this->pageObj->onStart()) ||
|
||||
($result = $this->page->runComponents()) ||
|
||||
($result = $this->pageObj->onEnd())) ? $result : null;
|
||||
CmsException::unmask();
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run remaining layout functions
|
||||
*/
|
||||
if ($this->layoutObj) {
|
||||
CmsException::mask($this->layout, 300);
|
||||
$response = ($result = $this->layoutObj->onEnd()) ? $result : null;
|
||||
CmsException::unmask();
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('page.end', [], true)) ||
|
||||
($event = Event::fire('cms.page.end', [$this], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
|
||||
/**
|
||||
* Initializes the Twig environment and loader.
|
||||
* Registers the \Cms\Twig\Extension object with Twig.
|
||||
|
|
@ -427,39 +532,9 @@ class Controller
|
|||
Event::fire('cms.page.initComponents', [$this, $this->page, $this->layout]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a component to the page object
|
||||
* @param mixed $name Component class name or short name
|
||||
* @param string $alias Alias to give the component
|
||||
* @param array $properties Component properties
|
||||
* @param bool $addToLayout Add to layout, instead of page
|
||||
* @return ComponentBase Component object
|
||||
*/
|
||||
public function addComponent($name, $alias, $properties, $addToLayout = false)
|
||||
{
|
||||
$manager = ComponentManager::instance();
|
||||
|
||||
if ($addToLayout) {
|
||||
if (!$componentObj = $manager->makeComponent($name, $this->layoutObj, $properties)) {
|
||||
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
||||
}
|
||||
|
||||
$componentObj->alias = $alias;
|
||||
$this->vars[$alias] = $this->layout->components[$alias] = $componentObj;
|
||||
}
|
||||
else {
|
||||
if (!$componentObj = $manager->makeComponent($name, $this->pageObj, $properties)) {
|
||||
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
||||
}
|
||||
|
||||
$componentObj->alias = $alias;
|
||||
$this->vars[$alias] = $this->page->components[$alias] = $componentObj;
|
||||
}
|
||||
|
||||
$this->setComponentPropertiesFromParams($componentObj);
|
||||
$componentObj->init();
|
||||
return $componentObj;
|
||||
}
|
||||
//
|
||||
// AJAX
|
||||
//
|
||||
|
||||
/**
|
||||
* Executes the page, layout, component and plugin AJAX handlers.
|
||||
|
|
@ -593,81 +668,9 @@ class Controller
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the current page cycle without rendering the page,
|
||||
* used by AJAX handler that may rely on the logic inside the action.
|
||||
*/
|
||||
public function pageCycle()
|
||||
{
|
||||
return $this->execPageCycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the page life cycle.
|
||||
* Creates an object from the PHP sections of the page and
|
||||
* it's layout, then executes their life cycle functions.
|
||||
*/
|
||||
protected function execPageCycle()
|
||||
{
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('page.start', [], true)) ||
|
||||
($event = Event::fire('cms.page.start', [$this], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run layout functions
|
||||
*/
|
||||
if ($this->layoutObj) {
|
||||
CmsException::mask($this->layout, 300);
|
||||
$response = (($result = $this->layoutObj->onStart()) ||
|
||||
($result = $this->layout->runComponents()) ||
|
||||
($result = $this->layoutObj->onBeforePageStart())) ? $result: null;
|
||||
CmsException::unmask();
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Run page functions
|
||||
*/
|
||||
CmsException::mask($this->page, 300);
|
||||
$response = (($result = $this->pageObj->onStart()) ||
|
||||
($result = $this->page->runComponents()) ||
|
||||
($result = $this->pageObj->onEnd())) ? $result : null;
|
||||
CmsException::unmask();
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run remaining layout functions
|
||||
*/
|
||||
if ($this->layoutObj) {
|
||||
CmsException::mask($this->layout, 300);
|
||||
$response = ($result = $this->layoutObj->onEnd()) ? $result : null;
|
||||
CmsException::unmask();
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('page.end', [], true)) ||
|
||||
($event = Event::fire('cms.page.end', [$this], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
//
|
||||
// Rendering
|
||||
//
|
||||
|
||||
/**
|
||||
* Renders a requested page.
|
||||
|
|
@ -913,6 +916,10 @@ class Controller
|
|||
return $this->renderPartial($name.'::default', [], false);
|
||||
}
|
||||
|
||||
//
|
||||
// Setters
|
||||
//
|
||||
|
||||
/**
|
||||
* Sets the status code for the current web response.
|
||||
* @param int $code Status code
|
||||
|
|
@ -923,6 +930,20 @@ class Controller
|
|||
return $this;
|
||||
}
|
||||
|
||||
//
|
||||
// Getters
|
||||
//
|
||||
|
||||
/**
|
||||
* Returns an existing instance of the controller.
|
||||
* If the controller doesn't exists, returns null.
|
||||
* @return mixed Returns the controller object or null.
|
||||
*/
|
||||
public static function getController()
|
||||
{
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current CMS theme.
|
||||
* @return \Cms\Classes\Theme
|
||||
|
|
@ -988,6 +1009,10 @@ class Controller
|
|||
return $this->layoutObj;
|
||||
}
|
||||
|
||||
//
|
||||
// Page helpers
|
||||
//
|
||||
|
||||
/**
|
||||
* Looks up the URL for a supplied page and returns it relative to the website root.
|
||||
*
|
||||
|
|
@ -1070,6 +1095,44 @@ class Controller
|
|||
return $this->router->getParameter($name, $default);
|
||||
}
|
||||
|
||||
//
|
||||
// Component helpers
|
||||
//
|
||||
|
||||
/**
|
||||
* Adds a component to the page object
|
||||
* @param mixed $name Component class name or short name
|
||||
* @param string $alias Alias to give the component
|
||||
* @param array $properties Component properties
|
||||
* @param bool $addToLayout Add to layout, instead of page
|
||||
* @return ComponentBase Component object
|
||||
*/
|
||||
public function addComponent($name, $alias, $properties, $addToLayout = false)
|
||||
{
|
||||
$manager = ComponentManager::instance();
|
||||
|
||||
if ($addToLayout) {
|
||||
if (!$componentObj = $manager->makeComponent($name, $this->layoutObj, $properties)) {
|
||||
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
||||
}
|
||||
|
||||
$componentObj->alias = $alias;
|
||||
$this->vars[$alias] = $this->layout->components[$alias] = $componentObj;
|
||||
}
|
||||
else {
|
||||
if (!$componentObj = $manager->makeComponent($name, $this->pageObj, $properties)) {
|
||||
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
||||
}
|
||||
|
||||
$componentObj->alias = $alias;
|
||||
$this->vars[$alias] = $this->page->components[$alias] = $componentObj;
|
||||
}
|
||||
|
||||
$this->setComponentPropertiesFromParams($componentObj);
|
||||
$componentObj->init();
|
||||
return $componentObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the layout and page components by an alias
|
||||
* @return ComponentBase The component object, if found
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ class Router
|
|||
*/
|
||||
protected $theme;
|
||||
|
||||
/**
|
||||
* @var string The last URL to be looked up using findByUrl().
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @var array A list of parameters names and values extracted from the URL pattern and URL string.
|
||||
*/
|
||||
|
|
@ -49,12 +54,12 @@ class Router
|
|||
/**
|
||||
* @var array Contains the URL map - the list of page file names and corresponding URL patterns.
|
||||
*/
|
||||
private static $urlMap = [];
|
||||
protected static $urlMap = [];
|
||||
|
||||
/**
|
||||
* October\Rain\Router\Router Router object with routes preloaded.
|
||||
*/
|
||||
private static $routerObj;
|
||||
protected static $routerObj;
|
||||
|
||||
/**
|
||||
* Creates the router instance.
|
||||
|
|
@ -72,6 +77,7 @@ class Router
|
|||
*/
|
||||
public function findByUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$url = RouterHelper::normalizeUrl($url);
|
||||
|
||||
$apiResult = Event::fire('cms.router.beforeRoute', [$url], true);
|
||||
|
|
@ -268,6 +274,15 @@ class Router
|
|||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last URL to be looked up.
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a routing parameter.
|
||||
* @return array
|
||||
|
|
|
|||
Loading…
Reference in New Issue