/** * Constructor * @param array $userSettings Key-Value array of application settings * @return void */ public function __construct($userSettings = array()) { //Setup Slim application $this->environment = Slim_Environment::getInstance(); $this->request = new Slim_Http_Request($this->environment); $this->response = new Slim_Http_Response(); $this->router = new Slim_Router($this->request->getResourceUri()); $this->settings = array_merge(self::getDefaultSettings(), $userSettings); $this->middleware = array($this); $this->add(new Slim_Middleware_Flash()); $this->add(new Slim_Middleware_MethodOverride()); //Determine application mode $this->getMode(); //Setup view $this->view($this->config('view')); //Make default if first instance if (is_null(self::getInstance())) { $this->setName('default'); } //Set default logger that writes to stderr (may be overridden with middleware) $logWriter = $this->config('log.writer'); if (!$logWriter) { $logWriter = new Slim_LogWriter($this->environment['slim.errors']); } $log = new Slim_Log($logWriter); $log->setEnabled($this->config('log.enabled')); $log->setLevel($this->config('log.level')); $this->environment['slim.log'] = $log; //Set global error handler set_error_handler(array('Slim', 'handleErrors')); }
/** * Run the Slim application * * This method is the "meat and potatoes" of Slim and should be the last * method called. This fires up Slim, invokes the Route that matches * the current request, and returns the response to the client. * * This method will invoke the Not Found handler if no matching * routes are found. * * This method will also catch any unexpected Exceptions thrown by this * application; the Exceptions will be logged to this application's log * and rethrown to the global Exception handler. * * @return void */ public function run() { try { try { $this->applyHook('slim.before'); ob_start(); $this->applyHook('slim.before.router'); $matchedRoutes = $this->router->getMatchedRoutes(); $dispatched = false; $httpMethod = $this->request()->getMethod(); $httpMethodsAllowed = array(); foreach ($matchedRoutes as $route) { if ($route->supportsHttpMethod($httpMethod)) { 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()->header('Allow', implode(' ', $httpMethodsAllowed)); $this->halt(405); } else { $this->notFound(); } } $this->response()->write(ob_get_clean()); $this->applyHook('slim.after.router'); if ($this->view->getData('flash')) { $this->view->getData('flash')->save(); } session_write_close(); $this->response->send(); $this->applyHook('slim.after'); } catch (Slim_Exception_RequestSlash $e) { $this->redirect($this->request->getRootUri() . $this->request->getResourceUri() . '/', 301); } catch (Exception $e) { if ($e instanceof Slim_Exception_Stop) { throw $e; } $this->getLog()->error($e); if ($this->config('debug') === true) { $this->halt(500, self::generateErrorMarkup($e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString())); } else { $this->error($e); } } } catch (Slim_Exception_Stop $e) { //Exit application context } }
/** * Call * * Iterate each matching Route until all Routes are exhausted. * * @return void */ public function call() { try { if (isset($this->environment['slim.flash'])) { $this->view()->setData('flash', $this->environment['slim.flash']); } $this->applyHook('slim.before'); ob_start(); $this->applyHook('slim.before.router'); $dispatched = false; $httpMethodsAllowed = array(); $this->router->setResourceUri($this->request->getResourceUri()); $this->router->getMatchedRoutes(); foreach ($this->router as $route) { if ($route->supportsHttpMethod($this->environment['REQUEST_METHOD'])) { try { $this->applyHook('slim.before.dispatch'); $dispatched = $this->router->dispatch($route); $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->stop(); } catch (Slim_Exception_Stop $e) { $this->response()->write(ob_get_clean()); $this->applyHook('slim.after'); } catch (Slim_Exception_RequestSlash $e) { $this->response->redirect($this->request->getPath() . '/', 301); } catch (Exception $e) { if ($this->config('debug')) { throw $e; } else { try { $this->error($e); } catch (Slim_Exception_Stop $e) { } } } }
/** * Return routes that match the current request * @return array[Slim_Route] */ public function getMatchedRoutes($reload = false) { if ($reload || is_null($this->matchedRoutes)) { $this->matchedRoutes = array(); foreach ($this->routes as $route) { if ($route->matches($this->request->getResourceUri())) { $this->matchedRoutes[] = $route; } } } return $this->matchedRoutes; }
/** * Return routes that match the current request * @return array[Slim_Route] */ public function getMatchedRoutes($reload = false) { if ($reload || is_null($this->matchedRoutes)) { $this->matchedRoutes = array(); $method = $this->request->isHead() ? Slim_Http_Request::METHOD_GET : $this->request->getMethod(); foreach ($this->routes[$method] as $route) { if ($route->matches($this->request->getResourceUri())) { $this->matchedRoutes[] = $route; } } } return $this->matchedRoutes; }
/** * Run the Slim application * * This method is the "meat and potatoes" of Slim and should be the last * method called. This fires up Slim, invokes the Route that matches * the current request, and returns the response to the client. * * This method will invoke the Not Found handler if no matching * routes are found. * * This method will also catch any unexpected Exceptions thrown by this * application; the Exceptions will be logged to this application's log * and rethrown to the global Exception handler. * * @return void */ public function run() { try { $this->applyHook('slim.before'); ob_start(); $this->applyHook('slim.before.router'); $dispatched = false; foreach ($this->router->getMatchedRoutes() as $route) { try { $this->applyHook('slim.before.dispatch'); $dispatched = $route->dispatch(); $this->applyHook('slim.after.dispatch'); if ($dispatched) { break; } } catch (Slim_Exception_Pass $e) { continue; } } if (!$dispatched) { $this->notFound(); } $this->response()->write(ob_get_clean()); $this->applyHook('slim.after.router'); $this->view->getData('flash')->save(); session_write_close(); $this->response->send(); $this->applyHook('slim.after'); } catch (Slim_Exception_RequestSlash $e) { try { $this->redirect($this->request->getRootUri() . $this->request->getResourceUri() . '/', 301); } catch (Slim_Exception_Stop $e2) { //Ignore Slim_Exception_Stop and exit application context } } catch (Slim_Exception_Stop $e) { //Exit application context } catch (Exception $e) { $this->getLog()->error($e); try { if ($this->config('debug') === true) { $this->halt(500, self::generateErrorMarkup($e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString())); } else { $this->error($e); } } catch (Slim_Exception_Stop $e2) { //Ignore Slim_Exception_Stop and exit application context } } }
/** * Test get [script name, root uri, path, path info, resource uri] in root directory with htaccess */ public function testAppPathsInRootDirectoryWithHtaccess() { $env = Slim_Environment::mock(array('SCRIPT_NAME' => '', 'PATH_INFO' => '/bar/xyz')); $req = new Slim_Http_Request($env); $this->assertEquals('', $req->getScriptName()); $this->assertEquals('', $req->getRootUri()); $this->assertEquals('/bar/xyz', $req->getPath()); $this->assertEquals('/bar/xyz', $req->getPathInfo()); $this->assertEquals('/bar/xyz', $req->getResourceUri()); }
public function testDispatchWithoutCallable() { Slim_Environment::mock(array('REQUEST_METHOD' => 'GET', 'REMOTE_ADDR' => '127.0.0.1', 'SCRIPT_NAME' => '', 'PATH_INFO' => '/hello/josh', 'QUERY_STRING' => 'one=1&two=2&three=3', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 80, 'slim.url_scheme' => 'http', 'slim.input' => '', 'slim.errors' => fopen('php://stderr', 'w'), 'HTTP_HOST' => 'slim')); $env = Slim_Environment::getInstance(); $req = new Slim_Http_Request($env); $res = new Slim_Http_Response(); $router = new Slim_Router($req, $res); $route = new Slim_Route('/hello/:name', 'foo'); $route->setRouter($router); $route->matches($req->getResourceUri()); //<-- Extracts params from resource URI $this->assertFalse($route->dispatch()); }
/** * Test get [script name, root uri, path, path info, resource uri] in root directory with htaccess */ public function testAppPathsInRootDirectoryWithHtaccess() { Slim_Environment::mock(array('REQUEST_METHOD' => 'GET', 'REMOTE_ADDR' => '127.0.0.1', 'SCRIPT_NAME' => '', 'PATH_INFO' => '/bar/xyz', 'QUERY_STRING' => 'one=1&two=2&three=3', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 80, 'slim.url_scheme' => 'http', 'slim.input' => '', 'slim.errors' => fopen('php://stderr', 'w'))); $env = Slim_Environment::getInstance(); $req = new Slim_Http_Request($env); $this->assertEquals('', $req->getScriptName()); $this->assertEquals('', $req->getRootUri()); $this->assertEquals('/bar/xyz', $req->getPath()); $this->assertEquals('/bar/xyz', $req->getPathInfo()); $this->assertEquals('/bar/xyz', $req->getResourceUri()); }
/** * Test request URI without htaccess * * Pre-conditions: * The HTTP request URI is /foo/index.php/foo/bar/. The mock HTTP request simulates * a scenario where the Slim app resides in a subdirectory of the document root directory * without htaccess URL rewriting. * * Post-conditions: * The Request root should be "/foo/index.php" and the resource "/foo/bar" */ public function testRequestUriInSubDirectoryWitoutHtaccess() { $_SERVER['REQUEST_URI'] = '/foo/bootstrap.php/foo/bar/'; $_SERVER['SCRIPT_NAME'] = '/foo/bootstrap.php'; $r = new Slim_Http_Request(); $this->assertEquals('/foo/bootstrap.php', $r->getRootUri()); $this->assertEquals('/foo/bar/', $r->getResourceUri()); }