-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support controllers as invalidation targets #233
Comments
As I workaround I have been able to get this working by physically defining a route for the controller:
And then in
|
i think you are asking for #69 ? can you check if that is the case? and would you be motivated to work on that? the idea was around for quite a while but we did not work on it yet... i am glad to help find out how and review a pull request. |
Currently, you can invalidate paths and routes. Invalidation controllers, which is what @benr77 asks for, is not the same thing as #69. Eventually, it’s always a URL (at the HTTP level) that we invalidate. I don’t think Symfony allows getting the path (or URL) for a controller if it has no route defined. The path that goes to that controller, after all, is defined in the routing. On the other hand, |
OK. I have got things working for now. I have discovered that when you use a route to define an invalidation rule, you must also use the route format for any sub-requests. e.g. invalidation of an ESI controller render will fail if you use the controller format I have also found that the controller() method causes problems with setting up the caching in the first place - if you have two or more To make invalidation work you must define a route for the sub-request and then use the route to create a URL in the render_esi() method:
with
Unfortunately this means that you need to hard-code a route for every ESI you have. Not too much of a hassle but not ideal. |
that workaround is one option. be sure to secure access to the fragment routes however, see for example http://stackoverflow.com/questions/22295858/how-do-i-invalidate-cache-for-a-controller-url your other option would be creating a ControllerReference (just with |
Sorry to relaunch this issue but I'm facing the same problem and I'm not really satisfy by the esi route path workaround. I think it can be a good idea to deep on the ESIFragementHandler::render method and find a way to encapsulated those things into the FOSHTTPCacheBundle. @dbu I'm not really sure to well understand the way you want to use this into the ControllerReference ? can you explain it a little bit more ? |
its been a while. i think the idea was to create a ControllerReference object and use the esi fragment render method to get the url to that fragment. then you can invalidate that. as this depends on parameters, there is no generic solution. i think #69 would solve this in an elegant way: the RequestMatcher can match on a _controller request attribute. then you could define rules that match on a controller name instead of a route. as this is a regular expression match, it could be quite useful in this scenario. |
Any news on this issue?
I've tried this but uri that goes from proxy client is different from what I've got:
vs
|
afaik nobody is actively working on this. if you have the time to figure out the details and propose documentation or code updates, they are welcome and i would review them. |
As workaround I use this helper class: namespace AppBundle\Cache;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface;
class FragmentPathResolver
{
/**
* @var FragmentRendererInterface
*/
private $fragmentRenderer;
/**
* @var RequestStack
*/
private $requestStack;
public function __construct(FragmentRendererInterface $fragmentRenderer, RequestStack $requestStack)
{
$this->fragmentRenderer = $fragmentRenderer;
$this->requestStack = $requestStack;
}
/**
* @param string $controller
* @param array $parameters
* @param array $query
* @return null|string
*/
public function resolve($controller, array $parameters = array(), array $query = array())
{
$controllerReference = new ControllerReference($controller, $parameters, $query);
$response = $this->fragmentRenderer->render($controllerReference, $this->requestStack->getMasterRequest());
return $this->parsePath($response->getContent());
}
/**
* @param string $content
* @return null|string
*/
private function parsePath($content)
{
if (empty($content)) {
return null;
}
if (!preg_match('/src=[\'"](.*?)[\'"]/iu', $content, $matches)) {
return null;
}
return $this->fixOrder($matches[1]);
}
/**
* @param $uri
* @return string
*/
private function fixOrder($uri)
{
$hashPosition = strpos($uri, '&_hash=');
if ($hashPosition === false) {
return null;
}
$hash = substr($uri, $hashPosition + 1);
$uri = substr($uri, 0, $hashPosition);
$queryPosition = strpos($uri, '?');
if ($queryPosition === false) {
return null;
}
$fragment = substr($uri, 0, $queryPosition + 1);
$query = substr($uri, $queryPosition + 1);
return sprintf('%s%s&%s', $fragment, $hash, $query);
}
} |
thanks @BoShurik ! |
When using the YML configuration to define invalidation, you can specify a list of routes to invalidate the cache for when a particular "match" is made.
However, I'm caching a ESI controller, and it would make sense to invalidate this controller's cache but it doesn't have a route of its own. Can the "routes" support controller names perhaps? Or add an additional option alongside routes called "controllers" which contains an array of controllers to invalidate - e.g. the bottom 4 lines of this
Is this the right approach? Any suggestions appreciated.
Thanks
Ben
The text was updated successfully, but these errors were encountered: