]> git.mxchange.org Git - friendica.git/blob - src/Core/Addon.php
Review update
[friendica.git] / src / Core / Addon.php
1 <?php\r
2 /**\r
3  * @file src/Core/Addon.php\r
4  */\r
5 namespace Friendica\Core;\r
6 \r
7 use Friendica\Core\Config;\r
8 use Friendica\Database\DBM;\r
9 \r
10 use dba;\r
11 \r
12 require_once 'include/dba.php';\r
13 \r
14 /**\r
15  * Some functions to handle addons\r
16  */\r
17 class Addon\r
18 {\r
19         /**\r
20          * @brief uninstalls an addon.\r
21          *\r
22          * @param string $addon name of the addon\r
23          * @return boolean\r
24          */\r
25         public static function uninstall($addon)\r
26         {\r
27                 logger("Addons: uninstalling " . $addon);\r
28                 dba::delete('addon', ['name' => $addon]);\r
29 \r
30                 @include_once('addon/' . $addon . '/' . $addon . '.php');\r
31                 if (function_exists($addon . '_uninstall')) {\r
32                         $func = $addon . '_uninstall';\r
33                         $func();\r
34                 }\r
35         }\r
36 \r
37         /**\r
38          * @brief installs an addon.\r
39          *\r
40          * @param string $addon name of the addon\r
41          * @return bool\r
42          */\r
43         public static function install($addon)\r
44         {\r
45                 // silently fail if addon was removed\r
46 \r
47                 if (!file_exists('addon/' . $addon . '/' . $addon . '.php')) {\r
48                         return false;\r
49                 }\r
50                 logger("Addons: installing " . $addon);\r
51                 $t = @filemtime('addon/' . $addon . '/' . $addon . '.php');\r
52                 @include_once('addon/' . $addon . '/' . $addon . '.php');\r
53                 if (function_exists($addon . '_install')) {\r
54                         $func = $addon . '_install';\r
55                         $func();\r
56 \r
57                         $addon_admin = (function_exists($addon."_addon_admin") ? 1 : 0);\r
58 \r
59                         dba::insert('addon', ['name' => $addon, 'installed' => true,\r
60                                                 'timestamp' => $t, 'plugin_admin' => $addon_admin]);\r
61 \r
62                         // we can add the following with the previous SQL\r
63                         // once most site tables have been updated.\r
64                         // This way the system won't fall over dead during the update.\r
65 \r
66                         if (file_exists('addon/' . $addon . '/.hidden')) {\r
67                                 dba::update('addon', ['hidden' => true], ['name' => $addon]);\r
68                         }\r
69                         return true;\r
70                 } else {\r
71                         logger("Addons: FAILED installing " . $addon);\r
72                         return false;\r
73                 }\r
74         }\r
75 \r
76         /**\r
77          * reload all updated addons\r
78          */\r
79         public static function reload()\r
80         {\r
81                 $addons = Config::get('system', 'addon');\r
82                 if (strlen($addons)) {\r
83                         $r = dba::select('addon', [], ['installed' => 1]);\r
84                         if (DBM::is_result($r)) {\r
85                                 $installed = dba::inArray($r);\r
86                         } else {\r
87                                 $installed = [];\r
88                         }\r
89 \r
90                         $addon_list = explode(',', $addons);\r
91 \r
92                         if (count($addon_list)) {\r
93                                 foreach ($addon_list as $addon) {\r
94                                         $addon = trim($addon);\r
95                                         $fname = 'addon/' . $addon . '/' . $addon . '.php';\r
96 \r
97                                         if (file_exists($fname)) {\r
98                                                 $t = @filemtime($fname);\r
99                                                 foreach ($installed as $i) {\r
100                                                         if (($i['name'] == $addon) && ($i['timestamp'] != $t)) {\r
101                                                                 logger('Reloading addon: ' . $i['name']);\r
102                                                                 @include_once($fname);\r
103 \r
104                                                                 if (function_exists($addon . '_uninstall')) {\r
105                                                                         $func = $addon . '_uninstall';\r
106                                                                         $func();\r
107                                                                 }\r
108                                                                 if (function_exists($addon . '_install')) {\r
109                                                                         $func = $addon . '_install';\r
110                                                                         $func();\r
111                                                                 }\r
112                                                                 dba::update('addon', ['timestamp' => $t], ['id' => $i['id']]);\r
113                                                         }\r
114                                                 }\r
115                                         }\r
116                                 }\r
117                         }\r
118                 }\r
119         }\r
120 \r
121         /**\r
122          * @brief check if addon is enabled\r
123          *\r
124          * @param string $addon\r
125          * @return boolean\r
126          */\r
127         public static function isEnabled($addon)\r
128         {\r
129                 return dba::exists('addon', ['installed' => true, 'name' => $addon]);\r
130         }\r
131 \r
132 \r
133         /**\r
134          * @brief registers a hook.\r
135          *\r
136          * @param string $hook the name of the hook\r
137          * @param string $file the name of the file that hooks into\r
138          * @param string $function the name of the function that the hook will call\r
139          * @param int $priority A priority (defaults to 0)\r
140          * @return mixed|bool\r
141          */\r
142         public static function registerHook($hook, $file, $function, $priority = 0)\r
143         {\r
144                 $condition = ['hook' => $hook, 'file' => $file, 'function' => $function];\r
145                 $exists = dba::exists('hook', $condition);\r
146                 if ($exists) {\r
147                         return true;\r
148                 }\r
149 \r
150                 $r = dba::insert('hook', ['hook' => $hook, 'file' => $file, 'function' => $function, 'priority' => $priority]);\r
151 \r
152                 return $r;\r
153         }\r
154 \r
155         /**\r
156          * @brief unregisters a hook.\r
157          *\r
158          * @param string $hook the name of the hook\r
159          * @param string $file the name of the file that hooks into\r
160          * @param string $function the name of the function that the hook called\r
161          * @return array\r
162          */\r
163         public static function unregisterHook($hook, $file, $function)\r
164         {\r
165                 $condition = ['hook' => $hook, 'file' => $file, 'function' => $function];\r
166                 $r = dba::delete('hook', $condition);\r
167                 return $r;\r
168         }\r
169 \r
170         /**\r
171          * Load hooks\r
172          */\r
173         public static function loadHooks()\r
174         {\r
175                 $a = get_app();\r
176                 $a->hooks = [];\r
177                 $r = dba::select('hook', ['hook', 'file', 'function'], [], ['order' => ['priority' => 'desc', 'file']]);\r
178 \r
179                 while ($rr = dba::fetch($r)) {\r
180                         if (! array_key_exists($rr['hook'], $a->hooks)) {\r
181                                 $a->hooks[$rr['hook']] = [];\r
182                         }\r
183                         $a->hooks[$rr['hook']][] = [$rr['file'],$rr['function']];\r
184                 }\r
185                 dba::close($r);\r
186         }\r
187 \r
188         /**\r
189          * @brief Calls a hook.\r
190          *\r
191          * Use this function when you want to be able to allow a hook to manipulate\r
192          * the provided data.\r
193          *\r
194          * @param string $name of the hook to call\r
195          * @param string|array &$data to transmit to the callback handler\r
196          */\r
197         public static function callHooks($name, &$data = null)\r
198         {\r
199                 $a = get_app();\r
200 \r
201                 if (is_array($a->hooks) && array_key_exists($name, $a->hooks)) {\r
202                         foreach ($a->hooks[$name] as $hook) {\r
203                                 self::callSingleHook($a, $name, $hook, $data);\r
204                         }\r
205                 }\r
206         }\r
207 \r
208         /**\r
209          * @brief Calls a single hook.\r
210          *\r
211          * @param string $name of the hook to call\r
212          * @param array $hook Hook data\r
213          * @param string|array &$data to transmit to the callback handler\r
214          */\r
215         public static function callSingleHook($a, $name, $hook, &$data = null)\r
216         {\r
217                 // Don't run a theme's hook if the user isn't using the theme\r
218                 if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false) {\r
219                         return;\r
220                 }\r
221 \r
222                 @include_once($hook[0]);\r
223                 if (function_exists($hook[1])) {\r
224                         $func = $hook[1];\r
225                         $func($a, $data);\r
226                 } else {\r
227                         // remove orphan hooks\r
228                         $condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]];\r
229                         dba::delete('hook', $condition);\r
230                 }\r
231         }\r
232 \r
233         /**\r
234          * check if an app_menu hook exist for addon $name.\r
235          * Return true if the addon is an app\r
236          */\r
237         public static function isApp($name)\r
238         {\r
239                 $a = get_app();\r
240 \r
241                 if (is_array($a->hooks) && (array_key_exists('app_menu', $a->hooks))) {\r
242                         foreach ($a->hooks['app_menu'] as $hook) {\r
243                                 if ($hook[0] == 'addon/'.$name.'/'.$name.'.php') {\r
244                                         return true;\r
245                                 }\r
246                         }\r
247                 }\r
248 \r
249                 return false;\r
250         }\r
251 \r
252         /**\r
253          * @brief Parse addon comment in search of addon infos.\r
254          *\r
255          * like\r
256          * \code\r
257          *...* Name: addon\r
258         *   * Description: An addon which plugs in\r
259         * . * Version: 1.2.3\r
260         *   * Author: John <profile url>\r
261         *   * Author: Jane <email>\r
262         *   *\r
263         *  *\endcode\r
264         * @param string $addon the name of the addon\r
265         * @return array with the addon information\r
266         */\r
267 \r
268         public static function getInfo($addon)\r
269         {\r
270                 $a = get_app();\r
271 \r
272                 $info=[\r
273                         'name' => $addon,\r
274                         'description' => "",\r
275                         'author' => [],\r
276                         'version' => "",\r
277                         'status' => ""\r
278                 ];\r
279 \r
280                 if (!is_file("addon/$addon/$addon.php")) {\r
281                         return $info;\r
282                 }\r
283 \r
284                 $stamp1 = microtime(true);\r
285                 $f = file_get_contents("addon/$addon/$addon.php");\r
286                 $a->save_timestamp($stamp1, "file");\r
287 \r
288                 $r = preg_match("|/\*.*\*/|msU", $f, $m);\r
289 \r
290                 if ($r) {\r
291                         $ll = explode("\n", $m[0]);\r
292                         foreach ($ll as $l) {\r
293                                 $l = trim($l, "\t\n\r */");\r
294                                 if ($l != "") {\r
295                                         list($k,$v) = array_map("trim", explode(":", $l, 2));\r
296                                         $k= strtolower($k);\r
297                                         if ($k == "author") {\r
298                                                 $r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);\r
299                                                 if ($r) {\r
300                                                         $info['author'][] = ['name'=>$m[1], 'link'=>$m[2]];\r
301                                                 } else {\r
302                                                         $info['author'][] = ['name'=>$v];\r
303                                                 }\r
304                                         } else {\r
305                                                 if (array_key_exists($k, $info)) {\r
306                                                         $info[$k]=$v;\r
307                                                 }\r
308                                         }\r
309                                 }\r
310                         }\r
311                 }\r
312                 return $info;\r
313         }\r
314 }\r