Merge pull request #10919 from nupplaphil/feat/storage_restructuring

Paradigm Restructuring Part 2 - Storage
This commit is contained in:
Hypolite Petovan 2021-10-28 10:12:34 -04:00 committed by GitHub
commit 0fe545ab17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 252 additions and 222 deletions

View file

@ -4,7 +4,7 @@ Friendica Storage Backend Addon development
* [Home](help) * [Home](help)
Storage backends can be added via addons. Storage backends can be added via addons.
A storage backend is implemented as a class, and the plugin register the class to make it avaiable to the system. A storage backend is implemented as a class, and the plugin register the class to make it available to the system.
## The Storage Backend Class ## The Storage Backend Class
@ -12,14 +12,14 @@ The class must live in `Friendica\Addon\youraddonname` namespace, where `youradd
There are two different interfaces you need to implement. There are two different interfaces you need to implement.
### `IWritableStorage` ### `ICanWriteToStorage`
The class must implement `Friendica\Model\Storage\IWritableStorage` interface. All method in the interface must be implemented: The class must implement `Friendica\Core\Storage\Capability\ICanWriteToStorage` interface. All method in the interface must be implemented:
```php ```php
namespace Friendica\Model\Storage\IWritableStorage; namespace Friendica\Core\Storage\Capability\ICanWriteToStorage;
interface IWritableStorage interface ICanWriteToStorage
{ {
public function get(string $reference); public function get(string $reference);
public function put(string $data, string $reference = ''); public function put(string $data, string $reference = '');
@ -33,17 +33,17 @@ interface IWritableStorage
- `put(string $data, string $reference)` saves data in `$data` to position `$reference`, or a new position if `$reference` is empty. - `put(string $data, string $reference)` saves data in `$data` to position `$reference`, or a new position if `$reference` is empty.
- `delete(string $reference)` delete data pointed by `$reference` - `delete(string $reference)` delete data pointed by `$reference`
### `IStorageConfiguration` ### `ICanConfigureStorage`
Each storage backend can have options the admin can set in admin page. Each storage backend can have options the admin can set in admin page.
To make the options possible, you need to implement the `Friendica\Model\Storage\IStorageConfiguration` interface. To make the options possible, you need to implement the `Friendica\Core\Storage\Capability\ICanConfigureStorage` interface.
All methods in the interface must be implemented: All methods in the interface must be implemented:
```php ```php
namespace Friendica\Model\Storage\IStorageConfiguration; namespace Friendica\Core\Storage\Capability\ICanConfigureStorage;
interface IStorageConfiguration interface ICanConfigureStorage
{ {
public function getOptions(); public function getOptions();
public function saveOptions(array $data); public function saveOptions(array $data);
@ -108,7 +108,7 @@ When the plugin is uninstalled, registered backends must be unregistered using
`DI::facStorage()->unregister(string $class)`. `DI::facStorage()->unregister(string $class)`.
You have to register a new hook in your addon, listening on `storage_instance(App $a, array $data)`. You have to register a new hook in your addon, listening on `storage_instance(App $a, array $data)`.
In case `$data['name']` is your storage class name, you have to instance a new instance of your `Friendica\Model\Storage\IStorage` class. In case `$data['name']` is your storage class name, you have to instance a new instance of your `Friendica\Core\Storage\Capability\ICanReadFromStorage` class.
Set the instance of your class as `$data['storage']` to pass it back to the backend. Set the instance of your class as `$data['storage']` to pass it back to the backend.
This is necessary because it isn't always clear, if you need further construction arguments. This is necessary because it isn't always clear, if you need further construction arguments.
@ -124,7 +124,7 @@ Add a new test class which's naming convention is `StorageClassTest`, which exte
Override the two necessary instances: Override the two necessary instances:
```php ```php
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
abstract class StorageTest abstract class StorageTest
{ {
@ -132,7 +132,7 @@ abstract class StorageTest
abstract protected function getInstance(); abstract protected function getInstance();
// Assertion for the option array you return for your new StorageClass // Assertion for the option array you return for your new StorageClass
abstract protected function assertOption(IWritableStorage $storage); abstract protected function assertOption(ICanWriteToStorage $storage);
} }
``` ```
@ -156,16 +156,16 @@ If there's a predecessor to this exception (e.g. you caught an exception and are
Example: Example:
```php ```php
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
class ExampleStorage implements IWritableStorage class ExampleStorage implements ICanWriteToStorage
{ {
public function get(string $reference) : string public function get(string $reference) : string
{ {
try { try {
throw new Exception('a real bad exception'); throw new Exception('a real bad exception');
} catch (Exception $exception) { } catch (Exception $exception) {
throw new \Friendica\Model\Storage\StorageException(sprintf('The Example Storage throws an exception for reference %s', $reference), 500, $exception); throw new \Friendica\Core\Storage\Exception\StorageException(sprintf('The Example Storage throws an exception for reference %s', $reference), 500, $exception);
} }
} }
} }
@ -186,12 +186,12 @@ The file will be `addon/samplestorage/SampleStorageBackend.php`:
<?php <?php
namespace Friendica\Addon\samplestorage; namespace Friendica\Addon\samplestorage;
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
class SampleStorageBackend implements IWritableStorage class SampleStorageBackend implements ICanWriteToStorage
{ {
const NAME = 'Sample Storage'; const NAME = 'Sample Storage';
@ -247,12 +247,12 @@ class SampleStorageBackend implements IWritableStorage
<?php <?php
namespace Friendica\Addon\samplestorage; namespace Friendica\Addon\samplestorage;
use Friendica\Model\Storage\IStorageConfiguration; use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
class SampleStorageBackendConfig implements IStorageConfiguration class SampleStorageBackendConfig implements ICanConfigureStorage
{ {
/** @var \Friendica\Core\Config\Capability\IManageConfigValues */ /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
private $config; private $config;
@ -357,8 +357,8 @@ function samplestorage_storage_config(App $a, array &$data)
**Theoretically - until tests for Addons are enabled too - create a test class with the name `addon/tests/SampleStorageTest.php`: **Theoretically - until tests for Addons are enabled too - create a test class with the name `addon/tests/SampleStorageTest.php`:
```php ```php
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Test\src\Model\Storage\StorageTest; use Friendica\Test\src\Core\Storage\StorageTest;
class SampleStorageTest extends StorageTest class SampleStorageTest extends StorageTest
{ {
@ -371,7 +371,7 @@ class SampleStorageTest extends StorageTest
} }
// Assertion for the option array you return for your new StorageClass // Assertion for the option array you return for your new StorageClass
protected function assertOption(IWritableStorage $storage) protected function assertOption(ICanWriteToStorage $storage)
{ {
$this->assertEquals([ $this->assertEquals([
'filename' => [ 'filename' => [

View file

@ -544,7 +544,7 @@ Called when a custom storage is used (e.g. webdav_storage)
Hook data: Hook data:
- **name** (input): the name of the used storage backend - **name** (input): the name of the used storage backend
- **data['storage']** (output): the storage instance to use (**must** implement `\Friendica\Model\Storage\IWritableStorage`) - **data['storage']** (output): the storage instance to use (**must** implement `\Friendica\Core\Storage\IWritableStorage`)
### storage_config ### storage_config
@ -552,7 +552,7 @@ Called when the admin of the node wants to configure a custom storage (e.g. webd
Hook data: Hook data:
- **name** (input): the name of the used storage backend - **name** (input): the name of the used storage backend
- **data['storage_config']** (output): the storage configuration instance to use (**must** implement `\Friendica\Model\Storage\IStorageConfiguration`) - **data['storage_config']** (output): the storage configuration instance to use (**must** implement `\Friendica\Core\Storage\Capability\IConfigureStorage`)
## Complete list of hook callbacks ## Complete list of hook callbacks

View file

@ -22,9 +22,9 @@
namespace Friendica\Console; namespace Friendica\Console;
use Asika\SimpleConsole\CommandArgsException; use Asika\SimpleConsole\CommandArgsException;
use Friendica\Core\StorageManager; use Friendica\Core\Storage\Repository\StorageManager;
use Friendica\Model\Storage\ReferenceStorageException; use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Model\Storage\StorageException; use Friendica\Core\Storage\Exception\StorageException;
/** /**
* tool to manage storage backend and stored data from CLI * tool to manage storage backend and stored data from CLI

View file

@ -19,12 +19,12 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Capability;
/** /**
* The interface to use for configurable storage backends * The interface to use for configurable storage backends
*/ */
interface IStorageConfiguration interface ICanConfigureStorage
{ {
/** /**
* Get info about storage options * Get info about storage options

View file

@ -19,12 +19,15 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Capability;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Exception\StorageException;
/** /**
* Interface for basic storage backends * Interface for basic storage backends
*/ */
interface IStorage interface ICanReadFromStorage
{ {
/** /**
* Get data from backend * Get data from backend
@ -43,7 +46,7 @@ interface IStorage
* *
* @return string * @return string
*/ */
public function __toString(); public function __toString(): string;
/** /**
* The name of the backend * The name of the backend

View file

@ -19,7 +19,10 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Capability;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Exception\StorageException;
/** /**
* Interface for writable storage backends * Interface for writable storage backends
@ -27,7 +30,7 @@ namespace Friendica\Model\Storage;
* Used for storages with CRUD functionality, mainly used for user data (e.g. photos, attachements). * Used for storages with CRUD functionality, mainly used for user data (e.g. photos, attachements).
* There's only one active writable storage possible. This type of storage is selectable by the current administrator. * There's only one active writable storage possible. This type of storage is selectable by the current administrator.
*/ */
interface IWritableStorage extends IStorage interface ICanWriteToStorage extends ICanReadFromStorage
{ {
/** /**
* Put data in backend as $ref. If $ref is not defined a new reference is created. * Put data in backend as $ref. If $ref is not defined a new reference is created.

View file

@ -19,7 +19,7 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Exception;
/** /**
* Storage Exception in case of invalid storage class * Storage Exception in case of invalid storage class

View file

@ -19,7 +19,7 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Exception;
/** /**
* Storage Exception in case of invalid references * Storage Exception in case of invalid references

View file

@ -19,7 +19,7 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Exception;
use Exception; use Exception;

View file

@ -19,12 +19,20 @@
* *
*/ */
namespace Friendica\Core; namespace Friendica\Core\Storage\Repository;
use Exception; use Exception;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Storage\Exception\InvalidClassStorageException;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Core\Storage\Capability\ICanReadFromStorage;
use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Model\Storage; use Friendica\Core\Storage\Type;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\InternalServerErrorException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -42,15 +50,15 @@ class StorageManager
// Default storage backends // Default storage backends
/** @var string[] */ /** @var string[] */
const DEFAULT_BACKENDS = [ const DEFAULT_BACKENDS = [
Storage\Filesystem::NAME, Type\Filesystem::NAME,
Storage\Database::NAME, Type\Database::NAME,
]; ];
/** @var string[] List of valid backend classes */ /** @var string[] List of valid backend classes */
private $validBackends; private $validBackends;
/** /**
* @var Storage\IStorage[] A local cache for storage instances * @var ICanReadFromStorage[] A local cache for storage instances
*/ */
private $backendInstances = []; private $backendInstances = [];
@ -63,7 +71,7 @@ class StorageManager
/** @var L10n */ /** @var L10n */
private $l10n; private $l10n;
/** @var Storage\IWritableStorage */ /** @var ICanWriteToStorage */
private $currentBackend; private $currentBackend;
/** /**
@ -72,8 +80,8 @@ class StorageManager
* @param LoggerInterface $logger * @param LoggerInterface $logger
* @param L10n $l10n * @param L10n $l10n
* *
* @throws Storage\InvalidClassStorageException in case the active backend class is invalid * @throws InvalidClassStorageException in case the active backend class is invalid
* @throws Storage\StorageException in case of unexpected errors during the active backend class loading * @throws StorageException in case of unexpected errors during the active backend class loading
*/ */
public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, L10n $l10n) public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, L10n $l10n)
{ {
@ -92,9 +100,9 @@ class StorageManager
/** /**
* Return current storage backend class * Return current storage backend class
* *
* @return Storage\IWritableStorage * @return ICanWriteToStorage
*/ */
public function getBackend() public function getBackend(): ICanWriteToStorage
{ {
return $this->currentBackend; return $this->currentBackend;
} }
@ -104,16 +112,16 @@ class StorageManager
* *
* @param string $name Backend name * @param string $name Backend name
* *
* @return Storage\IWritableStorage * @return ICanWriteToStorage
* *
* @throws Storage\InvalidClassStorageException in case there's no backend class for the name * @throws InvalidClassStorageException in case there's no backend class for the name
* @throws Storage\StorageException in case of an unexpected failure during the hook call * @throws StorageException in case of an unexpected failure during the hook call
*/ */
public function getWritableStorageByName(string $name): Storage\IWritableStorage public function getWritableStorageByName(string $name): ICanWriteToStorage
{ {
$storage = $this->getByName($name, $this->validBackends); $storage = $this->getByName($name, $this->validBackends);
if (!$storage instanceof Storage\IWritableStorage) { if (!$storage instanceof ICanWriteToStorage) {
throw new Storage\InvalidClassStorageException(sprintf('Backend %s is not writable', $name)); throw new InvalidClassStorageException(sprintf('Backend %s is not writable', $name));
} }
return $storage; return $storage;
@ -124,19 +132,19 @@ class StorageManager
* *
* @param string $name Backend name * @param string $name Backend name
* *
* @return Storage\IStorageConfiguration|false * @return ICanConfigureStorage|false
* *
* @throws Storage\InvalidClassStorageException in case there's no backend class for the name * @throws InvalidClassStorageException in case there's no backend class for the name
* @throws Storage\StorageException in case of an unexpected failure during the hook call * @throws StorageException in case of an unexpected failure during the hook call
*/ */
public function getConfigurationByName(string $name) public function getConfigurationByName(string $name)
{ {
switch ($name) { switch ($name) {
// Try the filesystem backend // Try the filesystem backend
case Storage\Filesystem::getName(): case Type\Filesystem::getName():
return new Storage\FilesystemConfig($this->config, $this->l10n); return new Type\FilesystemConfig($this->config, $this->l10n);
// try the database backend // try the database backend
case Storage\Database::getName(): case Type\Database::getName():
return false; return false;
default: default:
$data = [ $data = [
@ -145,13 +153,13 @@ class StorageManager
]; ];
try { try {
Hook::callAll('storage_config', $data); Hook::callAll('storage_config', $data);
if (!($data['storage_config'] ?? null) instanceof Storage\IStorageConfiguration) { if (!($data['storage_config'] ?? null) instanceof ICanConfigureStorage) {
throw new Storage\InvalidClassStorageException(sprintf('Configuration for backend %s was not found', $name)); throw new InvalidClassStorageException(sprintf('Configuration for backend %s was not found', $name));
} }
return $data['storage_config']; return $data['storage_config'];
} catch (InternalServerErrorException $exception) { } catch (InternalServerErrorException $exception) {
throw new Storage\StorageException(sprintf('Failed calling hook::storage_config for backend %s', $name), $exception); throw new StorageException(sprintf('Failed calling hook::storage_config for backend %s', $name), $exception);
} }
} }
} }
@ -162,36 +170,36 @@ class StorageManager
* @param string $name Backend name * @param string $name Backend name
* @param string[]|null $validBackends possible, manual override of the valid backends * @param string[]|null $validBackends possible, manual override of the valid backends
* *
* @return Storage\IStorage * @return ICanReadFromStorage
* *
* @throws Storage\InvalidClassStorageException in case there's no backend class for the name * @throws InvalidClassStorageException in case there's no backend class for the name
* @throws Storage\StorageException in case of an unexpected failure during the hook call * @throws StorageException in case of an unexpected failure during the hook call
*/ */
public function getByName(string $name, array $validBackends = null): Storage\IStorage public function getByName(string $name, array $validBackends = null): ICanReadFromStorage
{ {
// If there's no cached instance create a new instance // If there's no cached instance create a new instance
if (!isset($this->backendInstances[$name])) { if (!isset($this->backendInstances[$name])) {
// If the current name isn't a valid backend (or the SystemResource instance) create it // If the current name isn't a valid backend (or the SystemResource instance) create it
if (!$this->isValidBackend($name, $validBackends)) { if (!$this->isValidBackend($name, $validBackends)) {
throw new Storage\InvalidClassStorageException(sprintf('Backend %s is not valid', $name)); throw new InvalidClassStorageException(sprintf('Backend %s is not valid', $name));
} }
switch ($name) { switch ($name) {
// Try the filesystem backend // Try the filesystem backend
case Storage\Filesystem::getName(): case Type\Filesystem::getName():
$storageConfig = new Storage\FilesystemConfig($this->config, $this->l10n); $storageConfig = new Type\FilesystemConfig($this->config, $this->l10n);
$this->backendInstances[$name] = new Storage\Filesystem($storageConfig->getStoragePath()); $this->backendInstances[$name] = new Type\Filesystem($storageConfig->getStoragePath());
break; break;
// try the database backend // try the database backend
case Storage\Database::getName(): case Type\Database::getName():
$this->backendInstances[$name] = new Storage\Database($this->dba); $this->backendInstances[$name] = new Type\Database($this->dba);
break; break;
// at least, try if there's an addon for the backend // at least, try if there's an addon for the backend
case Storage\SystemResource::getName(): case Type\SystemResource::getName():
$this->backendInstances[$name] = new Storage\SystemResource(); $this->backendInstances[$name] = new Type\SystemResource();
break; break;
case Storage\ExternalResource::getName(): case Type\ExternalResource::getName():
$this->backendInstances[$name] = new Storage\ExternalResource(); $this->backendInstances[$name] = new Type\ExternalResource();
break; break;
default: default:
$data = [ $data = [
@ -200,13 +208,13 @@ class StorageManager
]; ];
try { try {
Hook::callAll('storage_instance', $data); Hook::callAll('storage_instance', $data);
if (!($data['storage'] ?? null) instanceof Storage\IStorage) { if (!($data['storage'] ?? null) instanceof ICanReadFromStorage) {
throw new Storage\InvalidClassStorageException(sprintf('Backend %s was not found', $name)); throw new InvalidClassStorageException(sprintf('Backend %s was not found', $name));
} }
$this->backendInstances[$data['name'] ?? $name] = $data['storage']; $this->backendInstances[$data['name'] ?? $name] = $data['storage'];
} catch (InternalServerErrorException $exception) { } catch (InternalServerErrorException $exception) {
throw new Storage\StorageException(sprintf('Failed calling hook::storage_instance for backend %s', $name), $exception); throw new StorageException(sprintf('Failed calling hook::storage_instance for backend %s', $name), $exception);
} }
break; break;
} }
@ -227,8 +235,8 @@ class StorageManager
{ {
$validBackends = $validBackends ?? array_merge($this->validBackends, $validBackends = $validBackends ?? array_merge($this->validBackends,
[ [
Storage\SystemResource::getName(), Type\SystemResource::getName(),
Storage\ExternalResource::getName(), Type\ExternalResource::getName(),
]); ]);
return in_array($name, $validBackends); return in_array($name, $validBackends);
} }
@ -236,11 +244,11 @@ class StorageManager
/** /**
* Set current storage backend class * Set current storage backend class
* *
* @param Storage\IWritableStorage $storage The storage class * @param ICanWriteToStorage $storage The storage class
* *
* @return boolean True, if the set was successful * @return boolean True, if the set was successful
*/ */
public function setBackend(Storage\IWritableStorage $storage): bool public function setBackend(ICanWriteToStorage $storage): bool
{ {
if ($this->config->set('storage', 'name', $storage::getName())) { if ($this->config->set('storage', 'name', $storage::getName())) {
$this->currentBackend = $storage; $this->currentBackend = $storage;
@ -271,9 +279,8 @@ class StorageManager
*/ */
public function register(string $class): bool public function register(string $class): bool
{ {
if (is_subclass_of($class, Storage\IStorage::class)) { if (is_subclass_of($class, ICanReadFromStorage::class)) {
/** @var Storage\IStorage $class */ /** @var ICanReadFromStorage $class */
if ($this->isValidBackend($class::getName(), $this->validBackends)) { if ($this->isValidBackend($class::getName(), $this->validBackends)) {
return true; return true;
} }
@ -299,15 +306,14 @@ class StorageManager
* *
* @return boolean True, if unregistering was successful * @return boolean True, if unregistering was successful
* *
* @throws Storage\StorageException * @throws StorageException
*/ */
public function unregister(string $class): bool public function unregister(string $class): bool
{ {
if (is_subclass_of($class, Storage\IStorage::class)) { if (is_subclass_of($class, ICanReadFromStorage::class)) {
/** @var Storage\IStorage $class */ /** @var ICanReadFromStorage $class */
if ($this->currentBackend::getName() == $class::getName()) { if ($this->currentBackend::getName() == $class::getName()) {
throw new Storage\StorageException(sprintf('Cannot unregister %s, because it\'s currently active.', $class::getName())); throw new StorageException(sprintf('Cannot unregister %s, because it\'s currently active.', $class::getName()));
} }
$key = array_search($class::getName(), $this->validBackends); $key = array_search($class::getName(), $this->validBackends);
@ -336,18 +342,18 @@ class StorageManager
* Copy existing data to destination storage and delete from source. * Copy existing data to destination storage and delete from source.
* This method cannot move to legacy in-table `data` field. * This method cannot move to legacy in-table `data` field.
* *
* @param Storage\IWritableStorage $destination Destination storage class name * @param ICanWriteToStorage $destination Destination storage class name
* @param array $tables Tables to look in for resources. Optional, defaults to ['photo', 'attach'] * @param array $tables Tables to look in for resources. Optional, defaults to ['photo', 'attach']
* @param int $limit Limit of the process batch size, defaults to 5000 * @param int $limit Limit of the process batch size, defaults to 5000
* *
* @return int Number of moved resources * @return int Number of moved resources
* @throws Storage\StorageException * @throws StorageException
* @throws Exception * @throws Exception
*/ */
public function move(Storage\IWritableStorage $destination, array $tables = self::TABLES, int $limit = 5000): int public function move(ICanWriteToStorage $destination, array $tables = self::TABLES, int $limit = 5000): int
{ {
if (!$this->isValidBackend($destination, $this->validBackends)) { if (!$this->isValidBackend($destination, $this->validBackends)) {
throw new Storage\StorageException(sprintf("Can't move to storage backend '%s'", $destination::getName())); throw new StorageException(sprintf("Can't move to storage backend '%s'", $destination::getName()));
} }
$moved = 0; $moved = 0;
@ -369,10 +375,10 @@ class StorageManager
$source = $this->getWritableStorageByName($resource['backend-class'] ?? ''); $source = $this->getWritableStorageByName($resource['backend-class'] ?? '');
$this->logger->info('Get data from old backend.', ['oldBackend' => $source, 'oldReference' => $sourceRef]); $this->logger->info('Get data from old backend.', ['oldBackend' => $source, 'oldReference' => $sourceRef]);
$data = $source->get($sourceRef); $data = $source->get($sourceRef);
} catch (Storage\InvalidClassStorageException $exception) { } catch (InvalidClassStorageException $exception) {
$this->logger->info('Get data from DB resource field.', ['oldReference' => $sourceRef]); $this->logger->info('Get data from DB resource field.', ['oldReference' => $sourceRef]);
$data = $resource['data']; $data = $resource['data'];
} catch (Storage\ReferenceStorageException $exception) { } catch (ReferenceStorageException $exception) {
$this->logger->info('Invalid source reference.', ['oldBackend' => $source, 'oldReference' => $sourceRef]); $this->logger->info('Invalid source reference.', ['oldBackend' => $source, 'oldReference' => $sourceRef]);
continue; continue;
} }
@ -385,7 +391,7 @@ class StorageManager
$this->logger->info('update row'); $this->logger->info('update row');
if ($this->dba->update($table, ['backend-class' => $destination::getName(), 'backend-ref' => $destinationRef, 'data' => ''], ['id' => $id])) { if ($this->dba->update($table, ['backend-class' => $destination::getName(), 'backend-ref' => $destinationRef, 'data' => ''], ['id' => $id])) {
if (!empty($source)) { if (!empty($source)) {
$this->logger->info('Delete data from old backend.', ['oldBackend' => $source, 'oldReference' => $sourceRef]); $this->logger->info('Deleted data from old backend.', ['oldBackend' => $source, 'oldReference' => $sourceRef]);
$source->delete($sourceRef); $source->delete($sourceRef);
} }
$moved++; $moved++;

View file

@ -19,9 +19,12 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Type;
use Exception; use Exception;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Database\Database as DBA; use Friendica\Database\Database as DBA;
/** /**
@ -29,7 +32,7 @@ use Friendica\Database\Database as DBA;
* *
* This class manage data stored in database table. * This class manage data stored in database table.
*/ */
class Database implements IWritableStorage class Database implements ICanWriteToStorage
{ {
const NAME = 'Database'; const NAME = 'Database';
@ -121,7 +124,7 @@ class Database implements IWritableStorage
return self::NAME; return self::NAME;
} }
public function __toString() public function __toString(): string
{ {
return self::getName(); return self::getName();
} }

View file

@ -19,9 +19,11 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Type;
use Exception; use Exception;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Capability\ICanReadFromStorage;
use Friendica\Util\HTTPSignature; use Friendica\Util\HTTPSignature;
/** /**
@ -30,7 +32,7 @@ use Friendica\Util\HTTPSignature;
* This class is used to load external resources, like images. * This class is used to load external resources, like images.
* Is not intended to be selectable by admins as default storage class. * Is not intended to be selectable by admins as default storage class.
*/ */
class ExternalResource implements IStorage class ExternalResource implements ICanReadFromStorage
{ {
const NAME = 'ExternalResource'; const NAME = 'ExternalResource';
@ -64,7 +66,7 @@ class ExternalResource implements IStorage
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function __toString() public function __toString(): string
{ {
return self::NAME; return self::NAME;
} }

View file

@ -19,9 +19,12 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Type;
use Exception; use Exception;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Util\Strings; use Friendica\Util\Strings;
/** /**
@ -34,7 +37,7 @@ use Friendica\Util\Strings;
* Each new resource gets a value as reference and is saved in a * Each new resource gets a value as reference and is saved in a
* folder tree stucture created from that value. * folder tree stucture created from that value.
*/ */
class Filesystem implements IWritableStorage class Filesystem implements ICanWriteToStorage
{ {
const NAME = 'Filesystem'; const NAME = 'Filesystem';
@ -175,7 +178,7 @@ class Filesystem implements IWritableStorage
return self::NAME; return self::NAME;
} }
public function __toString() public function __toString(): string
{ {
return self::getName(); return self::getName();
} }

View file

@ -19,15 +19,16 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Type;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Storage\Capability\ICanConfigureStorage;
/** /**
* Filesystem based storage backend configuration * Filesystem based storage backend configuration
*/ */
class FilesystemConfig implements IStorageConfiguration class FilesystemConfig implements ICanConfigureStorage
{ {
// Default base folder // Default base folder
const DEFAULT_BASE_FOLDER = 'storage'; const DEFAULT_BASE_FOLDER = 'storage';

View file

@ -19,7 +19,11 @@
* *
*/ */
namespace Friendica\Model\Storage; namespace Friendica\Core\Storage\Type;
use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Core\Storage\Capability\ICanReadFromStorage;
/** /**
* System resource storage class * System resource storage class
@ -27,7 +31,7 @@ namespace Friendica\Model\Storage;
* This class is used to load system resources, like images. * This class is used to load system resources, like images.
* Is not intended to be selectable by admins as default storage class. * Is not intended to be selectable by admins as default storage class.
*/ */
class SystemResource implements IStorage class SystemResource implements ICanReadFromStorage
{ {
const NAME = 'SystemResource'; const NAME = 'SystemResource';
@ -58,7 +62,7 @@ class SystemResource implements IStorage
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function __toString() public function __toString(): string
{ {
return self::NAME; return self::NAME;
} }

View file

@ -211,11 +211,11 @@ abstract class DI
} }
/** /**
* @return Core\StorageManager * @return \Friendica\Core\Storage\Repository\StorageManager
*/ */
public static function storageManager() public static function storageManager()
{ {
return self::$dice->create(Core\StorageManager::class); return self::$dice->create(Core\Storage\Repository\StorageManager::class);
} }
// //
@ -395,11 +395,11 @@ abstract class DI
} }
/** /**
* @return Model\Storage\IWritableStorage * @return Core\Storage\Capability\ICanWriteToStorage
*/ */
public static function storage() public static function storage()
{ {
return self::$dice->create(Model\Storage\IWritableStorage::class); return self::$dice->create(Core\Storage\Capability\ICanWriteToStorage::class);
} }
/** /**

View file

@ -25,8 +25,8 @@ use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Storage\InvalidClassStorageException; use Friendica\Core\Storage\Exception\InvalidClassStorageException;
use Friendica\Model\Storage\ReferenceStorageException; use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Mimetype; use Friendica\Util\Mimetype;

View file

@ -27,11 +27,11 @@ use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Storage\ExternalResource; use Friendica\Core\Storage\Type\ExternalResource;
use Friendica\Model\Storage\InvalidClassStorageException; use Friendica\Core\Storage\Exception\InvalidClassStorageException;
use Friendica\Model\Storage\ReferenceStorageException; use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Model\Storage\StorageException; use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Model\Storage\SystemResource; use Friendica\Core\Storage\Type\SystemResource;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images; use Friendica\Util\Images;

View file

@ -23,9 +23,9 @@ namespace Friendica\Module\Admin;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Storage\InvalidClassStorageException; use Friendica\Core\Storage\Exception\InvalidClassStorageException;
use Friendica\Model\Storage\IStorageConfiguration; use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Module\BaseAdmin; use Friendica\Module\BaseAdmin;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -40,7 +40,7 @@ class Storage extends BaseAdmin
$storagebackend = Strings::escapeTags(trim($parameters['name'] ?? '')); $storagebackend = Strings::escapeTags(trim($parameters['name'] ?? ''));
try { try {
/** @var IStorageConfiguration|false $newStorageConfig */ /** @var ICanConfigureStorage|false $newStorageConfig */
$newStorageConfig = DI::storageManager()->getConfigurationByName($storagebackend); $newStorageConfig = DI::storageManager()->getConfigurationByName($storagebackend);
} catch (InvalidClassStorageException $storageException) { } catch (InvalidClassStorageException $storageException) {
notice(DI::l10n()->t('Storage backend, %s is invalid.', $storagebackend)); notice(DI::l10n()->t('Storage backend, %s is invalid.', $storagebackend));
@ -78,7 +78,6 @@ class Storage extends BaseAdmin
if (!empty($_POST['submit_save_set'])) { if (!empty($_POST['submit_save_set'])) {
try { try {
/** @var IWritableStorage $newstorage */
$newstorage = DI::storageManager()->getWritableStorageByName($storagebackend); $newstorage = DI::storageManager()->getWritableStorageByName($storagebackend);
if (!DI::storageManager()->setBackend($newstorage)) { if (!DI::storageManager()->setBackend($newstorage)) {
@ -129,7 +128,7 @@ class Storage extends BaseAdmin
'name' => $name, 'name' => $name,
'prefix' => $storage_form_prefix, 'prefix' => $storage_form_prefix,
'form' => $storage_form, 'form' => $storage_form,
'active' => $current_storage_backend instanceof IWritableStorage && $name === $current_storage_backend::getName(), 'active' => $current_storage_backend instanceof ICanWriteToStorage && $name === $current_storage_backend::getName(),
]; ];
} }
@ -147,7 +146,7 @@ class Storage extends BaseAdmin
'$noconfig' => DI::l10n()->t('This backend doesn\'t have custom settings'), '$noconfig' => DI::l10n()->t('This backend doesn\'t have custom settings'),
'$baseurl' => DI::baseUrl()->get(true), '$baseurl' => DI::baseUrl()->get(true),
'$form_security_token' => self::getFormSecurityToken("admin_storage"), '$form_security_token' => self::getFormSecurityToken("admin_storage"),
'$storagebackend' => $current_storage_backend instanceof IWritableStorage ? $current_storage_backend::getName() : DI::l10n()->t('Database (legacy)'), '$storagebackend' => $current_storage_backend instanceof ICanWriteToStorage ? $current_storage_backend::getName() : DI::l10n()->t('Database (legacy)'),
'$availablestorageforms' => $available_storage_forms, '$availablestorageforms' => $available_storage_forms,
]); ]);
} }

View file

@ -29,8 +29,8 @@ use Friendica\Model\Contact;
use Friendica\Model\Photo as MPhoto; use Friendica\Model\Photo as MPhoto;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\Profile; use Friendica\Model\Profile;
use Friendica\Model\Storage\ExternalResource; use Friendica\Core\Storage\Type\ExternalResource;
use Friendica\Model\Storage\SystemResource; use Friendica\Core\Storage\Type\SystemResource;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Object\Image; use Friendica\Object\Image;

View file

@ -42,10 +42,10 @@ use Friendica\Core\L10n;
use Friendica\Core\Lock; use Friendica\Core\Lock;
use Friendica\Core\Process; use Friendica\Core\Process;
use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleSessions;
use Friendica\Core\StorageManager; use Friendica\Core\Storage\Repository\StorageManager;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Factory; use Friendica\Factory;
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Model\User\Cookie; use Friendica\Model\User\Cookie;
use Friendica\Model\Log\ParsedLogIterator; use Friendica\Model\Log\ParsedLogIterator;
use Friendica\Network; use Friendica\Network;
@ -218,7 +218,7 @@ return [
$_SERVER, $_COOKIE $_SERVER, $_COOKIE
], ],
], ],
IWritableStorage::class => [ ICanWriteToStorage::class => [
'instanceOf' => StorageManager::class, 'instanceOf' => StorageManager::class,
'call' => [ 'call' => [
['getBackend', [], Dice::CHAIN_CALL], ['getBackend', [], Dice::CHAIN_CALL],

View file

@ -22,14 +22,14 @@
namespace Friendica\Test\Util; namespace Friendica\Test\Util;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Core\L10n; use Friendica\Core\L10n;
/** /**
* A backend storage example class * A backend storage example class
*/ */
class SampleStorageBackend implements IWritableStorage class SampleStorageBackend implements ICanWriteToStorage
{ {
const NAME = 'Sample Storage'; const NAME = 'Sample Storage';
@ -102,7 +102,7 @@ class SampleStorageBackend implements IWritableStorage
return $this->options; return $this->options;
} }
public function __toString() public function __toString(): string
{ {
return self::NAME; return self::NAME;
} }

View file

@ -19,10 +19,10 @@
* *
*/ */
namespace Friendica\Test\src\Model\Storage; namespace Friendica\Test\src\Core\Storage;
use Friendica\Core\Config\Factory\Config; use Friendica\Core\Config\Factory\Config;
use Friendica\Model\Storage\Database; use Friendica\Core\Storage\Type\Database;
use Friendica\Test\DatabaseTestTrait; use Friendica\Test\DatabaseTestTrait;
use Friendica\Test\Util\Database\StaticDatabase; use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait; use Friendica\Test\Util\VFSTrait;

View file

@ -19,12 +19,12 @@
* *
*/ */
namespace Friendica\Test\src\Model\Storage; namespace Friendica\Test\src\Core\Storage;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Model\Storage\FilesystemConfig; use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Model\Storage\IStorageConfiguration; use Friendica\Core\Storage\Type\FilesystemConfig;
use Friendica\Test\Util\VFSTrait; use Friendica\Test\Util\VFSTrait;
use Mockery\MockInterface; use Mockery\MockInterface;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
@ -54,7 +54,7 @@ class FilesystemStorageConfigTest extends StorageConfigTest
return new FilesystemConfig($config, $l10n); return new FilesystemConfig($config, $l10n);
} }
protected function assertOption(IStorageConfiguration $storage) protected function assertOption(ICanConfigureStorage $storage)
{ {
self::assertEquals([ self::assertEquals([
'storagepath' => [ 'storagepath' => [

View file

@ -19,11 +19,11 @@
* *
*/ */
namespace Friendica\Test\src\Model\Storage; namespace Friendica\Test\src\Core\Storage;
use Friendica\Model\Storage\Filesystem; use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Model\Storage\FilesystemConfig; use Friendica\Core\Storage\Type\Filesystem;
use Friendica\Model\Storage\StorageException; use Friendica\Core\Storage\Type\FilesystemConfig;
use Friendica\Test\Util\VFSTrait; use Friendica\Test\Util\VFSTrait;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;

View file

@ -19,7 +19,7 @@
* *
*/ */
namespace Friendica\Test\src\Core; namespace Friendica\Test\src\Core\Storage\Repository;
use Dice\Dice; use Dice\Dice;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
@ -28,12 +28,18 @@ use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleSessions;
use Friendica\Core\Session\Type\Memory; use Friendica\Core\Session\Type\Memory;
use Friendica\Core\StorageManager; use Friendica\Core\Storage\Exception\InvalidClassStorageException;
use Friendica\Core\Storage\Capability\ICanReadFromStorage;
use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Core\Storage\Exception\StorageException;
use Friendica\Core\Storage\Repository\StorageManager;
use Friendica\Core\Storage\Type\Filesystem;
use Friendica\Core\Storage\Type\SystemResource;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\DI; use Friendica\DI;
use Friendica\Core\Config\Factory\Config; use Friendica\Core\Config\Factory\Config;
use Friendica\Core\Config\Repository; use Friendica\Core\Config\Repository;
use Friendica\Model\Storage; use Friendica\Core\Storage\Type;
use Friendica\Network\HTTPClient; use Friendica\Network\HTTPClient;
use Friendica\Test\DatabaseTest; use Friendica\Test\DatabaseTest;
use Friendica\Test\Util\Database\StaticDatabase; use Friendica\Test\Util\Database\StaticDatabase;
@ -64,7 +70,7 @@ class StorageManagerTest extends DatabaseTest
$this->setUpVfsDir(); $this->setUpVfsDir();
vfsStream::newDirectory(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER, 0777)->at($this->root); vfsStream::newDirectory(Type\FilesystemConfig::DEFAULT_BASE_FOLDER, 0777)->at($this->root);
$this->logger = new NullLogger(); $this->logger = new NullLogger();
@ -83,7 +89,7 @@ class StorageManagerTest extends DatabaseTest
$configModel = new Repository\Config($this->dba); $configModel = new Repository\Config($this->dba);
$this->config = new PreloadConfig($configCache, $configModel); $this->config = new PreloadConfig($configCache, $configModel);
$this->config->set('storage', 'name', 'Database'); $this->config->set('storage', 'name', 'Database');
$this->config->set('storage', 'filesystem_path', $this->root->getChild(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER)->url()); $this->config->set('storage', 'filesystem_path', $this->root->getChild(Type\FilesystemConfig::DEFAULT_BASE_FOLDER)->url());
$this->l10n = \Mockery::mock(L10n::class); $this->l10n = \Mockery::mock(L10n::class);
@ -92,7 +98,7 @@ class StorageManagerTest extends DatabaseTest
protected function tearDown(): void protected function tearDown(): void
{ {
$this->root->removeChild(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER); $this->root->removeChild(Type\FilesystemConfig::DEFAULT_BASE_FOLDER);
parent::tearDown(); parent::tearDown();
} }
@ -113,30 +119,30 @@ class StorageManagerTest extends DatabaseTest
'empty' => [ 'empty' => [
'name' => '', 'name' => '',
'valid' => false, 'valid' => false,
'interface' => Storage\IStorage::class, 'interface' => ICanReadFromStorage::class,
'assert' => null, 'assert' => null,
'assertName' => '', 'assertName' => '',
], ],
'database' => [ 'database' => [
'name' => Storage\Database::NAME, 'name' => Type\Database::NAME,
'valid' => true, 'valid' => true,
'interface' => Storage\IWritableStorage::class, 'interface' => ICanWriteToStorage::class,
'assert' => Storage\Database::class, 'assert' => Type\Database::class,
'assertName' => Storage\Database::NAME, 'assertName' => Type\Database::NAME,
], ],
'filesystem' => [ 'filesystem' => [
'name' => Storage\Filesystem::NAME, 'name' => Filesystem::NAME,
'valid' => true, 'valid' => true,
'interface' => Storage\IWritableStorage::class, 'interface' => ICanWriteToStorage::class,
'assert' => Storage\Filesystem::class, 'assert' => Filesystem::class,
'assertName' => Storage\Filesystem::NAME, 'assertName' => Filesystem::NAME,
], ],
'systemresource' => [ 'systemresource' => [
'name' => Storage\SystemResource::NAME, 'name' => SystemResource::NAME,
'valid' => true, 'valid' => true,
'interface' => Storage\IStorage::class, 'interface' => ICanReadFromStorage::class,
'assert' => Storage\SystemResource::class, 'assert' => SystemResource::class,
'assertName' => Storage\SystemResource::NAME, 'assertName' => SystemResource::NAME,
], ],
'invalid' => [ 'invalid' => [
'name' => 'invalid', 'name' => 'invalid',
@ -157,16 +163,16 @@ class StorageManagerTest extends DatabaseTest
public function testGetByName($name, $valid, $interface, $assert, $assertName) public function testGetByName($name, $valid, $interface, $assert, $assertName)
{ {
if (!$valid) { if (!$valid) {
$this->expectException(Storage\InvalidClassStorageException::class); $this->expectException(InvalidClassStorageException::class);
} }
if ($interface === Storage\IWritableStorage::class) { if ($interface === ICanWriteToStorage::class) {
$this->config->set('storage', 'name', $name); $this->config->set('storage', 'name', $name);
} }
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n); $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
if ($interface === Storage\IWritableStorage::class) { if ($interface === ICanWriteToStorage::class) {
$storage = $storageManager->getWritableStorageByName($name); $storage = $storageManager->getWritableStorageByName($name);
} else { } else {
$storage = $storageManager->getByName($name); $storage = $storageManager->getByName($name);
@ -189,8 +195,8 @@ class StorageManagerTest extends DatabaseTest
// true in every of the backends // true in every of the backends
self::assertEquals(!empty($assertName), $storageManager->isValidBackend($name)); self::assertEquals(!empty($assertName), $storageManager->isValidBackend($name));
// if it's a IWritableStorage, the valid backend should return true, otherwise false // if it's a ICanWriteToStorage, the valid backend should return true, otherwise false
self::assertEquals($interface === Storage\IWritableStorage::class, $storageManager->isValidBackend($name, StorageManager::DEFAULT_BACKENDS)); self::assertEquals($interface === ICanWriteToStorage::class, $storageManager->isValidBackend($name, StorageManager::DEFAULT_BACKENDS));
} }
/** /**
@ -210,8 +216,8 @@ class StorageManagerTest extends DatabaseTest
*/ */
public function testGetBackend($name, $valid, $interface, $assert, $assertName) public function testGetBackend($name, $valid, $interface, $assert, $assertName)
{ {
if ($interface !== Storage\IWritableStorage::class) { if ($interface !== ICanWriteToStorage::class) {
static::markTestSkipped('only works for IWritableStorage'); static::markTestSkipped('only works for ICanWriteToStorage');
} }
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n); $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
@ -230,8 +236,8 @@ class StorageManagerTest extends DatabaseTest
public function testPresetBackend($name, $valid, $interface, $assert, $assertName) public function testPresetBackend($name, $valid, $interface, $assert, $assertName)
{ {
$this->config->set('storage', 'name', $name); $this->config->set('storage', 'name', $name);
if ($interface !== Storage\IWritableStorage::class) { if ($interface !== ICanWriteToStorage::class) {
$this->expectException(Storage\InvalidClassStorageException::class); $this->expectException(InvalidClassStorageException::class);
} }
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n); $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
@ -250,9 +256,9 @@ class StorageManagerTest extends DatabaseTest
{ {
/// @todo Remove dice once "Hook" is dynamic and mockable /// @todo Remove dice once "Hook" is dynamic and mockable
$dice = (new Dice()) $dice = (new Dice())
->addRules(include __DIR__ . '/../../../static/dependencies.config.php') ->addRules(include __DIR__ . '/../../../../../static/dependencies.config.php')
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true]) ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
->addRule(IHandleSessions::class, ['instanceOf' => Session\Type\Memory::class, 'shared' => true, 'call' => null]); ->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]);
DI::init($dice); DI::init($dice);
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n); $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
@ -278,7 +284,7 @@ class StorageManagerTest extends DatabaseTest
{ {
/// @todo Remove dice once "Hook" is dynamic and mockable /// @todo Remove dice once "Hook" is dynamic and mockable
$dice = (new Dice()) $dice = (new Dice())
->addRules(include __DIR__ . '/../../../static/dependencies.config.php') ->addRules(include __DIR__ . '/../../../../../static/dependencies.config.php')
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true]) ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]); ->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]);
DI::init($dice); DI::init($dice);
@ -303,7 +309,7 @@ class StorageManagerTest extends DatabaseTest
self::assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend()); self::assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
self::expectException(Storage\StorageException::class); self::expectException(StorageException::class);
self::expectExceptionMessage('Cannot unregister Sample Storage, because it\'s currently active.'); self::expectExceptionMessage('Cannot unregister Sample Storage, because it\'s currently active.');
$storageManager->unregister(SampleStorageBackend::class); $storageManager->unregister(SampleStorageBackend::class);
@ -316,11 +322,11 @@ class StorageManagerTest extends DatabaseTest
*/ */
public function testMoveStorage($name, $valid, $interface, $assert, $assertName) public function testMoveStorage($name, $valid, $interface, $assert, $assertName)
{ {
if ($interface !== Storage\IWritableStorage::class) { if ($interface !== ICanWriteToStorage::class) {
self::markTestSkipped("No user backend"); self::markTestSkipped("No user backend");
} }
$this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba); $this->loadFixture(__DIR__ . '/../../../../datasets/storage/database.fixture.php', $this->dba);
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n); $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
$storage = $storageManager->getWritableStorageByName($name); $storage = $storageManager->getWritableStorageByName($name);
@ -343,11 +349,11 @@ class StorageManagerTest extends DatabaseTest
*/ */
public function testWrongWritableStorage() public function testWrongWritableStorage()
{ {
$this->expectException(Storage\InvalidClassStorageException::class); $this->expectException(InvalidClassStorageException::class);
$this->expectExceptionMessage('Backend SystemResource is not valid'); $this->expectExceptionMessage('Backend SystemResource is not valid');
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n); $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
$storage = $storageManager->getWritableStorageByName(Storage\SystemResource::getName()); $storage = $storageManager->getWritableStorageByName(SystemResource::getName());
$storageManager->move($storage); $storageManager->move($storage);
} }
} }

View file

@ -19,17 +19,17 @@
* *
*/ */
namespace Friendica\Test\src\Model\Storage; namespace Friendica\Test\src\Core\Storage;
use Friendica\Model\Storage\IStorageConfiguration; use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Test\MockedTest; use Friendica\Test\MockedTest;
abstract class StorageConfigTest extends MockedTest abstract class StorageConfigTest extends MockedTest
{ {
/** @return IStorageConfiguration */ /** @return ICanConfigureStorage */
abstract protected function getInstance(); abstract protected function getInstance();
abstract protected function assertOption(IStorageConfiguration $storage); abstract protected function assertOption(ICanConfigureStorage $storage);
/** /**
* Test if the "getOption" is asserted * Test if the "getOption" is asserted

View file

@ -19,16 +19,16 @@
* *
*/ */
namespace Friendica\Test\src\Model\Storage; namespace Friendica\Test\src\Core\Storage;
use Friendica\Model\Storage\IWritableStorage; use Friendica\Core\Storage\Capability\ICanReadFromStorage;
use Friendica\Model\Storage\IStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Model\Storage\ReferenceStorageException; use Friendica\Core\Storage\Exception\ReferenceStorageException;
use Friendica\Test\MockedTest; use Friendica\Test\MockedTest;
abstract class StorageTest extends MockedTest abstract class StorageTest extends MockedTest
{ {
/** @return IWritableStorage */ /** @return ICanWriteToStorage */
abstract protected function getInstance(); abstract protected function getInstance();
/** /**
@ -37,7 +37,7 @@ abstract class StorageTest extends MockedTest
public function testInstance() public function testInstance()
{ {
$instance = $this->getInstance(); $instance = $this->getInstance();
self::assertInstanceOf(IStorage::class, $instance); self::assertInstanceOf(ICanReadFromStorage::class, $instance);
} }
/** /**

View file

@ -41,6 +41,7 @@
*/ */
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Storage\Capability\ICanReadFromStorage;
use Friendica\Core\Update; use Friendica\Core\Update;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\Database; use Friendica\Database\Database;
@ -54,7 +55,6 @@ use Friendica\Model\Notification;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\Profile; use Friendica\Model\Profile;
use Friendica\Model\Storage;
use Friendica\Security\PermissionSet\Repository\PermissionSet; use Friendica\Security\PermissionSet\Repository\PermissionSet;
use Friendica\Worker\Delivery; use Friendica\Worker\Delivery;
@ -183,7 +183,7 @@ function update_1330()
// set the name of the storage instead of the classpath as config // set the name of the storage instead of the classpath as config
if (!empty($currStorage)) { if (!empty($currStorage)) {
/** @var Storage\IStorage $currStorage */ /** @var ICanReadFromStorage $currStorage */
if (!DI::config()->set('storage', 'name', $currStorage::getName())) { if (!DI::config()->set('storage', 'name', $currStorage::getName())) {
return Update::FAILED; return Update::FAILED;
} }
@ -989,7 +989,7 @@ function update_1434()
// in case of an empty config, set "Database" as default storage backend // in case of an empty config, set "Database" as default storage backend
if (empty($name)) { if (empty($name)) {
DI::config()->set('storage', 'name', Storage\Database::getName()); DI::config()->set('storage', 'name', \Friendica\Core\Storage\Type\Database::getName());
} }
// In case of a Using deprecated storage class value, set the right name for it // In case of a Using deprecated storage class value, set the right name for it

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2021.12-dev\n" "Project-Id-Version: 2021.12-dev\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-24 23:21-0400\n" "POT-Creation-Date: 2021-10-27 20:01+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -2087,11 +2087,11 @@ msgid ""
"your site allow private mail from unknown senders." "your site allow private mail from unknown senders."
msgstr "" msgstr ""
#: src/App.php:456 #: src/App.php:455
msgid "No system theme config value set." msgid "No system theme config value set."
msgstr "" msgstr ""
#: src/App/Module.php:240 #: src/App/Module.php:241
msgid "You must be logged in to use addons. " msgid "You must be logged in to use addons. "
msgstr "" msgstr ""
@ -3877,6 +3877,20 @@ msgstr ""
msgid "template engine is not registered!" msgid "template engine is not registered!"
msgstr "" msgstr ""
#: src/Core/Storage/Type/FilesystemConfig.php:78
msgid "Storage base path"
msgstr ""
#: src/Core/Storage/Type/FilesystemConfig.php:80
msgid ""
"Folder where uploaded files are saved. For maximum security, This should be "
"a path outside web server folder tree"
msgstr ""
#: src/Core/Storage/Type/FilesystemConfig.php:93
msgid "Enter a valid existing folder"
msgstr ""
#: src/Core/Update.php:67 #: src/Core/Update.php:67
#, php-format #, php-format
msgid "" msgid ""
@ -4414,20 +4428,6 @@ msgstr ""
msgid "Contact information and Social Networks" msgid "Contact information and Social Networks"
msgstr "" msgstr ""
#: src/Model/Storage/FilesystemConfig.php:77
msgid "Storage base path"
msgstr ""
#: src/Model/Storage/FilesystemConfig.php:79
msgid ""
"Folder where uploaded files are saved. For maximum security, This should be "
"a path outside web server folder tree"
msgstr ""
#: src/Model/Storage/FilesystemConfig.php:92
msgid "Enter a valid existing folder"
msgstr ""
#: src/Model/User.php:208 src/Model/User.php:1050 #: src/Model/User.php:208 src/Model/User.php:1050
msgid "SERIOUS ERROR: Generation of security keys failed." msgid "SERIOUS ERROR: Generation of security keys failed."
msgstr "" msgstr ""
@ -4475,13 +4475,13 @@ msgstr ""
msgid "Invalid OpenID url" msgid "Invalid OpenID url"
msgstr "" msgstr ""
#: src/Model/User.php:962 src/Security/Authentication.php:223 #: src/Model/User.php:962 src/Security/Authentication.php:224
msgid "" msgid ""
"We encountered a problem while logging in with the OpenID you provided. " "We encountered a problem while logging in with the OpenID you provided. "
"Please check the correct spelling of the ID." "Please check the correct spelling of the ID."
msgstr "" msgstr ""
#: src/Model/User.php:962 src/Security/Authentication.php:223 #: src/Model/User.php:962 src/Security/Authentication.php:224
msgid "The error message was:" msgid "The error message was:"
msgstr "" msgstr ""
@ -10579,20 +10579,20 @@ msgstr ""
msgid "The folder view/smarty3/ must be writable by webserver." msgid "The folder view/smarty3/ must be writable by webserver."
msgstr "" msgstr ""
#: src/Security/Authentication.php:209 #: src/Security/Authentication.php:210
msgid "Login failed." msgid "Login failed."
msgstr "" msgstr ""
#: src/Security/Authentication.php:250 #: src/Security/Authentication.php:251
msgid "Login failed. Please check your credentials." msgid "Login failed. Please check your credentials."
msgstr "" msgstr ""
#: src/Security/Authentication.php:348 #: src/Security/Authentication.php:349
#, php-format #, php-format
msgid "Welcome %s" msgid "Welcome %s"
msgstr "" msgstr ""
#: src/Security/Authentication.php:349 #: src/Security/Authentication.php:350
msgid "Please upload a profile photo." msgid "Please upload a profile photo."
msgstr "" msgstr ""