Skip to content

Commit 750407d

Browse files
vidarlandrerom
authored andcommitted
EZEE-1780: Plugin support (#19)
* Revert "Allows http purge type to work (#22)" This reverts commit 6b1dafa. * Added plugin support for purge clients * Renamed FOSPurgeClient.php to VarnishPurgeClient.php * Added plugin support for TagHandler * Updated declaration of PurgeClientInterface * Added doc on how to write http cache drivers * Changed DI alias to ez_platform_cache by renaming EzSystemsPlatformHttpCacheExtension class * Updated composer.json as we depend on ezpublish-kernel PR #2136 * Changed to single quites on services.yml
1 parent 0b89356 commit 750407d

12 files changed

Lines changed: 178 additions & 39 deletions

File tree

composer.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
"email": "dev-team@ez.no"
1010
}
1111
],
12-
"minimum-stability": "stable",
1312
"require": {
14-
"ezsystems/ezpublish-kernel": "^6.7@dev || ^7.0@dev",
13+
"ezsystems/ezpublish-kernel": "~6.7.7@dev || ^6.12.1@dev || ^7.0@dev",
1514
"friendsofsymfony/http-cache-bundle": "~1.2|^1.3.8",
1615
"symfony/symfony": "^2.7 | ^3.1"
1716
},
@@ -33,7 +32,7 @@
3332
},
3433
"extra": {
3534
"branch-alias": {
36-
"dev-master": "0.1.x-dev"
35+
"dev-master": "0.3.x-dev"
3736
}
3837
}
3938
}

docs/drivers.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Driver support
2+
3+
You may add integration with other http caches using the extension points provided by this bundle.
4+
5+
The following extension points are available
6+
- PurgeClient
7+
- TagHandler
8+
- FOS TagHandler
9+
10+
If you write a new PurgeClient driver, you **must** also create a corresponding TagHandler and vice
11+
versa. Creating a FOS TagHandler is optional.
12+
13+
14+
## PurgeClient
15+
16+
The PurgeClient is responsible for sending purge requests to the http cache when content is about to be invalidated.
17+
The PurgeClient must implement EzSystems\PlatformHttpCacheBundle\PurgeClient\PurgeClientInterface and can be registered
18+
with the following code in services.yml:
19+
20+
```
21+
services:
22+
ezplatform.http_cache_myhttpcachebundle.purge_client.myhttpcache:
23+
class: EzSystems\PlatformMyHttpCacheBundle\PurgeClient\MyHttpCachePurgeClient
24+
arguments: ['@ezplatform.http_cache.cache_manager']
25+
tags:
26+
- {name: ezplatform.http_cache.purge_client, purge_type: myhttpcache}
27+
```
28+
29+
Any service which implements the PurgeClientInterface must be tagged with `ezplatform.http_cache.purge_client` in order
30+
to be registered as such.
31+
`purge_type` specifies what the value of the purge_type setting in `app/config/ezplatform.yml` should be in order to
32+
enable this driver.
33+
34+
35+
## TagHandler
36+
37+
The TagHandler is responsible for tagging responses with headers which the http cache recognizes.
38+
The TagHandler must implement EzSystems\PlatformHttpCacheBundle\Handler\TagHandlerInterface and can be registered with
39+
the following code in services.yml:
40+
41+
```
42+
ezplatform.http_cache_myhttpcachebundle.tag_handler.myhttpcache:
43+
class: EzSystems\PlatformMyHttpCacheBundle\Handler\MyHttpCacheTagHandler
44+
tags:
45+
- {name: ezplatform.http_cache.tag_handler, purge_type: myhttpcache}
46+
47+
```
48+
49+
Any service which implements the TagHandlerInterface must be tagged with `ezplatform.http_cache.tag_handler` in order
50+
to be registered as such.
51+
52+
## FOS TagHandler
53+
54+
The FOS Http cache bundle also has a TagHandler which is not used by eZ Platform except for one thing, the
55+
`fos:httpcache:invalidate:tag` command. With this command you may explicitly invalidate cache by tag.
56+
57+
Normally, you would not need to implement your own FOS TagHandler as the ezplatform-http-cache bundle ships with a
58+
default one which uses the PurgeClient to invalidate the given tags.
59+
If you need to write your own FOS TagHandler anyway, you may register it with the following code in services.yml:
60+
61+
```
62+
ezplatform.http_cache_myhttpcachebundle.fos_tag_handler.myhttpcache:
63+
class: EzSystems\PlatformMyHttpCacheBundle\Handler\MyHttpCacheFosTagHandler
64+
tags:
65+
- {name: ezplatform.http_cache.fos_tag_handler, purge_type: myhttpcache}
66+
```

