/** * Call * * Iterate each matching Route until all Routes are exhausted. * Return an array of HTTP status, header, and body. * * @param array $env Key-value array of environment properties * @return array [status, header, body] */ public function call(&$env) { try { if (isset($env['slim.flash'])) { $this->view()->setData('flash', $env['slim.flash']); } $this->applyHook('slim.before'); ob_start(); $this->applyHook('slim.before.router'); $dispatched = false; $httpMethodsAllowed = array(); foreach ($this->router as $route) { if ($route->supportsHttpMethod($env['REQUEST_METHOD'])) { try { $this->applyHook('slim.before.dispatch'); $dispatched = $route->dispatch(); $this->applyHook('slim.after.dispatch'); if ($dispatched) { break; } } catch (Slim_Exception_Pass $e) { continue; } } else { $httpMethodsAllowed = array_merge($httpMethodsAllowed, $route->getHttpMethods()); } } if (!$dispatched) { if ($httpMethodsAllowed) { $this->response['Allow'] = implode(' ', $httpMethodsAllowed); $this->halt(405, 'HTTP method not allowed for the requested resource. Use one of these instead: ' . implode(', ', $httpMethodsAllowed)); } else { $this->notFound(); } } $this->applyHook('slim.after.router'); $this->response->write(ob_get_clean()); $this->applyHook('slim.after'); $this->stop(); } catch (Slim_Exception_Stop $e) { $this->response()->write(ob_get_contents()); return $this->response->finalize(); } catch (Slim_Exception_RequestSlash $e) { $this->response->redirect($this->request->getPath() . '/', 301); return $this->response->finalize(); } catch (Exception $e) { if ($this->config('debug')) { throw $e; } else { try { $this->error($e); } catch (Slim_Exception_Stop $e) { } return $this->response->finalize(); } } }
/** * Error Handler * * This method defines or invokes the application-wide Error handler. * There are two contexts in which this method may be invoked: * * 1. When declaring the handler: * * If the $argument parameter is callable, this * method will register the callable to be invoked when an uncaught * Exception is detected, or when otherwise explicitly invoked. * The handler WILL NOT be invoked in this context. * * 2. When invoking the handler: * * If the $argument parameter is not callable, Slim assumes you want * to invoke an already-registered handler. If the handler has been * registered and is callable, it is invoked and passed the caught Exception * as its one and only argument. The error handler's output is captured * into an output buffer and sent as the body of a 500 HTTP Response. * * @param mixed $argument Callable|Exception * @return void */ public function error($argument = null) { if (is_callable($argument)) { //Register error handler $this->router->error($argument); } else { //Invoke error handler $this->response->status(500); $this->response->body(''); $this->response->write($this->callErrorHandler($argument)); $this->stop(); } }
/** * Test body and write * * Pre-conditions: * Case A: Response body set to "Foo bar" * Case B: Same response body is changed to "abc123" * Case C: Same response body is appended with "xyz" * * Post-conditions: * Case A: Response body is "Foo bar", and Content-Length = 7 * Case B: Response body is "abc123" and Content-Length = 6 * Case C: Response body is "abc123xyz" and Content-Length = 9 */ public function testBody() { //Case A $r1 = new Slim_Http_Response(new Slim_Http_Request()); $r1->body('Foo bar'); $this->assertEquals('Foo bar', $r1->body()); $this->assertEquals(7, $r1->header('Content-Length')); //Case B $r1->body('abc123'); $this->assertEquals('abc123', $r1->body()); $this->assertEquals(6, $r1->header('Content-Length')); //Case C $r1->write('xyz'); $this->assertEquals('abc123xyz', $r1->body()); $this->assertEquals(9, $r1->header('Content-Length')); }
/** * Test finalize */ public function testFinalizeWithoutBody() { $r = new Slim_Http_Response(); $r->status(204); $r['Content-Type'] = 'application/json'; $r->write('Foo'); $result = $r->finalize(); $this->assertEquals(3, count($result)); $this->assertEquals('', $result[2]); }