PageRenderTime 23ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/fsn-site-central/mediatheque/include/functions_plugins.inc.php

https://gitlab.com/team_fsn/fsn-php
PHP | 451 lines | 251 code | 55 blank | 145 comment | 38 complexity | cfbc58b2c1f543d2e408775a7755185d MD5 | raw file
  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Piwigo - a PHP based photo gallery |
  4. // +-----------------------------------------------------------------------+
  5. // | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
  6. // | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
  7. // | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
  8. // +-----------------------------------------------------------------------+
  9. // | This program is free software; you can redistribute it and/or modify |
  10. // | it under the terms of the GNU General Public License as published by |
  11. // | the Free Software Foundation |
  12. // | |
  13. // | This program is distributed in the hope that it will be useful, but |
  14. // | WITHOUT ANY WARRANTY; without even the implied warranty of |
  15. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
  16. // | General Public License for more details. |
  17. // | |
  18. // | You should have received a copy of the GNU General Public License |
  19. // | along with this program; if not, write to the Free Software |
  20. // | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
  21. // | USA. |
  22. // +-----------------------------------------------------------------------+
  23. /**
  24. * @package functions\plugins
  25. */
  26. /** base directory of plugins */
  27. define('PHPWG_PLUGINS_PATH', PHPWG_ROOT_PATH.'plugins/');
  28. /** default priority for plugins handlers */
  29. define('EVENT_HANDLER_PRIORITY_NEUTRAL', 50);
  30. /**
  31. * Used to declare maintenance methods of a plugin.
  32. */
  33. class PluginMaintain
  34. {
  35. /** @var string $plugin_id */
  36. protected $plugin_id;
  37. /**
  38. * @param string $id
  39. */
  40. function __construct($id)
  41. {
  42. $this->plugin_id = $id;
  43. }
  44. /**
  45. * @param string $plugin_version
  46. * @param array &$errors - used to return error messages
  47. */
  48. function install($plugin_version, &$errors=array()) {}
  49. /**
  50. * @param string $plugin_version
  51. * @param array &$errors - used to return error messages
  52. */
  53. function activate($plugin_version, &$errors=array()) {}
  54. function deactivate() {}
  55. function uninstall() {}
  56. /**
  57. * @param string $old_version
  58. * @param string $new_version
  59. * @param array &$errors - used to return error messages
  60. */
  61. function update($old_version, $new_version, &$errors=array()) {}
  62. /**
  63. * @removed 2.7
  64. */
  65. function autoUpdate()
  66. {
  67. if (is_admin() && !defined('IN_WS'))
  68. {
  69. trigger_error('Function PluginMaintain::autoUpdate deprecated', E_USER_WARNING);
  70. }
  71. }
  72. }
  73. /**
  74. * Used to declare maintenance methods of a theme.
  75. */
  76. class ThemeMaintain
  77. {
  78. /** @var string $theme_id */
  79. protected $theme_id;
  80. /**
  81. * @param string $id
  82. */
  83. function __construct($id)
  84. {
  85. $this->theme_id = $id;
  86. }
  87. /**
  88. * @param string $theme_version
  89. * @param array &$errors - used to return error messages
  90. */
  91. function activate($theme_version, &$errors=array()) {}
  92. function deactivate() {}
  93. function delete() {}
  94. }
  95. /**
  96. * Register an event handler.
  97. *
  98. * @param string $event the name of the event to listen to
  99. * @param Callable $func the callback function
  100. * @param int $priority greater priority will be executed at last
  101. * @param string $include_path file to include before executing the callback
  102. * @return bool false is handler already exists
  103. */
  104. function add_event_handler($event, $func,
  105. $priority=EVENT_HANDLER_PRIORITY_NEUTRAL, $include_path=null)
  106. {
  107. global $pwg_event_handlers;
  108. if (isset($pwg_event_handlers[$event][$priority]))
  109. {
  110. foreach ($pwg_event_handlers[$event][$priority] as $handler)
  111. {
  112. if ($handler['function'] == $func)
  113. {
  114. return false;
  115. }
  116. }
  117. }
  118. $pwg_event_handlers[$event][$priority][] = array(
  119. 'function' => $func,
  120. 'include_path' => is_string($include_path) ? $include_path : null,
  121. );
  122. ksort($pwg_event_handlers[$event]);
  123. return true;
  124. }
  125. /**
  126. * Removes an event handler.
  127. * @see add_event_handler()
  128. *
  129. * @param string $event
  130. * @param Callable $func
  131. * @param int $priority
  132. */
  133. function remove_event_handler($event, $func,
  134. $priority=EVENT_HANDLER_PRIORITY_NEUTRAL)
  135. {
  136. global $pwg_event_handlers;
  137. if (!isset($pwg_event_handlers[$event][$priority]))
  138. {
  139. return false;
  140. }
  141. for ($i=0; $i<count($pwg_event_handlers[$event][$priority]); $i++)
  142. {
  143. if ($pwg_event_handlers[$event][$priority][$i]['function']==$func)
  144. {
  145. unset($pwg_event_handlers[$event][$priority][$i]);
  146. $pwg_event_handlers[$event][$priority] =
  147. array_values($pwg_event_handlers[$event][$priority]);
  148. if (empty($pwg_event_handlers[$event][$priority]))
  149. {
  150. unset($pwg_event_handlers[$event][$priority]);
  151. if (empty($pwg_event_handlers[$event]))
  152. {
  153. unset($pwg_event_handlers[$event]);
  154. }
  155. }
  156. return true;
  157. }
  158. }
  159. return false;
  160. }
  161. /**
  162. * Triggers a modifier event and calls all registered event handlers.
  163. * trigger_change() is used as a modifier: it allows to transmit _$data_
  164. * through all handlers, thus each handler MUST return a value,
  165. * optional _$args_ are not transmitted.
  166. *
  167. * @since 2.6
  168. *
  169. * @param string $event
  170. * @param mixed $data data to transmit to all handlers
  171. * @param mixed $args,... optional arguments
  172. * @return mixed $data
  173. */
  174. function trigger_change($event, $data=null)
  175. {
  176. global $pwg_event_handlers;
  177. if (isset($pwg_event_handlers['trigger']))
  178. {// debugging
  179. trigger_notify('trigger',
  180. array('type'=>'event', 'event'=>$event, 'data'=>$data)
  181. );
  182. }
  183. if (!isset($pwg_event_handlers[$event]))
  184. {
  185. return $data;
  186. }
  187. $args = func_get_args();
  188. array_shift($args);
  189. foreach ($pwg_event_handlers[$event] as $priority => $handlers)
  190. {
  191. foreach ($handlers as $handler)
  192. {
  193. $args[0] = $data;
  194. if (!empty($handler['include_path']))
  195. {
  196. include_once($handler['include_path']);
  197. }
  198. $data = call_user_func_array($handler['function'], $args);
  199. }
  200. }
  201. if (isset($pwg_event_handlers['trigger']))
  202. {// debugging
  203. trigger_notify('trigger',
  204. array('type'=>'post_event', 'event'=>$event, 'data'=>$data)
  205. );
  206. }
  207. return $data;
  208. }
  209. /**
  210. * Triggers a notifier event and calls all registered event handlers.
  211. * trigger_notify() is only used as a notifier, no modification of data is possible
  212. *
  213. * @since 2.6
  214. *
  215. * @param string $event
  216. * @param mixed $args,... optional arguments
  217. */
  218. function trigger_notify($event)
  219. {
  220. global $pwg_event_handlers;
  221. if (isset($pwg_event_handlers['trigger']) and $event!='trigger')
  222. {// debugging - avoid recursive calls
  223. trigger_notify('trigger',
  224. array('type'=>'action', 'event'=>$event, 'data'=>null)
  225. );
  226. }
  227. if (!isset($pwg_event_handlers[$event]))
  228. {
  229. return;
  230. }
  231. $args = func_get_args();
  232. array_shift($args);
  233. foreach ($pwg_event_handlers[$event] as $priority => $handlers)
  234. {
  235. foreach ($handlers as $handler)
  236. {
  237. if (!empty($handler['include_path']))
  238. {
  239. include_once($handler['include_path']);
  240. }
  241. call_user_func_array($handler['function'], $args);
  242. }
  243. }
  244. }
  245. /**
  246. * Saves some data with the associated plugin id, data are only available
  247. * during script lifetime.
  248. * @depracted 2.6
  249. *
  250. * @param string $plugin_id
  251. * @param mixed &$data
  252. * @return bool
  253. */
  254. function set_plugin_data($plugin_id, &$data)
  255. {
  256. global $pwg_loaded_plugins;
  257. if ( isset($pwg_loaded_plugins[$plugin_id]) )
  258. {
  259. $pwg_loaded_plugins[$plugin_id]['plugin_data'] = &$data;
  260. return true;
  261. }
  262. return false;
  263. }
  264. /**
  265. * Retrieves plugin data saved previously with set_plugin_data.
  266. * @see set_plugin_data()
  267. * @depracted 2.6
  268. *
  269. * @param string $plugin_id
  270. * @return mixed
  271. */
  272. function &get_plugin_data($plugin_id)
  273. {
  274. global $pwg_loaded_plugins;
  275. if ( isset($pwg_loaded_plugins[$plugin_id]['plugin_data']) )
  276. {
  277. return $pwg_loaded_plugins[$plugin_id]['plugin_data'];
  278. }
  279. return null;
  280. }
  281. /**
  282. * Returns an array of plugins defined in the database.
  283. *
  284. * @param string $state optional filter
  285. * @param string $id returns only data about given plugin
  286. * @return array
  287. */
  288. function get_db_plugins($state='', $id='')
  289. {
  290. $query = '
  291. SELECT * FROM '.PLUGINS_TABLE;
  292. $clauses = array();
  293. if (!empty($state))
  294. {
  295. $clauses[] = 'state=\''.$state.'\'';
  296. }
  297. if (!empty($id))
  298. {
  299. $clauses[] = 'id="'.$id.'"';
  300. }
  301. if (count($clauses))
  302. {
  303. $query .= '
  304. WHERE '. implode(' AND ', $clauses);
  305. }
  306. return query2array($query);
  307. }
  308. /**
  309. * Loads a plugin in memory.
  310. * It performs autoupdate, includes the main.inc.php file and updates *$pwg_loaded_plugins*.
  311. *
  312. * @param string $plugin
  313. */
  314. function load_plugin($plugin)
  315. {
  316. $file_name = PHPWG_PLUGINS_PATH.$plugin['id'].'/main.inc.php';
  317. if (file_exists($file_name))
  318. {
  319. autoupdate_plugin($plugin);
  320. global $pwg_loaded_plugins;
  321. $pwg_loaded_plugins[ $plugin['id'] ] = $plugin;
  322. include_once($file_name);
  323. }
  324. }
  325. /**
  326. * Performs update task of a plugin.
  327. * Autoupdate is only performed if the plugin has a maintain.class.php file.
  328. *
  329. * @since 2.7
  330. *
  331. * @param array &$plugin (id, version, state) will be updated if version changes
  332. */
  333. function autoupdate_plugin(&$plugin)
  334. {
  335. // try to find the filesystem version in lines 2 to 10 of main.inc.php
  336. $fh = fopen(PHPWG_PLUGINS_PATH.$plugin['id'].'/main.inc.php', 'r');
  337. $fs_version = null;
  338. $i = -1;
  339. while (($line = fgets($fh))!==false && $fs_version==null && $i<10)
  340. {
  341. $i++;
  342. if ($i < 2) continue; // first lines are typically "<?php" and "/*"
  343. if (preg_match('/Version:\\s*([\\w.-]+)/', $line, $matches))
  344. {
  345. $fs_version = $matches[1];
  346. }
  347. }
  348. fclose($fh);
  349. // if version is auto (dev) or superior
  350. if ($fs_version != null && (
  351. $fs_version == 'auto' || $plugin['version'] == 'auto' ||
  352. safe_version_compare($plugin['version'], $fs_version, '<')
  353. )
  354. ) {
  355. $plugin['version'] = $fs_version;
  356. $maintain_file = PHPWG_PLUGINS_PATH.$plugin['id'].'/maintain.class.php';
  357. // autoupdate is applicable only to plugins with 2.7 architecture
  358. if (file_exists($maintain_file))
  359. {
  360. global $page;
  361. // call update method
  362. include_once($maintain_file);
  363. $classname = $plugin['id'].'_maintain';
  364. $plugin_maintain = new $classname($plugin['id']);
  365. $plugin_maintain->update($plugin['version'], $fs_version, $page['errors']);
  366. }
  367. // update database (only on production)
  368. if ($plugin['version'] != 'auto')
  369. {
  370. $query = '
  371. UPDATE '. PLUGINS_TABLE .'
  372. SET version = "'. $plugin['version'] .'"
  373. WHERE id = "'. $plugin['id'] .'"
  374. ;';
  375. pwg_query($query);
  376. }
  377. }
  378. }
  379. /**
  380. * Loads all the registered plugins.
  381. */
  382. function load_plugins()
  383. {
  384. global $conf, $pwg_loaded_plugins;
  385. $pwg_loaded_plugins = array();
  386. if ($conf['enable_plugins'])
  387. {
  388. $plugins = get_db_plugins('active');
  389. foreach( $plugins as $plugin)
  390. {// include main from a function to avoid using same function context
  391. load_plugin($plugin);
  392. }
  393. trigger_notify('plugins_loaded');
  394. }
  395. }
  396. ?>