alecpl
2012-04-13 0c259682f65eaaf23ea4ccb56a706d6baf3007e4
commit | author | age
cc97ea 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_plugin.php                                      |
6  |                                                                       |
e019f2 7  | This file is part of the Roundcube Webmail client                     |
f5e7b3 8  | Copyright (C) 2008-2009, The Roundcube Dev Team                       |
7fe381 9  |                                                                       |
T 10  | Licensed under the GNU General Public License version 3 or            |
11  | any later version with exceptions for skins & plugins.                |
12  | See the README file for a full license statement.                     |
cc97ea 13  |                                                                       |
T 14  | PURPOSE:                                                              |
15  |  Abstract plugins interface/class                                     |
16  |  All plugins need to extend this class                                |
17  +-----------------------------------------------------------------------+
18  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
19  +-----------------------------------------------------------------------+
20
1d786c 21  $Id$
cc97ea 22
T 23 */
24
25 /**
26  * Plugin interface class
27  *
d062db 28  * @package PluginAPI
cc97ea 29  */
T 30 abstract class rcube_plugin
31 {
2cd443 32   /**
A 33    * Class name of the plugin instance
34    *
35    * @var string
36    */
cc97ea 37   public $ID;
5c461b 38
A 39   /**
2cd443 40    * Instance of Plugin API
5c461b 41    *
A 42    * @var rcube_plugin_api
43    */
cc97ea 44   public $api;
2cd443 45
A 46   /**
47    * Regular expression defining task(s) to bind with 
48    *
49    * @var string
50    */
cc97ea 51   public $task;
2cd443 52
A 53   /**
54    * Disables plugin in AJAX requests
55    *
56    * @var boolean
57    */
58   public $noajax = false;
59
60   /**
61    * Disables plugin in framed mode
62    *
63    * @var boolean
64    */
65   public $noframe = false;
66
cc97ea 67   protected $home;
T 68   protected $urlbase;
05a631 69   private $mytask;
cc97ea 70
2cd443 71
cc97ea 72   /**
T 73    * Default constructor.
5c461b 74    *
A 75    * @param rcube_plugin_api $api Plugin API
cc97ea 76    */
T 77   public function __construct($api)
78   {
79     $this->ID = get_class($this);
80     $this->api = $api;
cdf1ae 81     $this->home = $api->dir . $this->ID;
cc97ea 82     $this->urlbase = $api->url . $this->ID . '/';
T 83   }
479af9 84
cc97ea 85   /**
T 86    * Initialization method, needs to be implemented by the plugin itself
87    */
88   abstract function init();
0501b6 89
T 90
91   /**
92    * Attempt to load the given plugin which is required for the current plugin
93    *
94    * @param string Plugin name
95    * @return boolean True on success, false on failure
96    */
97   public function require_plugin($plugin_name)
98   {
99     return $this->api->load_plugin($plugin_name);
100   }
101
102
c73b19 103   /**
T 104    * Load local config file from plugins directory.
105    * The loaded values are patched over the global configuration.
106    *
5c461b 107    * @param string $fname Config file name relative to the plugin's folder
029c2f 108    * @return boolean True on success, false on failure
c73b19 109    */
T 110   public function load_config($fname = 'config.inc.php')
111   {
112     $fpath = $this->home.'/'.$fname;
0c2596 113     $rcmail = rcube::get_instance();
b545d3 114     if (is_file($fpath) && !$rcmail->config->load_from_file($fpath)) {
0c2596 115       rcube::raise_error(array(
A 116         'code' => 527, 'type' => 'php',
10eedb 117         'file' => __FILE__, 'line' => __LINE__,
A 118         'message' => "Failed to load config from $fpath"), true, false);
029c2f 119       return false;
T 120     }
479af9 121
029c2f 122     return true;
c73b19 123   }
cc97ea 124
T 125   /**
126    * Register a callback function for a specific (server-side) hook
127    *
5c461b 128    * @param string $hook Hook name
A 129    * @param mixed  $callback Callback function as string or array with object reference and method name
cc97ea 130    */
T 131   public function add_hook($hook, $callback)
132   {
133     $this->api->register_hook($hook, $callback);
134   }
479af9 135
A 136   /**
137    * Unregister a callback function for a specific (server-side) hook.
138    *
139    * @param string $hook Hook name
140    * @param mixed  $callback Callback function as string or array with object reference and method name
141    */
142   public function remove_hook($hook, $callback)
143   {
144     $this->api->unregister_hook($hook, $callback);
145   }
146
cc97ea 147   /**
T 148    * Load localized texts from the plugins dir
149    *
5c461b 150    * @param string $dir Directory to search in
A 151    * @param mixed  $add2client Make texts also available on the client (array with list or true for all)
cc97ea 152    */
T 153   public function add_texts($dir, $add2client = false)
154   {
155     $domain = $this->ID;
479af9 156
cc97ea 157     $lang = $_SESSION['language'];
T 158     $locdir = slashify(realpath(slashify($this->home) . $dir));
159     $texts = array();
7c9850 160
A 161     // use buffering to handle empty lines/spaces after closing PHP tag
162     ob_start();
163
cc97ea 164     foreach (array('en_US', $lang) as $lng) {
aecadc 165       $fpath = $locdir . $lng . '.inc';
A 166       if (is_file($fpath) && is_readable($fpath)) {
167         include($fpath);
168         $texts = (array)$labels + (array)$messages + (array)$texts;
169       }
cc97ea 170     }
T 171
7c9850 172     ob_end_clean();
A 173
cc97ea 174     // prepend domain to text keys and add to the application texts repository
T 175     if (!empty($texts)) {
176       $add = array();
177       foreach ($texts as $key => $value)
178         $add[$domain.'.'.$key] = $value;
179
0c2596 180       $rcmail = rcube::get_instance();
cc97ea 181       $rcmail->load_language($lang, $add);
479af9 182
cc97ea 183       // add labels to client
T 184       if ($add2client) {
185         $js_labels = is_array($add2client) ? array_map(array($this, 'label_map_callback'), $add2client) : array_keys($add);
186         $rcmail->output->add_label($js_labels);
187       }
188     }
189   }
479af9 190
cc97ea 191   /**
T 192    * Wrapper for rcmail::gettext() adding the plugin ID as domain
193    *
5c461b 194    * @param string $p Message identifier
cc97ea 195    * @return string Localized text
T 196    * @see rcmail::gettext()
197    */
1c932d 198   public function gettext($p)
cc97ea 199   {
0c2596 200     return rcube::get_instance()->gettext($p, $this->ID);
cc97ea 201   }
1c932d 202
T 203   /**
204    * Register this plugin to be responsible for a specific task
205    *
5c461b 206    * @param string $task Task name (only characters [a-z0-9_.-] are allowed)
1c932d 207    */
T 208   public function register_task($task)
209   {
05a631 210     if ($this->api->register_task($task, $this->ID))
T 211       $this->mytask = $task;
1c932d 212   }
T 213
cc97ea 214   /**
T 215     * Register a handler for a specific client-request action
216     *
217     * The callback will be executed upon a request like /?_task=mail&_action=plugin.myaction
218     *
5c461b 219     * @param string $action  Action name (should be unique)
A 220     * @param mixed $callback Callback function as string or array with object reference and method name
cc97ea 221    */
T 222   public function register_action($action, $callback)
223   {
05a631 224     $this->api->register_action($action, $this->ID, $callback, $this->mytask);
cc97ea 225   }
T 226
227   /**
228    * Register a handler function for a template object
229    *
230    * When parsing a template for display, tags like <roundcube:object name="plugin.myobject" />
231    * will be replaced by the return value if the registered callback function.
232    *
5c461b 233    * @param string $name Object name (should be unique and start with 'plugin.')
A 234    * @param mixed  $callback Callback function as string or array with object reference and method name
cc97ea 235    */
T 236   public function register_handler($name, $callback)
237   {
238     $this->api->register_handler($name, $this->ID, $callback);
239   }
240
241   /**
242    * Make this javascipt file available on the client
243    *
5c461b 244    * @param string $fn File path; absolute or relative to the plugin directory
cc97ea 245    */
T 246   public function include_script($fn)
247   {
eb6f19 248     $this->api->include_script($this->resource_url($fn));
cc97ea 249   }
T 250
251   /**
252    * Make this stylesheet available on the client
253    *
5c461b 254    * @param string $fn File path; absolute or relative to the plugin directory
cc97ea 255    */
T 256   public function include_stylesheet($fn)
257   {
eb6f19 258     $this->api->include_stylesheet($this->resource_url($fn));
cc97ea 259   }
479af9 260
cc97ea 261   /**
T 262    * Append a button to a certain container
263    *
5c461b 264    * @param array $p Hash array with named parameters (as used in skin templates)
A 265    * @param string $container Container name where the buttons should be added to
cc97ea 266    * @see rcube_remplate::button()
T 267    */
268   public function add_button($p, $container)
269   {
270     if ($this->api->output->type == 'html') {
271       // fix relative paths
272       foreach (array('imagepas', 'imageact', 'imagesel') as $key)
273         if ($p[$key])
eb6f19 274           $p[$key] = $this->api->url . $this->resource_url($p[$key]);
479af9 275
cc97ea 276       $this->api->add_content($this->api->output->button($p), $container);
T 277     }
278   }
479af9 279
24e219 280   /**
T 281    * Generate an absolute URL to the given resource within the current
282    * plugin directory
283    *
5c461b 284    * @param string $fn The file name
24e219 285    * @return string Absolute URL to the given resource
T 286    */
287   public function url($fn)
288   {
289       return $this->api->url . $this->resource_url($fn);
290   }
cc97ea 291
T 292   /**
293    * Make the given file name link into the plugin directory
5c461b 294    *
A 295    * @param string $fn Filename
cc97ea 296    */
eb6f19 297   private function resource_url($fn)
cc97ea 298   {
23a2ee 299     if ($fn[0] != '/' && !preg_match('|^https?://|i', $fn))
cc97ea 300       return $this->ID . '/' . $fn;
T 301     else
302       return $fn;
303   }
715a1b 304
01acca 305   /**
T 306    * Provide path to the currently selected skin folder within the plugin directory
307    * with a fallback to the default skin folder.
308    *
309    * @return string Skin path relative to plugins directory
310    */
715a1b 311   public function local_skin_path()
01acca 312   {
0c2596 313     $rcmail = rcube::get_instance();
A 314     $skin_path = 'skins/' . $rcmail->config->get('skin');
315     if (!is_dir(realpath(slashify($this->home) . $skin_path)))
316       $skin_path = 'skins/default';
01acca 317     return $skin_path;
T 318   }
cc97ea 319
T 320   /**
321    * Callback function for array_map
5c461b 322    *
A 323    * @param string $key Array key.
324    * @return string
cc97ea 325    */
T 326   private function label_map_callback($key)
327   {
328     return $this->ID.'.'.$key;
329   }
330
331 }