347 lines
7.4 KiB
PHP
347 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace League\Flysystem\Cached;
|
|
|
|
use League\Flysystem\AdapterInterface;
|
|
use League\Flysystem\Config;
|
|
|
|
class CachedAdapter implements AdapterInterface
|
|
{
|
|
/**
|
|
* @var AdapterInterface
|
|
*/
|
|
private $adapter;
|
|
|
|
/**
|
|
* @var CacheInterface
|
|
*/
|
|
private $cache;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param AdapterInterface $adapter
|
|
* @param CacheInterface $cache
|
|
*/
|
|
public function __construct(AdapterInterface $adapter, CacheInterface $cache)
|
|
{
|
|
$this->adapter = $adapter;
|
|
$this->cache = $cache;
|
|
$this->cache->load();
|
|
}
|
|
|
|
/**
|
|
* Get the underlying Adapter implementation.
|
|
*
|
|
* @return AdapterInterface
|
|
*/
|
|
public function getAdapter()
|
|
{
|
|
return $this->adapter;
|
|
}
|
|
|
|
/**
|
|
* Get the used Cache implementation.
|
|
*
|
|
* @return CacheInterface
|
|
*/
|
|
public function getCache()
|
|
{
|
|
return $this->cache;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function write($path, $contents, Config $config)
|
|
{
|
|
$result = $this->adapter->write($path, $contents, $config);
|
|
|
|
if ($result !== false) {
|
|
$result['type'] = 'file';
|
|
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function writeStream($path, $resource, Config $config)
|
|
{
|
|
$result = $this->adapter->writeStream($path, $resource, $config);
|
|
|
|
if ($result !== false) {
|
|
$result['type'] = 'file';
|
|
$contents = false;
|
|
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function update($path, $contents, Config $config)
|
|
{
|
|
$result = $this->adapter->update($path, $contents, $config);
|
|
|
|
if ($result !== false) {
|
|
$result['type'] = 'file';
|
|
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function updateStream($path, $resource, Config $config)
|
|
{
|
|
$result = $this->adapter->updateStream($path, $resource, $config);
|
|
|
|
if ($result !== false) {
|
|
$result['type'] = 'file';
|
|
$contents = false;
|
|
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function rename($path, $newPath)
|
|
{
|
|
$result = $this->adapter->rename($path, $newPath);
|
|
|
|
if ($result !== false) {
|
|
$this->cache->rename($path, $newPath);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function copy($path, $newpath)
|
|
{
|
|
$result = $this->adapter->copy($path, $newpath);
|
|
|
|
if ($result !== false) {
|
|
$this->cache->copy($path, $newpath);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function delete($path)
|
|
{
|
|
$result = $this->adapter->delete($path);
|
|
|
|
if ($result !== false) {
|
|
$this->cache->delete($path);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function deleteDir($dirname)
|
|
{
|
|
$result = $this->adapter->deleteDir($dirname);
|
|
|
|
if ($result !== false) {
|
|
$this->cache->deleteDir($dirname);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function createDir($dirname, Config $config)
|
|
{
|
|
$result = $this->adapter->createDir($dirname, $config);
|
|
|
|
if ($result !== false) {
|
|
$type = 'dir';
|
|
$path = $dirname;
|
|
$this->cache->updateObject($dirname, compact('path', 'type'), true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function setVisibility($path, $visibility)
|
|
{
|
|
$result = $this->adapter->setVisibility($path, $visibility);
|
|
|
|
if ($result !== false) {
|
|
$this->cache->updateObject($path, compact('path', 'visibility'), true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function has($path)
|
|
{
|
|
$cacheHas = $this->cache->has($path);
|
|
|
|
if ($cacheHas !== null) {
|
|
return $cacheHas;
|
|
}
|
|
|
|
$adapterResponse = $this->adapter->has($path);
|
|
|
|
if (! $adapterResponse) {
|
|
$this->cache->storeMiss($path);
|
|
} else {
|
|
$cacheEntry = is_array($adapterResponse) ? $adapterResponse : compact('path');
|
|
$this->cache->updateObject($path, $cacheEntry, true);
|
|
}
|
|
|
|
return $adapterResponse;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function read($path)
|
|
{
|
|
return $this->callWithFallback('contents', $path, 'read');
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function readStream($path)
|
|
{
|
|
return $this->adapter->readStream($path);
|
|
}
|
|
|
|
/**
|
|
* Get the path prefix.
|
|
*
|
|
* @return string|null path prefix or null if pathPrefix is empty
|
|
*/
|
|
public function getPathPrefix()
|
|
{
|
|
return $this->adapter->getPathPrefix();
|
|
}
|
|
|
|
/**
|
|
* Prefix a path.
|
|
*
|
|
* @param string $path
|
|
*
|
|
* @return string prefixed path
|
|
*/
|
|
public function applyPathPrefix($path)
|
|
{
|
|
return $this->adapter->applyPathPrefix($path);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function listContents($directory = '', $recursive = false)
|
|
{
|
|
if ($this->cache->isComplete($directory, $recursive)) {
|
|
return $this->cache->listContents($directory, $recursive);
|
|
}
|
|
|
|
$result = $this->adapter->listContents($directory, $recursive);
|
|
|
|
if ($result !== false) {
|
|
$this->cache->storeContents($directory, $result, $recursive);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getMetadata($path)
|
|
{
|
|
return $this->callWithFallback(null, $path, 'getMetadata');
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getSize($path)
|
|
{
|
|
return $this->callWithFallback('size', $path, 'getSize');
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getMimetype($path)
|
|
{
|
|
return $this->callWithFallback('mimetype', $path, 'getMimetype');
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getTimestamp($path)
|
|
{
|
|
return $this->callWithFallback('timestamp', $path, 'getTimestamp');
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getVisibility($path)
|
|
{
|
|
return $this->callWithFallback('visibility', $path, 'getVisibility');
|
|
}
|
|
|
|
/**
|
|
* Call a method and cache the response.
|
|
*
|
|
* @param string $property
|
|
* @param string $path
|
|
* @param string $method
|
|
*
|
|
* @return mixed
|
|
*/
|
|
protected function callWithFallback($property, $path, $method)
|
|
{
|
|
$result = $this->cache->{$method}($path);
|
|
|
|
if ($result !== false && ($property === null || array_key_exists($property, $result))) {
|
|
return $result;
|
|
}
|
|
|
|
$result = $this->adapter->{$method}($path);
|
|
|
|
if ($result) {
|
|
$object = $result + compact('path');
|
|
$this->cache->updateObject($path, $object, true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|