/** * Triggers all filter functions for a given $eventType. * * @param string $eventType The type of event, e.g. 'beforeRoute'. * @param Context $context The optional context to be applied to the filter functions. * @return bool Returns whether execution should continue or not. */ public function trigger($eventType, Context $context = null) { $continue = true; if (!isset($this->handlers[$eventType])) { return $continue; } foreach ($this->handlers[$eventType] as $filterFunction) { $params = []; if (!empty($context)) { $params = $context->determineParamValues($filterFunction); } $returnValue = call_user_func_array($filterFunction, $params); if ($returnValue === false) { $continue = false; break; } } return $continue; }
/** * Executes a route action, given a callable and a context. * * @param callable $targetFunc The target function to be executed. * @param Context $context The context the target function should be executed under (for dependency injection). * @return mixed The function's return value. * @throws \Exception If an exception is raised during execution, it will be rethrown. */ private function executeAction(callable $targetFunc, Context $context) { $returnValue = null; $paramValues = $context->determineParamValues($targetFunc); try { $returnValue = call_user_func_array($targetFunc, $paramValues); } catch (\Exception $ex) { $context->registerInstance($ex); $this->filters->trigger(Filters::ON_EXCEPTION, $context); if (!$this->filters->anyHandlersForEvent(Filters::ON_EXCEPTION)) { // If this exception was unhandled, rethrow it so it can be handled in the global scope throw $ex; } } return $returnValue; }
public function testContextSelfReference() { $context = new Context(); $myFunc = function (Context $ctx) { // .. }; $expectedParams = [$context]; $actualParams = $context->determineParamValues($myFunc); $this->assertEquals($expectedParams, $actualParams); }