Skip to content

Commit aea9081

Browse files
committed
Дамп контейнера пересобирается при изменении /bitrix/.settings.php
1 parent 9da561c commit aea9081

File tree

3 files changed

+172
-5
lines changed

3 files changed

+172
-5
lines changed

lib/DI/CompilerContainer.php

Lines changed: 110 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Proklung\Redis\DI;
44

55
use InvalidArgumentException;
6+
use Proklung\Redis\DI\Resource\FileBitrixSettingsResource;
67
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
78
use Symfony\Component\Config\ConfigCache;
89
use Symfony\Component\DependencyInjection\Container;
@@ -16,9 +17,82 @@
1617
* @package Proklung\Redis\DI
1718
*
1819
* @since 14.07.2021
20+
*
21+
* @internal Файлы .meta -> .gitignore.
1922
*/
2023
class CompilerContainer
2124
{
25+
/**
26+
* @var string $projectRoot DOCUMENT_ROOT.
27+
*/
28+
private $projectRoot;
29+
30+
/**
31+
* CompilerContainer constructor.
32+
*
33+
* @param string $projectRoot DOCUMENT_ROOT.
34+
*/
35+
public function __construct(string $projectRoot)
36+
{
37+
$this->projectRoot = $projectRoot;
38+
}
39+
40+
/**
41+
* Свежий основной конфиг Битрикса или нет.
42+
*
43+
* @param string $configFile Конфигурационный файл.
44+
*
45+
* @return boolean
46+
*/
47+
public function isConfigFresh(string $configFile = '/bitrix/.settings.php') : bool
48+
{
49+
$meta = $configFile . '.meta';
50+
51+
// Не существует мета-файл = конфиг потенциально не свежий.
52+
if (!@file_exists($this->projectRoot . $meta)) {
53+
return false;
54+
}
55+
56+
$content = file_get_contents($this->projectRoot . $meta);
57+
58+
/** @var FileBitrixSettingsResource $checker */
59+
$checker = unserialize($content);
60+
// Кривизна в мета-файле = конфиг потенциально не свежий.
61+
if ($checker === false) {
62+
return false;
63+
}
64+
65+
$timestamp = filemtime($this->projectRoot . $configFile);
66+
67+
return $checker->isFresh($timestamp);
68+
}
69+
70+
/**
71+
* Записать мета-информацию на основной конфиг битрикса.
72+
*
73+
* @param string $configFile Конфиг.
74+
*
75+
* @return void
76+
*/
77+
public function createConfigMeta(string $configFile = '/bitrix/.settings.php') : void
78+
{
79+
$checker = new FileBitrixSettingsResource($this->projectRoot . $configFile);
80+
81+
@file_put_contents($this->projectRoot . $configFile . '.meta', serialize($checker));
82+
}
83+
84+
/**
85+
* Удалить дамп контейнера.
86+
*
87+
* @param string $cacheDirectory Директория, где лежит дамп контейнера.
88+
*
89+
* @return void
90+
*/
91+
public function deleteDumpContainer(string $cacheDirectory) : void
92+
{
93+
$this->rrmdir($cacheDirectory);
94+
}
95+
2296
/**
2397
* @param ContainerBuilder $container Контейнер.
2498
* @param string $cacheDirectory Директория кэша.
@@ -46,7 +120,15 @@ public function cacheContainer(
46120
// Класс скомпилированного контейнера.
47121
$classCompiledContainerName = $this->getContainerClass($environment, $debug) . md5($filename);
48122

49-
if (!$containerConfigCache->isFresh()) {
123+
$hasContainerFresh = $containerConfigCache->isFresh();
124+
125+
// Если /bitrix/.settings.php изменился - пересобрать дамп контейнера.
126+
if (!$this->isConfigFresh('/bitrix/.settings.php')) {
127+
$this->createConfigMeta('/bitrix/.settings.php');
128+
$hasContainerFresh = false;
129+
}
130+
131+
if (!$hasContainerFresh) {
50132
// Загрузить, инициализировать и скомпилировать контейнер.
51133
$newContainer = $initializerContainer();
52134

@@ -99,7 +181,7 @@ public function cacheContainer(
99181
/**
100182
* Если надо создать директорию для компилированного контейнера.
101183
*
102-
* @param string $dir
184+
* @param string $dir Директория.
103185
*
104186
* @return void
105187
*/
@@ -115,8 +197,8 @@ private function createCacheDirectory(string $dir) : void
115197
/**
116198
* Gets the container class.
117199
*
118-
* @param string $env
119-
* @param boolean $debug
200+
* @param string $env Окружение.
201+
* @param boolean $debug Режим отладки.
120202
*
121203
* @return string The container class.
122204
*/
@@ -196,4 +278,28 @@ private function dumpContainer(ConfigCache $cache, ContainerBuilder $container,
196278
$container->getResources()
197279
);
198280
}
281+
282+
/**
283+
* Рекурсивно удалить папки и файлы в них.
284+
*
285+
* @param string $dir Директория.
286+
*
287+
* @return void
288+
*/
289+
private function rrmdir(string $dir) : void
290+
{
291+
if (is_dir($dir)) {
292+
$objects = scandir($dir);
293+
foreach ($objects as $object) {
294+
if ($object !== '.' && $object !== '..') {
295+
if (is_dir($dir.DIRECTORY_SEPARATOR.$object) && !is_link($dir.'/'.$object)) {
296+
$this->rrmdir($dir.DIRECTORY_SEPARATOR.$object);
297+
} else {
298+
unlink($dir.DIRECTORY_SEPARATOR.$object);
299+
}
300+
}
301+
}
302+
rmdir($dir);
303+
}
304+
}
199305
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Proklung\Redis\DI\Resource;
4+
5+
use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
6+
7+
/**
8+
* @final
9+
*/
10+
final class FileBitrixSettingsResource implements SelfCheckingResourceInterface
11+
{
12+
/**
13+
* @var string|false
14+
*/
15+
private $resource;
16+
17+
/**
18+
* @var integer $timestamp
19+
*/
20+
private $timestamp;
21+
22+
/**
23+
* @param string $resource The file path to the resource.
24+
*
25+
* @throws \InvalidArgumentException
26+
*/
27+
public function __construct(string $resource)
28+
{
29+
$this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
30+
31+
if (false === $this->resource) {
32+
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
33+
}
34+
35+
$this->timestamp = (int)filemtime($this->resource);
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function __toString(): string
42+
{
43+
return $this->resource;
44+
}
45+
46+
/**
47+
* @return string The canonicalized, absolute path to the resource.
48+
*/
49+
public function getResource(): string
50+
{
51+
return $this->resource;
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function isFresh(int $timestamp): bool
58+
{
59+
return false !== @filemtime($this->resource) && $this->timestamp >= $timestamp;
60+
}
61+
}

lib/DI/services.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public function load() : void
130130
}
131131

132132
$this->createContainer();
133-
$compilerContainer = new CompilerContainer();
133+
$compilerContainer = new CompilerContainer($_SERVER['DOCUMENT_ROOT']);
134134

135135
// Кэшировать контейнер?
136136
if (!in_array($this->environment, $this->parameters['compile_container_envs'], true)) {

0 commit comments

Comments
 (0)