2018-12-12 20:36:56 +01:00
|
|
|
Friendica Storage Backend Addon development
|
|
|
|
===========================================
|
|
|
|
|
|
|
|
* [Home](help)
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
## The Storage Backend Class
|
|
|
|
|
|
|
|
The class must live in `Friendica\Addon\youraddonname` namespace, where `youraddonname` the folder name of your addon.
|
|
|
|
|
|
|
|
The class must implement `Friendica\Model\Storage\IStorage` interface. All method in the interface must be implemented:
|
|
|
|
|
|
|
|
namespace Friendica\Model\Storage;
|
|
|
|
|
2018-12-12 20:52:09 +01:00
|
|
|
```php
|
|
|
|
interface IStorage
|
|
|
|
{
|
|
|
|
public static function get($ref);
|
|
|
|
public static function put($data, $ref = "");
|
|
|
|
public static function delete($ref);
|
|
|
|
public static function getOptions();
|
|
|
|
public static function saveOptions($data);
|
|
|
|
}
|
|
|
|
```
|
2018-12-12 20:36:56 +01:00
|
|
|
|
|
|
|
- `get($ref)` returns data pointed by `$ref`
|
|
|
|
- `put($data, $ref)` saves data in `$data` to position `$ref`, or a new position if `$ref` is empty.
|
|
|
|
- `delete($ref)` delete data pointed by `$ref`
|
|
|
|
|
|
|
|
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.
|
|
|
|
- `saveOptions($data)` get `$data` from admin page, validate it and save it.
|
|
|
|
|
|
|
|
The array returned by `getOptions()` is defined as:
|
|
|
|
|
|
|
|
[
|
|
|
|
'option1name' => [ ..info.. ],
|
|
|
|
'option2name' => [ ..info.. ],
|
|
|
|
...
|
|
|
|
]
|
|
|
|
|
|
|
|
An empty array can be returned if backend doesn't have any options.
|
|
|
|
|
|
|
|
The info array for each option is defined as:
|
|
|
|
|
|
|
|
[
|
|
|
|
'type',
|
|
|
|
|
|
|
|
define the field used in form, and the type of data.
|
|
|
|
one of 'checkbox', 'combobox', 'custom', 'datetime', 'input', 'intcheckbox', 'password', 'radio', 'richtext', 'select', 'select_raw', 'textarea', 'yesno'
|
|
|
|
|
|
|
|
'label',
|
|
|
|
|
|
|
|
Translatable label of the field. This label will be shown in admin page
|
|
|
|
|
|
|
|
value,
|
|
|
|
|
|
|
|
Current value of the option
|
|
|
|
|
|
|
|
'help text',
|
|
|
|
|
|
|
|
Translatable description for the field. Will be shown in admin page
|
|
|
|
|
|
|
|
extra data
|
|
|
|
|
|
|
|
Optional. Depends on which 'type' this option is:
|
|
|
|
|
|
|
|
- 'select': array `[ value => label ]` of choices
|
|
|
|
- 'intcheckbox': value of input element
|
|
|
|
- 'select_raw': prebuild html string of `<option >` tags
|
|
|
|
- 'yesno': array `[ 'label no', 'label yes']`
|
|
|
|
|
|
|
|
Each label should be translatable
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
See doxygen documentation of `IStorage` interface for details about each method.
|
|
|
|
|
|
|
|
## Register a storage backend class
|
|
|
|
|
|
|
|
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.
|
|
|
|
The `$name` must be univocal and will be shown to admin.
|
|
|
|
|
|
|
|
When the plugin is uninstalled, registered backends must be unregistered using
|
|
|
|
`Friendica\Core\StorageManager::unregister($class)`.
|
|
|
|
|
|
|
|
## Example
|
|
|
|
|
|
|
|
Here an hypotetical addon which register an unusefull storage backend.
|
|
|
|
Let's call it `samplestorage`.
|
|
|
|
|
|
|
|
This backend will discard all data we try to save and will return always the same image when we ask for some data.
|
|
|
|
The image returned can be set by the administrator in admin page.
|
|
|
|
|
|
|
|
First, the backend class.
|
|
|
|
The file will be `addon/samplestorage/SampleStorageBackend.php`:
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
namespace Friendica\Addon\samplestorage;
|
|
|
|
|
|
|
|
use Friendica\Model\Storage\IStorage;
|
|
|
|
|
|
|
|
use Friendica\Core\Config;
|
|
|
|
use Friendica\Core\L10n;
|
|
|
|
|
|
|
|
class SampleStorageBackend implements IStorage
|
|
|
|
{
|
|
|
|
public static function get($ref)
|
|
|
|
{
|
|
|
|
// we return alwais the same image data. Which file we load is defined by
|
|
|
|
// a config key
|
|
|
|
$filename = Config::get("storage", "samplestorage", "sample.jpg");
|
|
|
|
return file_get_contents($filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function put($data, $ref = "")
|
|
|
|
{
|
|
|
|
if ($ref === "") {
|
|
|
|
$ref = "sample";
|
|
|
|
}
|
|
|
|
// we don't save $data !
|
|
|
|
return $ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function delete($ref)
|
|
|
|
{
|
|
|
|
// we pretend to delete the data
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getOptions()
|
|
|
|
{
|
|
|
|
$filename = Config::get("storage", "samplestorage", "sample.jpg");
|
|
|
|
return [
|
|
|
|
"filename" => [
|
|
|
|
"input", // will use a simple text input
|
|
|
|
L10n::t("The file to return"), // the label
|
|
|
|
$filename, // the current value
|
|
|
|
L10n::t("Enter the path to a file"), // the help text
|
|
|
|
// no extra data for "input" type..
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function saveOptions($data)
|
|
|
|
{
|
|
|
|
// the keys in $data are the same keys we defined in getOptions()
|
|
|
|
$newfilename = trim($data["filename"]);
|
|
|
|
|
|
|
|
// this function should always validate the data.
|
|
|
|
// in this example we check if file exists
|
|
|
|
if (!file_exists($newfilename)) {
|
|
|
|
// in case of error we return an array with
|
|
|
|
// ["optionname" => "error message"]
|
|
|
|
return ["filename" => "The file doesn't exists"];
|
|
|
|
}
|
|
|
|
|
|
|
|
Config::set("storage", "samplestorage", $newfilename);
|
|
|
|
|
|
|
|
// no errors, return empty array
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Now the plugin main file. Here we register and unregister the backend class.
|
|
|
|
|
|
|
|
The file is `addon/samplestorage/samplestorage.php`
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Name: Sample Storage Addon
|
|
|
|
* Description: A sample addon which implements an unusefull storage backend
|
|
|
|
* Version: 1.0.0
|
|
|
|
* Author: Alice <https://alice.social/~alice>
|
|
|
|
*/
|
|
|
|
|
|
|
|
use Friendica\Core\StorageManager;
|
|
|
|
use Friendica\Addon\samplestorage\SampleStorageBackend;
|
|
|
|
|
|
|
|
function samplestorage_install()
|
|
|
|
{
|
|
|
|
// on addon install, we register our class with name "Sample Storage".
|
|
|
|
// note: we use `::class` property, which returns full class name as string
|
|
|
|
// this save us the problem of correctly escape backslashes in class name
|
|
|
|
StorageManager::register("Sample Storage", SampleStorageBackend::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
function samplestorage_unistall()
|
|
|
|
{
|
|
|
|
// when the plugin is uninstalled, we unregister the backend.
|
|
|
|
StorageManager::unregister("Sample Storage");
|
|
|
|
}
|
2018-12-12 20:52:09 +01:00
|
|
|
```
|
2018-12-12 20:36:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
|