初始化代码

This commit is contained in:
2025-12-22 14:34:25 +08:00
parent c2c5ae2fdd
commit a77dbc743f
1510 changed files with 213008 additions and 0 deletions

View File

@@ -0,0 +1,417 @@
<?php
namespace League\Flysystem\Cached\Storage;
use League\Flysystem\Cached\CacheInterface;
use League\Flysystem\Util;
abstract class AbstractCache implements CacheInterface
{
/**
* @var bool
*/
protected $autosave = true;
/**
* @var array
*/
protected $cache = [];
/**
* @var array
*/
protected $complete = [];
/**
* Destructor.
*/
public function __destruct()
{
if (! $this->autosave) {
$this->save();
}
}
/**
* Get the autosave setting.
*
* @return bool autosave
*/
public function getAutosave()
{
return $this->autosave;
}
/**
* Get the autosave setting.
*
* @param bool $autosave
*/
public function setAutosave($autosave)
{
$this->autosave = $autosave;
}
/**
* Store the contents listing.
*
* @param string $directory
* @param array $contents
* @param bool $recursive
*
* @return array contents listing
*/
public function storeContents($directory, array $contents, $recursive = false)
{
$directories = [$directory];
foreach ($contents as $object) {
$this->updateObject($object['path'], $object);
$object = $this->cache[$object['path']];
if ($recursive && $this->pathIsInDirectory($directory, $object['path'])) {
$directories[] = $object['dirname'];
}
}
foreach (array_unique($directories) as $directory) {
$this->setComplete($directory, $recursive);
}
$this->autosave();
}
/**
* Update the metadata for an object.
*
* @param string $path object path
* @param array $object object metadata
* @param bool $autosave whether to trigger the autosave routine
*/
public function updateObject($path, array $object, $autosave = false)
{
if (! $this->has($path)) {
$this->cache[$path] = Util::pathinfo($path);
}
$this->cache[$path] = array_merge($this->cache[$path], $object);
if ($autosave) {
$this->autosave();
}
$this->ensureParentDirectories($path);
}
/**
* Store object hit miss.
*
* @param string $path
*/
public function storeMiss($path)
{
$this->cache[$path] = false;
$this->autosave();
}
/**
* Get the contents listing.
*
* @param string $dirname
* @param bool $recursive
*
* @return array contents listing
*/
public function listContents($dirname = '', $recursive = false)
{
$result = [];
foreach ($this->cache as $object) {
if ($object === false) {
continue;
}
if ($object['dirname'] === $dirname) {
$result[] = $object;
} elseif ($recursive && $this->pathIsInDirectory($dirname, $object['path'])) {
$result[] = $object;
}
}
return $result;
}
/**
* {@inheritdoc}
*/
public function has($path)
{
if ($path !== false && array_key_exists($path, $this->cache)) {
return $this->cache[$path] !== false;
}
if ($this->isComplete(Util::dirname($path), false)) {
return false;
}
}
/**
* {@inheritdoc}
*/
public function read($path)
{
if (isset($this->cache[$path]['contents']) && $this->cache[$path]['contents'] !== false) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function readStream($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function rename($path, $newpath)
{
if ($this->has($path)) {
$object = $this->cache[$path];
unset($this->cache[$path]);
$object['path'] = $newpath;
$object = array_merge($object, Util::pathinfo($newpath));
$this->cache[$newpath] = $object;
$this->autosave();
}
}
/**
* {@inheritdoc}
*/
public function copy($path, $newpath)
{
if ($this->has($path)) {
$object = $this->cache[$path];
$object = array_merge($object, Util::pathinfo($newpath));
$this->updateObject($newpath, $object, true);
}
}
/**
* {@inheritdoc}
*/
public function delete($path)
{
$this->storeMiss($path);
}
/**
* {@inheritdoc}
*/
public function deleteDir($dirname)
{
foreach ($this->cache as $path => $object) {
if ($this->pathIsInDirectory($dirname, $path) || $path === $dirname) {
unset($this->cache[$path]);
}
}
unset($this->complete[$dirname]);
$this->autosave();
}
/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
if (isset($this->cache[$path]['mimetype'])) {
return $this->cache[$path];
}
if (! $result = $this->read($path)) {
return false;
}
$mimetype = Util::guessMimeType($path, $result['contents']);
$this->cache[$path]['mimetype'] = $mimetype;
return $this->cache[$path];
}
/**
* {@inheritdoc}
*/
public function getSize($path)
{
if (isset($this->cache[$path]['size'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function getTimestamp($path)
{
if (isset($this->cache[$path]['timestamp'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function getVisibility($path)
{
if (isset($this->cache[$path]['visibility'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function getMetadata($path)
{
if (isset($this->cache[$path]['type'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function isComplete($dirname, $recursive)
{
if (! array_key_exists($dirname, $this->complete)) {
return false;
}
if ($recursive && $this->complete[$dirname] !== 'recursive') {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function setComplete($dirname, $recursive)
{
$this->complete[$dirname] = $recursive ? 'recursive' : true;
}
/**
* Filter the contents from a listing.
*
* @param array $contents object listing
*
* @return array filtered contents
*/
public function cleanContents(array $contents)
{
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
]);
foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}
return $contents;
}
/**
* {@inheritdoc}
*/
public function flush()
{
$this->cache = [];
$this->complete = [];
$this->autosave();
}
/**
* {@inheritdoc}
*/
public function autosave()
{
if ($this->autosave) {
$this->save();
}
}
/**
* Retrieve serialized cache data.
*
* @return string serialized data
*/
public function getForStorage()
{
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete]);
}
/**
* Load from serialized cache data.
*
* @param string $json
*/
public function setFromStorage($json)
{
list($cache, $complete) = json_decode($json, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($cache) && is_array($complete)) {
$this->cache = $cache;
$this->complete = $complete;
}
}
/**
* Ensure parent directories of an object.
*
* @param string $path object path
*/
public function ensureParentDirectories($path)
{
$object = $this->cache[$path];
while ($object['dirname'] !== '' && ! isset($this->cache[$object['dirname']])) {
$object = Util::pathinfo($object['dirname']);
$object['type'] = 'dir';
$this->cache[$object['path']] = $object;
}
}
/**
* Determines if the path is inside the directory.
*
* @param string $directory
* @param string $path
*
* @return bool
*/
protected function pathIsInDirectory($directory, $path)
{
return $directory === '' || strpos($path, $directory . '/') === 0;
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace League\Flysystem\Cached\Storage;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
class Adapter extends AbstractCache
{
/**
* @var AdapterInterface An adapter
*/
protected $adapter;
/**
* @var string the file to cache to
*/
protected $file;
/**
* @var int|null seconds until cache expiration
*/
protected $expire = null;
/**
* Constructor.
*
* @param AdapterInterface $adapter adapter
* @param string $file the file to cache to
* @param int|null $expire seconds until cache expiration
*/
public function __construct(AdapterInterface $adapter, $file, $expire = null)
{
$this->adapter = $adapter;
$this->file = $file;
$this->setExpire($expire);
}
/**
* Set the expiration time in seconds.
*
* @param int $expire relative expiration time
*/
protected function setExpire($expire)
{
if ($expire) {
$this->expire = $this->getTime($expire);
}
}
/**
* Get expiration time in seconds.
*
* @param int $time relative expiration time
*
* @return int actual expiration time
*/
protected function getTime($time = 0)
{
return intval(microtime(true)) + $time;
}
/**
* {@inheritdoc}
*/
public function setFromStorage($json)
{
list($cache, $complete, $expire) = json_decode($json, true);
if (! $expire || $expire > $this->getTime()) {
$this->cache = $cache;
$this->complete = $complete;
} else {
$this->adapter->delete($this->file);
}
}
/**
* {@inheritdoc}
*/
public function load()
{
if ($this->adapter->has($this->file)) {
$file = $this->adapter->read($this->file);
if ($file && !empty($file['contents'])) {
$this->setFromStorage($file['contents']);
}
}
}
/**
* {@inheritdoc}
*/
public function getForStorage()
{
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete, $this->expire]);
}
/**
* {@inheritdoc}
*/
public function save()
{
$config = new Config();
$contents = $this->getForStorage();
if ($this->adapter->has($this->file)) {
$this->adapter->update($this->file, $contents, $config);
} else {
$this->adapter->write($this->file, $contents, $config);
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Memcached as NativeMemcached;
class Memcached extends AbstractCache
{
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* @var \Memcached Memcached instance
*/
protected $memcached;
/**
* Constructor.
*
* @param \Memcached $memcached
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(NativeMemcached $memcached, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->expire = $expire;
$this->memcached = $memcached;
}
/**
* {@inheritdoc}
*/
public function load()
{
$contents = $this->memcached->get($this->key);
if ($contents !== false) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$expiration = $this->expire === null ? 0 : time() + $this->expire;
$this->memcached->set($this->key, $contents, $expiration);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace League\Flysystem\Cached\Storage;
class Memory extends AbstractCache
{
/**
* {@inheritdoc}
*/
public function save()
{
// There is nothing to save
}
/**
* {@inheritdoc}
*/
public function load()
{
// There is nothing to load
}
}

View File

@@ -0,0 +1,171 @@
<?php
namespace League\Flysystem\Cached\Storage;
class Noop extends AbstractCache
{
/**
* {@inheritdoc}
*/
protected $autosave = false;
/**
* {@inheritdoc}
*/
public function updateObject($path, array $object, $autosave = false)
{
return $object;
}
/**
* {@inheritdoc}
*/
public function isComplete($dirname, $recursive)
{
return false;
}
/**
* {@inheritdoc}
*/
public function setComplete($dirname, $recursive)
{
//
}
/**
* {@inheritdoc}
*/
public function copy($path, $newpath)
{
return false;
}
/**
* {@inheritdoc}
*/
public function rename($path, $newpath)
{
return false;
}
/**
* {@inheritdoc}
*/
public function storeContents($directory, array $contents, $recursive = false)
{
return $contents;
}
/**
* {@inheritdoc}
*/
public function storeMiss($path)
{
return $this;
}
/**
* {@inheritdoc}
*/
public function flush()
{
//
}
/**
* {@inheritdoc}
*/
public function autosave()
{
//
}
/**
* {@inheritdoc}
*/
public function save()
{
//
}
/**
* {@inheritdoc}
*/
public function load()
{
//
}
/**
* {@inheritdoc}
*/
public function has($path)
{
return;
}
/**
* {@inheritdoc}
*/
public function read($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function readStream($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function listContents($directory = '', $recursive = false)
{
return [];
}
/**
* {@inheritdoc}
*/
public function getMetadata($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getSize($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getTimestamp($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getVisibility($path)
{
return false;
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Redis;
class PhpRedis extends AbstractCache
{
/**
* @var Redis PhpRedis Client
*/
protected $client;
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* Constructor.
*
* @param Redis|null $client phpredis client
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(Redis $client = null, $key = 'flysystem', $expire = null)
{
$this->client = $client ?: new Redis();
$this->key = $key;
$this->expire = $expire;
}
/**
* {@inheritdoc}
*/
public function load()
{
$contents = $this->client->get($this->key);
if ($contents !== false) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$this->client->set($this->key, $contents);
if ($this->expire !== null) {
$this->client->expire($this->key, $this->expire);
}
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Predis\Client;
class Predis extends AbstractCache
{
/**
* @var \Predis\Client Predis Client
*/
protected $client;
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* Constructor.
*
* @param \Predis\Client $client predis client
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(Client $client = null, $key = 'flysystem', $expire = null)
{
$this->client = $client ?: new Client();
$this->key = $key;
$this->expire = $expire;
}
/**
* {@inheritdoc}
*/
public function load()
{
if (($contents = $this->executeCommand('get', [$this->key])) !== null) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$this->executeCommand('set', [$this->key, $contents]);
if ($this->expire !== null) {
$this->executeCommand('expire', [$this->key, $this->expire]);
}
}
/**
* Execute a Predis command.
*
* @param string $name
* @param array $arguments
*
* @return string
*/
protected function executeCommand($name, array $arguments)
{
$command = $this->client->createCommand($name, $arguments);
return $this->client->executeCommand($command);
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Psr\Cache\CacheItemPoolInterface;
class Psr6Cache extends AbstractCache
{
/**
* @var CacheItemPoolInterface
*/
private $pool;
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* Constructor.
*
* @param CacheItemPoolInterface $pool
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(CacheItemPoolInterface $pool, $key = 'flysystem', $expire = null)
{
$this->pool = $pool;
$this->key = $key;
$this->expire = $expire;
}
/**
* {@inheritdoc}
*/
public function save()
{
$item = $this->pool->getItem($this->key);
$item->set($this->getForStorage());
$item->expiresAfter($this->expire);
$this->pool->save($item);
}
/**
* {@inheritdoc}
*/
public function load()
{
$item = $this->pool->getItem($this->key);
if ($item->isHit()) {
$this->setFromStorage($item->get());
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Stash\Pool;
class Stash extends AbstractCache
{
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* @var \Stash\Pool Stash pool instance
*/
protected $pool;
/**
* Constructor.
*
* @param \Stash\Pool $pool
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(Pool $pool, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->expire = $expire;
$this->pool = $pool;
}
/**
* {@inheritdoc}
*/
public function load()
{
$item = $this->pool->getItem($this->key);
$contents = $item->get();
if ($item->isMiss() === false) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$item = $this->pool->getItem($this->key);
$item->set($contents, $this->expire);
}
}