build: полная сборка в git — серверные PHP-зависимости lib/Vendor (438 файлов, из пиннированного релиза v22.0.12)
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Теперь master f7_talk = ПОЛНЫЙ деплой-артефакт: built js (наша сборка) + lib/Vendor (серверные PHP-deps) + патч Listener + version 22.0.12.1. Готов к брендингу dev-f7 и подписи dev-appstore. Апстрим-подписи (appinfo/signature.json) в репо нет — переподпишет dev-appstore при публикации.
This commit is contained in:
+136
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache;
|
||||
|
||||
use OCA\Talk\Vendor\Psr\SimpleCache\CacheInterface;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @template EntryType
|
||||
* @implements WarmupCache<EntryType>
|
||||
*/
|
||||
final class ChainCache implements WarmupCache
|
||||
{
|
||||
/** @var array<CacheInterface<EntryType>> */
|
||||
private array $delegates;
|
||||
|
||||
private int $count;
|
||||
|
||||
/**
|
||||
* @param CacheInterface<EntryType> ...$delegates
|
||||
*/
|
||||
public function __construct(CacheInterface ...$delegates)
|
||||
{
|
||||
$this->delegates = $delegates;
|
||||
$this->count = count($delegates);
|
||||
}
|
||||
|
||||
public function warmup(): void
|
||||
{
|
||||
foreach ($this->delegates as $delegate) {
|
||||
if ($delegate instanceof WarmupCache) {
|
||||
$delegate->warmup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get($key, $default = null): mixed
|
||||
{
|
||||
foreach ($this->delegates as $i => $delegate) {
|
||||
$value = $delegate->get($key, $default);
|
||||
|
||||
if (null !== $value) {
|
||||
while (--$i >= 0) {
|
||||
$this->delegates[$i]->set($key, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
$saved = true;
|
||||
$i = $this->count;
|
||||
|
||||
while ($i--) {
|
||||
$saved = $this->delegates[$i]->set($key, $value, $ttl) && $saved;
|
||||
}
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function delete($key): bool
|
||||
{
|
||||
$deleted = true;
|
||||
$i = $this->count;
|
||||
|
||||
while ($i--) {
|
||||
$deleted = $this->delegates[$i]->delete($key) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
$cleared = true;
|
||||
$i = $this->count;
|
||||
|
||||
while ($i--) {
|
||||
$cleared = $this->delegates[$i]->clear() && $cleared;
|
||||
}
|
||||
|
||||
return $cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Traversable<string, EntryType|null>
|
||||
*/
|
||||
public function getMultiple($keys, $default = null): Traversable
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $this->get($key, $default);
|
||||
}
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
$saved = true;
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$saved = $this->set($key, $value, $ttl) && $saved;
|
||||
}
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
$deleted = true;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$deleted = $this->delete($key) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
public function has($key): bool
|
||||
{
|
||||
foreach ($this->delegates as $cache) {
|
||||
if ($cache->has($key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/** @internal */
|
||||
final class CacheDirectoryNotWritable extends RuntimeException
|
||||
{
|
||||
public function __construct(string $directory)
|
||||
{
|
||||
parent::__construct(
|
||||
"Provided directory `$directory` is not writable.",
|
||||
1616445016
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/** @internal */
|
||||
final class CompiledPhpCacheFileNotWritten extends RuntimeException
|
||||
{
|
||||
public function __construct(string $file)
|
||||
{
|
||||
parent::__construct(
|
||||
"File `$file` could not be written.",
|
||||
1616445695
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/** @internal */
|
||||
final class CorruptedCompiledPhpCacheFile extends RuntimeException
|
||||
{
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct(
|
||||
"Compiled php cache file `$filename` has corrupted value.",
|
||||
1628949607
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception;
|
||||
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\Parser\Exception\InvalidType;
|
||||
use RuntimeException;
|
||||
|
||||
/** @internal */
|
||||
final class InvalidSignatureToWarmup extends RuntimeException
|
||||
{
|
||||
public function __construct(string $signature, InvalidType $exception)
|
||||
{
|
||||
parent::__construct(
|
||||
"Cannot warm up invalid signature `$signature`: {$exception->getMessage()}",
|
||||
1653330261,
|
||||
$exception
|
||||
);
|
||||
}
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache;
|
||||
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception\CacheDirectoryNotWritable;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception\CompiledPhpCacheFileNotWritten;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception\CorruptedCompiledPhpCacheFile;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\ClassDefinition;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\FunctionDefinition;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\Repository\Cache\Compiler\ClassDefinitionCompiler;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\Repository\Cache\Compiler\FunctionDefinitionCompiler;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Normalizer\Transformer\EvaluatedTransformer;
|
||||
use Error;
|
||||
use FilesystemIterator;
|
||||
use Traversable;
|
||||
|
||||
use function bin2hex;
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
use function random_bytes;
|
||||
use function rename;
|
||||
use function rmdir;
|
||||
use function str_contains;
|
||||
use function unlink;
|
||||
use function var_export;
|
||||
|
||||
/**
|
||||
* @api
|
||||
*
|
||||
* @template EntryType
|
||||
* @implements WarmupCache<EntryType>
|
||||
*/
|
||||
final class FileSystemCache implements WarmupCache
|
||||
{
|
||||
private const TEMPORARY_DIR_PERMISSION = 510;
|
||||
|
||||
private const GENERATED_MESSAGE = 'Generated by ' . self::class;
|
||||
|
||||
private string $cacheDir;
|
||||
|
||||
private ClassDefinitionCompiler $classDefinitionCompiler;
|
||||
|
||||
private FunctionDefinitionCompiler $functionDefinitionCompiler;
|
||||
|
||||
public function __construct(string $cacheDir)
|
||||
{
|
||||
$this->cacheDir = $cacheDir;
|
||||
$this->classDefinitionCompiler = new ClassDefinitionCompiler();
|
||||
$this->functionDefinitionCompiler = new FunctionDefinitionCompiler();
|
||||
}
|
||||
|
||||
public function warmup(): void
|
||||
{
|
||||
$this->createTemporaryDir();
|
||||
}
|
||||
|
||||
public function has($key): bool
|
||||
{
|
||||
$filename = $this->path($key);
|
||||
|
||||
return file_exists($filename);
|
||||
}
|
||||
|
||||
public function get($key, $default = null): mixed
|
||||
{
|
||||
$filename = $this->path($key);
|
||||
|
||||
if (! file_exists($filename)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
try {
|
||||
return include $filename;
|
||||
} catch (Error) {
|
||||
throw new CorruptedCompiledPhpCacheFile($filename);
|
||||
}
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
$filename = $this->path($key);
|
||||
|
||||
$code = $this->compile($value);
|
||||
|
||||
$tmpDir = $this->createTemporaryDir();
|
||||
|
||||
/** @infection-ignore-all */
|
||||
$tmpFilename = $tmpDir . DIRECTORY_SEPARATOR . bin2hex(random_bytes(16));
|
||||
|
||||
try {
|
||||
if (! @file_put_contents($tmpFilename, $code)) {
|
||||
throw new CompiledPhpCacheFileNotWritten($tmpFilename);
|
||||
}
|
||||
|
||||
if (! file_exists($filename) && ! @rename($tmpFilename, $filename)) {
|
||||
throw new CompiledPhpCacheFileNotWritten($filename);
|
||||
}
|
||||
} finally {
|
||||
if (file_exists($tmpFilename)) {
|
||||
unlink($tmpFilename);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($key): bool
|
||||
{
|
||||
$filename = $this->path($key);
|
||||
|
||||
if (file_exists($filename)) {
|
||||
return @unlink($filename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
if (! is_dir($this->cacheDir)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$success = true;
|
||||
$shouldDeleteRootDir = true;
|
||||
|
||||
/** @var FilesystemIterator $file */
|
||||
foreach (new FilesystemIterator($this->cacheDir) as $file) {
|
||||
if ($file->getFilename() === '.valinor.tmp') {
|
||||
$success = @rmdir($this->cacheDir . DIRECTORY_SEPARATOR . $file->getFilename()) && $success;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $file->isFile()) {
|
||||
$shouldDeleteRootDir = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
$line = $file->openFile()->getCurrentLine();
|
||||
|
||||
if (! $line || ! str_contains($line, self::GENERATED_MESSAGE)) {
|
||||
$shouldDeleteRootDir = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
$success = @unlink($this->cacheDir . DIRECTORY_SEPARATOR . $file->getFilename()) && $success;
|
||||
}
|
||||
|
||||
if ($shouldDeleteRootDir) {
|
||||
$success = @rmdir($this->cacheDir) && $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Traversable<string, EntryType|null>
|
||||
*/
|
||||
public function getMultiple($keys, $default = null): Traversable
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $this->get($key, $default);
|
||||
}
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
$this->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
$deleted = true;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$deleted = $this->delete($key) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
private function compile(mixed $value): string
|
||||
{
|
||||
$generatedMessage = self::GENERATED_MESSAGE;
|
||||
|
||||
$code = match (true) {
|
||||
$value instanceof ClassDefinition => $this->classDefinitionCompiler->compile($value),
|
||||
$value instanceof FunctionDefinition => $this->functionDefinitionCompiler->compile($value),
|
||||
$value instanceof EvaluatedTransformer => $value->code,
|
||||
default => var_export($value, true),
|
||||
};
|
||||
|
||||
return <<<PHP
|
||||
<?php // $generatedMessage
|
||||
return $code;
|
||||
PHP;
|
||||
}
|
||||
|
||||
private function createTemporaryDir(): string
|
||||
{
|
||||
$tmpDir = $this->cacheDir . DIRECTORY_SEPARATOR . '.valinor.tmp';
|
||||
|
||||
if (! is_dir($tmpDir) && ! @mkdir($tmpDir, self::TEMPORARY_DIR_PERMISSION, true)) {
|
||||
throw new CacheDirectoryNotWritable($this->cacheDir);
|
||||
}
|
||||
|
||||
return $tmpDir;
|
||||
}
|
||||
|
||||
private function path(string $key): string
|
||||
{
|
||||
/** @infection-ignore-all */
|
||||
return $this->cacheDir . DIRECTORY_SEPARATOR . $key . '.php';
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache;
|
||||
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\ClassDefinition;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\FunctionDefinition;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Utility\Reflection\Reflection;
|
||||
use OCA\Talk\Vendor\Psr\SimpleCache\CacheInterface;
|
||||
|
||||
use function file_exists;
|
||||
use function filemtime;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* This cache implementation will watch the files of the application and
|
||||
* invalidate cache entries when a PHP file is modified — preventing the library
|
||||
* not behaving as expected when the signature of a property or a method
|
||||
* changes.
|
||||
*
|
||||
* This is especially useful when the application runs in a development
|
||||
* environment, where source files are often modified by developers.
|
||||
*
|
||||
* It should decorate the original cache implementation and should be given to
|
||||
* the mapper builder: @see \OCA\Talk\Vendor\CuyZ\Valinor\MapperBuilder::withCache
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @phpstan-type TimestampsArray = array<string, int>
|
||||
* @template EntryType
|
||||
* @implements WarmupCache<EntryType|TimestampsArray>
|
||||
*/
|
||||
final class FileWatchingCache implements WarmupCache
|
||||
{
|
||||
/** @var array<string, TimestampsArray> */
|
||||
private array $timestamps = [];
|
||||
|
||||
public function __construct(
|
||||
/** @var CacheInterface<EntryType|TimestampsArray> */
|
||||
private CacheInterface $delegate
|
||||
) {}
|
||||
|
||||
public function warmup(): void
|
||||
{
|
||||
if ($this->delegate instanceof WarmupCache) {
|
||||
$this->delegate->warmup();
|
||||
}
|
||||
}
|
||||
|
||||
public function has($key): bool
|
||||
{
|
||||
foreach ($this->timestamps($key) as $fileName => $timestamp) {
|
||||
if (! file_exists($fileName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filemtime($fileName) !== $timestamp) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->delegate->has($key);
|
||||
}
|
||||
|
||||
public function get($key, $default = null): mixed
|
||||
{
|
||||
if (! $this->has($key)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->delegate->get($key, $default);
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
$this->saveTimestamps($key, $value);
|
||||
|
||||
return $this->delegate->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
public function delete($key): bool
|
||||
{
|
||||
return $this->delegate->delete($key);
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
$this->timestamps = [];
|
||||
|
||||
return $this->delegate->clear();
|
||||
}
|
||||
|
||||
public function getMultiple($keys, $default = null): iterable
|
||||
{
|
||||
return $this->delegate->getMultiple($keys, $default);
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
$this->saveTimestamps($key, $value);
|
||||
}
|
||||
|
||||
return $this->delegate->setMultiple($values, $ttl);
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
return $this->delegate->deleteMultiple($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TimestampsArray
|
||||
*/
|
||||
private function timestamps(string $key): array
|
||||
{
|
||||
return $this->timestamps[$key] ??= $this->delegate->get("$key.timestamps", []); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
private function saveTimestamps(string $key, mixed $value): void
|
||||
{
|
||||
$this->timestamps[$key] = [];
|
||||
|
||||
$fileNames = [];
|
||||
|
||||
if ($value instanceof ClassDefinition) {
|
||||
$reflection = Reflection::class($value->name);
|
||||
|
||||
do {
|
||||
$fileNames[] = $reflection->getFileName();
|
||||
} while ($reflection = $reflection->getParentClass());
|
||||
}
|
||||
|
||||
if ($value instanceof FunctionDefinition) {
|
||||
$fileNames[] = $value->fileName;
|
||||
}
|
||||
|
||||
foreach ($fileNames as $fileName) {
|
||||
if (! is_string($fileName)) {
|
||||
// @infection-ignore-all
|
||||
continue;
|
||||
}
|
||||
|
||||
$time = @filemtime($fileName);
|
||||
|
||||
// @infection-ignore-all
|
||||
if (false === $time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->timestamps[$key][$fileName] = $time;
|
||||
}
|
||||
|
||||
if (! empty($this->timestamps[$key])) {
|
||||
$this->delegate->set("$key.timestamps", $this->timestamps[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache;
|
||||
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Library\Settings;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Utility\Package;
|
||||
use OCA\Talk\Vendor\Psr\SimpleCache\CacheInterface;
|
||||
use Traversable;
|
||||
|
||||
use function hash;
|
||||
use function strstr;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @template EntryType
|
||||
* @implements WarmupCache<EntryType>
|
||||
*/
|
||||
final class KeySanitizerCache implements WarmupCache
|
||||
{
|
||||
private static string $version;
|
||||
|
||||
public function __construct(
|
||||
/** @var CacheInterface<EntryType> */
|
||||
private CacheInterface $delegate,
|
||||
private Settings $settings,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Two things:
|
||||
* 1. We append the current version of the package to the cache key in order
|
||||
* to avoid collisions between entries from different versions of the
|
||||
* library.
|
||||
* 2. The key is hashed so that it does not contain illegal characters.
|
||||
* @see https://www.php-fig.org/psr/psr-16/#12-definitions
|
||||
*
|
||||
* @infection-ignore-all
|
||||
*/
|
||||
private function sanitize(string $key): string
|
||||
{
|
||||
self::$version ??= PHP_VERSION . '/' . Package::version();
|
||||
|
||||
$firstPart = strstr($key, "\0", before_needle: true);
|
||||
|
||||
return $firstPart . hash('xxh128', $key . $this->settings->hash() . self::$version);
|
||||
}
|
||||
|
||||
public function warmup(): void
|
||||
{
|
||||
if ($this->delegate instanceof WarmupCache) {
|
||||
$this->delegate->warmup();
|
||||
}
|
||||
}
|
||||
|
||||
public function get($key, $default = null): mixed
|
||||
{
|
||||
return $this->delegate->get($this->sanitize($key), $default);
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
return $this->delegate->set($this->sanitize($key), $value, $ttl);
|
||||
}
|
||||
|
||||
public function delete($key): bool
|
||||
{
|
||||
return $this->delegate->delete($this->sanitize($key));
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
return $this->delegate->clear();
|
||||
}
|
||||
|
||||
public function has($key): bool
|
||||
{
|
||||
return $this->delegate->has($this->sanitize($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Traversable<string, EntryType|null>
|
||||
*/
|
||||
public function getMultiple($keys, $default = null): Traversable
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $this->delegate->get($this->sanitize($key), $default);
|
||||
}
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
$versionedValues = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$versionedValues[$this->sanitize($key)] = $value;
|
||||
}
|
||||
|
||||
return $this->delegate->setMultiple($versionedValues, $ttl);
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
$transformedKeys = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$transformedKeys[] = $this->sanitize($key);
|
||||
}
|
||||
|
||||
return $this->delegate->deleteMultiple($transformedKeys);
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache;
|
||||
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Normalizer\Transformer\EvaluatedTransformer;
|
||||
use OCA\Talk\Vendor\Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* Simple PSR-16-compatible runtime cache implementation.
|
||||
*
|
||||
* Used by default by the library so that entries can be cached in memory during
|
||||
* runtime.
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-16/
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @template EntryType
|
||||
* @implements CacheInterface<EntryType>
|
||||
*/
|
||||
final class RuntimeCache implements CacheInterface
|
||||
{
|
||||
/** @var array<string, EntryType> */
|
||||
private array $entries = [];
|
||||
|
||||
public function get($key, $default = null): mixed
|
||||
{
|
||||
return $this->entries[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
if ($value instanceof EvaluatedTransformer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->entries[$key] = $value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($key): bool
|
||||
{
|
||||
unset($this->entries[$key]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
$this->entries = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getMultiple($keys, $default = null): iterable
|
||||
{
|
||||
$entries = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$entries[$key] = $this->get($key, $default);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
$this->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
$this->delete($key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function has($key): bool
|
||||
{
|
||||
return isset($this->entries[$key]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache\Warmup;
|
||||
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Cache\Exception\InvalidSignatureToWarmup;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Cache\WarmupCache;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Definition\Repository\ClassDefinitionRepository;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Mapper\Object\Factory\ObjectBuilderFactory;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Mapper\Tree\Builder\ObjectImplementations;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\ClassType;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\CompositeType;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\Parser\Exception\InvalidType;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\Parser\TypeParser;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\Type;
|
||||
use OCA\Talk\Vendor\CuyZ\Valinor\Type\Types\InterfaceType;
|
||||
use OCA\Talk\Vendor\Psr\SimpleCache\CacheInterface;
|
||||
|
||||
use function in_array;
|
||||
|
||||
/** @internal */
|
||||
final class RecursiveCacheWarmupService
|
||||
{
|
||||
/** @var list<class-string> */
|
||||
private array $classesWarmedUp = [];
|
||||
|
||||
private bool $warmupWasDone = false;
|
||||
|
||||
public function __construct(
|
||||
private TypeParser $parser,
|
||||
/** @var CacheInterface<mixed> */
|
||||
private CacheInterface $cache,
|
||||
private ObjectImplementations $implementations,
|
||||
private ClassDefinitionRepository $classDefinitionRepository,
|
||||
private ObjectBuilderFactory $objectBuilderFactory
|
||||
) {}
|
||||
|
||||
public function warmup(string ...$signatures): void
|
||||
{
|
||||
if (! $this->warmupWasDone) {
|
||||
$this->warmupWasDone = true;
|
||||
|
||||
if ($this->cache instanceof WarmupCache) {
|
||||
$this->cache->warmup();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($signatures as $signature) {
|
||||
try {
|
||||
$this->warmupType($this->parser->parse($signature));
|
||||
} catch (InvalidType $exception) {
|
||||
throw new InvalidSignatureToWarmup($signature, $exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function warmupType(Type $type): void
|
||||
{
|
||||
if ($type instanceof InterfaceType) {
|
||||
$this->warmupInterfaceType($type);
|
||||
}
|
||||
|
||||
if ($type instanceof ClassType) {
|
||||
$this->warmupClassType($type);
|
||||
}
|
||||
|
||||
if ($type instanceof CompositeType) {
|
||||
foreach ($type->traverse() as $subType) {
|
||||
$this->warmupType($subType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function warmupInterfaceType(InterfaceType $type): void
|
||||
{
|
||||
$interfaceName = $type->className();
|
||||
|
||||
if (! $this->implementations->has($interfaceName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$function = $this->implementations->function($interfaceName);
|
||||
|
||||
$this->warmupType($function->returnType);
|
||||
|
||||
foreach ($function->parameters as $parameter) {
|
||||
$this->warmupType($parameter->type);
|
||||
}
|
||||
}
|
||||
|
||||
private function warmupClassType(ClassType $type): void
|
||||
{
|
||||
if (in_array($type->className(), $this->classesWarmedUp, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->classesWarmedUp[] = $type->className();
|
||||
|
||||
$classDefinition = $this->classDefinitionRepository->for($type);
|
||||
$objectBuilders = $this->objectBuilderFactory->for($classDefinition);
|
||||
|
||||
foreach ($objectBuilders as $builder) {
|
||||
foreach ($builder->describeArguments() as $argument) {
|
||||
$this->warmupType($argument->type());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\Talk\Vendor\CuyZ\Valinor\Cache;
|
||||
|
||||
use OCA\Talk\Vendor\Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @template T
|
||||
* @extends CacheInterface<T>
|
||||
*/
|
||||
interface WarmupCache extends CacheInterface
|
||||
{
|
||||
public function warmup(): void;
|
||||
}
|
||||
Reference in New Issue
Block a user