spec/DependencyInjection/Compiler/KernelPassSpec.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ function it_disables_the_kernels_httpcache_services(ContainerBuilder $container,
5252
]
5353
])->shouldBeCalled();
5454

55-
$container->getParameter('purge_type')->shouldBeCalled();
56-
5755
$this->process($container);
5856
}
5957
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace EzSystems\PlatformHttpCacheBundle\DependencyInjection\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
use Symfony\Component\DependencyInjection\Reference;
8+
9+
/**
10+
* We support http cache drivers to be provided by 3rd party bundles.
11+
* This pass loads those drivers as documented in doc/drivers.md.
12+
*/
13+
class DriverPass implements CompilerPassInterface
14+
{
15+
public function process(ContainerBuilder $container)
16+
{
17+
$container->removeAlias('ezpublish.http_cache.purge_client');
18+
19+
$purgeType = $container->getParameter('ezpublish.http_cache.purge_type');
20+
$configuredPurgeClientServiceId = static::getTaggedService($container, 'ezplatform.http_cache.purge_client');
21+
if ($configuredPurgeClientServiceId === null) {
22+
throw new \InvalidArgumentException("No driver found being able to handle purge_type '$purgeType'.");
23+
}
24+
$container->setAlias('ezplatform.http_cache.purge_client', $configuredPurgeClientServiceId);
25+
26+
// TagHandler is responsible for setting correct tags (recognized by the http cache) on responses
27+
$configuredTagHandlerServiceId = static::getTaggedService($container, 'ezplatform.http_cache.tag_handler');
28+
if ($configuredTagHandlerServiceId !== null) {
29+
$container->setAlias('ezplatform.http_cache.tag_handler', $configuredTagHandlerServiceId);
30+
}
31+
32+
// FOS TagHandler is making sure running "php app/console fos:httpcache:invalidate:tag <tag>" works
33+
$configuredFosTagHandlerServiceId = static::getTaggedService($container, 'ezplatform.http_cache.fos_tag_handler');
34+
if ($configuredFosTagHandlerServiceId === null) {
35+
// We default to xkey handler. This one should anyway work for most drivers as it just passes a purge request
36+
// on to the purge client
37+
$configuredFosTagHandlerServiceId = 'ezplatform.http_cache.tag_handler.xkey';
38+
}
39+
$fosTagHandlerDefinition = $container->getDefinition($configuredFosTagHandlerServiceId);
40+
$definition = $container->getDefinition('fos_http_cache.handler.tag_handler');
41+
$definition->setClass($fosTagHandlerDefinition->getClass());
42+
$definition->addArgument(new Reference('ezplatform.http_cache.purge_client'));
43+
}
44+
45+
public static function getTaggedService(ContainerBuilder $container, $tag)
46+
{
47+
$purgeType = $container->getParameter('ezpublish.http_cache.purge_type');
48+
$configuredTagHandlerServiceId = null;
49+
50+
$tagHandlerServiceIds = $container->findTaggedServiceIds($tag);
51+
foreach ($tagHandlerServiceIds as $tagHandlerServiceId => $attributes) {
52+
$currentPurgeTypeId = null;
53+
$currentTagHandlerServiceId = null;
54+
foreach ($attributes as $attribute) {
55+
if (array_key_exists('purge_type', $attribute)) {
56+
$currentPurgeTypeId = $attribute['purge_type'];
57+
}
58+
if ($currentPurgeTypeId !== null) {
59+
if ($purgeType === $attribute['purge_type']) {
60+
$configuredTagHandlerServiceId = $tagHandlerServiceId;
61+
break 2;
62+
}
63+
}
64+
}
65+
if ($currentPurgeTypeId === null) {
66+
throw new \InvalidArgumentException("Missing attribute 'purge_type' in tagged service '$tagHandlerServiceId'.");
67+
}
68+
}
69+
70+
return $configuredTagHandlerServiceId;
71+
}
72+
}

src/DependencyInjection/Compiler/KernelPass.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
99
use Symfony\Component\DependencyInjection\ContainerBuilder;
10-
use Symfony\Component\DependencyInjection\Reference;
11-
use EzSystems\PlatformHttpCacheBundle\Handler\TagHandler;
1210

