Skip to content

Commit 712de49

Browse files
committed
Have a method to add tags to the TagSubscriber directly, for when the request does not exist yet
1 parent cdf3b88 commit 712de49

29 files changed

+230
-79
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ Changelog
44
1.3.0
55
-----
66

7+
* **2015-05-08** Configured/annotated cache tags on subrequests
8+
(twig `render(controller())`) are no longer ignored. Additionally, it is now
9+
possible to add tags from code before the response object has been created,
10+
by using the TagHandler.
11+
If you defined custom services for the `InvalidateTagCommand`, you should
12+
now inject the TagHandler instead of the CacheManager.
13+
14+
**deprecated** `CacheManager::tagResponse` in favor of `TagHandler::addTags`
715
* **2015-05-08** Added configuration option for custom proxy client (#208)
816

917
1.2.0

CacheManager.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public function setGenerateUrlType($generateUrlType)
6767
* response
6868
*
6969
* @return $this
70+
*
71+
* @deprecated Add tags with TagHandler::addTags and then use TagHandler::tagResponse
7072
*/
7173
public function tagResponse(Response $response, array $tags, $replace = false)
7274
{

Command/InvalidateTagCommand.php

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,25 @@
1111

1212
namespace FOS\HttpCacheBundle\Command;
1313

14+
use FOS\HttpCacheBundle\CacheManager;
15+
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
1416
use Symfony\Component\Console\Input\InputInterface;
1517
use Symfony\Component\Console\Output\OutputInterface;
1618
use Symfony\Component\Console\Input\InputArgument;
17-
use FOS\HttpCacheBundle\CacheManager;
19+
use FOS\HttpCache\Handler\TagHandler;
1820

1921
/**
2022
* A command to trigger cache invalidation by tag from the command line.
2123
*
2224
* @author David Buchmann <[email protected]>
2325
*/
24-
class InvalidateTagCommand extends BaseInvalidateCommand
26+
class InvalidateTagCommand extends ContainerAwareCommand
2527
{
28+
/**
29+
* @var TagHandler
30+
*/
31+
private $tagHandler;
32+
2633
/**
2734
* @var string
2835
*/
@@ -32,13 +39,24 @@ class InvalidateTagCommand extends BaseInvalidateCommand
3239
* If no cache manager is specified explicitly, fos_http_cache.cache_manager
3340
* is automatically loaded.
3441
*
35-
* @param CacheManager|null $cacheManager The cache manager to talk to.
36-
* @param string $commandName Name of this command, in case you want to reuse it.
42+
* Passing CacheManager as argument is deprecated and will be restricted to TagHandler in 2.0.
43+
*
44+
* @param TagHandler|CacheManager|null $tagHandler The tag handler to talk to.
45+
* @param string $commandName Name of this command, in case you want to reuse it.
3746
*/
38-
public function __construct(CacheManager $cacheManager = null, $commandName = 'fos:httpcache:invalidate:tag')
47+
public function __construct($tagHandler = null, $commandName = 'fos:httpcache:invalidate:tag')
3948
{
49+
if (!($tagHandler instanceof TagHandler || $tagHandler instanceof CacheManager || null === $tagHandler)) {
50+
throw new \InvalidArgumentException(
51+
sprintf(
52+
'Expected instance of TagHandler, CacheManager or null, but got %s',
53+
get_class($tagHandler)
54+
)
55+
);
56+
}
4057
$this->commandName = $commandName;
41-
parent::__construct($cacheManager);
58+
$this->tagHandler = $tagHandler;
59+
parent::__construct();
4260
}
4361

4462
/**
@@ -72,6 +90,18 @@ protected function execute(InputInterface $input, OutputInterface $output)
7290
{
7391
$tags = $input->getArgument('tags');
7492

75-
$this->getCacheManager()->invalidateTags($tags);
93+
$this->getTagManager()->invalidateTags($tags);
94+
}
95+
96+
/**
97+
* @return TagHandler|CacheManager
98+
*/
99+
protected function getTagManager()
100+
{
101+
if (!$this->tagHandler) {
102+
$this->tagHandler = $this->getContainer()->get('fos_http_cache.handler.tag_handler');
103+
}
104+
105+
return $this->tagHandler;
76106
}
77107
}

DependencyInjection/FOSHttpCacheExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public function load(array $configs, ContainerBuilder $container)
8787
$container->setParameter($this->getAlias().'.compiler_pass.tag_annotations', $config['tags']['enabled']);
8888
if ($config['tags']['enabled']) {
8989
// true or auto
90+
$container->setParameter($this->getAlias().'.tag_handler.header', $config['tags']['header']);
9091
$loader->load('tag_listener.xml');
9192
if (!empty($config['tags']['rules'])) {
9293
$this->loadTagRules($container, $config['tags']['rules']);

EventListener/TagSubscriber.php

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
namespace FOS\HttpCacheBundle\EventListener;
1313

14-
use FOS\HttpCacheBundle\CacheManager;
14+
use FOS\HttpCacheBundle\Handler\TagHandler;
1515
use FOS\HttpCacheBundle\Configuration\Tag;
1616
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1717
use Symfony\Component\HttpFoundation\Request;
1818
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
19+
use Symfony\Component\HttpKernel\HttpKernelInterface;
1920
use Symfony\Component\HttpKernel\KernelEvents;
2021
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
2122

@@ -27,9 +28,9 @@
2728
class TagSubscriber extends AbstractRuleSubscriber implements EventSubscriberInterface
2829
{
2930
/**
30-
* @var CacheManager
31+
* @var TagHandler
3132
*/
32-
private $cacheManager;
33+
private $tagHandler;
3334

3435
/**
3536
* @var ExpressionLanguage
@@ -39,14 +40,14 @@ class TagSubscriber extends AbstractRuleSubscriber implements EventSubscriberInt
3940
/**
4041
* Constructor
4142
*
42-
* @param CacheManager $cacheManager
43+
* @param TagHandler $tagHandler
4344
* @param ExpressionLanguage|null $expressionLanguage
4445
*/
4546
public function __construct(
46-
CacheManager $cacheManager,
47+
TagHandler $tagHandler,
4748
ExpressionLanguage $expressionLanguage = null
4849
) {
49-
$this->cacheManager = $cacheManager;
50+
$this->tagHandler = $tagHandler;
5051
$this->expressionLanguage = $expressionLanguage;
5152
}
5253

@@ -65,32 +66,28 @@ public function onKernelResponse(FilterResponseEvent $event)
6566
$response = $event->getResponse();
6667

6768
$tags = array();
68-
6969
// Only set cache tags or invalidate them if response is successful
7070
if ($response->isSuccessful()) {
7171
$tags = $this->getAnnotationTags($request);
7272
}
7373

7474
$configuredTags = $this->matchRule($request, $response);
7575
if ($configuredTags) {
76-
foreach ($configuredTags['tags'] as $tag) {
77-
$tags[] = $tag;
78-
}
76+
$tags = array_merge($tags, $configuredTags['tags']);
7977
foreach ($configuredTags['expressions'] as $expression) {
8078
$tags[] = $this->evaluateTag($expression, $request);
8179
}
8280
}
8381

84-
if (!count($tags)) {
85-
return;
86-
}
87-
8882
if ($request->isMethodSafe()) {
89-
// For safe requests (GET and HEAD), set cache tags on response
90-
$this->cacheManager->tagResponse($response, $tags);
91-
} else {
83+
$this->tagHandler->addTags($tags);
84+
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
85+
// For safe requests (GET and HEAD), set cache tags on response
86+
$this->tagHandler->tagResponse($response);
87+
}
88+
} elseif (count($tags)) {
9289
// For non-safe methods, invalidate the tags
93-
$this->cacheManager->invalidateTags($tags);
90+
$this->tagHandler->invalidateTags($tags);
9491
}
9592
}
9693

Handler/TagHandler.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace FOS\HttpCacheBundle\Handler;
4+
5+
use FOS\HttpCache\Handler\TagHandler as BaseTagHandler;
6+
use Symfony\Component\HttpFoundation\Response;
7+
8+
class TagHandler extends BaseTagHandler
9+
{
10+
/**
11+
* Tag response with the previously added tags.
12+
*
13+
* @param Response $response
14+
* @param bool $replace Whether to replace the current tags on the
15+
* response. If false, parses the header to merge
16+
* tags.
17+
*
18+
* @return $this
19+
*/
20+
public function tagResponse(Response $response, $replace = false)
21+
{
22+
if (!$replace && $response->headers->has($this->getTagsHeaderName())) {
23+
$header = $response->headers->get($this->getTagsHeaderName());
24+
if ('' !== $header) {
25+
$this->addTags(explode(',', $response->headers->get($this->getTagsHeaderName())));
26+
}
27+
}
28+
29+
if ($this->hasTags()) {
30+
$response->headers->set($this->getTagsHeaderName(), $this->getTagsHeaderValue());
31+
}
32+
33+
return $this;
34+
}
35+
}

Resources/config/cache_manager.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
</service>
4646

4747
<service id="fos_http_cache.command.invalidate_tag" class="%fos_http_cache.command.invalidate_tag.class%">
48-
<argument type="service" id="fos_http_cache.cache_manager" />
48+
<argument type="service" id="fos_http_cache.handler.tag_handler" />
4949
<tag name="console.command"/>
5050
</service>
5151

Resources/config/tag_listener.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
99
</parameters>
1010

1111
<services>
12+
<service id="fos_http_cache.handler.tag_handler" class="FOS\HttpCacheBundle\Handler\TagHandler">
13+
<argument type="service" id="fos_http_cache.cache_manager"/>
14+
<argument>%fos_http_cache.tag_handler.header%</argument>
15+
</service>
16+
1217
<service id="fos_http_cache.event_listener.tag"
1318
class="%fos_http_cache.event_listener.tag.class%">
14-
<argument type="service" id="fos_http_cache.cache_manager" />
19+
<argument type="service" id="fos_http_cache.handler.tag_handler" />
1520
<tag name="kernel.event_subscriber" />
1621
</service>
1722
</services>

Resources/doc/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@
5656
# built documents.
5757
#
5858
# The short X.Y version.
59-
version = '1.0.0'
59+
version = '1.3.0'
6060
# The full version, including alpha/beta/rc tags.
61-
release = '1.0.0'
61+
release = '1.3.0'
6262

6363
# The language for content autogenerated by Sphinx. Refer to documentation
6464
# for a list of supported languages.

Resources/doc/features/tagging.rst

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,30 @@ Setting and Invalidating Tags
3535
You can tag responses in three ways: with the cache manager, configuration and
3636
annotations.
3737

38-
Cache Manager
39-
~~~~~~~~~~~~~
38+
Tagging from code
39+
~~~~~~~~~~~~~~~~~
4040

41-
Use ``tagResponse($response, $tags)`` to set tags on a response::
41+
Inject the ``TagHandler`` (service ``fos_http_cache.handler.tag_handler``) and
42+
use ``addTags($tags)`` to add tags that will be set on the response::
4243

43-
use Symfony\Component\HttpFoundation\Response;
44+
use FOS\HttpCacheBundle\Handler\TagHandler;
4445

4546
class NewsController
4647
{
48+
/**
49+
* @var TagHandler
50+
*/
51+
private $tagHandler;
52+
4753
public function articleAction($id)
4854
{
49-
$response = new Response('Some news article');
50-
$this->cacheManager->tagResponse($response, array('news', 'news-' . $id));
55+
$this->tagHandler->addTags(array('news', 'news-' . $id));
5156

52-
return $response;
57+
// ...
5358
}
5459
}
5560

56-
Then call ``invalidateTags($tags)`` to invalidate the tags you set::
61+
To invalidate tags, call ``TagHandler::invalidateTags($tags)``::
5762

5863
class NewsController
5964
{
@@ -63,13 +68,13 @@ Then call ``invalidateTags($tags)`` to invalidate the tags you set::
6368
{
6469
// ...
6570

66-
$this->cacheManager->invalidateTags(array('news-' . $id))->flush();
71+
$this->tagHandler->invalidateTags(array('news-' . $id));
6772

6873
// ...
6974
}
7075
}
7176

72-
See the :ref:`Cache Manager reference <cache_manager_tags>` for full details.
77+
See the :ref:`Tag Handler reference <tag_handler_addtags>` for full details.
7378

7479
Configuration
7580
~~~~~~~~~~~~~

Resources/doc/reference.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ annotations and public methods.
1010
reference/configuration
1111
reference/annotations
1212
reference/cache-manager
13+
reference/tag-handler
1314
reference/glossary

Resources/doc/reference/cache-manager.rst

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,12 @@ Refresh a Route::
8282

8383
.. _cache_manager_tags:
8484

85-
``tagResponse()``
86-
-----------------
85+
``tagResponse()``, ``invalidateTags()``
86+
---------------------------------------
8787

88-
Use the Cache Manager to tag responses::
89-
90-
// $response is a \Symfony\Component\HttpFoundation\Response object
91-
$cacheManager->tagResponse($response, array('some-tag', 'other-tag'));
92-
93-
The tags are appended to already existing tags, unless you set the ``$replace``
94-
option to true::
95-
96-
$cacheManager->tagResponse($response, array('different'), true);
97-
98-
``invalidateTags()``
99-
--------------------
100-
101-
Invalidate cache tags::
102-
103-
$cacheManager->invalidateTags(array('some-tag', 'other-tag'));
88+
.. versionadded:: 1.3
89+
Since version 1.3, use the :doc:`TagHandler <tag-handler>` instead of the
90+
CacheManager for working with tags.
10491

10592
.. _flushing:
10693

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
The Tag Handler
2+
===============
3+
4+
Service to work with :doc:`Cache Tagging <../features/tagging>`. You can add tags to the
5+
handler and generate invalidation requests that are queued in the invalidator.
6+
7+
A response listener checks the ``TagHandler`` to detect tags that need to be
8+
set on a response. As with other invalidation operations, invalidation requests
9+
are flushed to the caching proxy :ref:`after the response has been sent <flushing>`.
10+
11+
.. _tag_handler_addtags:
12+
13+
``addTags()``
14+
-------------
15+
16+
Add tags to be sent with the response::
17+
18+
$tagHandler->addTags(array('some-tag', 'other-tag'));
19+
20+
This method can be called regardless of whether the response object already
21+
exists or not.
22+
23+
``invalidateTags()``
24+
--------------------
25+
26+
Invalidate cache tags::
27+
28+
$tagHandler->invalidateTags(array('some-tag', 'other-tag'));

Resources/doc/spelling_word_list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ symfony
77
github
88
subdomains
99
yaml
10+
invalidator

0 commit comments

Comments
 (0)