Skip to content

Commit 9a84864

Browse files
committed
Added subscriber options to HttpCache
Based on #177, ref #170 This PR adds 2 options that one can add in their `getOptions()`: * `fos_native_subscribers`: bit options to activate/deactivate subscribers provided by FOSHttpCacheBundle * `fos_subscribers`: Array of custom subscribers to add to the event dispatcher > By default **all native subscribers are activated** (`HttpCache::SUBSCRIBER_ALL`). **ALL native subscribers EXCEPT the user context one** ```php public function getOptions() { return [ 'fos_native_subscribers' => self::SUBSCRIBER_ALL | ~self::SUBSCRIBER_USER_CONTEXT ] } ``` **NO native subscribers** ```php public function getOptions() { return [ 'fos_native_subscribers' => self::SUBSCRIBER_NONE ] } ``` **ONLY user context subscribers** ```php public function getOptions() { return [ 'fos_native_subscribers' => self::SUBSCRIBER_USER_CONTEXT ] } ``` **User context subscriber AND Foo subscriber** ```php public function getOptions() { return [ 'fos_native_subscribers' => self::SUBSCRIBER_USER_CONTEXT | self::SUBSCRIBER_FOO ] } ``` **NO native subscribers + custom subscriber ** ```php public function getOptions() { return [ 'fos_native_subscribers' => self::SUBSCRIBER_NONE, 'fos_subscribers' => [new MySubscriber()] ] } ``` **ALL native subscribers (default) + custom subscriber ** ```php public function getOptions() { return [ 'fos_subscribers' => [new MySubscriber()] ] } ```
1 parent d964fdb commit 9a84864

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

HttpCache.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace FOS\HttpCacheBundle;
1313

14+
use FOS\HttpCacheBundle\SymfonyCache\UserContextSubscriber;
1415
use FOS\HttpCacheBundle\SymfonyCache\CacheEvent;
1516
use FOS\HttpCacheBundle\SymfonyCache\Events;
1617
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache as BaseHttpCache;
@@ -22,18 +23,40 @@
2223

