Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #35747 [Routing][FrameworkBundle] Allow using env() in route …
…conditions (atailouloute) This PR was merged into the 5.1-dev branch. Discussion ---------- [Routing][FrameworkBundle] Allow using env() in route conditions | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | | License | MIT | Doc PR | TODO This is a second implementation of #35727, it overcomes the limitation mentioned by nicolas in (#35727 (comment)) The goal of this feature is to be able to use env variables in Route conditions ```php /** * @route("/only-for-dev", condition="env('APP_ENV') === 'dev'") */ public function __invoke() { echo "This will be executed only when APP_ENV = dev"; } ``` it supports also env processors/ loaders ```php /** * @route("/only-for-dev", condition="env('trim:APP_ENV') === 'dev'") */ ```` **TODOs:** - [x] Complete unit tests Commits ------- b574460 [Routing][FrameworkBundle] Allow using env() in route conditions
- Loading branch information
Showing
10 changed files
with
175 additions
and
13 deletions.
There are no files selected for viewing
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
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
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
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
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
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
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
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
54 changes: 54 additions & 0 deletions
54
src/Symfony/Component/Routing/Matcher/ExpressionLanguageProvider.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Routing\Matcher; | ||
|
||
use Symfony\Component\ExpressionLanguage\ExpressionFunction; | ||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; | ||
use Symfony\Contracts\Service\ServiceProviderInterface; | ||
|
||
/** | ||
* Exposes functions defined in the request context to route conditions. | ||
* | ||
* @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com> | ||
*/ | ||
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface | ||
{ | ||
private $functions; | ||
|
||
public function __construct(ServiceProviderInterface $functions) | ||
{ | ||
$this->functions = $functions; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFunctions() | ||
{ | ||
foreach ($this->functions->getProvidedServices() as $function => $type) { | ||
yield new ExpressionFunction( | ||
$function, | ||
static function (...$args) use ($function) { | ||
return sprintf('($context->getParameter(\'_functions\')->get(%s)(%s))', var_export($function, true), implode(', ', $args)); | ||
}, | ||
function ($values, ...$args) use ($function) { | ||
return $values['context']->getParameter('_functions')->get($function)(...$args); | ||
} | ||
); | ||
} | ||
} | ||
|
||
public function get(string $function): callable | ||
{ | ||
return $this->functions->get($function); | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
src/Symfony/Component/Routing/Tests/Matcher/ExpressionLanguageProviderTest.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Routing\Tests\Matcher; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Component\DependencyInjection\ServiceLocator; | ||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | ||
use Symfony\Component\Routing\Matcher\ExpressionLanguageProvider; | ||
use Symfony\Component\Routing\RequestContext; | ||
|
||
class ExpressionLanguageProviderTest extends TestCase | ||
{ | ||
private $context; | ||
private $expressionLanguage; | ||
|
||
protected function setUp(): void | ||
{ | ||
$functionProvider = new ServiceLocator([ | ||
'env' => function () { | ||
// function with one arg | ||
return function (string $arg) { | ||
return [ | ||
'APP_ENV' => 'test', | ||
'PHP_VERSION' => '7.2', | ||
][$arg] ?? null; | ||
}; | ||
}, | ||
'sum' => function () { | ||
// function with multiple args | ||
return function ($a, $b) { return $a + $b; }; | ||
}, | ||
'foo' => function () { | ||
// function with no arg | ||
return function () { return 'bar'; }; | ||
}, | ||
]); | ||
|
||
$this->context = new RequestContext(); | ||
$this->context->setParameter('_functions', $functionProvider); | ||
|
||
$this->expressionLanguage = new ExpressionLanguage(); | ||
$this->expressionLanguage->registerProvider(new ExpressionLanguageProvider($functionProvider)); | ||
} | ||
|
||
/** | ||
* @dataProvider compileProvider | ||
*/ | ||
public function testCompile(string $expression, string $expected) | ||
{ | ||
$this->assertSame($expected, $this->expressionLanguage->compile($expression)); | ||
} | ||
|
||
public function compileProvider(): iterable | ||
{ | ||
return [ | ||
['env("APP_ENV")', '($context->getParameter(\'_functions\')->get(\'env\')("APP_ENV"))'], | ||
['sum(1, 2)', '($context->getParameter(\'_functions\')->get(\'sum\')(1, 2))'], | ||
['foo()', '($context->getParameter(\'_functions\')->get(\'foo\')())'], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider evaluateProvider | ||
*/ | ||
public function testEvaluate(string $expression, $expected) | ||
{ | ||
$this->assertSame($expected, $this->expressionLanguage->evaluate($expression, ['context' => $this->context])); | ||
} | ||
|
||
public function evaluateProvider(): iterable | ||
{ | ||
return [ | ||
['env("APP_ENV")', 'test'], | ||
['env("PHP_VERSION")', '7.2'], | ||
['env("unknown_env_variable")', null], | ||
['sum(1, 2)', 3], | ||
['foo()', 'bar'], | ||
]; | ||
} | ||
} |