1311
/**
1412
* Disables some of the http-cache services declared by the kernel so that
@@ -43,18 +41,6 @@ public function process(ContainerBuilder $container)
4341
return true;
4442
}));
4543
$container->getDefinition('cache_clearer')->setArguments($arguments);
46-
47-
if ($container->getAlias('ezpublish.http_cache.purge_client') == 'ezpublish.http_cache.purge_client.fos') {
48-
$container->setAlias('ezplatform.http_cache.purge_client', 'ezplatform.http_cache.purge_client.fos');
49-
}
50-
51-
$purgeType = $container->getParameter('purge_type');
52-
if ($purgeType === 'http') {
53-
// Injecting our own Tag handler
54-
$definition = $container->getDefinition('fos_http_cache.handler.tag_handler');
55-
$definition->setClass(TagHandler::class);
56-
$definition->addArgument(new Reference('ezplatform.http_cache.purge_client.fos'));
57-
}
5844
}
5945

6046
/**

src/DependencyInjection/Configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Configuration implements ConfigurationInterface
1818
public function getConfigTreeBuilder()
1919
{
2020
$treeBuilder = new TreeBuilder();
21-
$rootNode = $treeBuilder->root('ez_systems_platform_http_cache');
21+
$rootNode = $treeBuilder->root('ez_platform_http_cache');
2222

2323
// Here you should define the parameters that are allowed to
2424
// configure your bundle. See the documentation linked above for

src/DependencyInjection/EzSystemsPlatformHttpCacheExtension.php renamed to src/DependencyInjection/EzPlatformHttpCacheExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Symfony\Component\DependencyInjection\Loader;
1111
use Symfony\Component\Yaml\Yaml;
1212

13-
class EzSystemsPlatformHttpCacheExtension extends Extension implements PrependExtensionInterface
13+
class EzPlatformHttpCacheExtension extends Extension implements PrependExtensionInterface
1414
{
1515
public function load(array $configs, ContainerBuilder $container)
1616
{

src/EzSystemsPlatformHttpCacheBundle.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
use EzSystems\PlatformHttpCacheBundle\DependencyInjection\Compiler\ResponseTaggersPass;
66
use EzSystems\PlatformHttpCacheBundle\DependencyInjection\Compiler\KernelPass;
7+
use EzSystems\PlatformHttpCacheBundle\DependencyInjection\Compiler\DriverPass;
78
use Symfony\Component\DependencyInjection\ContainerBuilder;
89
use Symfony\Component\HttpKernel\Bundle\Bundle;
10+
use EzSystems\PlatformHttpCacheBundle\DependencyInjection\EzPlatformHttpCacheExtension;
911

1012
class EzSystemsPlatformHttpCacheBundle extends Bundle
1113
{
@@ -15,5 +17,11 @@ public function build(ContainerBuilder $container)
1517

1618
$container->addCompilerPass(new ResponseTaggersPass());
1719
$container->addCompilerPass(new KernelPass());
20+
$container->addCompilerPass(new DriverPass());
21+
}
22+
23+
public function getContainerExtension()
24+
{
25+
return new EzPlatformHttpCacheExtension();
1826
}
1927
}

src/PurgeClient/PurgeClientInterface.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@
1616
interface PurgeClientInterface extends KernelPurgeClientInterface
1717
{
1818
/**
19-
* Triggers the cache purge $locationIds.
19+
* Triggers the cache purge of $tags.
2020
*
21-
* It's up to the implementor to decide whether to purge $locationIds right away or to delegate to a separate process.
21+
* It's up to the implementor to decide whether to purge tags right away or to delegate to a separate process.
2222
*
23-
* @param array $locationIds Cache resource(s) to purge (e.g. array of URI to purge in a reverse proxy)
23+
* @param array $tags Array of tags to purge
2424
*/
25-
public function purge($locationIds);
25+
public function purge($tags);
26+
27+
/**
28+
* Purge the whole http cache.
29+
*/
30+
public function purgeAll();
2631
}
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@
1010

1111
/**
1212
* Purge client based on FOSHttpCacheBundle.
13-
*
14-
* Only support BAN requests on purpose, to be able to invalidate cache for a
15-
* collection of Location/Content objects.
1613
*/
17-
class FOSPurgeClient implements PurgeClientInterface
14+
class VarnishPurgeClient implements PurgeClientInterface
1815
{
1916
/**
2017
* @var \FOS\HttpCacheBundle\CacheManager

0 commit comments

Comments
 (0)