public function testFiltersWithContext() { $filters = new Filters(); $filters->register('myEventType', function (Filters $contextFilters) use($filters) { $this->assertEquals($filters, $contextFilters, 'Context should pass data to our filter function'); }); $context = new Context(); $context->registerInstance($filters); $filters->trigger('myEventType', $context); }
/** * Triggers any "not allowed" filters and prepares an appropriate 404 error response. */ private function prepareNotAllowedResponse() { ob_clean(); $this->response = new Response(); $this->response->setResponseCode(ResponseCode::HTTP_METHOD_NOT_ALLOWED); $this->context->registerInstance($this->response); $this->filters->trigger(Filters::METHOD_NOT_ALLOWED, $this->context); $this->finalizeOutputBuffer(); if (empty($this->response->getBody())) { $this->serveStaticPage('method_not_allowed'); } }
/** * 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; }
public function testControllerDispatchingWithBeforeResponseSkipsPrimaryAction() { $context = new Context(); $request = new Request(); $context->registerInstance($request); $route = new Route('/', 'Enlighten\\Tests\\Routing\\Sample\\SampleControllerWithBeforeResponse'); $this->assertInstanceOf('Enlighten\\Http\\Response', $route->action($context)); $this->expectOutputString(''); // This test SHOULD result in the route's primary action NOT being called. // (if it is called, an exception is thrown - see the SampleControllerWithBeforeResponse class) }
/** * Attempts to translate this route's target to a function within a controller class. * * @param Context $context * @return array * @throws RoutingException */ private function translateToClassCallable(Context $context) { // Load the class and create an instance of it $targetParts = explode('@', strval($this->getTarget()), 2); $targetClass = $targetParts[0]; $targetFuncName = count($targetParts) > 1 ? $targetParts[1] : 'action'; if (!class_exists($targetClass, true)) { throw new RoutingException('Could not locate class: ' . $targetClass); } $classObj = null; // Invoke constructor with dependency injection $parameterList = $context->determineParamValuesForConstructor($targetClass); try { $reflection = new \ReflectionClass($targetClass); $classObj = $reflection->newInstanceArgs($parameterList); } catch (\TypeError $ex) { throw new RoutingException('Type error thrown when calling constructor on ' . $targetClass, 0, $ex); } // Verify target function and return a callable $targetFunc = [$classObj, $targetFuncName]; if (!is_callable($targetFunc)) { throw new RoutingException('Route target function is not callable: ' . $this->getTarget()); } return $targetFunc; }
public function testCreateRedirect() { // Prepare: Prepare environment to capture response $response = new Response(); $request = new Request(); $request->setRequestUri('/redirect/bla'); $context = new Context(); $context->registerInstance($response); $context->registerInstance($request); $router = new Router(); $router->setContext($context); $route = $router->createRedirect('/redirect/$testVar', '/target/$testVar', true); $this->assertEquals('/redirect/$testVar', $route->getPattern()); $routeResult = $router->route($request); $this->assertEquals($route, $routeResult); $router->dispatch($routeResult, $request); $this->assertEquals(ResponseCode::HTTP_MOVED_PERMANENTLY, $response->getResponseCode()); $this->assertEquals('/target/bla', $response->getHeader('Location')); }
public function testGetVariables() { $context = new Context(); $this->assertEquals([], $context->getRegisteredVariables()); $context->registerVariable('test1', 'hello'); $context->registerVariable('test2', 12.34); $this->assertEquals(['test1' => 'hello', 'test2' => 12.34], $context->getRegisteredVariables()); }
/** * Dispatches a Route, executing its action. * * @param Route $route The route to be executed. * @param Request $request The request information, if available. Used for mapping route variables. * @return mixed Route target function return value, if any. */ public function dispatch(Route $route, Request $request = null) { $context = $this->context; if (empty($this->context) && !empty($request)) { // If we have no context, but do have a request, prepare a context to store path variables in. // Otherwise routing path variables would be lost for no good reason. $context = new Context(); $context->registerInstance($request); } if (!empty($context)) { // If we have a context, ensure that the route is made available in it. $context->registerInstance($route); if (!empty($request)) { // If we have a request, map the path variables and pass them to the context as primitive types by name. // This will allow us to inject info from a route e.g. "/view/$userId" to a $userId variable. $pathVariables = VariableUrl::extractUrlVariables($request->getRequestUri(), $route->getPattern()); foreach ($pathVariables as $name => $value) { $context->registerVariable($name, $value); } } } return $route->action($context); }