Skip to content

Commit b56af0b

Browse files
committed
Agnostic routes loader.
1 parent 6dcc642 commit b56af0b

File tree

2 files changed

+163
-5
lines changed

2 files changed

+163
-5
lines changed

Services/Agnostic/RoutesLoader.php

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
use Symfony\Component\Config\Loader\DelegatingLoader;
77
use Symfony\Component\Config\Loader\LoaderResolver;
88
use Symfony\Component\Config\Resource\SelfCheckingResourceChecker;
9+
use Symfony\Component\Config\ResourceCheckerConfigCache;
910
use Symfony\Component\Config\ResourceCheckerConfigCacheFactory;
11+
use Symfony\Component\Filesystem\Filesystem;
1012
use Symfony\Component\HttpFoundation\Request;
1113
use Symfony\Component\Routing\Loader\PhpFileLoader;
1214
use Symfony\Component\Routing\Loader\XmlFileLoader;
@@ -30,6 +32,26 @@ class RoutesLoader
3032
*/
3133
private $router;
3234

35+
/**
36+
* @var ResourceCheckerConfigCacheFactory $cacheFactory
37+
*/
38+
private $cacheFactory;
39+
40+
/**
41+
* @var SelfCheckingResourceChecker $checker
42+
*/
43+
private $checker;
44+
45+
/**
46+
* @var ResourceCheckerConfigCache $cacheFreshChecker
47+
*/
48+
private $cacheFreshChecker;
49+
50+
/**
51+
* @var string|null $cacheDir Путь к кэшу. Null -> не кэшировать.
52+
*/
53+
private $cacheDir;
54+
3355
/**
3456
* AgnosticRouteLoader constructor.
3557
*
@@ -42,6 +64,8 @@ public function __construct(
4264
?string $cacheDir = null,
4365
bool $debug = true
4466
) {
67+
$this->cacheDir = $cacheDir;
68+
4569
$resolver = new LoaderResolver(
4670
[
4771
new YamlFileLoader(new FileLocator()),
@@ -55,8 +79,8 @@ public function __construct(
5579
$requestContext = new RequestContext();
5680
$request = Request::createFromGlobals();
5781

58-
$checker = new SelfCheckingResourceChecker();
59-
$cacheFactory = new ResourceCheckerConfigCacheFactory([$checker]);
82+
$this->checker = new SelfCheckingResourceChecker();
83+
$this->cacheFactory = new ResourceCheckerConfigCacheFactory([$this->checker]);
6084

6185
$this->router = new Router(
6286
$delegatingLoader,
@@ -73,7 +97,12 @@ public function __construct(
7397
);
7498

7599
if ($cacheDir) {
76-
$this->router->setConfigCacheFactory($cacheFactory);
100+
$this->cacheFreshChecker = new ResourceCheckerConfigCache(
101+
$this->cacheDir . '/url_generating_routes.php',
102+
[$this->checker]
103+
);
104+
105+
$this->warmUpCache();
77106
}
78107
}
79108

@@ -84,6 +113,61 @@ public function __construct(
84113
*/
85114
public function getRoutes() : RouteCollection
86115
{
116+
if ($this->cacheDir) {
117+
$compiledRoutesFile = $this->cacheDir . '/route_collection.json';
118+
119+
if ($this->cacheFreshChecker !== null
120+
&&
121+
$this->cacheFreshChecker->isFresh()
122+
&&
123+
@file_exists($compiledRoutesFile)) {
124+
$collection = file_get_contents($compiledRoutesFile);
125+
if ($collection) {
126+
$collection = unserialize($collection);
127+
return $collection;
128+
}
129+
}
130+
}
131+
87132
return $this->router->getRouteCollection();
88133
}
89-
}
134+
135+
/**
136+
* Удалить кэш.
137+
*
138+
* @return void
139+
*/
140+
public function purgeCache() : void
141+
{
142+
$filesystem = new Filesystem();
143+
144+
if (!$filesystem->exists($this->cacheDir)) {
145+
return;
146+
}
147+
148+
$filesystem->remove($this->cacheDir);
149+
}
150+
151+
/**
152+
* Создать (если надо), кэш.
153+
*
154+
* @return void
155+
*/
156+
private function warmUpCache() : void
157+
{
158+
$this->router->setConfigCacheFactory($this->cacheFactory);
159+
160+
if (!$this->cacheFreshChecker->isFresh()) {
161+
if (!@file_exists($this->cacheDir)) {
162+
@mkdir($this->cacheDir, 0777);
163+
}
164+
165+
file_put_contents(
166+
$this->cacheDir . '/route_collection.json',
167+
serialize($this->router->getRouteCollection())
168+
);
169+
}
170+
171+
$this->router->getGenerator(); // Трюк по созданию кэша.
172+
}
173+
}

