Last active
February 16, 2018 06:46
-
-
Save l0gicgate/b47f084f7180ca119e06cc4fc55ee99b to your computer and use it in GitHub Desktop.
Determine all allowed request methods for a request outside of slim app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Slim\App; | |
$app = new App(); | |
/** | |
* Routes | |
*/ | |
$app->get('/foo', function ($req, ResponseInterface $res) { | |
return $res->withStatus(200); | |
}); | |
$app->post('/foo', function ($req, ResponseInterface $res) { | |
return $res->withStatus(200); | |
}); | |
/** | |
* @var Router $router | |
*/ | |
$router = $app->getContainer()->get('router'); | |
/** | |
* @var RequestInterface $request | |
* You will need to instantiate a Request object outside of the Slim app | |
* This can be done from Global variables easily, this is how it's done in a testing environment | |
*/ | |
$env = Environment::mock([ | |
'SCRIPT_NAME' => '/index.php', | |
'REQUEST_URI' => '/foo', | |
'REQUEST_METHOD' => 'GET, | |
]); | |
$uri = Uri::createFromEnvironment($env); | |
$headers = Headers::createFromEnvironment($env); | |
$cookies = []; | |
$serverParams = $env->all(); | |
$body = new RequestBody(); | |
$request = new Request($method, $uri, $headers, $cookies, $serverParams, $body); | |
/** | |
* Here we instantiate the RequestMethodDetector | |
* The results of the `RequestMethodDetector::getAllowedMethods()` is an array of allowed methods for the request's route | |
* In this instance, $allowedMethods will be ['GET', 'POST'] as per the routes defined above. | |
*/ | |
$requestMethodDetector = new RequestMethodDetector($router); | |
$allowedMethods = $requestMethodDetector->getAllowedMethods($request); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use FastRoute\Dispatcher; | |
use FastRoute\RouteParser; | |
use FastRoute\RouteParser\Std as StdParser; | |
use FastRoute\RouteCollector; | |
use FastRoute\DataGenerator\GroupCountBased as GroupCountBasedDataGenerator; | |
use Psr\Http\Message\RequestInterface; | |
use Slim\Route; | |
use Slim\Router; | |
/** | |
* Class RequestMethodDetector | |
* @package RMD | |
*/ | |
class RequestMethodDetector | |
{ | |
/** | |
* @var Router | |
*/ | |
protected $router; | |
/** | |
* @var Dispatcher|null | |
*/ | |
protected $dispatcher; | |
/** | |
* @var RouteParser | |
*/ | |
protected $routeParser; | |
/** | |
* @var array|null | |
*/ | |
protected $cacheFile; | |
/** | |
* RequestMethodDetector constructor. | |
* @param Router $router | |
* @param array|null $cacheFile | |
*/ | |
public function __construct(Router $router, $cacheFile = null) | |
{ | |
$this->router = $router; | |
$this->cacheFile = $cacheFile; | |
$this->routeParser = new StdParser(); | |
$this->dispatcher = $this->createDispatcher(); | |
} | |
/** | |
* @return \FastRoute\Dispatcher | |
*/ | |
protected function createDispatcher() | |
{ | |
$routeMap = $this->getRouteMap(); | |
return new RequestMethodDetectorDispatcher($routeMap); | |
} | |
/** | |
* @return array | |
*/ | |
public function getRouteMap() | |
{ | |
if ($this->cacheFile) { | |
$dispatchData = require $this->cacheFile; | |
if (!is_array($dispatchData)) { | |
throw new \RuntimeException("Invalid cache file `{$this->cacheFile}``."); | |
} | |
return $dispatchData; | |
} | |
$dataGenerator = new GroupCountBasedDataGenerator(); | |
$routeCollector = new RouteCollector($this->routeParser, $dataGenerator); | |
foreach ($this->getRoutes() as $route) { | |
$routeCollector->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier()); | |
} | |
return $routeCollector->getData(); | |
} | |
/** | |
* @return Route[] | |
*/ | |
public function getRoutes() | |
{ | |
return $this->router->getRoutes(); | |
} | |
/** | |
* @return Dispatcher|null | |
*/ | |
public function getDispatcher() | |
{ | |
return $this->dispatcher; | |
} | |
/** | |
* @param RequestInterface $request | |
* @param bool $returnAllMethods | |
* @return array | |
*/ | |
public function getAllowedMethods(RequestInterface $request, $returnAllMethods = true) | |
{ | |
$method = $returnAllMethods ? 'UnknownMethod' : $request->getMethod(); | |
$uri = '/' . ltrim($request->getUri()->getPath(), '/'); | |
return $this->dispatcher->dispatch($method, $uri); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use FastRoute\Dispatcher\GroupCountBased; | |
/** | |
* Class RequestMethodDetectorDispatcher | |
* @package RMD | |
*/ | |
class RequestMethodDetectorDispatcher extends GroupCountBased | |
{ | |
/** | |
* @param string $httpMethod | |
* @param string $uri | |
* @return array | |
*/ | |
public function dispatch($httpMethod, $uri) | |
{ | |
$varRouteData = $this->variableRouteData; | |
$allowedMethods = []; | |
foreach ($this->staticRouteMap as $method => $uriMap) { | |
if ($method !== $httpMethod && isset($uriMap[$uri])) { | |
$allowedMethods[] = $method; | |
} | |
} | |
foreach ($varRouteData as $method => $routeData) { | |
if ($method === $httpMethod) { | |
continue; | |
} | |
$result = $this->dispatchVariableRoute($routeData, $uri); | |
if ($result[0] === self::FOUND) { | |
$allowedMethods[] = $method; | |
} | |
} | |
return $allowedMethods; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment