Update AddonStorageBackend documentation

This commit is contained in:
Philipp Holzer 2020-01-05 22:33:27 +01:00
parent 08edeae2f9
commit cc501439af
No known key found for this signature in database
GPG Key ID: D8365C3D36B77D90
1 changed files with 108 additions and 31 deletions

View File

@ -17,22 +17,23 @@ namespace Friendica\Model\Storage;
```php ```php
interface IStorage interface IStorage
{ {
public static function get($ref); public function get(string $reference);
public static function put($data, $ref = ""); public function put(string $data, string $reference = '');
public static function delete($ref); public function delete(string $reference);
public static function getOptions(); public function getOptions();
public static function saveOptions($data); public function saveOptions(array $data);
public function __toString();
} }
``` ```
- `get($ref)` returns data pointed by `$ref` - `get(string $reference)` returns data pointed by `$reference`
- `put($data, $ref)` saves data in `$data` to position `$ref`, or a new position if `$ref` is empty. - `put(string $data, string $reference)` saves data in `$data` to position `$reference`, or a new position if `$reference` is empty.
- `delete($ref)` delete data pointed by `$ref` - `delete(string $reference)` delete data pointed by `$reference`
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.
- `getOptions()` returns an array with details about each option to build the interface. - `getOptions()` returns an array with details about each option to build the interface.
- `saveOptions($data)` get `$data` from admin page, validate it and save it. - `saveOptions(array $data)` get `$data` from admin page, validate it and save it.
The array returned by `getOptions()` is defined as: The array returned by `getOptions()` is defined as:
@ -84,11 +85,33 @@ See doxygen documentation of `IStorage` interface for details about each method.
Each backend must be registered in the system when the plugin is installed, to be aviable. Each backend must be registered in the system when the plugin is installed, to be aviable.
`Friendica\Core\StorageManager::register($name, $class)` is used to register the backend class. `DI::facStorage()->register(string $name, string $class)` is used to register the backend class.
The `$name` must be univocal and will be shown to admin. The `$name` must be univocal and will be shown to admin.
When the plugin is uninstalled, registered backends must be unregistered using When the plugin is uninstalled, registered backends must be unregistered using
`Friendica\Core\StorageManager::unregister($class)`. `DI::facStorage()->unregister(string $name)`.
## Adding tests
**Currently testing is limited to core Friendica only, this shows theoretically how tests should work in the future**
Each new Storage class should be added to the test-environment at [Storage Tests](https://github.com/friendica/friendica/tree/develop/tests/src/Model/Storage/).
Add a new test class which's naming convention is `StorageClassTest`, which extend the `StorageTest` in the same directory.
Override the two necessary instances:
```php
use Friendica\Model\Storage\IStorage;
abstract class StorageTest
{
// returns an instance of your newly created storage class
abstract protected function getInstance();
// Assertion for the option array you return for your new StorageClass
abstract protected function assertOption(IStorage $storage);
}
```
## Example ## Example
@ -112,60 +135,86 @@ use Friendica\Core\L10n;
class SampleStorageBackend implements IStorage class SampleStorageBackend implements IStorage
{ {
public static function get($ref) const NAME = 'Sample Storage';
/** @var Config\IConfiguration */
private $config;
/** @var L10n\L10n */
private $l10n;
/**
* SampleStorageBackend constructor.
* @param Config\IConfiguration $config The configuration of Friendica
*
* You can add here every dynamic class as dependency you like and add them to a private field
* Friendica automatically creates these classes and passes them as argument to the constructor
*/
public function __construct(Config\IConfiguration $config, L10n\L10n $l10n)
{ {
// we return alwais the same image data. Which file we load is defined by $this->config = $config;
$this->l10n = $l10n;
}
public function get(string $reference)
{
// we return always the same image data. Which file we load is defined by
// a config key // a config key
$filename = Config::get("storage", "samplestorage", "sample.jpg"); $filename = $this->config->get('storage', 'samplestorage', 'sample.jpg');
return file_get_contents($filename); return file_get_contents($filename);
} }
public static function put($data, $ref = "") public function put(string $data, string $reference = '')
{ {
if ($ref === "") { if ($reference === '') {
$ref = "sample"; $reference = 'sample';
} }
// we don't save $data ! // we don't save $data !
return $ref; return $reference;
} }
public static function delete($ref) public function delete(string $reference)
{ {
// we pretend to delete the data // we pretend to delete the data
return true; return true;
} }
public static function getOptions() public function getOptions()
{ {
$filename = Config::get("storage", "samplestorage", "sample.jpg"); $filename = $this->config->get('storage', 'samplestorage', 'sample.jpg');
return [ return [
"filename" => [ 'filename' => [
"input", // will use a simple text input 'input', // will use a simple text input
L10n::t("The file to return"), // the label $this->l10n->t('The file to return'), // the label
$filename, // the current value $filename, // the current value
L10n::t("Enter the path to a file"), // the help text $this->l10n->t('Enter the path to a file'), // the help text
// no extra data for "input" type.. // no extra data for 'input' type..
],
]; ];
} }
public static function saveOptions($data) public function saveOptions(array $data)
{ {
// the keys in $data are the same keys we defined in getOptions() // the keys in $data are the same keys we defined in getOptions()
$newfilename = trim($data["filename"]); $newfilename = trim($data['filename']);
// this function should always validate the data. // this function should always validate the data.
// in this example we check if file exists // in this example we check if file exists
if (!file_exists($newfilename)) { if (!file_exists($newfilename)) {
// in case of error we return an array with // in case of error we return an array with
// ["optionname" => "error message"] // ['optionname' => 'error message']
return ["filename" => "The file doesn't exists"]; return ['filename' => 'The file doesn\'t exists'];
} }
Config::set("storage", "samplestorage", $newfilename); $this->config->set('storage', 'samplestorage', $newfilename);
// no errors, return empty array // no errors, return empty array
return []; return [];
} }
public function __toString()
{
return self::NAME;
}
} }
``` ```
@ -200,5 +249,33 @@ function samplestorage_unistall()
} }
``` ```
**Theoretically - until tests for Addons are enabled too - create a test class with the name `addon/tests/SampleStorageTest.php`:
```php
use Friendica\Model\Storage\IStorage;
use Friendica\Test\src\Model\Storage\StorageTest;
class SampleStorageTest extends StorageTest
{
// returns an instance of your newly created storage class
protected function getInstance()
{
// create a new SampleStorageBackend instance with all it's dependencies
// Have a look at DatabaseStorageTest or FilesystemStorageTest for further insights
return new SampleStorageBackend();
}
// Assertion for the option array you return for your new StorageClass
protected function assertOption(IStorage $storage)
{
$this->assertEquals([
'filename' => [
'input',
'The file to return',
'sample.jpg',
'Enter the path to a file'
],
], $storage->getOptions());
}
}
```