thomascube
2012-01-18 7fe3811c65a7c63154f03610e289a6d196f3ae2e
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   }
84   
85   /**
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;
113     $rcmail = rcmail::get_instance();
b545d3 114     if (is_file($fpath) && !$rcmail->config->load_from_file($fpath)) {
10eedb 115       raise_error(array('code' => 527, 'type' => 'php',
A 116         'file' => __FILE__, 'line' => __LINE__,
117         'message' => "Failed to load config from $fpath"), true, false);
029c2f 118       return false;
T 119     }
120     
121     return true;
c73b19 122   }
cc97ea 123
T 124   /**
125    * Register a callback function for a specific (server-side) hook
126    *
5c461b 127    * @param string $hook Hook name
A 128    * @param mixed  $callback Callback function as string or array with object reference and method name
cc97ea 129    */
T 130   public function add_hook($hook, $callback)
131   {
132     $this->api->register_hook($hook, $callback);
133   }
134   
135   /**
136    * Load localized texts from the plugins dir
137    *
5c461b 138    * @param string $dir Directory to search in
A 139    * @param mixed  $add2client Make texts also available on the client (array with list or true for all)
cc97ea 140    */
T 141   public function add_texts($dir, $add2client = false)
142   {
143     $domain = $this->ID;
144     
145     $lang = $_SESSION['language'];
146     $locdir = slashify(realpath(slashify($this->home) . $dir));
147     $texts = array();
7c9850 148
A 149     // use buffering to handle empty lines/spaces after closing PHP tag
150     ob_start();
151
cc97ea 152     foreach (array('en_US', $lang) as $lng) {
aecadc 153       $fpath = $locdir . $lng . '.inc';
A 154       if (is_file($fpath) && is_readable($fpath)) {
155         include($fpath);
156         $texts = (array)$labels + (array)$messages + (array)$texts;
157       }
cc97ea 158     }
T 159
7c9850 160     ob_end_clean();
A 161
cc97ea 162     // prepend domain to text keys and add to the application texts repository
T 163     if (!empty($texts)) {
164       $add = array();
165       foreach ($texts as $key => $value)
166         $add[$domain.'.'.$key] = $value;
167
168       $rcmail = rcmail::get_instance();
169       $rcmail->load_language($lang, $add);
170       
171       // add labels to client
172       if ($add2client) {
173         $js_labels = is_array($add2client) ? array_map(array($this, 'label_map_callback'), $add2client) : array_keys($add);
174         $rcmail->output->add_label($js_labels);
175       }
176     }
177   }
178   
179   /**
180    * Wrapper for rcmail::gettext() adding the plugin ID as domain
181    *
5c461b 182    * @param string $p Message identifier
cc97ea 183    * @return string Localized text
T 184    * @see rcmail::gettext()
185    */
1c932d 186   public function gettext($p)
cc97ea 187   {
T 188     return rcmail::get_instance()->gettext($p, $this->ID);
189   }
1c932d 190
T 191   /**
192    * Register this plugin to be responsible for a specific task
193    *
5c461b 194    * @param string $task Task name (only characters [a-z0-9_.-] are allowed)
1c932d 195    */
T 196   public function register_task($task)
197   {
05a631 198     if ($this->api->register_task($task, $this->ID))
T 199       $this->mytask = $task;
1c932d 200   }
T 201
cc97ea 202   /**
T 203     * Register a handler for a specific client-request action
204     *
205     * The callback will be executed upon a request like /?_task=mail&_action=plugin.myaction
206     *
5c461b 207     * @param string $action  Action name (should be unique)
A 208     * @param mixed $callback Callback function as string or array with object reference and method name
cc97ea 209    */
T 210   public function register_action($action, $callback)
211   {
05a631 212     $this->api->register_action($action, $this->ID, $callback, $this->mytask);
cc97ea 213   }
T 214
215   /**
216    * Register a handler function for a template object
217    *
218    * When parsing a template for display, tags like <roundcube:object name="plugin.myobject" />
219    * will be replaced by the return value if the registered callback function.
220    *
5c461b 221    * @param string $name Object name (should be unique and start with 'plugin.')
A 222    * @param mixed  $callback Callback function as string or array with object reference and method name
cc97ea 223    */
T 224   public function register_handler($name, $callback)
225   {
226     $this->api->register_handler($name, $this->ID, $callback);
227   }
228
229   /**
230    * Make this javascipt file available on the client
231    *
5c461b 232    * @param string $fn File path; absolute or relative to the plugin directory
cc97ea 233    */
T 234   public function include_script($fn)
235   {
eb6f19 236     $this->api->include_script($this->resource_url($fn));
cc97ea 237   }
T 238
239   /**
240    * Make this stylesheet available on the client
241    *
5c461b 242    * @param string $fn File path; absolute or relative to the plugin directory
cc97ea 243    */
T 244   public function include_stylesheet($fn)
245   {
eb6f19 246     $this->api->include_stylesheet($this->resource_url($fn));
cc97ea 247   }
T 248   
249   /**
250    * Append a button to a certain container
251    *
5c461b 252    * @param array $p Hash array with named parameters (as used in skin templates)
A 253    * @param string $container Container name where the buttons should be added to
cc97ea 254    * @see rcube_remplate::button()
T 255    */
256   public function add_button($p, $container)
257   {
258     if ($this->api->output->type == 'html') {
259       // fix relative paths
260       foreach (array('imagepas', 'imageact', 'imagesel') as $key)
261         if ($p[$key])
eb6f19 262           $p[$key] = $this->api->url . $this->resource_url($p[$key]);
cc97ea 263       
T 264       $this->api->add_content($this->api->output->button($p), $container);
265     }
266   }
24e219 267   
T 268   /**
269    * Generate an absolute URL to the given resource within the current
270    * plugin directory
271    *
5c461b 272    * @param string $fn The file name
24e219 273    * @return string Absolute URL to the given resource
T 274    */
275   public function url($fn)
276   {
277       return $this->api->url . $this->resource_url($fn);
278   }
cc97ea 279
T 280   /**
281    * Make the given file name link into the plugin directory
5c461b 282    *
A 283    * @param string $fn Filename
cc97ea 284    */
eb6f19 285   private function resource_url($fn)
cc97ea 286   {
23a2ee 287     if ($fn[0] != '/' && !preg_match('|^https?://|i', $fn))
cc97ea 288       return $this->ID . '/' . $fn;
T 289     else
290       return $fn;
291   }
715a1b 292
01acca 293   /**
T 294    * Provide path to the currently selected skin folder within the plugin directory
295    * with a fallback to the default skin folder.
296    *
297    * @return string Skin path relative to plugins directory
298    */
715a1b 299   public function local_skin_path()
01acca 300   {
1ac543 301       $skin_path = 'skins/'.$this->api->config->get('skin');
01acca 302       if (!is_dir(realpath(slashify($this->home) . $skin_path)))
T 303         $skin_path = 'skins/default';
304     return $skin_path;
305   }
cc97ea 306
T 307   /**
308    * Callback function for array_map
5c461b 309    *
A 310    * @param string $key Array key.
311    * @return string
cc97ea 312    */
T 313   private function label_map_callback($key)
314   {
315     return $this->ID.'.'.$key;
316   }
317
318
319 }
320