Dep: update

주로 PHAN
This commit is contained in:
2021-08-06 22:39:09 +09:00
parent 5310c2e7f6
commit b306601c72
1098 changed files with 92137 additions and 33228 deletions
@@ -39,12 +39,12 @@ final class CacheExtension extends Nette\DI\CompilerExtension
if (extension_loaded('pdo_sqlite')) {
$builder->addDefinition($this->prefix('journal'))
->setType(Nette\Caching\Storages\IJournal::class)
->setType(Nette\Caching\Storages\Journal::class)
->setFactory(Nette\Caching\Storages\SQLiteJournal::class, [$dir . '/journal.s3db']);
}
$builder->addDefinition($this->prefix('storage'))
->setType(Nette\Caching\IStorage::class)
->setType(Nette\Caching\Storage::class)
->setFactory(Nette\Caching\Storages\FileStorage::class, [$dir]);
if ($this->name === 'cache') {
+41 -14
View File
@@ -59,8 +59,10 @@ final class CacheMacro implements Latte\IMacro
$this->used = true;
$node->empty = false;
$node->openingCode = Latte\PhpWriter::using($node)
->write('<?php if (Nette\Bridges\CacheLatte\CacheMacro::createCache($this->global->cacheStorage, %var, $this->global->cacheStack, %node.array?)) { ?>',
Nette\Utils\Random::generate()
->write(
'<?php if (Nette\Bridges\CacheLatte\CacheMacro::createCache($this->global->cacheStorage, %var, $this->global->cacheStack, %node.array?)) /* line %var */ try { ?>',
Nette\Utils\Random::generate(),
$node->startLine
);
}
@@ -72,7 +74,14 @@ final class CacheMacro implements Latte\IMacro
public function nodeClosed(Latte\MacroNode $node)
{
$node->closingCode = Latte\PhpWriter::using($node)
->write('<?php Nette\Bridges\CacheLatte\CacheMacro::endCache($this->global->cacheStack, %node.array?); } ?>');
->write(
'<?php
Nette\Bridges\CacheLatte\CacheMacro::endCache($this->global->cacheStack, %node.array?) /* line %var */;
} catch (\Throwable $ʟ_e) {
Nette\Bridges\CacheLatte\CacheMacro::rollback($this->global->cacheStack); throw $ʟ_e;
} ?>',
$node->startLine
);
}
@@ -94,8 +103,12 @@ final class CacheMacro implements Latte\IMacro
* Starts the output cache. Returns Nette\Caching\OutputHelper object if buffering was started.
* @return Nette\Caching\OutputHelper|\stdClass
*/
public static function createCache(Nette\Caching\IStorage $cacheStorage, string $key, ?array &$parents, array $args = null)
{
public static function createCache(
Nette\Caching\Storage $cacheStorage,
string $key,
?array &$parents,
array $args = null
) {
if ($args) {
if (array_key_exists('if', $args) && !$args['if']) {
return $parents[] = new \stdClass;
@@ -119,18 +132,32 @@ final class CacheMacro implements Latte\IMacro
* @param Nette\Caching\OutputHelper[] $parents
*/
public static function endCache(array &$parents, array $args = null): void
{
$helper = array_pop($parents);
if (!$helper instanceof Nette\Caching\OutputHelper) {
return;
}
if (isset($args['dependencies'])) {
$args += $args['dependencies']();
}
if (isset($args['expire'])) {
$args['expiration'] = $args['expire']; // back compatibility
}
$helper->dependencies[Cache::TAGS] = $args['tags'] ?? null;
$helper->dependencies[Cache::EXPIRATION] = $args['expiration'] ?? '+ 7 days';
$helper->end();
}
/**
* @param Nette\Caching\OutputHelper[] $parents
*/
public static function rollback(array &$parents): void
{
$helper = array_pop($parents);
if ($helper instanceof Nette\Caching\OutputHelper) {
if (isset($args['dependencies'])) {
$args += $args['dependencies']();
}
if (isset($args['expire'])) {
$args['expiration'] = $args['expire']; // back compatibility
}
$helper->dependencies[Cache::TAGS] = $args['tags'] ?? null;
$helper->dependencies[Cache::EXPIRATION] = $args['expiration'] ?? '+ 7 days';
$helper->end();
$helper->rollback();
}
}
}
@@ -13,12 +13,14 @@ namespace Nette\Caching;
/**
* Cache storage with a bulk read support.
*/
interface IBulkReader
interface BulkReader
{
/**
* Reads from cache in bulk.
* @return array key => value pairs, missing items are omitted
*/
function bulkRead(array $keys): array;
}
class_exists(IBulkReader::class);
+50 -36
View File
@@ -36,14 +36,14 @@ class Cache
/** @internal */
public const NAMESPACE_SEPARATOR = "\x00";
/** @var IStorage */
/** @var Storage */
private $storage;
/** @var string */
private $namespace;
public function __construct(IStorage $storage, string $namespace = null)
public function __construct(Storage $storage, string $namespace = null)
{
$this->storage = $storage;
$this->namespace = $namespace . self::NAMESPACE_SEPARATOR;
@@ -53,7 +53,7 @@ class Cache
/**
* Returns cache storage.
*/
final public function getStorage(): IStorage
final public function getStorage(): Storage
{
return $this->storage;
}
@@ -74,8 +74,7 @@ class Cache
*/
public function derive(string $namespace)
{
$derived = new static($this->storage, $this->namespace . $namespace);
return $derived;
return new static($this->storage, $this->namespace . $namespace);
}
@@ -84,13 +83,19 @@ class Cache
* @param mixed $key
* @return mixed
*/
public function load($key, callable $fallback = null)
public function load($key, callable $generator = null)
{
$data = $this->storage->read($this->generateKey($key));
if ($data === null && $fallback) {
return $this->save($key, function (&$dependencies) use ($fallback) {
return $fallback(...[&$dependencies]);
});
$storageKey = $this->generateKey($key);
$data = $this->storage->read($storageKey);
if ($data === null && $generator) {
$this->storage->lock($storageKey);
try {
$data = $generator(...[&$dependencies]);
} catch (\Throwable $e) {
$this->storage->remove($storageKey);
throw $e;
}
$this->save($key, $data, $dependencies);
}
return $data;
}
@@ -99,7 +104,7 @@ class Cache
/**
* Reads multiple items from the cache.
*/
public function bulkLoad(array $keys, callable $fallback = null): array
public function bulkLoad(array $keys, callable $generator = null): array
{
if (count($keys) === 0) {
return [];
@@ -109,30 +114,31 @@ class Cache
throw new Nette\InvalidArgumentException('Only scalar keys are allowed in bulkLoad()');
}
}
$storageKeys = array_map([$this, 'generateKey'], $keys);
if (!$this->storage instanceof IBulkReader) {
$result = array_combine($keys, array_map([$this->storage, 'read'], $storageKeys));
if ($fallback !== null) {
foreach ($result as $key => $value) {
if ($value === null) {
$result[$key] = $this->save($key, function (&$dependencies) use ($key, $fallback) {
return $fallback(...[$key, &$dependencies]);
});
}
}
$result = [];
if (!$this->storage instanceof BulkReader) {
foreach ($keys as $key) {
$result[$key] = $this->load(
$key,
$generator
? function (&$dependencies) use ($key, $generator) {
return $generator(...[$key, &$dependencies]);
}
: null
);
}
return $result;
}
$storageKeys = array_map([$this, 'generateKey'], $keys);
$cacheData = $this->storage->bulkRead($storageKeys);
$result = [];
foreach ($keys as $i => $key) {
$storageKey = $storageKeys[$i];
if (isset($cacheData[$storageKey])) {
$result[$key] = $cacheData[$storageKey];
} elseif ($fallback) {
$result[$key] = $this->save($key, function (&$dependencies) use ($key, $fallback) {
return $fallback(...[$key, &$dependencies]);
} elseif ($generator) {
$result[$key] = $this->load($key, function (&$dependencies) use ($key, $generator) {
return $generator(...[$key, &$dependencies]);
});
} else {
$result[$key] = null;
@@ -206,7 +212,7 @@ class Cache
// convert FILES into CALLBACKS
if (isset($dp[self::FILES])) {
foreach (array_unique((array) $dp[self::FILES]) as $item) {
$dp[self::CALLBACKS][] = [[__CLASS__, 'checkFile'], $item, @filemtime($item) ?: null]; // @ - stat may fail
$dp[self::CALLBACKS][] = [[self::class, 'checkFile'], $item, @filemtime($item) ?: null]; // @ - stat may fail
}
unset($dp[self::FILES]);
}
@@ -219,7 +225,7 @@ class Cache
// convert CONSTS into CALLBACKS
if (isset($dp[self::CONSTS])) {
foreach (array_unique((array) $dp[self::CONSTS]) as $item) {
$dp[self::CALLBACKS][] = [[__CLASS__, 'checkConst'], $item, constant($item)];
$dp[self::CALLBACKS][] = [[self::class, 'checkConst'], $item, constant($item)];
}
unset($dp[self::CONSTS]);
}
@@ -280,15 +286,14 @@ class Cache
public function wrap(callable $function, array $dependencies = null): \Closure
{
return function () use ($function, $dependencies) {
$key = [$function, func_get_args()];
$key = [$function, $args = func_get_args()];
if (is_array($function) && is_object($function[0])) {
$key[0][0] = get_class($function[0]);
}
$data = $this->load($key);
if ($data === null) {
$data = $this->save($key, $function(...$key[1]), $dependencies);
}
return $data;
return $this->load($key, function (&$deps) use ($function, $args, $dependencies) {
$deps = $dependencies;
return $function(...$args);
});
};
}
@@ -297,7 +302,7 @@ class Cache
* Starts the output cache.
* @param mixed $key
*/
public function start($key): ?OutputHelper
public function capture($key): ?OutputHelper
{
$data = $this->load($key);
if ($data === null) {
@@ -308,6 +313,15 @@ class Cache
}
/**
* @deprecated use capture()
*/
public function start($key): ?OutputHelper
{
return $this->capture($key);
}
/**
* Generates internal cache key.
*/
+10
View File
@@ -48,4 +48,14 @@ class OutputHelper
$this->cache->save($this->key, ob_get_flush(), $dependencies + $this->dependencies);
$this->cache = null;
}
/**
* Stops and throws away the output.
*/
public function rollback(): void
{
ob_end_flush();
$this->cache = null;
}
}
@@ -13,9 +13,8 @@ namespace Nette\Caching;
/**
* Cache storage.
*/
interface IStorage
interface Storage
{
/**
* Read from cache.
* @return mixed
@@ -42,3 +41,6 @@ interface IStorage
*/
function clean(array $conditions): void;
}
class_exists(IStorage::class);
@@ -15,7 +15,7 @@ use Nette;
/**
* Cache dummy storage.
*/
class DevNullStorage implements Nette\Caching\IStorage
class DevNullStorage implements Nette\Caching\Storage
{
use Nette\SmartObject;
+27 -28
View File
@@ -16,7 +16,7 @@ use Nette\Caching\Cache;
/**
* Cache file storage.
*/
class FileStorage implements Nette\Caching\IStorage
class FileStorage implements Nette\Caching\Storage
{
use Nette\SmartObject;
@@ -56,14 +56,14 @@ class FileStorage implements Nette\Caching\IStorage
/** @var string */
private $dir;
/** @var IJournal */
/** @var Journal */
private $journal;
/** @var array */
private $locks;
public function __construct(string $dir, IJournal $journal = null)
public function __construct(string $dir, Journal $journal = null)
{
if (!is_dir($dir)) {
throw new Nette\DirectoryNotFoundException("Directory '$dir' not found.");
@@ -81,12 +81,9 @@ class FileStorage implements Nette\Caching\IStorage
public function read(string $key)
{
$meta = $this->readMetaAndLock($this->getCacheFile($key), LOCK_SH);
if ($meta && $this->verify($meta)) {
return $this->readData($meta); // calls fclose()
} else {
return null;
}
return $meta && $this->verify($meta)
? $this->readData($meta) // calls fclose()
: null;
}
@@ -135,10 +132,12 @@ class FileStorage implements Nette\Caching\IStorage
@mkdir($dir); // @ - directory may already exist
}
$handle = fopen($cacheFile, 'c+b');
if ($handle) {
$this->locks[$key] = $handle;
flock($handle, LOCK_EX);
if (!$handle) {
return;
}
$this->locks[$key] = $handle;
flock($handle, LOCK_EX);
}
@@ -272,12 +271,14 @@ class FileStorage implements Nette\Caching\IStorage
} elseif ($namespaces) {
foreach ($namespaces as $namespace) {
$dir = $this->dir . '/_' . urlencode($namespace);
if (is_dir($dir)) {
foreach (Nette\Utils\Finder::findFiles('_*')->in($dir) as $entry) {
$this->delete((string) $entry);
}
@rmdir($dir); // may already contain new files
if (!is_dir($dir)) {
continue;
}
foreach (Nette\Utils\Finder::findFiles('_*')->in($dir) as $entry) {
$this->delete((string) $entry);
}
@rmdir($dir); // may already contain new files
}
}
@@ -327,11 +328,7 @@ class FileStorage implements Nette\Caching\IStorage
flock($meta[self::HANDLE], LOCK_UN);
fclose($meta[self::HANDLE]);
if (empty($meta[self::META_SERIALIZED])) {
return $data;
} else {
return unserialize($data);
}
return empty($meta[self::META_SERIALIZED]) ? $data : unserialize($data);
}
@@ -365,12 +362,14 @@ class FileStorage implements Nette\Caching\IStorage
if (!$handle) {
$handle = @fopen($file, 'r+'); // @ - file may not exist
}
if ($handle) {
flock($handle, LOCK_EX);
ftruncate($handle, 0);
flock($handle, LOCK_UN);
fclose($handle);
@unlink($file); // @ - file may not already exist
if (!$handle) {
return;
}
flock($handle, LOCK_EX);
ftruncate($handle, 0);
flock($handle, LOCK_UN);
fclose($handle);
@unlink($file); // @ - file may not already exist
}
}
@@ -13,9 +13,8 @@ namespace Nette\Caching\Storages;
/**
* Cache journal provider.
*/
interface IJournal
interface Journal
{
/**
* Writes entry information into the journal.
*/
@@ -27,3 +26,6 @@ interface IJournal
*/
function clean(array $conditions): ?array;
}
class_exists(IJournal::class);
@@ -16,7 +16,7 @@ use Nette\Caching\Cache;
/**
* Memcached storage using memcached extension.
*/
class MemcachedStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkReader
class MemcachedStorage implements Nette\Caching\Storage, Nette\Caching\BulkReader
{
use Nette\SmartObject;
@@ -32,7 +32,7 @@ class MemcachedStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkRea
/** @var string */
private $prefix;
/** @var IJournal */
/** @var Journal */
private $journal;
@@ -45,8 +45,12 @@ class MemcachedStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkRea
}
public function __construct(string $host = 'localhost', int $port = 11211, string $prefix = '', IJournal $journal = null)
{
public function __construct(
string $host = 'localhost',
int $port = 11211,
string $prefix = '',
Journal $journal = null
) {
if (!static::isAvailable()) {
throw new Nette\NotSupportedException("PHP extension 'memcached' is not loaded.");
}
@@ -62,7 +66,7 @@ class MemcachedStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkRea
public function addServer(string $host = 'localhost', int $port = 11211): void
{
if ($this->memcached->addServer($host, $port, 1) === false) {
if (@$this->memcached->addServer($host, $port, 1) === false) { // @ is escalated to exception
$error = error_get_last();
throw new Nette\InvalidStateException("Memcached::addServer(): $error[message].");
}
@@ -15,7 +15,7 @@ use Nette;
/**
* Memory cache storage.
*/
class MemoryStorage implements Nette\Caching\IStorage
class MemoryStorage implements Nette\Caching\Storage
{
use Nette\SmartObject;
@@ -16,7 +16,7 @@ use Nette\Caching\Cache;
/**
* SQLite based journal.
*/
class SQLiteJournal implements IJournal
class SQLiteJournal implements Journal
{
use Nette\SmartObject;
+14 -8
View File
@@ -16,7 +16,7 @@ use Nette\Caching\Cache;
/**
* SQLite storage.
*/
class SQLiteStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkReader
class SQLiteStorage implements Nette\Caching\Storage, Nette\Caching\BulkReader
{
use Nette\SmartObject;
@@ -56,12 +56,14 @@ class SQLiteStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkReader
{
$stmt = $this->pdo->prepare('SELECT data, slide FROM cache WHERE key=? AND (expire IS NULL OR expire >= ?)');
$stmt->execute([$key, time()]);
if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($row['slide'] !== null) {
$this->pdo->prepare('UPDATE cache SET expire = ? + slide WHERE key=?')->execute([time(), $key]);
}
return unserialize($row['data']);
if (!$row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
return;
}
if ($row['slide'] !== null) {
$this->pdo->prepare('UPDATE cache SET expire = ? + slide WHERE key=?')->execute([time(), $key]);
}
return unserialize($row['data']);
}
@@ -92,8 +94,12 @@ class SQLiteStorage implements Nette\Caching\IStorage, Nette\Caching\IBulkReader
public function write(string $key, $data, array $dependencies): void
{
$expire = isset($dependencies[Cache::EXPIRATION]) ? $dependencies[Cache::EXPIRATION] + time() : null;
$slide = isset($dependencies[Cache::SLIDING]) ? $dependencies[Cache::EXPIRATION] : null;
$expire = isset($dependencies[Cache::EXPIRATION])
? $dependencies[Cache::EXPIRATION] + time()
: null;
$slide = isset($dependencies[Cache::SLIDING])
? $dependencies[Cache::EXPIRATION]
: null;
$this->pdo->exec('BEGIN TRANSACTION');
$this->pdo->prepare('REPLACE INTO cache (key, data, expire, slide) VALUES (?, ?, ?, ?)')
+39
View File
@@ -0,0 +1,39 @@
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Nette\Caching;
if (false) {
/** @deprecated use Nette\Caching\BulkReader */
interface IBulkReader extends BulkReader
{
}
} elseif (!interface_exists(IBulkReader::class)) {
class_alias(BulkReader::class, IBulkReader::class);
}
if (false) {
/** @deprecated use Nette\Caching\Storage */
interface IStorage extends Storage
{
}
} elseif (!interface_exists(IStorage::class)) {
class_alias(Storage::class, IStorage::class);
}
namespace Nette\Caching\Storages;
if (false) {
/** @deprecated use Nette\Caching\Storages\Journal */
interface IJournal extends Journal
{
}
} elseif (!interface_exists(IJournal::class)) {
class_alias(Journal::class, IJournal::class);
}