2324
/**
2425
* Base class for enhanced Symfony reverse proxy.
26+
* It can register event subscribers that may alter the request received.
2527
*
2628
* @author Jérôme Vieilledent <[email protected]> (courtesy of eZ Systems AS)
2729
*
2830
* {@inheritdoc}
2931
*/
3032
abstract class HttpCache extends BaseHttpCache
3133
{
34+
/**
35+
* Options to indicate which native subscriber(s) to use.
36+
* They are to be used in the hash returned by getOptions(), with "fos_native_subscribers" key.
37+
*
38+
* These are bit options, use bitwise operators to combine them:
39+
* self::SUBSCRIBER_ALL | ~SUBSCRIBER_USER_CONTEXT => All but user context.
40+
* self::SUBSCRIBER_USER_CONTEXT | self::SUBSCRIBER_FOO => User context AND foo subscribers ONLY.
41+
*/
42+
const SUBSCRIBER_ALL = -1; // Equals to ~0
43+
const SUBSCRIBER_NONE = 0;
44+
const SUBSCRIBER_USER_CONTEXT = 1;
45+
3246
/**
3347
* @var EventDispatcherInterface
3448
*/
3549
private $eventDispatcher;
3650

51+
public function __construct(HttpKernelInterface $kernel, $cacheDir = null)
52+
{
53+
parent::__construct($kernel, $cacheDir);
54+
55+
foreach ($this->getSubscribers() as $subscriber) {
56+
$this->addSubscriber($subscriber);
57+
}
58+
}
59+
3760
/**
3861
* Set event dispatcher
3962
*
@@ -74,6 +97,23 @@ public function addSubscriber(EventSubscriberInterface $subscriber)
7497
return $this;
7598
}
7699

100+
/**
101+
* Returns subscribers to be added to the event dispatcher, in respect to options defined in `getOptions()`.
102+
*
103+
* @return EventSubscriberInterface[]
104+
*/
105+
public function getSubscribers()
106+
{
107+
$options = $this->getOptions();
108+
$subscribers = isset($options['fos_subscribers']) ? $options['fos_subscribers'] : array();
109+
$nativeSubscribersOption = isset($options['fos_native_subscribers']) ? $options['fos_native_subscribers'] : self::SUBSCRIBER_ALL;
110+
if ($nativeSubscribersOption & self::SUBSCRIBER_USER_CONTEXT) {
111+
$subscribers[] = new UserContextSubscriber();
112+
}
113+
114+
return $subscribers;
115+
}
116+
77117
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
78118
{
79119
if ($this->getEventDispatcher()->hasListeners(Events::PRE_HANDLE)) {

SymfonyCache/UserContextSubscriber.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,7 @@ public static function getSubscribedEvents()
7878
/**
7979
* Check on the handle event.
8080
*
81-
* @param Request $request
82-
* @param $type
83-
* @param $catch
81+
* @param CacheEvent $event
8482
*
8583
* @return Response|null If response is returned, this response should be used.
8684
* Otherwise let the kernel handle this request.

Tests/Unit/SymfonyCache/HttpCacheTest.php

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use FOS\HttpCacheBundle\HttpCache;
1515
use FOS\HttpCacheBundle\SymfonyCache\CacheEvent;
1616
use FOS\HttpCacheBundle\SymfonyCache\Events;
17-
use FOS\HttpCacheBundle\SymfonyCache\UserContextHandler;
17+
use FOS\HttpCacheBundle\SymfonyCache\UserContextSubscriber;
1818
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1919
use Symfony\Component\HttpFoundation\Request;
2020
use Symfony\Component\HttpFoundation\Response;
@@ -103,6 +103,63 @@ public function testAbort()
103103
$this->assertEquals(1, $subscriber->hits);
104104
$this->assertSame($response, $httpCache->handle($request, HttpKernelInterface::MASTER_REQUEST, $catch));
105105
}
106+
107+
/**
108+
* @dataProvider configuredSubscribersProvider
109+
*/
110+
public function testConfiguredSubscribers(array $options, array $expectedSubscribers)
111+
{
112+
$cacheKernel = $this->getHttpCachePartialMock(array('getOptions'));
113+
$cacheKernel
114+
->expects($this->once())
115+
->method('getOptions')
116+
->will($this->returnValue($options));
117+
118+
$this->assertEquals($expectedSubscribers, $cacheKernel->getSubscribers());
119+
}
120+
121+
public function configuredSubscribersProvider()
122+
{
123+
$mockSubscriber1 = $this->getMock('\Symfony\Component\EventDispatcher\EventSubscriberInterface');
124+
$mockSubscriber2 = $this->getMock('\Symfony\Component\EventDispatcher\EventSubscriberInterface');
125+
$mockSubscriber3 = $this->getMock('\Symfony\Component\EventDispatcher\EventSubscriberInterface');
126+
127+
return array(
128+
array(array(), array(new UserContextSubscriber())),
129+
array(
130+
array(
131+
'fos_native_subscribers' => HttpCache::SUBSCRIBER_ALL,
132+
),
133+
array(new UserContextSubscriber())
134+
),
135+
array(
136+
array(
137+
'fos_native_subscribers' => HttpCache::SUBSCRIBER_NONE,
138+
),
139+
array()
140+
),
141+
array(
142+
array(
143+
'fos_native_subscribers' => HttpCache::SUBSCRIBER_USER_CONTEXT,
144+
'fos_subscribers' => array($mockSubscriber1)
145+
),
146+
array($mockSubscriber1, new UserContextSubscriber())
147+
),
148+
array(
149+
array(
150+
'fos_native_subscribers' => HttpCache::SUBSCRIBER_NONE,
151+
'fos_subscribers' => array($mockSubscriber1, $mockSubscriber2)
152+
),
153+
array($mockSubscriber1, $mockSubscriber2)
154+
),
155+
array(
156+
array(
157+
'fos_subscribers' => array($mockSubscriber1, $mockSubscriber2, $mockSubscriber3)
158+
),
159+
array($mockSubscriber1, $mockSubscriber2, $mockSubscriber3, new UserContextSubscriber())
160+
),
161+
);
162+
}
106163
}
107164

108165
class TestSubscriber implements EventSubscriberInterface

0 commit comments

Comments
 (0)