source: trunk/include/functions_plugins.inc.php @ 27221

Last change on this file since 27221 was 27221, checked in by mistic100, 10 years ago

PluginMaintain is not abstract anymore, allowing partial declaration

  • Property svn:eol-style set to LF
File size: 11.1 KB
RevLine 
[1578]1<?php
2// +-----------------------------------------------------------------------+
[8728]3// | Piwigo - a PHP based photo gallery                                    |
[2297]4// +-----------------------------------------------------------------------+
[26461]5// | Copyright(C) 2008-2014 Piwigo Team                  http://piwigo.org |
[2297]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// +-----------------------------------------------------------------------+
[1578]23
[25601]24/**
25 * @package functions\plugins
26 */
[1578]27
[25601]28
29/** base directory of plugins */
[1699]30define('PHPWG_PLUGINS_PATH', PHPWG_ROOT_PATH.'plugins/');
[25601]31/** default priority for plugins handlers */
[1590]32define('EVENT_HANDLER_PRIORITY_NEUTRAL', 50);
33
[25406]34
35/**
[25601]36 * Used to declare maintenance methods of a plugin.
[25406]37 */
[27221]38class PluginMaintain 
[25406]39{
[25601]40  /** @var string $plugin_id */
[25406]41  protected $plugin_id;
[25601]42
43  /**
44   * @param string $id
45   */
[25406]46  function __construct($id)
47  {
48    $this->plugin_id = $id;
49  }
[25601]50
51  /**
52   * @param string $plugin_version
[25658]53   * @param array &$errors - used to return error messages
[25601]54   */
[27221]55  function install($plugin_version, &$errors=array()) {}
[25601]56
57  /**
58   * @param string $plugin_version
[25658]59   * @param array &$errors - used to return error messages
[25601]60   */
[27221]61  function activate($plugin_version, &$errors=array()) {}
[25601]62
[27221]63  function deactivate() {}
[25601]64
[27221]65  function uninstall() {}
[25601]66
67  /**
68   * Tests if the plugin needs to be updated and call an update function
69   *
70   * @param string $version version exposed by the plugin (potentially new)
71   * @param string $on_update name of a method to call when an update is needed
[25406]72   *          it receives the previous version as first parameter
73   */
74  function autoUpdate($version, $on_update=null)
75  {
76    global $pwg_loaded_plugins;
77   
78    $current_version = $pwg_loaded_plugins[$this->plugin_id]['version'];
79   
80    if ( $version == 'auto' or $current_version == 'auto'
[26591]81        or safe_version_compare($current_version, $version, '<')
[25406]82      )
83    {
84      if (!empty($on_update))
85      {
86        call_user_func(array(&$this, $on_update), $current_version);
87      }
88     
89      if ($version != 'auto')
90      {
91        $query = '
92UPDATE '. PLUGINS_TABLE .'
93  SET version = "'. $version .'"
94  WHERE id = "'. $this->plugin_id .'"
95;';
96        pwg_query($query);
97       
98        $pwg_loaded_plugins[$this->plugin_id]['version'] = $version;
99      }
100    }
101  }
102}
103
104/**
[25601]105 * Used to declare maintenance methods of a theme.
[25406]106 */
[27221]107class ThemeMaintain 
[25406]108{
[25601]109  /** @var string $theme_id */
[25406]110  protected $theme_id;
[25601]111
112  /**
113   * @param string $id
114   */
[25406]115  function __construct($id)
116  {
117    $this->theme_id = $id;
118  }
[25601]119
120  /**
121   * @param string $theme_version
[25658]122   * @param array &$errors - used to return error messages
[25601]123   */
[27221]124  function activate($theme_version, &$errors=array()) {}
[25601]125
[27221]126  function deactivate() {}
[25601]127
[27221]128  function delete() {}
[25406]129 
[25601]130  /**
131   * Tests if the theme needs to be updated and call an update function
132   *
133   * @param string $version version exposed by the theme (potentially new)
134   * @param string $on_update name of a method to call when an update is needed
[25406]135   *          it receives the previous version as first parameter
136   */
137  function autoUpdate($version, $on_update=null)
138  {
139    $query = '
140SELECT version
141  FROM '. THEMES_TABLE .'
142  WHERE id = "'. $this->theme_id .'"
143;';
144    list($current_version) = pwg_db_fetch_row(pwg_query($query));
145   
146    if ( $version == 'auto' or $current_version == 'auto'
[26591]147        or safe_version_compare($current_version, $version, '<')
[25406]148      )
149    {
150      if (!empty($on_update))
151      {
152        call_user_func(array(&$this, $on_update), $current_version);
153      }
154     
155      if ($version != 'auto')
156      {
157        $query = '
158UPDATE '. THEMES_TABLE .'
159  SET version = "'. $version .'"
160  WHERE id = "'. $this->theme_id .'"
161;';
162        pwg_query($query);
163      }
164    }
165  }
166}
167
168
[25601]169/**
170 * Register an event handler.
171 *
[1578]172 * @param string $event the name of the event to listen to
[25601]173 * @param Callable $func the callback function
174 * @param int $priority greater priority will be executed at last
175 */
[1590]176function add_event_handler($event, $func,
177    $priority=EVENT_HANDLER_PRIORITY_NEUTRAL, $accepted_args=1)
[1578]178{
179  global $pwg_event_handlers;
180
[1590]181  if ( isset($pwg_event_handlers[$event][$priority]) )
[1578]182  {
[1590]183    foreach($pwg_event_handlers[$event][$priority] as $handler)
[1578]184    {
185      if ( $handler['function'] == $func )
186      {
[1604]187        return false;
[1578]188      }
189    }
190  }
191
[1590]192  $pwg_event_handlers[$event][$priority][] =
[1578]193    array(
194      'function'=>$func,
195      'accepted_args'=>$accepted_args);
[1590]196  ksort( $pwg_event_handlers[$event] );
[1578]197  return true;
198}
199
[25601]200/**
201 * Removes an event handler.
202 * @see add_event_handler()
203 *
204 * @param string $event
205 * @param Callable $func
206 * @param int $priority
207 */
[1590]208function remove_event_handler($event, $func,
209   $priority=EVENT_HANDLER_PRIORITY_NEUTRAL)
210{
211  global $pwg_event_handlers;
[1578]212
[1590]213  if (!isset( $pwg_event_handlers[$event][$priority] ) )
214  {
215    return false;
216  }
217  for ($i=0; $i<count($pwg_event_handlers[$event][$priority]); $i++)
218  {
219    if ($pwg_event_handlers[$event][$priority][$i]['function']==$func)
220    {
221      unset($pwg_event_handlers[$event][$priority][$i]);
222      $pwg_event_handlers[$event][$priority] =
223        array_values($pwg_event_handlers[$event][$priority]);
224
225      if ( empty($pwg_event_handlers[$event][$priority]) )
226      {
227        unset( $pwg_event_handlers[$event][$priority] );
228        if (empty( $pwg_event_handlers[$event] ) )
229        {
230          unset( $pwg_event_handlers[$event] );
231        }
232      }
233      return true;
234    }
235  }
236  return false;
237}
238
[25601]239/**
240 * Triggers a modifier event and calls all registered event handlers.
[25602]241 * trigger_change() is used as a modifier: it allows to transmit _$data_
[25601]242 * through all handlers, thus each handler MUST return a value,
243 * optional _$args_ are not transmitted.
244 *
[25602]245 * @since 2.6
246 * @todo remove trigger_event()
247 *
[25601]248 * @param string $event
249 * @param mixed $data data to transmit to all handlers
250 * @param mixed $args,... optional arguments
251 * @return mixed $data
252 */
[25602]253function trigger_change($event, $data=null)
254{
[26846]255  $args = func_get_args();
256  return call_user_func_array('trigger_event', $args);
[25602]257}
258
259/**
260 * @deprecated 2.6
261 * @see trigger_change
262 */
[1578]263function trigger_event($event, $data=null)
264{
265  global $pwg_event_handlers;
[1590]266
[3136]267  if ( isset($pwg_event_handlers['trigger']) )
268  {// just for debugging
269    trigger_action('trigger',
270        array('type'=>'event', 'event'=>$event, 'data'=>$data) );
271  }
[1578]272
273  if ( !isset($pwg_event_handlers[$event]) )
274  {
275    return $data;
276  }
[8263]277  $args = func_get_args();
[1578]278
279  foreach ($pwg_event_handlers[$event] as $priority => $handlers)
280  {
[3136]281    foreach($handlers as $handler)
[1578]282    {
[3136]283      $function_name = $handler['function'];
284      $accepted_args = $handler['accepted_args'];
[8263]285      $args[1] = $data;
286      $data = call_user_func_array($function_name, array_slice($args,1,$accepted_args) );
[1578]287    }
288  }
[3136]289  trigger_action('trigger',
290       array('type'=>'post_event', 'event'=>$event, 'data'=>$data) );
[1590]291  return $data;
292}
[1578]293
[25601]294/**
[25602]295 * Triggers a notifier event and calls all registered event handlers.
296 * trigger_notify() is only used as a notifier, no modification of data is possible
[25601]297 *
[25602]298 * @since 2.6
299 * @todo remove trigger_action()
300 *
[25601]301 * @param string $event
302 * @param mixed $args,... optional arguments
303 */
[25602]304function trigger_notify($event)
305{
[26846]306  $args = func_get_args();
307  return call_user_func_array('trigger_action', $args);
[25602]308}
309
310/**
311 * @deprecated 2.6
312 * @see trigger_notify
313 */
[25601]314function trigger_action($event)
[1590]315{
316  global $pwg_event_handlers;
[3136]317  if ( isset($pwg_event_handlers['trigger']) and $event!='trigger' )
[1590]318  {// special case for debugging - avoid recursive calls
[3136]319    trigger_action('trigger',
[25601]320        array('type'=>'action', 'event'=>$event, 'data'=>null) );
[1578]321  }
322
[1590]323  if ( !isset($pwg_event_handlers[$event]) )
324  {
325    return;
326  }
[8263]327  $args = func_get_args();
[1578]328
[1590]329  foreach ($pwg_event_handlers[$event] as $priority => $handlers)
330  {
[3136]331    foreach($handlers as $handler)
[1590]332    {
[3136]333      $function_name = $handler['function'];
334      $accepted_args = $handler['accepted_args'];
[1578]335
[8263]336      call_user_func_array($function_name, array_slice($args,1,$accepted_args) );
[1590]337    }
338  }
339}
[1578]340
[25601]341/**
342 * Saves some data with the associated plugin id, data are only available
343 * during script lifetime.
344 * @depracted 2.6
345 *
346 * @param string $plugin_id
[25658]347 * @param mixed &$data
[25601]348 * @return bool
[1705]349 */
350function set_plugin_data($plugin_id, &$data)
351{
352  global $pwg_loaded_plugins;
353  if ( isset($pwg_loaded_plugins[$plugin_id]) )
354  {
355    $pwg_loaded_plugins[$plugin_id]['plugin_data'] = &$data;
356    return true;
357  }
358  return false;
359}
[1590]360
[25601]361/**
362 * Retrieves plugin data saved previously with set_plugin_data.
363 * @see set_plugin_data()
364 * @depracted 2.6
365 *
366 * @param string $plugin_id
367 * @return mixed
[1705]368 */
369function &get_plugin_data($plugin_id)
370{
371  global $pwg_loaded_plugins;
[25601]372  if ( isset($pwg_loaded_plugins[$plugin_id]['plugin_data']) )
[1705]373  {
374    return $pwg_loaded_plugins[$plugin_id]['plugin_data'];
375  }
376  return null;
377}
378
[25601]379/**
380 * Returns an array of plugins defined in the database.
381 *
382 * @param string $state optional filter
383 * @param string $id returns only data about given plugin
384 * @return array
385 */
[1584]386function get_db_plugins($state='', $id='')
[1578]387{
[1584]388  $query = '
389SELECT * FROM '.PLUGINS_TABLE;
[3136]390  $clauses = array();
391  if (!empty($state))
[1578]392  {
[4367]393    $clauses[] = 'state=\''.$state.'\'';
[3136]394  }
395  if (!empty($id))
396  {
397    $clauses[] = 'id="'.$id.'"';
398  }
399  if (count($clauses))
400  {
[27221]401    $query .= '
[3136]402  WHERE '. implode(' AND ', $clauses);
[1578]403  }
[27221]404 
405  return query2array($query);
[1578]406}
407
[25601]408/**
409 * Loads a plugin, it includes the main.inc.php file and updates _$pwg_loaded_plugins_.
410 *
411 * @param string $plugin
412 */
[1604]413function load_plugin($plugin)
414{
415  $file_name = PHPWG_PLUGINS_PATH.$plugin['id'].'/main.inc.php';
416  if ( file_exists($file_name) )
417  {
[1705]418    global $pwg_loaded_plugins;
419    $pwg_loaded_plugins[ $plugin['id'] ] = $plugin;
[1604]420    include_once( $file_name );
421  }
422}
423
[25601]424/**
425 * Loads all the registered plugins.
426 */
[1578]427function load_plugins()
428{
[1705]429  global $conf, $pwg_loaded_plugins;
430  $pwg_loaded_plugins = array();
[1616]431  if ($conf['enable_plugins'])
[1584]432  {
[1616]433    $plugins = get_db_plugins('active');
434    foreach( $plugins as $plugin)
435    {// include main from a function to avoid using same function context
436      load_plugin($plugin);
437    }
438    trigger_action('plugins_loaded');
[1584]439  }
[1578]440}
[24160]441
[1578]442?>
Note: See TracBrowser for help on using the repository browser.