This section covers advanced configurations for mapping route parameters in scenarios where properties alone are not sufficient. You’ll learn how to work with nested properties, collections, non-property values, and dynamically provided values to create flexible and powerful purge rules.
You can access nested properties of an entity to define route parameters by using Symfony’s Property Access syntax:
#[Route('/author/{id<\d+>}', name: 'author_details', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['id' => 'author.id'])]
public function detailsAction(Author $author)
{
}
If the nested object is nullable, you can use the null-safe operator (?
) to skip generating the URL if the nested
property is null
:
#[Route('/author/{id<\d+>}', name: 'author_details', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['id' => 'author?.id'])]
public function detailsAction(Author $author)
{
}
If the route parameter itself is optional, the URL will be generated without it.
When working with collections, you can map route parameters to each element within the collection:
#[Route('/post/{id<\d+>}', name: 'post_details', methods: 'GET')]
#[PurgeOn(Author::class, routeParams: ['id' => 'posts[*].id'])]
public function detailsAction(Post $post)
{
}
In this example, the id
parameter is extracted from each item in the posts
collection, generating a URL for each
individual post. This ensures that each item in the collection has its corresponding URL purged.
When working with multiple collections, the bundle generates a Cartesian product of URLs, ensuring that all combinations of elements within the collections are purged:
#[Route('/posts/{tag}/{commentId<\d+>}', name: 'posts_list', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['tag' => 'tags[*].id', 'commentId' => 'comments[*].id'])]
public function listAction(string $tag, Comment $comment)
{
}
In this example, URLs are generated for all combinations of tag
and commentId
based on the elements in the tags
and comments
collections. This ensures that each unique combination within the collections is accounted for.
In addition to mapping entity properties to route parameters, you can use various other value types. This flexibility allows you to customize routes based on raw values, backed enums, or even dynamic values provided by services.
You can specify raw values directly in the route parameters:
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\RawValues;
#[Route('/posts/{type}', name: 'posts_list', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['type' => new RawValues('foo')])]
public function listAction(string $type)
{
}
In this example, the route parameter type
is explicitly set to the value foo
.
If you have a predefined set of values in a backed enum, you can map route parameters to those enum values:
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\EnumValues;
#[Route('/posts/{type}', name: 'posts_list', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['type' => new EnumValues(TypeEnum::class)])]
public function listAction(string $type)
{
}
Here, multiple URLs are generated based on all values defined in the TypeEnum
class for the type
parameter.
You can combine multiple sources of values, such as enums and raw values, using CompoundValues
:
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\CompoundValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\EnumValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\RawValues;
#[Route('/posts/{lang}', name: 'posts_list', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['lang' => new CompoundValues(
new EnumValues(LanguageCodes::class),
new RawValues('XK'), // Kosovo code
)])]
public function listAction(string $lang)
{
}
In this example, multiple URLs are generated based on all values from the LanguageCodes
enum and the raw value XK
for the lang
parameter.
You can also map route parameters to values provided dynamically by a service. This is particularly useful when you need route parameters that depend on context or runtime information:
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\DynamicValues;
#[Route('/posts/{type}', name: 'posts_list', methods: 'GET')]
#[PurgeOn(Post::class, routeParams: ['type' => new DynamicValues('my_service')])]
public function listAction(string $lang)
{
}
To make this work, ensure your service is tagged correctly in the service configuration:
# services.yaml
App\MyService:
tags:
- { name: 'purgatory.route_parameter_service', alias: my_service }
Alternatively, you can use the #[AsRouteParamService]
attribute directly in the service class:
use Sofascore\PurgatoryBundle\Attribute\AsRouteParamService;
#[AsRouteParamService('my_service')]
class MyService
{
public function __invoke(Post $post)
{
// Return the desired value for the route parameter
}
}