Tests/Cases/AgnosticRoutesLoaderTest.php

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Prokl\WpSymfonyRouterBundle\Services\Agnostic\RoutesLoader;
66
use Prokl\TestingTools\Base\BaseTestCase;
7+
use Symfony\Component\Filesystem\Filesystem;
78

89
/**
910
* Class AgnosticRoutesLoaderTest
@@ -19,17 +20,48 @@ class AgnosticRoutesLoaderTest extends BaseTestCase
1920
*/
2021
protected $obTestObject;
2122

23+
/**
24+
* @var Filesystem $filesystem Файловая система.
25+
*/
26+
private $filesystem;
27+
28+
/**
29+
* @var string $cacheDir
30+
*/
31+
private $cacheDir = __DIR__ . '/../Fixture/cache';
32+
33+
/**
34+
* @var string $routesConfig
35+
*/
36+
private $routesConfig = __DIR__ . '/../Fixture/bitrix_routes.yaml';
37+
2238
/**
2339
* @inheritdoc
2440
*/
2541
protected function setUp(): void
2642
{
2743
parent::setUp();
44+
45+
$this->filesystem = new Filesystem();
46+
2847
$this->obTestObject = new RoutesLoader(
29-
__DIR__ . '/../Fixture/agnostic_routes.yaml',
48+
$this->routesConfig,
3049
null,
3150
true
3251
);
52+
53+
}
54+
55+
/**
56+
* @inheritdoc
57+
*/
58+
protected function tearDown(): void
59+
{
60+
parent::tearDown();
61+
62+
if ($this->filesystem->exists($this->cacheDir)) {
63+
$this->filesystem->remove($this->cacheDir);
64+
}
3365
}
3466

3567
/**
@@ -45,4 +77,46 @@ public function testGetRoutes() : void
4577

4678
$this->assertSame($routes->getPath(), '/foo/{param}/');
4779
}
80+
81+
/**
82+
* Caching.
83+
*
84+
* @return void
85+
*/
86+
public function testCaching() : void
87+
{
88+
$this->obTestObject = new RoutesLoader(
89+
$this->routesConfig,
90+
$this->cacheDir,
91+
true
92+
);
93+
94+
$this->assertFileExists($this->cacheDir . '/route_collection.json');
95+
$this->assertFileExists($this->cacheDir . '/url_generating_routes.php');
96+
$this->assertFileExists($this->cacheDir . '/url_generating_routes.php.meta');
97+
}
98+
99+
/**
100+
* purgeCache().
101+
*
102+
* @return void
103+
*/
104+
public function testpurgeCache(): void
105+
{
106+
$this->obTestObject = new RoutesLoader(
107+
$this->routesConfig,
108+
$this->cacheDir,
109+
true
110+
);
111+
112+
if (!$this->filesystem->exists($this->cacheDir)) {
113+
@mkdir($this->cacheDir);
114+
}
115+
116+
file_put_contents($this->cacheDir . '/test', 'OK');
117+
118+
$this->obTestObject->purgeCache();
119+
120+
$this->assertDirectoryDoesNotExist($this->cacheDir);
121+
}
48122
}

0 commit comments

Comments
 (0)