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