thomascube
2011-08-18 fbe54043cf598b19a753dc2b21a7ed558d23fd15
commit | author | age
197601 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_config.php                                      |
6  |                                                                       |
e019f2 7  | This file is part of the Roundcube Webmail client                     |
f5e7b3 8  | Copyright (C) 2008-2010, The Roundcube Dev Team                       |
197601 9  | Licensed under the GNU GPL                                            |
T 10  |                                                                       |
11  | PURPOSE:                                                              |
12  |   Class to read configuration settings                                |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
1d786c 18  $Id$
197601 19
T 20 */
21
22 /**
e019f2 23  * Configuration class for Roundcube
197601 24  *
T 25  * @package Core
26  */
27 class rcube_config
28 {
2eb794 29     private $prop = array();
A 30     private $errors = array();
31     private $userprefs = array();
197601 32
T 33
2eb794 34     /**
A 35      * Object constructor
36      */
37     public function __construct()
2471d3 38     {
2eb794 39         $this->load();
2471d3 40     }
2eb794 41
A 42
43     /**
44      * Load config from local config file
45      *
46      * @todo Remove global $CONFIG
47      */
48     private function load()
2471d3 49     {
2eb794 50         // load main config file
A 51         if (!$this->load_from_file(RCMAIL_CONFIG_DIR . '/main.inc.php'))
52             $this->errors[] = 'main.inc.php was not found.';
53
54         // load database config
55         if (!$this->load_from_file(RCMAIL_CONFIG_DIR . '/db.inc.php'))
56             $this->errors[] = 'db.inc.php was not found.';
f52c4f 57
2eb794 58         // load host-specific configuration
A 59         $this->load_host_config();
60
61         // set skin (with fallback to old 'skin_path' property)
62         if (empty($this->prop['skin']) && !empty($this->prop['skin_path']))
63             $this->prop['skin'] = str_replace('skins/', '', unslashify($this->prop['skin_path']));
64         else if (empty($this->prop['skin']))
65             $this->prop['skin'] = 'default';
66
67         // fix paths
68         $this->prop['log_dir'] = $this->prop['log_dir'] ? realpath(unslashify($this->prop['log_dir'])) : INSTALL_PATH . 'logs';
69         $this->prop['temp_dir'] = $this->prop['temp_dir'] ? realpath(unslashify($this->prop['temp_dir'])) : INSTALL_PATH . 'temp';
f52c4f 70
2eb794 71         // fix default imap folders encoding
A 72         foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder)
73             $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP');
74
75         if (!empty($this->prop['default_imap_folders']))
76             foreach ($this->prop['default_imap_folders'] as $n => $folder)
77                 $this->prop['default_imap_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
78
79         // set PHP error logging according to config
80         if ($this->prop['debug_level'] & 1) {
81             ini_set('log_errors', 1);
82
83             if ($this->prop['log_driver'] == 'syslog') {
84                 ini_set('error_log', 'syslog');
85             }
86             else {
87                 ini_set('error_log', $this->prop['log_dir'].'/errors');
88             }
89         }
23b495 90
A 91         // enable display_errors in 'show' level, but not for ajax requests
92         ini_set('display_errors', intval(empty($_REQUEST['_remote']) && ($this->prop['debug_level'] & 4)));
2eb794 93
A 94         // export config data
95         $GLOBALS['CONFIG'] = &$this->prop;
2471d3 96     }
1854c4 97
2eb794 98     /**
A 99      * Load a host-specific config file if configured
100      * This will merge the host specific configuration with the given one
101      */
102     private function load_host_config()
103     {
104         $fname = null;
10eedb 105
2eb794 106         if (is_array($this->prop['include_host_config'])) {
A 107             $fname = $this->prop['include_host_config'][$_SERVER['HTTP_HOST']];
108         }
109         else if (!empty($this->prop['include_host_config'])) {
110             $fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $_SERVER['HTTP_HOST']) . '.inc.php';
111         }
2471d3 112
2eb794 113         if ($fname) {
A 114             $this->load_from_file(RCMAIL_CONFIG_DIR . '/' . $fname);
115         }
83a763 116     }
T 117
2eb794 118
A 119     /**
120      * Read configuration from a file
121      * and merge with the already stored config values
122      *
5c461b 123      * @param string $fpath Full path to the config file to be loaded
2eb794 124      * @return booelan True on success, false on failure
A 125      */
126     public function load_from_file($fpath)
127     {
128         if (is_file($fpath) && is_readable($fpath)) {
7c9850 129             // use output buffering, we don't need any output here 
A 130             ob_start();
2eb794 131             include($fpath);
7c9850 132             ob_end_clean();
A 133
2eb794 134             if (is_array($rcmail_config)) {
A 135                 $this->prop = array_merge($this->prop, $rcmail_config, $this->userprefs);
136                 return true;
137             }
138         }
139
140         return false;
141     }
142
143
144     /**
145      * Getter for a specific config parameter
146      *
5c461b 147      * @param  string $name Parameter name
A 148      * @param  mixed  $def  Default value if not set
2eb794 149      * @return mixed  The requested config value
A 150      */
151     public function get($name, $def = null)
152     {
183717 153         $result = isset($this->prop[$name]) ? $this->prop[$name] : $def;
A 154         $rcmail = rcmail::get_instance();
155
156         if (is_object($rcmail->plugins)) {
157             $plugin = $rcmail->plugins->exec_hook('config_get', array(
158                 'name' => $name, 'default' => $def, 'result' => $result));
159
160             return $plugin['result'];
161         }
162
163         return $result;
2eb794 164     }
A 165
166
167     /**
168      * Setter for a config parameter
169      *
5c461b 170      * @param string $name  Parameter name
A 171      * @param mixed  $value Parameter value
2eb794 172      */
A 173     public function set($name, $value)
174     {
175         $this->prop[$name] = $value;
176     }
177
178
179     /**
180      * Override config options with the given values (eg. user prefs)
181      *
5c461b 182      * @param array $prefs Hash array with config props to merge over
2eb794 183      */
A 184     public function merge($prefs)
185     {
186         $this->prop = array_merge($this->prop, $prefs, $this->userprefs);
187     }
188
189
190     /**
191      * Merge the given prefs over the current config
192      * and make sure that they survive further merging.
193      *
5c461b 194      * @param array $prefs Hash array with user prefs
2eb794 195      */
A 196     public function set_user_prefs($prefs)
197     {
bfb7d6 198         // Honor the dont_override setting for any existing user preferences
A 199         $dont_override = $this->get('dont_override');
200         if (is_array($dont_override) && !empty($dont_override)) {
201             foreach ($prefs as $key => $pref) {
202                 if (in_array($key, $dont_override)) {
203                     unset($prefs[$key]);
204                 }
205             }
206         }
207
2eb794 208         $this->userprefs = $prefs;
bfb7d6 209         $this->prop      = array_merge($this->prop, $prefs);
2eb794 210     }
A 211
212
213     /**
214      * Getter for all config options
215      *
216      * @return array  Hash array containg all config properties
217      */
218     public function all()
219     {
220         return $this->prop;
221     }
222
223
224     /**
225      * Return requested DES crypto key.
226      *
5c461b 227      * @param string $key Crypto key name
2eb794 228      * @return string Crypto key
A 229      */
230     public function get_crypto_key($key)
231     {
232         // Bomb out if the requested key does not exist
233         if (!array_key_exists($key, $this->prop)) {
234             raise_error(array(
235                 'code' => 500, 'type' => 'php',
236                 'file' => __FILE__, 'line' => __LINE__,
237                 'message' => "Request for unconfigured crypto key \"$key\""
238             ), true, true);
239         }
240
241         $key = $this->prop[$key];
242
243         // Bomb out if the configured key is not exactly 24 bytes long
244         if (strlen($key) != 24) {
245             raise_error(array(
246                 'code' => 500, 'type' => 'php',
247                 'file' => __FILE__, 'line' => __LINE__,
248                 'message' => "Configured crypto key '$key' is not exactly 24 bytes long"
249             ), true, true);
250         }
251
252         return $key;
253     }
254
255
256     /**
257      * Try to autodetect operating system and find the correct line endings
258      *
259      * @return string The appropriate mail header delimiter
260      */
261     public function header_delimiter()
262     {
263         // use the configured delimiter for headers
086767 264         if (!empty($this->prop['mail_header_delimiter'])) {
A 265             $delim = $this->prop['mail_header_delimiter'];
266             if ($delim == "\n" || $delim == "\r\n")
267                 return $delim;
268             else
269                 raise_error(array(
270                     'code' => 500, 'type' => 'php',
271                     'file' => __FILE__, 'line' => __LINE__,
272                     'message' => "Invalid mail_header_delimiter setting"
273                 ), true, false);
274         }
2eb794 275
A 276         $php_os = strtolower(substr(PHP_OS, 0, 3));
277
278         if ($php_os == 'win')
279             return "\r\n";
280
281         if ($php_os == 'mac')
282             return "\r\n";
283
284         return "\n";
285     }
286
287
288     /**
289      * Return the mail domain configured for the given host
290      *
5c461b 291      * @param string  $host   IMAP host
A 292      * @param boolean $encode If true, domain name will be converted to IDN ASCII
2eb794 293      * @return string Resolved SMTP host
A 294      */
e99991 295     public function mail_domain($host, $encode=true)
2eb794 296     {
A 297         $domain = $host;
298
299         if (is_array($this->prop['mail_domain'])) {
300             if (isset($this->prop['mail_domain'][$host]))
301                 $domain = $this->prop['mail_domain'][$host];
302         }
303         else if (!empty($this->prop['mail_domain']))
bb8721 304             $domain = rcube_parse_host($this->prop['mail_domain']);
A 305
e99991 306         if ($encode)
e8d5bd 307             $domain = rcube_idn_to_ascii($domain);
e99991 308
2eb794 309         return $domain;
A 310     }
bb8721 311
A 312
2eb794 313     /**
A 314      * Getter for error state
315      *
316      * @return mixed Error message on error, False if no errors
317      */
318     public function get_error()
319     {
320         return empty($this->errors) ? false : join("\n", $this->errors);
321     }
83a763 322
197601 323 }