Skip to content

Commit 55790f4

Browse files
committed
Add ExpressionValues
1 parent ab9abe7 commit 55790f4

6 files changed

Lines changed: 107 additions & 3 deletions

File tree

config/services.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Sofascore\PurgatoryBundle\RouteParamValueResolver\CompoundValuesResolver;
2929
use Sofascore\PurgatoryBundle\RouteParamValueResolver\DynamicValuesResolver;
3030
use Sofascore\PurgatoryBundle\RouteParamValueResolver\EnumValuesResolver;
31+
use Sofascore\PurgatoryBundle\RouteParamValueResolver\ExpressionValuesResolver;
3132
use Sofascore\PurgatoryBundle\RouteParamValueResolver\PropertyValuesResolver;
3233
use Sofascore\PurgatoryBundle\RouteParamValueResolver\RawValuesResolver;
3334
use Sofascore\PurgatoryBundle\RouteProvider\AbstractEntityRouteProvider;
@@ -224,6 +225,12 @@
224225
service('sofascore.purgatory.property_accessor'),
225226
])
226227

228+
->set('sofascore.purgatory.route_parameter_resolver.expression', ExpressionValuesResolver::class)
229+
->tag('purgatory.route_param_value_resolver')
230+
->args([
231+
service('sofascore.purgatory.expression_language')->nullOnInvalid(),
232+
])
233+
227234
->set('sofascore.purgatory.property_accessor', PurgatoryPropertyAccessor::class)
228235
->args([
229236
service('property_accessor'),
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sofascore\PurgatoryBundle\Attribute\RouteParamValue;
6+
7+
use Sofascore\PurgatoryBundle\Exception\LogicException;
8+
use Symfony\Component\ExpressionLanguage\Expression;
9+
10+
final class ExpressionValues extends AbstractValues
11+
{
12+
private readonly Expression $expression;
13+
14+
public function __construct(
15+
string $expression,
16+
) {
17+
$this->expression = self::normalizeExpression($expression);
18+
}
19+
20+
/**
21+
* @return array{0: Expression}
22+
*/
23+
public function getValues(): array
24+
{
25+
return [$this->expression];
26+
}
27+
28+
public static function type(): string
29+
{
30+
return 'expression';
31+
}
32+
33+
private static function normalizeExpression(string $expression): Expression
34+
{
35+
if (!class_exists(Expression::class)) {
36+
throw new LogicException(\sprintf('You cannot use "%s" because the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".', self::class));
37+
}
38+
39+
return new Expression($expression);
40+
}
41+
}

src/Cache/RouteMetadata/YamlMetadataProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\CompoundValues;
99
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\DynamicValues;
1010
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\EnumValues;
11+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ExpressionValues;
1112
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\PropertyValues;
1213
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\RawValues;
1314
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
@@ -182,12 +183,14 @@ private function buildRouteParam(string|array|TaggedValue $routeParam): string|a
182183
CompoundValues::type() => new CompoundValues(...array_map($this->buildRouteParam(...), $value)),
183184
DynamicValues::type() => new DynamicValues(...((array) $value)),
184185
EnumValues::type() => new EnumValues($value),
186+
ExpressionValues::type() => new ExpressionValues($value),
185187
PropertyValues::type() => new PropertyValues(...((array) $value)),
186188
RawValues::type() => new RawValues(...((array) $value)),
187189
default => throw new UnknownYamlTagException($tag, [
188190
CompoundValues::type(),
189191
DynamicValues::type(),
190192
EnumValues::type(),
193+
ExpressionValues::type(),
191194
PropertyValues::type(),
192195
RawValues::type(),
193196
]),

src/Cache/Subscription/PurgeSubscriptionProvider.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Doctrine\Persistence\ManagerRegistry;
88
use Psr\Container\ContainerInterface;
9+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ExpressionValues;
910
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\PropertyValues;
1011
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
1112
use Sofascore\PurgatoryBundle\Attribute\Target\TargetInterface;
@@ -58,7 +59,7 @@ private function provideFromMetadata(RouteMetadataProviderInterface $routeMetada
5859
$purgeOn = $routeMetadata->purgeOn;
5960

6061
if (null !== $purgeOn->if) {
61-
$this->validateIfExpression($purgeOn->if, $routeMetadata->routeName);
62+
$this->validateExpression($purgeOn->if, $routeMetadata->routeName);
6263
}
6364

6465
// if route parameters are not specified, they are same as path variables
@@ -73,6 +74,11 @@ private function provideFromMetadata(RouteMetadataProviderInterface $routeMetada
7374
$routeParams[$pathVariable] = new PropertyValues($pathVariable);
7475
}
7576
} else {
77+
foreach ($purgeOn->routeParams as $values) {
78+
if ($values instanceof ExpressionValues) {
79+
$this->validateExpression($values->getValues()[0], $routeMetadata->routeName);
80+
}
81+
}
7682
$this->validateRouteParams(array_keys($purgeOn->routeParams), $routeMetadata);
7783
$routeParams = $purgeOn->routeParams;
7884
}
@@ -140,7 +146,7 @@ private function validateRouteParams(array $routeParams, RouteMetadata $routeMet
140146
}
141147
}
142148

143-
private function validateIfExpression(Expression $expression, string $routeName): void
149+
private function validateExpression(Expression $expression, string $routeName): void
144150
{
145151
try {
146152
$this->expressionLanguage?->lint($expression, ['obj']);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sofascore\PurgatoryBundle\RouteParamValueResolver;
6+
7+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ExpressionValues;
8+
use Sofascore\PurgatoryBundle\Exception\LogicException;
9+
use Symfony\Component\ExpressionLanguage\Expression;
10+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
11+
12+
/**
13+
* @implements ValuesResolverInterface<array{0: Expression}>
14+
*/
15+
final class ExpressionValuesResolver implements ValuesResolverInterface
16+
{
17+
public function __construct(
18+
private readonly ?ExpressionLanguage $expressionLanguage,
19+
) {
20+
}
21+
22+
/**
23+
* {@inheritDoc}
24+
*/
25+
public static function for(): string
26+
{
27+
return ExpressionValues::type();
28+
}
29+
30+
/**
31+
* {@inheritDoc}
32+
*/
33+
public function resolve(array $unresolvedValues, object $entity): array
34+
{
35+
$expression = $unresolvedValues[0];
36+
37+
$values = $this->getExpressionLanguage()->evaluate($expression, ['obj' => $entity]);
38+
39+
return \is_array($values) ? $values : [$values];
40+
}
41+
42+
private function getExpressionLanguage(): ExpressionLanguage
43+
{
44+
return $this->expressionLanguage
45+
?? throw new LogicException('You cannot use expressions because the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
46+
}
47+
}

tests/Cache/RouteMetadata/YamlMetadataProviderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public function testExceptionIsThrownForInvalidRoute(): void
255255
}
256256

257257
#[TestWith(['purge_on_with_unknown_target_tag.yaml', 'Unknown YAML tag "for_unknown" provided, known tags are "for_groups", "for_properties".'])]
258-
#[TestWith(['purge_on_with_unknown_route_param_tag.yaml', 'Unknown YAML tag "unknown" provided, known tags are "compound", "dynamic", "enum", "property", "raw".'])]
258+
#[TestWith(['purge_on_with_unknown_route_param_tag.yaml', 'Unknown YAML tag "unknown" provided, known tags are "compound", "dynamic", "enum", "expression", "property", "raw".'])]
259259
public function testExceptionIsThrownForUnknownTags(string $file, string $message): void
260260
{
261261
$collection = new RouteCollection();

0 commit comments

Comments
 (0)