packageStatesFile = $packageStatesFile; $this->coreCache = $coreCache; } public function fetch(): PackageCacheEntry { $packageData = $this->coreCache->require(self::CACHE_IDENTIFIER_PREFIX . $this->getIdentifier()); if ($packageData === false || !is_array($packageData)) { throw new PackageManagerCacheUnavailableException('The package state cache could not be loaded.', 1714031925); } return PackageCacheEntry::fromCache($packageData ?: []); } public function store(PackageCacheEntry $cacheEntry): void { $cacheIdentifier = $this->getIdentifier(); $this->coreCache->set( self::CACHE_IDENTIFIER_PREFIX . $cacheIdentifier, 'return ' . PHP_EOL . $cacheEntry->withIdentifier($cacheIdentifier)->serialize() . ';' ); } public function invalidate(): void { if (!isset($this->cacheIdentifier)) { return; } $this->coreCache->remove($this->cacheIdentifier); $this->cacheIdentifier = null; clearstatcache(); } /** * Combines mtime and filesize to detect PackageStates.php changes. * mtime alone has 1-second resolution: a write within the same second * produces an identical identifier, causing PackageActivationService * to load a stale DI container missing the just-activated extension. * * @throws PackageManagerCacheUnavailableException */ public function getIdentifier(): string { if (!isset($this->cacheIdentifier)) { $stat = @stat($this->packageStatesFile); if ($stat === false) { throw new PackageManagerCacheUnavailableException('The package state cache could not be loaded.', 1629817141); } $this->cacheIdentifier = md5((string)(new Typo3Version()) . $this->packageStatesFile . $stat['mtime'] . $stat['size']); } return $this->cacheIdentifier; } }