Skip to content

Commit 96ca0b3

Browse files
[Config] Generate a meta file in JSON format for resource tracking
1 parent cf6d4f3 commit 96ca0b3

5 files changed

+76
-7
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
---
66

77
* Add `#[WhenNot]` attribute to prevent service from being registered in a specific environment
8+
* Generate a meta file in JSON format for resource tracking
9+
* Add `SkippingResourceChecker`
810

911
7.1
1012
---

ConfigCache.php

+12-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
namespace Symfony\Component\Config;
1313

14+
use Symfony\Component\Config\Resource\ResourceInterface;
1415
use Symfony\Component\Config\Resource\SelfCheckingResourceChecker;
16+
use Symfony\Component\Config\Resource\SkippingResourceChecker;
1517

1618
/**
1719
* ConfigCache caches arbitrary content in files on disk.
@@ -26,18 +28,23 @@
2628
class ConfigCache extends ResourceCheckerConfigCache
2729
{
2830
/**
29-
* @param string $file The absolute cache path
30-
* @param bool $debug Whether debugging is enabled or not
31-
* @param string|null $metaFile The absolute path to the meta file
31+
* @param string $file The absolute cache path
32+
* @param bool $debug Whether debugging is enabled or not
33+
* @param string|null $metaFile The absolute path to the meta file
34+
* @param class-string<ResourceInterface>[]|null $skippedResourceTypes
3235
*/
3336
public function __construct(
3437
string $file,
3538
private bool $debug,
3639
?string $metaFile = null,
40+
array|null $skippedResourceTypes = null,
3741
) {
3842
$checkers = [];
39-
if (true === $this->debug) {
40-
$checkers = [new SelfCheckingResourceChecker()];
43+
if ($this->debug) {
44+
if (null !== $skippedResourceTypes) {
45+
$checkers[] = new SkippingResourceChecker($skippedResourceTypes);
46+
}
47+
$checkers[] = new SelfCheckingResourceChecker();
4148
}
4249

4350
parent::__construct($file, $checkers, $metaFile);

Resource/SkippingResourceChecker.php

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Config\Resource;
13+
14+
use Symfony\Component\Config\ResourceCheckerInterface;
15+
16+
class SkippingResourceChecker implements ResourceCheckerInterface
17+
{
18+
private array $skippedResourceTypes;
19+
20+
/**
21+
* @param class-string<ResourceInterface>[] $skippedResourceTypes
22+
*/
23+
public function __construct(array $skippedResourceTypes = [])
24+
{
25+
$this->skippedResourceTypes = array_flip($skippedResourceTypes);
26+
}
27+
28+
public function supports(ResourceInterface $metadata): bool
29+
{
30+
return !$this->skippedResourceTypes || isset($this->skippedResourceTypes[$metadata::class]);
31+
}
32+
33+
public function isFresh(ResourceInterface $resource, int $timestamp): bool
34+
{
35+
return true;
36+
}
37+
}

ResourceCheckerConfigCache.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,26 @@ public function write(string $content, ?array $metadata = null): void
118118
}
119119

120120
if (null !== $metadata) {
121-
$filesystem->dumpFile($this->metaFile, serialize($metadata));
121+
$filesystem->dumpFile($this->metaFile, $ser = serialize($metadata));
122122
try {
123123
$filesystem->chmod($this->metaFile, $mode, $umask);
124124
} catch (IOException) {
125125
// discard chmod failure (some filesystem may not support it)
126126
}
127+
128+
$ser = preg_replace_callback('/;O:(\d+):"/', static fn ($m) => ';O:'.(9 + $m[1]).':"Tracking\\', $ser);
129+
$ser = preg_replace_callback('/s:(\d+):"\0[^\0]++\0/', static fn ($m) => 's:'.($m[1] - \strlen($m[0]) + 6).':"', $ser);
130+
$ser = unserialize($ser);
131+
$ser = @json_encode($ser) ?: [];
132+
$ser = str_replace('"__PHP_Incomplete_Class_Name":"Tracking\\\\', '"@type":"', $ser);
133+
$ser = \sprintf('{"resources":%s}', $ser);
134+
135+
$filesystem->dumpFile($this->metaFile.'.json', $ser);
136+
try {
137+
$filesystem->chmod($this->metaFile.'.json', $mode, $umask);
138+
} catch (IOException) {
139+
// discard chmod failure (some filesystem may not support it)
140+
}
127141
}
128142

129143
if (\function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL)) {

Tests/ResourceCheckerConfigCacheTest.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected function setUp(): void
3030

3131
protected function tearDown(): void
3232
{
33-
$files = [$this->cacheFile, "{$this->cacheFile}.meta", $this->metaFile];
33+
$files = [$this->cacheFile, $this->cacheFile.'.meta', $this->cacheFile.'.meta.json', $this->metaFile, $this->metaFile.'.json'];
3434

3535
foreach ($files as $file) {
3636
if (file_exists($file)) {
@@ -160,5 +160,14 @@ public function testCacheWithCustomMetaFile()
160160
$cache->write('foo', [new FileResource(__FILE__)]);
161161

162162
$this->assertStringNotEqualsFile($this->metaFile, '');
163+
164+
$this->assertStringEqualsFile($this->metaFile.'.json', json_encode([
165+
'resources' => [
166+
[
167+
'@type' => FileResource::class,
168+
'resource' => __FILE__,
169+
],
170+
],
171+
]));
163172
}
164173
}

0 commit comments

Comments
 (0)