/** * Call * * This method finds and iterates all route objects that match the current request URI. */ 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; $matchedRoutes = $this->router->getMatchedRoutes($this->request->getMethod(), $this->request->getResourceUri()); foreach ($matchedRoutes as $route) { 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; } } if (!$dispatched) { $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 (\Exception $e) { \Log::log_slim_exception($e); // Statamic's error logger if ($this->config('debug')) { throw $e; } else { try { $this->error($e); } catch (\Slim\Exception\Stop $e) { // Do nothing } } } }
/** * @param \Slim\Http\Request $request * @param \Slim\Http\Response $response * @param callable $next * @return mixed */ public function sanitizeRequestBody(Request $request, Response $response, callable $next) { if ($inputs = $request->getParsedBody()) { $inputs = array_filter($inputs, function (&$value) { if (is_string($value)) { $value = filter_var(trim($value), FILTER_SANITIZE_STRING); } return $value ?: null; }); if (isset($inputs['_METHOD']) && $request->getMethod() == $inputs['_METHOD']) { unset($inputs['_METHOD']); } $request = $request->withParsedBody($inputs); } if ($request->getHeaderLine('Accept') == 'application/json') { $request = $request->withHeader('X-Requested-With', 'XMLHttpRequest'); } return $next($request, $response); }
/** * Run application. * Find route matching requesst uri and execute associated controller callback, or * set 404 variable. */ public function run() { $display404 = true; $uri = $this->request->getResourceUri(); $method = $this->request->getMethod(); foreach ($this->routes as $i => $route) { if ($route->matches($uri)) { if ($route->supportsHttpMethod($method) || $route->supportsHttpMethod("ANY")) { call_user_func_array($route->getCallable(), array_values($route->getParams())); $display404 = false; } } } if ($display404) { if (is_callable($this->errorHandler)) { call_user_func($this->errorHandler); } else { echo "404 - route not found"; } } }
/** * Invoke middleware. * * @param RequestInterface $req PSR7 request object * @param ResponseInterface $res PSR7 response object * @param callable $next Next middleware callable * * @return ResponseInterface PSR7 response object */ public function __invoke(Request $req, Response $res, callable $next) { if (!$req->getAttribute('route')) { return $res->withStatus(404); } $isAllowed = false; if ($this->acl->hasResource('route' . $req->getAttribute('route')->getPattern())) { $isAllowed = $isAllowed || $this->acl->isAllowed($this->currentUserRole, 'route' . $req->getAttribute('route')->getPattern(), strtolower($req->getMethod())); } if (is_string($req->getAttribute('route')->getCallable()) && $this->acl->hasResource('callable/' . $req->getAttribute('route')->getCallable())) { $isAllowed = $isAllowed || $this->acl->isAllowed($this->currentUserRole, 'callable/' . $req->getAttribute('route')->getCallable()); } if (!$isAllowed && $this->currentUserRole === $this->defaultRole) { return $res->withRedirect($this->loginUrl); } if (!$isAllowed) { $res = $res->withStatus(403, $this->currentUserRole . ' is not allowed access to this location.'); $res->getBody()->write('Forbidden'); return $res; } return $next($req, $res); }
public function testGetMethodOverrideParameterFromBodyArray() { $uri = Uri::createFromString('https://example.com:443/foo/bar?abc=123'); $headers = new Headers(['Content-Type' => 'application/x-www-form-urlencoded']); $cookies = []; $serverParams = []; $body = new RequestBody(); $body->write('_METHOD=PUT'); $body->rewind(); $request = new Request('POST', $uri, $headers, $cookies, $serverParams, $body); $request->registerMediaTypeParser('application/x-www-form-urlencoded', function ($input) { parse_str($input, $body); return $body; // <-- Array }); $this->assertEquals('PUT', $request->getMethod()); }
/** * Dispatch request and build response * * This method will route the provided Request object against all available * application routes. The provided response will reflect the status, header, and body * set by the invoked matching route. * * The provided Request and Response objects are updated by reference. There is no * value returned by this method. * * @param \Slim\Http\Request The request instance * @param \Slim\Http\Response The response instance */ protected function dispatchRequest(\Slim\Http\Request $request, \Slim\Http\Response $response) { try { $this->applyHook('slim.before'); ob_start(); $this->applyHook('slim.before.router'); $dispatched = false; $matchedRoutes = $this['router']->getMatchedRoutes($request->getMethod(), $request->getPathInfo(), false); foreach ($matchedRoutes 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->applyHook('slim.after.router'); } catch (\Slim\Exception\Stop $e) { } $response->write(ob_get_clean()); $this->applyHook('slim.after'); }
protected function getMethod() { return $this->request->getMethod(); }
/** * Handle the edit requests * GET: the edit form * POST: the result view * * @param Request $request * @param Response $response * @param integer $productId * @return Response */ protected function handleEdit(Request $request, Response $response, $productId) { $logger = LoggerSingleton::getInstance()->getLogger(); switch ($request->getMethod()) { case 'GET': $model = new ProductCreationModel(); $product = null; try { $product = $this->service->read($productId); $model->setProduct($product); } catch (NotFoundException $ex) { $logger->notice(__METHOD__ . " (" . __LINE__ . "): " . $ex->getMessage()); return $response->withStatus(302)->withAddedHeader("Location", $this->container->get('router')->pathFor('productList')); } return TwigUtil::render($this->container, $response, 'product/edit_form.twig', $model->jsonSerialize()); case 'POST': $product = $this->productFromCreateEditForm($request); $files = $request->getUploadedFiles(); /** @var UploadedFile $file */ $file = null; if (array_key_exists('image', $files)) { $file = $files['image']; } $model = new ProductCreationModel(); $this->validateProduct($product, $file, $model); if (!$model->isSuccess()) { $model->setProduct($product); return TwigUtil::render($this->container, $response, 'product/edit_form.twig', $model->jsonSerialize()); } $model->setIsSuccess($this->service->update($product)); // default: success $template = 'product/edit_success.twig'; if ($model->isSuccess()) { try { // delete previous image if ($file->getSize()) { foreach (glob(getenv('PRODUCT_IMAGES_DIRECTORY') . '*') as $entry) { if (preg_match("/.*\\/{$productId}\\.[a-z]+\$/", $entry)) { unlink($entry); } } } Utils::writeUploadedFileToPath($file, getenv(PRODUCT_IMAGES_DIRECTORY), $product->getId()); } catch (\RuntimeException $ex) { $model->setIsSuccess(false); $message = "Can't write image file to the upload directory"; $model->appendMessage("{$message}. Please retry again later."); $logger->error(__FILE__ . "(" . __LINE__ . "): {$message} :: " . $ex->getMessage()); $template = 'product/edit_form.twig'; } } else { // error: back to the form $template = 'product/edit_form.twig'; } return TwigUtil::render($this->container, $response, $template, $model->jsonSerialize()); $model->setIsSuccess($this->service->create($product)); return $response->withStatus(501); // Not implemented yet // Not implemented yet default: return $response->withStatus(404); // Should never happen } }
/** * Get the controller method based on request method. * * @param \Slim\Http\Request * @return string */ protected function getMethod(Request $request) { return strtolower($request->getMethod()) . self::METHOD_SUFFIX; }
/** * This provide a method-overwrite for GET and POST request * * @param \Slim\Http\Request $req * @return \Slim\Http\Request */ protected function filterRequestMethod(Request $req) { $method = strtoupper($req->getMethod()); $params = []; if ($method == 'GET') { $params = $req->getQueryParams(); } elseif ($method == 'POST') { $params = $req->getParsedBody(); } if (isset($params['_method'])) { $req = $req->withMethod($params['_method']); } return $req; }