/*
* MST_Library v3.1
* @autohr Janpoem
*/
if (!defined('IN_MST_CORE'))
exit('MST_ActionController Can\'t be include single!');
if (!defined(MST_Core::LITE_MODE)) {
MST_Core::import(array(
'MST/ActionController/Request',
'MST/ActionController/Router',
), MST_Core::P_LIB);
}
abstract class MST_ActionController {
const
NO_RENDER= false,
IS_RENDER= 'CONTROLLER_IS_RENDER',
PF_CONTROLLER= 'Controller',
PF_ACTION= 'Action',
FILE= 'file',
VIEW= 'view',
TEXT= 'text',
ACTION= 'action',
WIDGET= 'widget',
CUSTOM_VIEW= 'custom_view';
private static
$_request = null,
$_instance = null,
$_currentView = null;
# @todo 此处的处理应该放到controller被实例化以后, dispatch应该有一个具体含义
final static public function dispatch(array $config = null, $beforeDispatch = null) {
if (self::$_instance == null) {
$request = new MST_ActionController_Request($config['request']);
$router = new MST_ActionController_Router($config['routes']);
$router->routing($request);
$controller = $request['controller'];
$controller = MST_String::camelize2($controller) . static::PF_CONTROLLER;
if ($request['module'] != null) {
$module = $request['module'];
if (strpos($module, '/') !== false)
$module = str_replace('/', '_', $module);
$controller = $module . '_' . $controller;
}
if (is_callable($beforeDispatch)) {
call_user_func_array($beforeDispatch, array($request, & $controller));
}
$GLOBALS['DATA_CACHE']['request'] = & $request;
if (!class_exists($controller))
MST_Core::error(202, $controller);
else
self::$_instance = new $controller();
}
}
public
$layout = false,
$format = 'html',
$params = null,
$autoLoadHelper = false;
protected
$comet = 0,
$viewPath = null,
$defaultRender = self::VIEW;
abstract public function application();
private function __construct()
{
if ($this->comet <= 0)
ob_start();
$this->params = & $GLOBALS['DATA_CACHE']['request'];
$this->viewPath = trim(
$this->params['module'] . '/' . $this->params['controller'], '/');
if ($this->application() !== self::NO_RENDER)
$this->action($this->params['action']);
}
public function __destruct() {
if (!defined(self::IS_RENDER) && self::$_currentView != null) {
switch ($this->defaultRender) {
case self::VIEW :
case self::TEXT :
case self::ACTION :
case self::WIDGET :
#$this->defaultRender = $mode;
break;
default :
$this->defaultRender = self::VIEW;
}
$this->render(
$this->defaultRender,
self::$_currentView
);
}
if (self::$_instance != null)
self::$_instance = null;
if (self::$_request != null)
self::$_request = null;
}
protected function action($action) {
$name = MST_String::camelize($action);
$actName = $name . self::PF_ACTION;
if (!method_exists($this, $actName))
MST_Core::error(203, $actName);
$actRef = new ReflectionMethod($this, $actName);
if ($actRef->isPrivate() || $actRef->isProtected()
&& !constant(MST_ActionController_Router::IS_MAP))
MST_Core::error(203, $actName);
if ($this->$actName() !== self::NO_RENDER && self::$_currentView == null)
self::$_currentView = $action;
return $this;
}
/**
* 输出,url跳转
*/
protected function redirect($url) {
if (defined(self::IS_RENDER)) return self::NO_RENDER;
define(self::IS_RENDER, true);
header('Location:'.linkUri($url));
return $this;
}
// render XML
// render JAVASCRIPT
protected function render(
$mode = null,
$content = null,
array $options = null)
{
if (defined(self::IS_RENDER)) return self::NO_RENDER;
define(self::IS_RENDER, true);
if ($mode == null) $mode = $this->defaultRender;
if ($mode == self::VIEW)
$content = $this->viewPath . '/' . $content;
MST_ActionView::instance()
->assign($this)
->setOptions($options)
->render($mode, $content);
return $this;
}
protected function customRender($file, $path, array $options = null) {
return $this->render(self::CUSTOM_VIEW, array($file, $path), $options);
}
protected function setView($val) {
self::$_currentView = $val;
}
protected function setViewOption($key, $val) {
MST_ActionView::instance()->setOption($key, $val);
return $this;
}
protected function getViewOption($key) {
return MST_ActionView::instance()->getOption($key);
}
protected function setViewOptions(array $options) {
MST_ActionView::instance()->setOptions($options);
return $this;
}
protected function getViewOptions() {
return MST_ActionView::instance()->getOptions();
}
protected function doComet(Closure $fn) {
$times = 0;
set_time_limit(0);
while(true) {
ob_flush();
flush();
$times++;
$result = call_user_func($fn, $times, $this);
if ($result === false) {
break;
}
usleep(10000);
sleep($this->comet);
}
}
}