I have a route defined in a symfony2 controller using annotations. EG:
@Route("/{year}", name="show_list_for_user", defaults={ "year" = "2012" })
Is it possible to make make the default year dynamic. Maybe to read the year from a service object?
I'm afraid that is not possible, the defaults are static.
You can set default parameters in RequestContext.
When Symfony generates an URL, it uses values in this order:
See Symfony\Component\Routing\Generator\UrlGenerator::doGenerate
:
$mergedParams = array_replace($defaults,
$this->context->getParameters(),
$parameters);
- user supplied parameters to generateUrl() function
- context parameters
- route defaults
You can set the context parameters in a request event listener to override Route defaults:
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Routing\RouterInterface;
class RequestListener
{
private $_router;
public function __construct(RouterInterface $router)
{
$this->_router = $router;
}
public function onRequest(GetResponseEvent $event)
{
$context = $this->_router->getContext();
if (!$context->hasParameter('year')) {
$context->setParameter('year', date('Y'));
}
}
}
Service configuration:
<service id="my.request_listener"
class="MyBundle\EventListener\RequestListener">
<argument id="router" type="service"/>
<tag name="kernel.event_listener"
event="kernel.request" method="onRequest" />
</service>
It depends on a use case, if you want to use dynamic default just to generate url, use code above. If you want your controller to dynamically pick right default value before executing action, you could probably use 'kernel.controller' event and set request attributes if not present.
This is not possible, but workarounds do exist. Create an additional controller which handles the default case.
Method a - forward the request
/**
* @Route("/recent", name="show_recent_list_for_user")
*/
public function recentAction()
{
$response = $this->forward('AcmeDemoBundle:Foo:bar', array(
'year' => 2012,
));
return $response;
}
Method b - redirect the request
/**
* @Route("/recent", name="show_recent_list_for_user")
*/
public function recentAction()
{
$response = $this->redirect($this->generateUrl('show_list_for_user', array(
'year' => 2012,
)));
return $response;
}
Use as default a placeholder, something like
defaults={ "year" = "CURRENT_YEAR" }
then in your controller do something like:
if ($year == "CURRENT_YEAR") {
$year = //do something to find the current year
}