Skip to content

Commit 41d4c34

Browse files
committed
Have a method to add tags to the TagSubscriber directly, for when the request does not exist yet
1 parent 89c09ec commit 41d4c34

File tree

4 files changed

+95
-7
lines changed

4 files changed

+95
-7
lines changed

EventListener/TagSubscriber.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class TagSubscriber extends AbstractRuleSubscriber implements EventSubscriberInt
3636
*/
3737
private $expressionLanguage;
3838

39+
/**
40+
* List of tags to add to response.
41+
*
42+
* @var string[]
43+
*/
44+
private $tags = array();
45+
3946
/**
4047
* Constructor
4148
*
@@ -50,6 +57,22 @@ public function __construct(
5057
$this->expressionLanguage = $expressionLanguage;
5158
}
5259

60+
/**
61+
* Add tags to set on the response to the current request.
62+
*
63+
* Contrary to CacheManager::tagResponse, this method can be called before
64+
* the response object exists.
65+
*
66+
* Adding a tag during an unsafe request is forbidden and leads to an
67+
* error. Use CacheManager::invalidateTags directly.
68+
*
69+
* @param array $tags List of tags to add.
70+
*/
71+
public function addTags(array $tags)
72+
{
73+
$this->tags = array_merge($this->tags, $tags);
74+
}
75+
5376
/**
5477
* Process the _tags request attribute, which is set when using the Tag
5578
* annotation
@@ -63,12 +86,16 @@ public function onKernelResponse(FilterResponseEvent $event)
6386
{
6487
$request = $event->getRequest();
6588
$response = $event->getResponse();
66-
67-
$tags = array();
89+
if ($request->isMethodSafe()) {
90+
$tags = $this->tags;
91+
$this->tags = array();
92+
} else {
93+
$tags = array();
94+
}
6895

6996
// Only set cache tags or invalidate them if response is successful
7097
if ($response->isSuccessful()) {
71-
$tags = $this->getAnnotationTags($request);
98+
$tags = array_merge($tags, $this->getAnnotationTags($request));
7299
}
73100

74101
$configuredTags = $this->matchRule($request, $response);

Resources/doc/features/tagging.rst

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,22 @@ 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 ``CacheManager`` (service ``fos_http_cache.cache_manager``) and
42+
use ``tagResponse($response, $tags)`` to set tags on a response::
4243

4344
use Symfony\Component\HttpFoundation\Response;
45+
use FOS\HttpCacheBundle\CacheManager;
4446

4547
class NewsController
4648
{
49+
/**
50+
* @var CacheManager
51+
*/
52+
private $cacheManager;
53+
4754
public function articleAction($id)
4855
{
4956
$response = new Response('Some news article');
@@ -53,7 +60,28 @@ Use ``tagResponse($response, $tags)`` to set tags on a response::
5360
}
5461
}
5562

56-
Then call ``invalidateTags($tags)`` to invalidate the tags you set::
63+
Or inject the ``TagSubscriber`` (service ``fos_http_cache.event_listener.tag``)
64+
and call ``addTags($tags)`` to set tags that will be added to the response once
65+
it exists::
66+
67+
use FOS\HttpCacheBundle\EventListener\TagSubscriber;
68+
69+
class Service
70+
{
71+
/**
72+
* @var TagSubscriber
73+
*/
74+
private $tagSubscriber;
75+
76+
public function doStuff($thing)
77+
{
78+
$this->tagSubscriber->addTags(array('news', 'news-' . $thing->getId()));
79+
80+
// ...
81+
}
82+
}
83+
84+
To invalidate tags, call ``CacheManager::invalidateTags($tags)``::
5785

5886
class NewsController
5987
{

Resources/doc/reference/cache-manager.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ option to true::
9595

9696
$cacheManager->tagResponse($response, array('different'), true);
9797

98+
.. tip::
99+
100+
If you do not yet have the response available, you can use the
101+
``TagSubscriber::addTags($tags)`` method to have your tags added once the
102+
response is being sent.
103+
98104
``invalidateTags()``
99105
--------------------
100106

Tests/Unit/EventListener/TagSubscriberTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,33 @@ public function testOnKernelResponsePost()
124124
$this->listener->onKernelResponse($event);
125125
}
126126

127+
public function testAddTagsGet()
128+
{
129+
$request = new Request();
130+
$request->setMethod('GET');
131+
132+
$this->listener->addTags(array('a', 'b'));
133+
$event = $this->getEvent($request);
134+
$this->listener->onKernelResponse($event);
135+
136+
$this->assertEquals(
137+
'a,b',
138+
$event->getResponse()->headers->get($this->cacheManager->getTagsHeader())
139+
);
140+
}
141+
142+
public function testAddTagsPost()
143+
{
144+
$request = new Request();
145+
$request->setMethod('POST');
146+
147+
$this->listener->addTags(array('a', 'b'));
148+
$event = $this->getEvent($request);
149+
$this->listener->onKernelResponse($event);
150+
151+
$this->assertFalse($event->getResponse()->headers->has($this->cacheManager->getTagsHeader()));
152+
}
153+
127154
protected function getEvent(Request $request, Response $response = null)
128155
{
129156
return new FilterResponseEvent(

0 commit comments

Comments
 (0)