Skip to content
Snippets Groups Projects
Commit 50701b66 authored by Andreas Gohr's avatar Andreas Gohr
Browse files

better action transitions

It should now catch any circular loops (by having a maxiumum recursion
depth) and it handles the automatic redirect after save (and others)
parent a3f6fae6
No related branches found
No related tags found
No related merge requests found
...@@ -21,6 +21,12 @@ class ActionRouter { ...@@ -21,6 +21,12 @@ class ActionRouter {
/** @var ActionRouter */ /** @var ActionRouter */
protected $instance; protected $instance;
/** @var int transition counter */
protected $transitions = 0;
/** maximum loop */
const MAX_TRANSITIONS = 5;
/** /**
* ActionRouter constructor. Singleton, thus protected! * ActionRouter constructor. Singleton, thus protected!
* *
...@@ -55,7 +61,6 @@ class ActionRouter { ...@@ -55,7 +61,6 @@ class ActionRouter {
* *
* @param string $actionname * @param string $actionname
* @triggers ACTION_ACT_PREPROCESS * @triggers ACTION_ACT_PREPROCESS
* @fixme implement redirect on action change with post
*/ */
protected function setupAction($actionname) { protected function setupAction($actionname) {
$presetup = $actionname; $presetup = $actionname;
...@@ -70,19 +75,13 @@ class ActionRouter { ...@@ -70,19 +75,13 @@ class ActionRouter {
// we should have gotten a new action // we should have gotten a new action
$actionname = $e->getNewAction(); $actionname = $e->getNewAction();
// no infinite recursion
if($actionname == $presetup) {
// FIXME this doesn't catch larger circles
$this->handleFatalException(new FatalException('Infinite loop in actions', 500, $e));
}
// this one should trigger a user message // this one should trigger a user message
if(is_a($e, ActionDisabledException::class)) { if(is_a($e, ActionDisabledException::class)) {
msg('Action disabled: ' . hsc($presetup), -1); msg('Action disabled: ' . hsc($presetup), -1);
} }
// do setup for new action // do setup for new action
$this->setupAction($actionname); $this->transitionAction($presetup, $actionname);
} catch(NoActionException $e) { } catch(NoActionException $e) {
// give plugins an opportunity to process the actionname // give plugins an opportunity to process the actionname
...@@ -93,7 +92,7 @@ class ActionRouter { ...@@ -93,7 +92,7 @@ class ActionRouter {
msg('Action unknown: ' . hsc($actionname), -1); msg('Action unknown: ' . hsc($actionname), -1);
$actionname = 'show'; $actionname = 'show';
} }
$this->setupAction($actionname); $this->transitionAction($presetup, $actionname);
} else { } else {
// event said the action should be kept, assume action plugin will handle it later // event said the action should be kept, assume action plugin will handle it later
$this->action = new Plugin(); $this->action = new Plugin();
...@@ -106,6 +105,41 @@ class ActionRouter { ...@@ -106,6 +105,41 @@ class ActionRouter {
} }
} }
/**
* Transitions from one action to another
*
* Basically just calls setupAction() again but does some checks before. Also triggers
* redirects for POST to show transitions
*
* @param string $from current action name
* @param string $to new action name
* @param null|ActionException $e any previous exception that caused the transition
*/
protected function transitionAction($from, $to, $e = null) {
global $INPUT;
global $ID;
$this->transitions++;
// no infinite recursion
if($from == $to) {
$this->handleFatalException(new FatalException('Infinite loop in actions', 500, $e));
}
// larger loops will be caught here
if($this->transitions >= self::MAX_TRANSITIONS) {
$this->handleFatalException(new FatalException('Maximum action transitions reached', 500, $e));
}
// POST transitions to show should be a redirect
if($to == 'show' && $from != $to && strtolower($INPUT->server->str('REQUEST_METHOD')) == 'post') {
act_redirect($ID, $from); // FIXME we may want to move this function to the class
}
// do the recursion
$this->setupAction($to);
}
/** /**
* Check that the given minimum permissions are reached * Check that the given minimum permissions are reached
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment