Last active
December 22, 2015 06:48
-
-
Save fabpot/6433461 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
require_once __DIR__.'/autoload.php.dist'; | |
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | |
use Symfony\Component\Routing\Matcher\UrlMatcher; | |
use Symfony\Component\Routing\Matcher\RequestMatcherInterface; | |
use Symfony\Component\Routing\RequestContext; | |
use Symfony\Component\Routing\RouteCollection; | |
use Symfony\Component\Routing\Route; | |
use Symfony\Component\HttpFoundation\Request; | |
// This condition should be true for the route to match | |
$condition = "method in ['GET', 'HEAD'] and request.headers.get('User-Agent') =~ '/firefox/i'"; | |
$routes = new RouteCollection(); | |
// here, I'm adding the condition as a Route option | |
$routes->add('hello', new Route('/hello/{name}', array(), array(), array('condition' => $condition))); | |
class RequestUrlMatcher extends UrlMatcher implements RequestMatcherInterface | |
{ | |
private $language; | |
public function setExpressionLanguage(ExpressionLanguage $language) | |
{ | |
$this->language = $language; | |
} | |
public function matchRequest(Request $request) | |
{ | |
$this->request = $request; | |
return $this->match($request->getPathInfo()); | |
} | |
protected function handleRouteRequirements($pathinfo, $name, Route $route) | |
{ | |
$options = $route->getOptions(); | |
$status = self::REQUIREMENT_MISMATCH; | |
if (!isset($options['condition'])) { | |
$status = self::REQUIREMENT_MATCH; | |
} else { | |
// the variables that can be accessed in the condition expression | |
$context = array( | |
'method' => $this->context->getMethod(), | |
'request' => $this->request, | |
); | |
// the route matches only if the condition evaluates to true | |
if ($this->language->evaluate($options['condition'], $context)) { | |
$status = self::REQUIREMENT_MATCH; | |
} | |
} | |
return array($status, null); | |
} | |
} | |
$context = new RequestContext(); | |
$request = Request::create('/hello/Fabien', 'GET', array(), array(), array(), array('HTTP_USER_AGENT' => 'Firefox/1.0')); | |
$context->fromRequest($request); | |
$matcher = new RequestUrlMatcher($routes, $context); | |
$matcher->setExpressionLanguage(new ExpressionLanguage()); | |
// this is going to match as the method is GET and the browser contains Firefox | |
var_export($matcher->matchRequest($request)); |
This file contains hidden or 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
# corresponding YAML configuration file for the code above | |
hello: | |
path: /hello/{name} | |
options: | |
condition: "method in ['GET', 'HEAD'] and request.headers.get('User-Agent') =~ '/firefox/i'" | |
# what we could do if condition would become a first class citizen in Symfony | |
hello: | |
path: /hello/{name} | |
condition: "method in ['GET', 'HEAD'] and request.headers.get('User-Agent') =~ '/firefox/i'" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment