- Fixing SystemResource
- Adding tests for StorageManager - Updating doc
This commit is contained in:
@@ -45,6 +45,7 @@ class StorageManager
|
||||
* @param Database $dba
|
||||
* @param IConfiguration $config
|
||||
* @param LoggerInterface $logger
|
||||
* @param Dice $dice
|
||||
*/
|
||||
public function __construct(Database $dba, IConfiguration $config, LoggerInterface $logger, Dice $dice)
|
||||
{
|
||||
@@ -76,27 +77,39 @@ class StorageManager
|
||||
/**
|
||||
* @brief Return storage backend class by registered name
|
||||
*
|
||||
* @param string $name Backend name
|
||||
* @param string|null $name Backend name
|
||||
*
|
||||
* @return Storage\IStorage|null null if no backend registered at $name
|
||||
*/
|
||||
public function getByName(string $name)
|
||||
public function getByName(string $name = null)
|
||||
{
|
||||
if (!$this->isValidBackend($name)) {
|
||||
if (!$this->isValidBackend($name) &&
|
||||
$name !== Storage\SystemResource::getName()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->dice->create($this->backends[$name]);
|
||||
/** @var Storage\IStorage $storage */
|
||||
$storage = null;
|
||||
|
||||
// If the storage of the file is a system resource,
|
||||
// create it directly since it isn't listed in the registered backends
|
||||
if ($name === Storage\SystemResource::getName()) {
|
||||
$storage = $this->dice->create(Storage\SystemResource::class);
|
||||
} else {
|
||||
$storage = $this->dice->create($this->backends[$name]);
|
||||
}
|
||||
|
||||
return $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if the storage is a valid backend
|
||||
*
|
||||
* @param string $name The name or class of the backend
|
||||
* @param string|null $name The name or class of the backend
|
||||
*
|
||||
* @return boolean True, if the backend is a valid backend
|
||||
*/
|
||||
public function isValidBackend(string $name)
|
||||
public function isValidBackend(string $name = null)
|
||||
{
|
||||
return array_key_exists($name, $this->backends);
|
||||
}
|
||||
@@ -108,7 +121,7 @@ class StorageManager
|
||||
*
|
||||
* @return boolean True, if the set was successful
|
||||
*/
|
||||
public function setBackend(string $name)
|
||||
public function setBackend(string $name = null)
|
||||
{
|
||||
if (!$this->isValidBackend($name)) {
|
||||
return false;
|
||||
@@ -135,23 +148,24 @@ class StorageManager
|
||||
/**
|
||||
* @brief Register a storage backend class
|
||||
*
|
||||
* @param string $name User readable backend name
|
||||
* @param string $class Backend class name
|
||||
*
|
||||
* @return boolean True, if the registration was successful
|
||||
*/
|
||||
public function register(string $name, string $class)
|
||||
public function register(string $class)
|
||||
{
|
||||
if (!is_subclass_of($class, Storage\IStorage::class)) {
|
||||
return false;
|
||||
}
|
||||
if (is_subclass_of($class, Storage\IStorage::class)) {
|
||||
/** @var Storage\IStorage $class */
|
||||
|
||||
$backends = $this->backends;
|
||||
$backends[$name] = $class;
|
||||
$backends = $this->backends;
|
||||
$backends[$class::getName()] = $class;
|
||||
|
||||
if ($this->config->set('storage', 'backends', $this->backends)) {
|
||||
$this->backends = $backends;
|
||||
return true;
|
||||
if ($this->config->set('storage', 'backends', $backends)) {
|
||||
$this->backends = $backends;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -160,14 +174,26 @@ class StorageManager
|
||||
/**
|
||||
* @brief Unregister a storage backend class
|
||||
*
|
||||
* @param string $name User readable backend name
|
||||
* @param string $class Backend class name
|
||||
*
|
||||
* @return boolean True, if unregistering was successful
|
||||
*/
|
||||
public function unregister(string $name)
|
||||
public function unregister(string $class)
|
||||
{
|
||||
unset($this->backends[$name]);
|
||||
return $this->config->set('storage', 'backends', $this->backends);
|
||||
if (is_subclass_of($class, Storage\IStorage::class)) {
|
||||
/** @var Storage\IStorage $class */
|
||||
|
||||
unset($this->backends[$class::getName()]);
|
||||
|
||||
if ($this->currentBackend instanceof $class) {
|
||||
$this->config->set('storage', 'name', null);
|
||||
$this->currentBackend = null;
|
||||
}
|
||||
|
||||
return $this->config->set('storage', 'backends', $this->backends);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +222,7 @@ class StorageManager
|
||||
$resources = $this->dba->select(
|
||||
$table,
|
||||
['id', 'data', 'backend-class', 'backend-ref'],
|
||||
['`backend-class` IS NULL or `backend-class` != ?', $destination],
|
||||
['`backend-class` IS NULL or `backend-class` != ?', $destination::getName()],
|
||||
['limit' => $limit]
|
||||
);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Storage\IStorage;
|
||||
use Friendica\Model\Storage\SystemResource;
|
||||
use Friendica\Object\Image;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Images;
|
||||
@@ -223,7 +224,7 @@ class Photo
|
||||
$values = array_fill(0, count($fields), "");
|
||||
|
||||
$photo = array_combine($fields, $values);
|
||||
$photo["backend-class"] = Storage\SystemResource::class;
|
||||
$photo["backend-class"] = SystemResource::NAME;
|
||||
$photo["backend-ref"] = $filename;
|
||||
$photo["type"] = $mimetype;
|
||||
$photo["cacheable"] = false;
|
||||
@@ -275,7 +276,7 @@ class Photo
|
||||
|
||||
if (DBA::isResult($existing_photo)) {
|
||||
$backend_ref = (string)$existing_photo["backend-ref"];
|
||||
$storage = DI::facStorage()->getByName((string)$existing_photo["backend-class"]);
|
||||
$storage = DI::facStorage()->getByName($existing_photo["backend-class"] ?? '');
|
||||
} else {
|
||||
$storage = DI::storage();
|
||||
}
|
||||
|
||||
32
src/Model/Storage/AbstractStorage.php
Normal file
32
src/Model/Storage/AbstractStorage.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Model\Storage;
|
||||
|
||||
use Friendica\Core\L10n\L10n;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* A general storage class which loads common dependencies and implements common methods
|
||||
*/
|
||||
abstract class AbstractStorage implements IStorage
|
||||
{
|
||||
/** @var L10n */
|
||||
protected $l10n;
|
||||
/** @var LoggerInterface */
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* @param L10n $l10n
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(L10n $l10n, LoggerInterface $logger)
|
||||
{
|
||||
$this->l10n = $l10n;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return static::getName();
|
||||
}
|
||||
}
|
||||
@@ -6,35 +6,32 @@
|
||||
|
||||
namespace Friendica\Model\Storage;
|
||||
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\L10n\L10n;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Friendica\Database\Database as DBA;
|
||||
|
||||
/**
|
||||
* @brief Database based storage system
|
||||
*
|
||||
* This class manage data stored in database table.
|
||||
*/
|
||||
class Database implements IStorage
|
||||
class Database extends AbstractStorage
|
||||
{
|
||||
const NAME = 'Database';
|
||||
|
||||
/** @var \Friendica\Database\Database */
|
||||
/** @var DBA */
|
||||
private $dba;
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
/** @var L10n\L10n */
|
||||
private $l10n;
|
||||
|
||||
/**
|
||||
* @param \Friendica\Database\Database $dba
|
||||
* @param LoggerInterface $logger
|
||||
* @param L10n\L10n $l10n
|
||||
* @param DBA $dba
|
||||
* @param LoggerInterface $logger
|
||||
* @param L10n $l10n
|
||||
*/
|
||||
public function __construct(\Friendica\Database\Database $dba, LoggerInterface $logger, L10n\L10n $l10n)
|
||||
public function __construct(DBA $dba, LoggerInterface $logger, L10n $l10n)
|
||||
{
|
||||
$this->dba = $dba;
|
||||
$this->logger = $logger;
|
||||
$this->l10n = $l10n;
|
||||
parent::__construct($l10n, $logger);
|
||||
|
||||
$this->dba = $dba;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,15 +55,15 @@ class Database implements IStorage
|
||||
if ($reference !== '') {
|
||||
$result = $this->dba->update('storage', ['data' => $data], ['id' => $reference]);
|
||||
if ($result === false) {
|
||||
$this->logger->warning('Failed to update data.', ['id' => $reference, 'errorCode' => $this->dba->errorNo(), 'errorMessage' => $this->dba->errorMessage()]);
|
||||
$this->logger->warning('Failed to update data.', ['id' => $reference, 'errorCode' => $this->dba->errorNo(), 'errorMessage' => $this->dba->errorMessage()]);
|
||||
throw new StorageException($this->l10n->t('Database storage failed to update %s', $reference));
|
||||
}
|
||||
}
|
||||
|
||||
return $reference;
|
||||
} else {
|
||||
$result = $this->dba->insert('storage', ['data' => $data]);
|
||||
if ($result === false) {
|
||||
$this->logger->warning('Failed to insert data.', ['errorCode' => $this->dba->errorNo(), 'errorMessage' => $this->dba->errorMessage()]);
|
||||
$this->logger->warning('Failed to insert data.', ['errorCode' => $this->dba->errorNo(), 'errorMessage' => $this->dba->errorMessage()]);
|
||||
throw new StorageException($this->l10n->t('Database storage failed to insert data'));
|
||||
}
|
||||
|
||||
@@ -101,7 +98,7 @@ class Database implements IStorage
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString()
|
||||
public static function getName()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ use Psr\Log\LoggerInterface;
|
||||
* Each new resource gets a value as reference and is saved in a
|
||||
* folder tree stucture created from that value.
|
||||
*/
|
||||
class Filesystem implements IStorage
|
||||
class Filesystem extends AbstractStorage
|
||||
{
|
||||
const NAME = 'Filesystem';
|
||||
|
||||
@@ -30,10 +30,6 @@ class Filesystem implements IStorage
|
||||
|
||||
/** @var IConfiguration */
|
||||
private $config;
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
/** @var L10n */
|
||||
private $l10n;
|
||||
|
||||
/** @var string */
|
||||
private $basePath;
|
||||
@@ -47,9 +43,9 @@ class Filesystem implements IStorage
|
||||
*/
|
||||
public function __construct(IConfiguration $config, LoggerInterface $logger, L10n $l10n)
|
||||
{
|
||||
parent::__construct($l10n, $logger);
|
||||
|
||||
$this->config = $config;
|
||||
$this->logger = $logger;
|
||||
$this->l10n = $l10n;
|
||||
|
||||
$path = $this->config->get('storage', 'filesystem_path', self::DEFAULT_BASE_FOLDER);
|
||||
$this->basePath = rtrim($path, '/');
|
||||
@@ -185,7 +181,7 @@ class Filesystem implements IStorage
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString()
|
||||
public static function getName()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
@@ -96,4 +96,11 @@ interface IStorage
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* The name of the backend
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName();
|
||||
}
|
||||
|
||||
@@ -16,10 +16,15 @@ use \BadMethodCallException;
|
||||
*/
|
||||
class SystemResource implements IStorage
|
||||
{
|
||||
const NAME = 'SystemResource';
|
||||
|
||||
// Valid folders to look for resources
|
||||
const VALID_FOLDERS = ["images"];
|
||||
|
||||
public static function get($filename)
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get(string $filename)
|
||||
{
|
||||
$folder = dirname($filename);
|
||||
if (!in_array($folder, self::VALID_FOLDERS)) {
|
||||
@@ -31,25 +36,48 @@ class SystemResource implements IStorage
|
||||
return file_get_contents($filename);
|
||||
}
|
||||
|
||||
|
||||
public static function put($data, $filename = "")
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function put(string $data, string $filename = '')
|
||||
{
|
||||
throw new BadMethodCallException();
|
||||
}
|
||||
|
||||
public static function delete($filename)
|
||||
public function delete(string $filename)
|
||||
{
|
||||
throw new BadMethodCallException();
|
||||
}
|
||||
|
||||
public static function getOptions()
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function saveOptions($data)
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function saveOptions(array $data)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getName()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user