ajout de la partie slam dans le dossier web
This commit is contained in:
		
							
								
								
									
										228
									
								
								ap23/web/doku/inc/ActionRouter.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								ap23/web/doku/inc/ActionRouter.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,228 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki; | ||||
|  | ||||
| use dokuwiki\Action\AbstractAction; | ||||
| use dokuwiki\Action\Exception\ActionDisabledException; | ||||
| use dokuwiki\Action\Exception\ActionException; | ||||
| use dokuwiki\Action\Exception\FatalException; | ||||
| use dokuwiki\Action\Exception\NoActionException; | ||||
| use dokuwiki\Action\Plugin; | ||||
|  | ||||
| /** | ||||
|  * Class ActionRouter | ||||
|  * @package dokuwiki | ||||
|  */ | ||||
| class ActionRouter { | ||||
|  | ||||
|     /** @var  AbstractAction */ | ||||
|     protected $action; | ||||
|  | ||||
|     /** @var  ActionRouter */ | ||||
|     protected static $instance = null; | ||||
|  | ||||
|     /** @var int transition counter */ | ||||
|     protected $transitions = 0; | ||||
|  | ||||
|     /** maximum loop */ | ||||
|     const MAX_TRANSITIONS = 5; | ||||
|  | ||||
|     /** @var string[] the actions disabled in the configuration */ | ||||
|     protected $disabled; | ||||
|  | ||||
|     /** | ||||
|      * ActionRouter constructor. Singleton, thus protected! | ||||
|      * | ||||
|      * Sets up the correct action based on the $ACT global. Writes back | ||||
|      * the selected action to $ACT | ||||
|      */ | ||||
|     protected function __construct() { | ||||
|         global $ACT; | ||||
|         global $conf; | ||||
|  | ||||
|         $this->disabled = explode(',', $conf['disableactions']); | ||||
|         $this->disabled = array_map('trim', $this->disabled); | ||||
|         $this->transitions = 0; | ||||
|  | ||||
|         $ACT = act_clean($ACT); | ||||
|         $this->setupAction($ACT); | ||||
|         $ACT = $this->action->getActionName(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the singleton instance | ||||
|      * | ||||
|      * @param bool $reinit | ||||
|      * @return ActionRouter | ||||
|      */ | ||||
|     public static function getInstance($reinit = false) { | ||||
|         if((self::$instance === null) || $reinit) { | ||||
|             self::$instance = new ActionRouter(); | ||||
|         } | ||||
|         return self::$instance; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setup the given action | ||||
|      * | ||||
|      * Instantiates the right class, runs permission checks and pre-processing and | ||||
|      * sets $action | ||||
|      * | ||||
|      * @param string $actionname this is passed as a reference to $ACT, for plugin backward compatibility | ||||
|      * @triggers ACTION_ACT_PREPROCESS | ||||
|      */ | ||||
|     protected function setupAction(&$actionname) { | ||||
|         $presetup = $actionname; | ||||
|  | ||||
|         try { | ||||
|             // give plugins an opportunity to process the actionname | ||||
|             $evt = new Extension\Event('ACTION_ACT_PREPROCESS', $actionname); | ||||
|             if ($evt->advise_before()) { | ||||
|                 $this->action = $this->loadAction($actionname); | ||||
|                 $this->checkAction($this->action); | ||||
|                 $this->action->preProcess(); | ||||
|             } else { | ||||
|                 // event said the action should be kept, assume action plugin will handle it later | ||||
|                 $this->action = new Plugin($actionname); | ||||
|             } | ||||
|             $evt->advise_after(); | ||||
|  | ||||
|         } catch(ActionException $e) { | ||||
|             // we should have gotten a new action | ||||
|             $actionname = $e->getNewAction(); | ||||
|  | ||||
|             // this one should trigger a user message | ||||
|             if(is_a($e, ActionDisabledException::class)) { | ||||
|                 msg('Action disabled: ' . hsc($presetup), -1); | ||||
|             } | ||||
|  | ||||
|             // some actions may request the display of a message | ||||
|             if($e->displayToUser()) { | ||||
|                 msg(hsc($e->getMessage()), -1); | ||||
|             } | ||||
|  | ||||
|             // do setup for new action | ||||
|             $this->transitionAction($presetup, $actionname); | ||||
|  | ||||
|         } catch(NoActionException $e) { | ||||
|             msg('Action unknown: ' . hsc($actionname), -1); | ||||
|             $actionname = 'show'; | ||||
|             $this->transitionAction($presetup, $actionname); | ||||
|         } catch(\Exception $e) { | ||||
|             $this->handleFatalException($e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Transitions from one action to another | ||||
|      * | ||||
|      * Basically just calls setupAction() again but does some checks before. | ||||
|      * | ||||
|      * @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) { | ||||
|         $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)); | ||||
|         } | ||||
|  | ||||
|         // do the recursion | ||||
|         $this->setupAction($to); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Aborts all processing with a message | ||||
|      * | ||||
|      * When a FataException instanc is passed, the code is treated as Status code | ||||
|      * | ||||
|      * @param \Exception|FatalException $e | ||||
|      * @throws FatalException during unit testing | ||||
|      */ | ||||
|     protected function handleFatalException(\Exception $e) { | ||||
|         if(is_a($e, FatalException::class)) { | ||||
|             http_status($e->getCode()); | ||||
|         } else { | ||||
|             http_status(500); | ||||
|         } | ||||
|         if(defined('DOKU_UNITTEST')) { | ||||
|             throw $e; | ||||
|         } | ||||
|         $msg = 'Something unforeseen has happened: ' . $e->getMessage(); | ||||
|         nice_die(hsc($msg)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Load the given action | ||||
|      * | ||||
|      * This translates the given name to a class name by uppercasing the first letter. | ||||
|      * Underscores translate to camelcase names. For actions with underscores, the different | ||||
|      * parts are removed beginning from the end until a matching class is found. The instatiated | ||||
|      * Action will always have the full original action set as Name | ||||
|      * | ||||
|      * Example: 'export_raw' -> ExportRaw then 'export' -> 'Export' | ||||
|      * | ||||
|      * @param $actionname | ||||
|      * @return AbstractAction | ||||
|      * @throws NoActionException | ||||
|      */ | ||||
|     public function loadAction($actionname) { | ||||
|         $actionname = strtolower($actionname); // FIXME is this needed here? should we run a cleanup somewhere else? | ||||
|         $parts = explode('_', $actionname); | ||||
|         while(!empty($parts)) { | ||||
|             $load = join('_', $parts); | ||||
|             $class = 'dokuwiki\\Action\\' . str_replace('_', '', ucwords($load, '_')); | ||||
|             if(class_exists($class)) { | ||||
|                 return new $class($actionname); | ||||
|             } | ||||
|             array_pop($parts); | ||||
|         } | ||||
|  | ||||
|         throw new NoActionException(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute all the checks to see if this action can be executed | ||||
|      * | ||||
|      * @param AbstractAction $action | ||||
|      * @throws ActionDisabledException | ||||
|      * @throws ActionException | ||||
|      */ | ||||
|     public function checkAction(AbstractAction $action) { | ||||
|         global $INFO; | ||||
|         global $ID; | ||||
|  | ||||
|         if(in_array($action->getActionName(), $this->disabled)) { | ||||
|             throw new ActionDisabledException(); | ||||
|         } | ||||
|  | ||||
|         $action->checkPreconditions(); | ||||
|  | ||||
|         if(isset($INFO)) { | ||||
|             $perm = $INFO['perm']; | ||||
|         } else { | ||||
|             $perm = auth_quickaclcheck($ID); | ||||
|         } | ||||
|  | ||||
|         if($perm < $action->minimumPermission()) { | ||||
|             throw new ActionException('denied'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the action handling the current request | ||||
|      * | ||||
|      * @return AbstractAction | ||||
|      */ | ||||
|     public function getAction() { | ||||
|         return $this->action; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user