mirror of
https://github.com/getgrav/grav.git
synced 2026-05-07 13:26:26 +02:00
44
composer.lock
generated
44
composer.lock
generated
@@ -4846,16 +4846,16 @@
|
||||
},
|
||||
{
|
||||
"name": "codeception/stub",
|
||||
"version": "4.2.0",
|
||||
"version": "4.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/Stub.git",
|
||||
"reference": "19014cec368cefc0579499779c451551cd288557"
|
||||
"reference": "0c573cd5c62a828dadadc41bc56f8434860bb7bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/Stub/zipball/19014cec368cefc0579499779c451551cd288557",
|
||||
"reference": "19014cec368cefc0579499779c451551cd288557",
|
||||
"url": "https://api.github.com/repos/Codeception/Stub/zipball/0c573cd5c62a828dadadc41bc56f8434860bb7bb",
|
||||
"reference": "0c573cd5c62a828dadadc41bc56f8434860bb7bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4881,9 +4881,9 @@
|
||||
"description": "Flexible Stub wrapper for PHPUnit's Mock Builder",
|
||||
"support": {
|
||||
"issues": "https://github.com/Codeception/Stub/issues",
|
||||
"source": "https://github.com/Codeception/Stub/tree/4.2.0"
|
||||
"source": "https://github.com/Codeception/Stub/tree/4.2.1"
|
||||
},
|
||||
"time": "2025-08-01T08:15:29+00:00"
|
||||
"time": "2025-12-05T13:37:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "getgrav/markdowndocs",
|
||||
@@ -5451,11 +5451,11 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "2.1.32",
|
||||
"version": "2.1.33",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227",
|
||||
"reference": "e126cad1e30a99b137b8ed75a85a676450ebb227",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f",
|
||||
"reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5500,7 +5500,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-11T15:18:17+00:00"
|
||||
"time": "2025-12-05T10:24:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-deprecation-rules",
|
||||
@@ -5886,16 +5886,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "11.5.44",
|
||||
"version": "11.5.45",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "c346885c95423eda3f65d85a194aaa24873cda82"
|
||||
"reference": "faf5fff4fb9beb290affa53f812b05380819c51a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c346885c95423eda3f65d85a194aaa24873cda82",
|
||||
"reference": "c346885c95423eda3f65d85a194aaa24873cda82",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/faf5fff4fb9beb290affa53f812b05380819c51a",
|
||||
"reference": "faf5fff4fb9beb290affa53f812b05380819c51a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5967,7 +5967,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.44"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.45"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5991,7 +5991,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-13T07:17:35+00:00"
|
||||
"time": "2025-12-01T07:38:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
@@ -6126,16 +6126,16 @@
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"version": "2.2.9",
|
||||
"version": "2.2.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rectorphp/rector.git",
|
||||
"reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05"
|
||||
"reference": "7bd21a40b0332b93d4bfee284093d7400696902d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/0b8e49ec234877b83244d2ecd0df7a4c16471f05",
|
||||
"reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/7bd21a40b0332b93d4bfee284093d7400696902d",
|
||||
"reference": "7bd21a40b0332b93d4bfee284093d7400696902d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6174,7 +6174,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/rectorphp/rector/issues",
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.2.9"
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.2.11"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6182,7 +6182,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-28T14:21:22+00:00"
|
||||
"time": "2025-12-02T11:23:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
||||
@@ -28,6 +28,7 @@ trait CompiledFile
|
||||
/**
|
||||
* Get/set parsed file contents.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @return array
|
||||
*/
|
||||
public function content(mixed $var = null)
|
||||
@@ -36,19 +37,47 @@ trait CompiledFile
|
||||
$filename = $this->filename;
|
||||
// If nothing has been loaded, attempt to get pre-compiled version of the file first.
|
||||
if ($var === null && $this->raw === null && $this->content === null) {
|
||||
$key = md5((string) $filename);
|
||||
$key = md5($filename);
|
||||
$file = PhpFile::instance(CACHE_DIR . "compiled/files/{$key}{$this->extension}.php");
|
||||
$cacheFilename = $file->filename();
|
||||
|
||||
$modified = $this->modified();
|
||||
if (!$modified) {
|
||||
// Improved support for opcache
|
||||
// Do not check timestamp if opcache.validate_timestamps = 0
|
||||
// https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.validate-timestamps
|
||||
$modified = false;
|
||||
|
||||
if (!filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) ||
|
||||
filter_var(ini_get('opcache.validate_timestamps'), \FILTER_VALIDATE_BOOLEAN)) {
|
||||
$modified = $this->modified();
|
||||
}
|
||||
|
||||
// Improved support for opcache
|
||||
//
|
||||
// If not modified and file exists in opcache
|
||||
// This requires opcache.enable_file_override = 1
|
||||
// https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.enable-file-override
|
||||
if (!$modified && is_file($cacheFilename)) {
|
||||
try {
|
||||
return $this->decode($this->raw());
|
||||
// Include the file directly to trigger loading from opcache
|
||||
$var = (array) include $cacheFilename;
|
||||
|
||||
if (is_array($var) && isset($var['data'])) {
|
||||
$var = $var['data'];
|
||||
} else {
|
||||
$var = null;
|
||||
}
|
||||
|
||||
if (!is_array($var)) {
|
||||
$var = $this->decode($this->raw());
|
||||
}
|
||||
|
||||
return $var;
|
||||
} catch (Throwable) {
|
||||
// If the compiled file is broken, we can safely ignore the error and continue.
|
||||
}
|
||||
}
|
||||
|
||||
$class = $this::class;
|
||||
$class = get_class($this);
|
||||
|
||||
$size = filesize($filename);
|
||||
$cache = $file->exists() ? $file->content() : null;
|
||||
@@ -88,11 +117,9 @@ trait CompiledFile
|
||||
|
||||
// Compile cached file into bytecode cache
|
||||
if (function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
|
||||
$lockName = $file->filename();
|
||||
|
||||
// Silence error if function exists, but is restricted.
|
||||
@opcache_invalidate($lockName, true);
|
||||
@opcache_compile_file($lockName);
|
||||
@opcache_invalidate($cacheFilename, true);
|
||||
@opcache_compile_file($cacheFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +161,7 @@ trait CompiledFile
|
||||
if ($locked) {
|
||||
$modified = $this->modified();
|
||||
$filename = $this->filename;
|
||||
$class = $this::class;
|
||||
$class = get_class($this);
|
||||
$size = filesize($filename);
|
||||
|
||||
// windows doesn't play nicely with this as it can't read when locked
|
||||
@@ -158,10 +185,10 @@ trait CompiledFile
|
||||
|
||||
// Compile cached file into bytecode cache
|
||||
if (function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
|
||||
$lockName = $file->filename();
|
||||
$cacheFilename = $file->filename();
|
||||
// Silence error if function exists, but is restricted.
|
||||
@opcache_invalidate($lockName, true);
|
||||
@opcache_compile_file($lockName);
|
||||
@opcache_invalidate($cacheFilename, true);
|
||||
@opcache_compile_file($cacheFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use Grav\Common\Language\Language;
|
||||
use Grav\Framework\Mime\MimeTypes;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
use RocketTheme\Toolbox\File\PhpFile;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
@@ -85,15 +86,24 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $container['locator'];
|
||||
|
||||
$cache = $locator->findResource('cache://compiled/blueprints', true, true);
|
||||
$cache = $locator->findResource('cache://compiled/blueprints', true, true);
|
||||
|
||||
$files = [];
|
||||
$paths = $locator->findResources('blueprints://config');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
$paths = $locator->findResources('plugins://');
|
||||
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'blueprints');
|
||||
$paths = $locator->findResources('themes://');
|
||||
$files += (new ConfigFileFinder)->setBase('themes')->locateInFolders($paths, 'blueprints');
|
||||
// Try to load cached file list to avoid filesystem scanning on every request
|
||||
$files = static::loadCachedFileList($locator, $cache, 'blueprints', $setup->environment);
|
||||
|
||||
if ($files === null) {
|
||||
// Cache miss - scan filesystem for blueprint files
|
||||
$files = [];
|
||||
$paths = $locator->findResources('blueprints://config');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
$paths = $locator->findResources('plugins://');
|
||||
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'blueprints');
|
||||
$paths = $locator->findResources('themes://');
|
||||
$files += (new ConfigFileFinder)->setBase('themes')->locateInFolders($paths, 'blueprints');
|
||||
|
||||
// Save file list cache for next request
|
||||
static::saveCachedFileList($locator, $cache, 'blueprints', $setup->environment, $files);
|
||||
}
|
||||
|
||||
$blueprints = new CompiledBlueprints($cache, $files, GRAV_ROOT);
|
||||
|
||||
@@ -112,15 +122,24 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $container['locator'];
|
||||
|
||||
$cache = $locator->findResource('cache://compiled/config', true, true);
|
||||
$cache = $locator->findResource('cache://compiled/config', true, true);
|
||||
|
||||
$files = [];
|
||||
$paths = $locator->findResources('config://');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
$paths = $locator->findResources('plugins://');
|
||||
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths);
|
||||
$paths = $locator->findResources('themes://');
|
||||
$files += (new ConfigFileFinder)->setBase('themes')->locateInFolders($paths);
|
||||
// Try to load cached file list to avoid filesystem scanning on every request
|
||||
$files = static::loadCachedFileList($locator, $cache, 'config', $setup->environment);
|
||||
|
||||
if ($files === null) {
|
||||
// Cache miss - scan filesystem for config files
|
||||
$files = [];
|
||||
$paths = $locator->findResources('config://');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
$paths = $locator->findResources('plugins://');
|
||||
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths);
|
||||
$paths = $locator->findResources('themes://');
|
||||
$files += (new ConfigFileFinder)->setBase('themes')->locateInFolders($paths);
|
||||
|
||||
// Save file list cache for next request
|
||||
static::saveCachedFileList($locator, $cache, 'config', $setup->environment, $files);
|
||||
}
|
||||
|
||||
$compiled = new CompiledConfig($cache, $files, GRAV_ROOT);
|
||||
$compiled->setBlueprints(fn() => $container['blueprints']);
|
||||
@@ -151,12 +170,22 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
|
||||
// Process languages only if enabled in configuration.
|
||||
if ($config->get('system.languages.translations', true)) {
|
||||
$paths = $locator->findResources('languages://');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
$paths = $locator->findResources('plugins://');
|
||||
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'languages');
|
||||
$paths = static::pluginFolderPaths($paths, 'languages');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
// Try to load cached file list to avoid filesystem scanning on every request
|
||||
$files = static::loadCachedFileList($locator, $cache, 'languages', $setup->environment);
|
||||
|
||||
if ($files === null) {
|
||||
// Cache miss - scan filesystem for language files
|
||||
$files = [];
|
||||
$paths = $locator->findResources('languages://');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
$paths = $locator->findResources('plugins://');
|
||||
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'languages');
|
||||
$paths = static::pluginFolderPaths($paths, 'languages');
|
||||
$files += (new ConfigFileFinder)->locateFiles($paths);
|
||||
|
||||
// Save file list cache for next request
|
||||
static::saveCachedFileList($locator, $cache, 'languages', $setup->environment, $files);
|
||||
}
|
||||
}
|
||||
|
||||
$languages = new CompiledLanguages($cache, $files, GRAV_ROOT);
|
||||
@@ -195,4 +224,130 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load cached file list if still valid (based on directory mtimes).
|
||||
*
|
||||
* @param UniformResourceLocator $locator
|
||||
* @param string $cacheDir
|
||||
* @param string $type
|
||||
* @param string $environment
|
||||
* @return array|null Returns cached files array or null if cache is invalid
|
||||
*/
|
||||
protected static function loadCachedFileList(UniformResourceLocator $locator, string $cacheDir, string $type, string $environment): ?array
|
||||
{
|
||||
$cacheFile = "{$cacheDir}/filelist-{$type}-{$environment}.php";
|
||||
|
||||
if (!file_exists($cacheFile)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cache = include $cacheFile;
|
||||
|
||||
if (!is_array($cache) || !isset($cache['directories'], $cache['files'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate cache by checking directory mtimes
|
||||
foreach ($cache['directories'] as $dir => $mtime) {
|
||||
// Check if directory still exists and mtime hasn't changed
|
||||
$currentMtime = @filemtime($dir);
|
||||
if ($currentMtime === false || $currentMtime !== $mtime) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $cache['files'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Save file list to cache with directory mtimes for validation.
|
||||
*
|
||||
* @param UniformResourceLocator $locator
|
||||
* @param string $cacheDir
|
||||
* @param string $type
|
||||
* @param string $environment
|
||||
* @param array $files
|
||||
* @return void
|
||||
*/
|
||||
protected static function saveCachedFileList(UniformResourceLocator $locator, string $cacheDir, string $type, string $environment, array $files): void
|
||||
{
|
||||
// Collect all directories that were scanned based on type
|
||||
$directories = [];
|
||||
|
||||
// Type-specific base directories
|
||||
if ($type === 'config') {
|
||||
$basePaths = $locator->findResources('config://');
|
||||
foreach ($basePaths as $path) {
|
||||
if (is_dir($path)) {
|
||||
$directories[$path] = filemtime($path);
|
||||
}
|
||||
}
|
||||
} elseif ($type === 'blueprints') {
|
||||
$basePaths = $locator->findResources('blueprints://config');
|
||||
foreach ($basePaths as $path) {
|
||||
if (is_dir($path)) {
|
||||
$directories[$path] = filemtime($path);
|
||||
}
|
||||
}
|
||||
} elseif ($type === 'languages') {
|
||||
$basePaths = $locator->findResources('languages://');
|
||||
foreach ($basePaths as $path) {
|
||||
if (is_dir($path)) {
|
||||
$directories[$path] = filemtime($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get plugin directories (used by all types)
|
||||
$pluginPaths = $locator->findResources('plugins://');
|
||||
foreach ($pluginPaths as $path) {
|
||||
if (is_dir($path)) {
|
||||
$directories[$path] = filemtime($path);
|
||||
// Also track individual plugin directories for granular invalidation
|
||||
$iterator = new DirectoryIterator($path);
|
||||
foreach ($iterator as $dir) {
|
||||
if ($dir->isDir() && !$dir->isDot()) {
|
||||
$directories[$dir->getPathname()] = $dir->getMTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get theme directories (used by config and blueprints)
|
||||
if ($type !== 'languages') {
|
||||
$themePaths = $locator->findResources('themes://');
|
||||
foreach ($themePaths as $path) {
|
||||
if (is_dir($path)) {
|
||||
$directories[$path] = filemtime($path);
|
||||
// Also track individual theme directories
|
||||
$iterator = new DirectoryIterator($path);
|
||||
foreach ($iterator as $dir) {
|
||||
if ($dir->isDir() && !$dir->isDot()) {
|
||||
$directories[$dir->getPathname()] = $dir->getMTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cache = [
|
||||
'@class' => static::class,
|
||||
'type' => $type,
|
||||
'environment' => $environment,
|
||||
'timestamp' => time(),
|
||||
'directories' => $directories,
|
||||
'files' => $files,
|
||||
];
|
||||
|
||||
// Ensure cache directory exists
|
||||
if (!is_dir($cacheDir)) {
|
||||
mkdir($cacheDir, 0775, true);
|
||||
}
|
||||
|
||||
$cacheFile = "{$cacheDir}/filelist-{$type}-{$environment}.php";
|
||||
$file = PhpFile::instance($cacheFile);
|
||||
$file->save($cache);
|
||||
$file->free();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user