Skip to content

Commit 38a5e25

Browse files
committed
Use a decorator for the router
1 parent 7b72bd0 commit 38a5e25

File tree

8 files changed

+195
-175
lines changed

8 files changed

+195
-175
lines changed

src/DependencyInjection/CacheExtension.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,24 @@ public function load(array $configs, ContainerBuilder $container)
3434
$config = $this->processConfiguration(new Configuration(), $configs);
3535

3636
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
37-
$loader->load('services.yml');
3837

38+
// Make sure config values are in the parameters
3939
foreach (['router', 'session', 'doctrine'] as $section) {
4040
if ($config[$section]['enabled']) {
4141
$container->setParameter('cache.'.$section, $config[$section]);
4242
}
4343
}
4444

4545
if ($config['router']['enabled']) {
46-
$container->getDefinition('cache.router_listener')
46+
$loader->load('router.yml');
47+
$container->getDefinition('cache.router')
48+
->setDecoratedService('router', null, 10)
4749
->replaceArgument(0, new Reference($config['router']['service_id']))
48-
->replaceArgument(1, $config['router']['ttl']);
49-
} else {
50-
$container->removeDefinition('cache.router_listener');
50+
->replaceArgument(2, $config['router']['ttl']);
5151
}
5252

53-
if (!$container->getParameter('kernel.debug')) {
54-
$container->removeDefinition('data_collector.cache');
53+
if ($container->getParameter('kernel.debug')) {
54+
$loader->load('data-collector.yml');
5555
}
5656
}
5757

src/DependencyInjection/Compiler/DataCollectorCompilerPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class DataCollectorCompilerPass extends BaseCompilerPass
2727
*/
2828
protected function prepare()
2929
{
30-
$collectorDefinition = $this->container->getDefinition('data_collector.cache');
30+
$collectorDefinition = $this->container->getDefinition('cache.data_collector');
3131
$serviceIds = $this->container->findTaggedServiceIds('cache.provider');
3232

3333
foreach (array_keys($serviceIds) as $id) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
cache.data_collector:
3+
class: Cache\CacheBundle\DataCollector\CacheDataCollector
4+
tags:
5+
- { name: data_collector, template: 'CacheBundle:Collector:cache.html.twig', id: 'cache' }

src/Resources/config/router.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
3+
cache.router:
4+
class: Cache\CacheBundle\Routing\CachingRouter
5+
arguments: [~, "@cache.router.inner", ~]
6+
7+

src/Resources/config/services.yml

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/Routing/CachingRouter.php

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php
2+
3+
/*
4+
* This file is part of php-cache\cache-bundle package.
5+
*
6+
* (c) 2015-2015 Aaron Scherer <[email protected]>
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*/
11+
12+
namespace Cache\CacheBundle\Routing;
13+
14+
use Cache\Taggable\TaggablePoolInterface;
15+
use Psr\Cache\CacheItemPoolInterface;
16+
use Symfony\Component\Routing\RequestContext;
17+
use Symfony\Component\Routing\RouterInterface;
18+
19+
/**
20+
* @author Tobias Nyholm <[email protected]>
21+
*/
22+
class CachingRouter implements RouterInterface
23+
{
24+
/**
25+
* @type CacheItemPoolInterface
26+
*/
27+
private $cache;
28+
29+
/**
30+
* @type int
31+
*/
32+
private $ttl;
33+
34+
/**
35+
* @type RouterInterface
36+
*/
37+
private $router;
38+
39+
/**
40+
* @param CacheItemPoolInterface $cache
41+
* @param RouterInterface $router
42+
* @param $ttl
43+
*/
44+
public function __construct(CacheItemPoolInterface $cache, RouterInterface $router, $ttl)
45+
{
46+
$this->cache = $cache;
47+
$this->ttl = $ttl;
48+
$this->router = $router;
49+
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
public function match($pathinfo)
55+
{
56+
$cacheItem = $this->getCacheItemMatch($pathinfo);
57+
if ($cacheItem->isHit()) {
58+
return $cacheItem->get();
59+
}
60+
61+
// Get the result form the router
62+
$result = $this->router->match($pathinfo);
63+
64+
// Save the result
65+
$cacheItem->set($result)
66+
->expiresAfter($this->ttl);
67+
$this->cache->save($cacheItem);
68+
69+
return $result;
70+
}
71+
72+
/**
73+
* {@inheritdoc}
74+
*/
75+
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
76+
{
77+
$cacheItem = $this->getCacheItemGenerate($name, $parameters, $referenceType);
78+
if ($cacheItem->isHit()) {
79+
return $cacheItem->get();
80+
}
81+
82+
// Get the result form the router
83+
$result = $this->router->generate($name, $parameters, $referenceType);
84+
85+
// Save the result
86+
$cacheItem->set($result)
87+
->expiresAfter($this->ttl);
88+
$this->cache->save($cacheItem);
89+
90+
return $result;
91+
}
92+
93+
/**
94+
* {@inheritdoc}
95+
*/
96+
public function getRouteCollection()
97+
{
98+
return $this->router->getRouteCollection();
99+
}
100+
101+
/**
102+
* {@inheritdoc}
103+
*/
104+
public function setContext(RequestContext $context)
105+
{
106+
$this->router->setContext($context);
107+
}
108+
109+
/**
110+
* {@inheritdoc}
111+
*/
112+
public function getContext()
113+
{
114+
return $this->router->getContext();
115+
}
116+
117+
/**
118+
* Get a cache item for a call to match().
119+
*
120+
* @param string $pathinfo
121+
*
122+
* @return \Psr\Cache\CacheItemInterface
123+
*/
124+
private function getCacheItemMatch($pathinfo)
125+
{
126+
/** @type RequestContext $c */
127+
$c = $this->getContext();
128+
$key = sprintf('routing:%s:%s:%s:%s', $c->getMethod(), $c->getHost(), $pathinfo, $c->getQueryString());
129+
130+
return $this->getCacheItemFromKey($key, 'match');
131+
}
132+
133+
/**
134+
* Get a cache item for a call to generate().
135+
*
136+
* @param $name
137+
* @param array $parameters
138+
* @param $referenceType
139+
*
140+
* @return \Psr\Cache\CacheItemInterface
141+
*/
142+
private function getCacheItemGenerate($name, array $parameters, $referenceType)
143+
{
144+
sort($parameters);
145+
$key = sprintf('generate:%s:%s:%s', $name, json_encode($parameters), $referenceType ? 'true' : 'false');
146+
147+
return $this->getCacheItemFromKey($key, 'generate');
148+
}
149+
150+
/**
151+
* Passes through all unknown calls onto the router object.
152+
*/
153+
public function __call($method, $args)
154+
{
155+
return call_user_func_array([$this->router, $method], $args);
156+
}
157+
158+
/**
159+
* @param string $key
160+
* @param string $tag
161+
*
162+
* @return \Psr\Cache\CacheItemInterface
163+
*/
164+
private function getCacheItemFromKey($key, $tag)
165+
{
166+
if ($this->cache instanceof TaggablePoolInterface) {
167+
$item = $this->cache->getItem($key, ['routing', $tag]);
168+
} else {
169+
$item = $this->cache->getItem($key);
170+
}
171+
172+
return $item;
173+
}
174+
}

src/Routing/RouterListener.php

Lines changed: 0 additions & 146 deletions
This file was deleted.

0 commit comments

Comments
 (0)