/**
* Do dispatch
* @param string $module
* @param string $controller
* @param array $params
* @throws ApplicationException
*
* @return View|callable
*/
protected function doDispatch($module, $controller, $params = array())
{
Logger::info("---:dispatch:do: " . $module . '/' . $controller);
$controllerFile = $this->getControllerFile($module, $controller);
$reflection = $this->reflection($controllerFile);
if ($reflection->getCache()) {
$cacheKey = 'view:' . $module . ':' . $controller . ':' . http_build_query($params);
if ($cachedView = Cache::get($cacheKey)) {
return $cachedView;
}
}
// process params
$params = $reflection->params($params);
// $view for use in closure
$view = new View();
// setup additional helper path
$view->addHelperPath($this->getPath() . '/layouts/helpers');
// setup additional partial path
$view->addPartialPath($this->getPath() . '/layouts/partial');
// setup default path
$view->setPath($this->getPath() . '/modules/' . $module . '/views');
// setup default template
$view->setTemplate($controller . '.phtml');
$bootstrapPath = $this->getPath() . '/modules/' . $module . '/bootstrap.php';
/**
* optional $bootstrap for use in closure
* @var \closure $bootstrap
*/
if (file_exists($bootstrapPath)) {
$bootstrap = (require $bootstrapPath);
} else {
$bootstrap = null;
}
unset($bootstrapPath);
/**
* @var \closure $controllerClosure
*/
$controllerClosure = (include $controllerFile);
if (!is_callable($controllerClosure)) {
throw new ApplicationException("Controller is not callable '{$module}/{$controller}'");
}
$result = $controllerClosure(...$params);
// switch statement for $result
switch (true) {
case $result === false:
// return false is equal to disable view and layout
$this->useLayout(false);
return function () {
// just empty closure
};
case is_callable($result):
case is_object($result):
// return closure is replace logic of controller
// or return any class
return $result;
case is_string($result):
// return string is equal to change view template
$view->setTemplate($result);
break;
case is_array($result):
// return array is equal to setup view
$view->setFromArray($result);
break;
}
if (isset($cacheKey)) {
Cache::set($cacheKey, $view, $reflection->getCache());
Cache::addTag($cacheKey, $module);
Cache::addTag($cacheKey, 'view');
Cache::addTag($cacheKey, 'view:' . $module);
Cache::addTag($cacheKey, 'view:' . $module . ':' . $controller);
}
return $view;
}