]> git.mxchange.org Git - friendica.git/blob - doc/AddonStorageBackend.md
Add docs about storage backend
[friendica.git] / doc / AddonStorageBackend.md
1 Friendica Storage Backend Addon development
2 ===========================================
3
4 * [Home](help)
5
6 Storage backends can be added via addons.
7 A storage backend is implemented as a class, and the plugin register the class to make it avaiable to the system.
8
9 ## The Storage Backend Class
10
11 The class must live in `Friendica\Addon\youraddonname` namespace, where `youraddonname` the folder name of your addon.
12
13 The class must implement `Friendica\Model\Storage\IStorage` interface. All method in the interface must be implemented:
14
15 namespace Friendica\Model\Storage;
16
17         interface IStorage
18         {
19                 public static function get($ref);
20                 public static function put($data, $ref = "");
21                 public static function delete($ref);
22                 public static function getOptions();
23                 public static function saveOptions($data);
24         }
25
26 - `get($ref)` returns data pointed by `$ref`
27 - `put($data, $ref)` saves data in `$data` to position `$ref`, or a new position if `$ref` is empty.
28 - `delete($ref)` delete data pointed by `$ref`
29
30 Each storage backend can have options the admin can set in admin page.
31
32 - `getOptions()` returns an array with details about each option to build the interface.
33 - `saveOptions($data)` get `$data` from admin page, validate it and save it.
34
35 The array returned by `getOptions()` is defined as:
36
37         [
38                 'option1name' => [ ..info.. ],
39                 'option2name' => [ ..info.. ],
40                 ...
41         ]
42
43 An empty array can be returned if backend doesn't have any options.
44
45 The info array for each option is defined as:
46
47         [
48                 'type',
49
50 define the field used in form, and the type of data.
51 one of 'checkbox', 'combobox', 'custom', 'datetime', 'input', 'intcheckbox', 'password', 'radio', 'richtext', 'select', 'select_raw', 'textarea', 'yesno'
52
53                 'label',
54
55 Translatable label of the field. This label will be shown in admin page
56
57                 value,
58
59 Current value of the option
60
61                 'help text',
62
63 Translatable description for the field. Will be shown in admin page
64
65                 extra data
66
67 Optional. Depends on which 'type' this option is:
68
69 - 'select': array `[ value => label ]` of choices
70 - 'intcheckbox': value of input element
71 - 'select_raw': prebuild html string of `<option >` tags
72 - 'yesno': array `[ 'label no', 'label yes']`
73
74 Each label should be translatable
75
76         ];
77
78
79 See doxygen documentation of `IStorage` interface for details about each method.
80
81 ## Register a storage backend class
82
83 Each backend must be registered in the system when the plugin is installed, to be aviable.
84
85 `Friendica\Core\StorageManager::register($name, $class)` is used to register the backend class.
86 The `$name` must be univocal and will be shown to admin.
87
88 When the plugin is uninstalled, registered backends must be unregistered using
89 `Friendica\Core\StorageManager::unregister($class)`.
90
91 ## Example
92
93 Here an hypotetical addon which register an unusefull storage backend.
94 Let's call it `samplestorage`.
95
96 This backend will discard all data we try to save and will return always the same image when we ask for some data.
97 The image returned can be set by the administrator in admin page.
98
99 First, the backend class.
100 The file will be `addon/samplestorage/SampleStorageBackend.php`:
101
102 ```php
103 <?php
104 namespace Friendica\Addon\samplestorage;
105
106 use Friendica\Model\Storage\IStorage;
107
108 use Friendica\Core\Config;
109 use Friendica\Core\L10n;
110
111 class SampleStorageBackend implements IStorage
112 {
113         public static function get($ref)
114         {
115                 // we return alwais the same image data. Which file we load is defined by
116                 // a config key
117                 $filename = Config::get("storage", "samplestorage", "sample.jpg");
118                 return file_get_contents($filename);
119         }
120         
121         public static function put($data, $ref = "")
122         {
123                 if ($ref === "") {
124                         $ref = "sample";
125                 }
126                 // we don't save $data !
127                 return $ref;
128         }
129         
130         public static function delete($ref)
131         {
132                 // we pretend to delete the data
133                 return true;
134         }
135         
136         public static function getOptions()
137         {
138                 $filename = Config::get("storage", "samplestorage", "sample.jpg");
139                 return [
140                         "filename" => [
141                                 "input",        // will use a simple text input
142                                 L10n::t("The file to return"),  // the label
143                                 $filename,      // the current value
144                                 L10n::t("Enter the path to a file"), // the help text
145                                 // no extra data for "input" type..
146                 ];
147         }
148         
149         public static function saveOptions($data)
150         {
151                 // the keys in $data are the same keys we defined in getOptions()
152                 $newfilename = trim($data["filename"]);
153                 
154                 // this function should always validate the data.
155                 // in this example we check if file exists
156                 if (!file_exists($newfilename)) {
157                         // in case of error we return an array with
158                         // ["optionname" => "error message"]
159                         return ["filename" => "The file doesn't exists"];
160                 }
161                 
162                 Config::set("storage", "samplestorage", $newfilename);
163                 
164                 // no errors, return empty array
165                 return [];
166         }
167 }
168 ```
169
170 Now the plugin main file. Here we register and unregister the backend class.
171
172 The file is `addon/samplestorage/samplestorage.php`
173
174 ```php
175 <?php
176 /**
177  * Name: Sample Storage Addon
178  * Description: A sample addon which implements an unusefull storage backend
179  * Version: 1.0.0
180  * Author: Alice <https://alice.social/~alice>
181  */
182
183 use Friendica\Core\StorageManager;
184 use Friendica\Addon\samplestorage\SampleStorageBackend;
185
186 function samplestorage_install()
187 {
188         // on addon install, we register our class with name "Sample Storage".
189         // note: we use `::class` property, which returns full class name as string
190         // this save us the problem of correctly escape backslashes in class name
191         StorageManager::register("Sample Storage", SampleStorageBackend::class);
192 }
193
194 function samplestorage_unistall()
195 {
196         // when the plugin is uninstalled, we unregister the backend.
197         StorageManager::unregister("Sample Storage");
198 }
199
200
201
202