Preparing more object-oriented Action handling

Action classes can now be run by calling the static function 'run'.
Eventually actions will be migrated so most functionality gets put
into parent classes, and the children don't have to have as much
duplicate code as they have now.
This commit is contained in:
Mikael Nordfeldth 2013-08-29 23:30:04 +02:00
parent 47eb3cf7e6
commit b18e24723f
2 changed files with 62 additions and 32 deletions

View File

@ -201,26 +201,6 @@ function setupRW()
return;
}
function checkMirror($action_obj, $args)
{
global $config;
if (common_config('db', 'mirror') && $action_obj->isReadOnly($args)) {
if (is_array(common_config('db', 'mirror'))) {
// "load balancing", ha ha
$arr = common_config('db', 'mirror');
$k = array_rand($arr);
$mirror = $arr[$k];
} else {
$mirror = common_config('db', 'mirror');
}
// everyone else uses the mirror
$config['db']['database'] = $mirror;
}
}
function isLoginAction($action)
{
static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp', 'opensearch', 'rsd', 'hostmeta');
@ -315,7 +295,7 @@ function main()
Event::handle('ArgsInitialize', array(&$args));
$action = $args['action'];
$action = basename($args['action']);
if (!$action || !preg_match('/^[a-zA-Z0-9_-]*$/', $action)) {
common_redirect(common_local_url('public'));
@ -356,14 +336,8 @@ function main()
$cac = new ClientErrorAction(_('Unknown action'), 404);
$cac->showPage();
} else {
$action_obj = new $action_class();
checkMirror($action_obj, $args);
try {
if ($action_obj->prepare($args)) {
$action_obj->handle($args);
}
call_user_func("$action_class::run", $args);
} catch (ClientException $cex) {
$cac = new ClientErrorAction($cex->getMessage(), $cex->getCode());
$cac->showPage();

View File

@ -55,7 +55,20 @@ require_once INSTALLDIR.'/lib/htmloutputter.php';
*/
class Action extends HTMLOutputter // lawsuit
{
var $args;
// This should be protected/private in the future
public $args = array();
// Action properties, set per-class
protected $action = false;
protected $ajax = false;
protected $menus = true;
// The currently scoped profile
protected $scoped = null;
// Messages to the front-end user
protected $error = null;
protected $msg = null;
/**
* Constructor
@ -73,6 +86,44 @@ class Action extends HTMLOutputter // lawsuit
parent::__construct($output, $indent);
}
function getError()
{
return $this->error;
}
function getInfo()
{
return $this->msg;
}
static public function run(array $args=array(), $output='php://output', $indent=null) {
$class = get_called_class();
$action = new $class($output, $indent);
$action->execute($args);
return $action;
}
public function execute(array $args=array()) {
// checkMirror stuff
if (common_config('db', 'mirror') && $this->isReadOnly($args)) {
if (is_array(common_config('db', 'mirror'))) {
// "load balancing", ha ha
$arr = common_config('db', 'mirror');
$k = array_rand($arr);
$mirror = $arr[$k];
} else {
$mirror = common_config('db', 'mirror');
}
// everyone else uses the mirror
common_config_set('db', 'database', $mirror);
}
if ($this->prepare($args)) {
$this->handle($args);
}
}
/**
* For initializing members of the class.
*
@ -80,14 +131,19 @@ class Action extends HTMLOutputter // lawsuit
*
* @return boolean true
*/
function prepare($argarray)
function prepare(array $args=array())
{
$this->args =& common_copy_args($argarray);
$this->args = common_copy_args($args);
if ($this->boolean('ajax')) {
$this->action = $this->trimmed('action');
if ($this->ajax || $this->boolean('ajax')) {
// check with StatusNet::isAjax()
StatusNet::setAjax(true);
}
$this->scoped = Profile::current();
return true;
}