alecpl
2010-09-25 e019f2d0f2dc2fbfa345ab5d7ae85e67bfdd76b8
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                     |
A 8  | Copyright (C) 2008-2010, Roundcube Dev. - Switzerland                 |
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         // start output buffering, we don't need any output yet, 
A 51         // it'll be cleared after reading of config files, etc.
52         ob_start();
53     
54         // load main config file
55         if (!$this->load_from_file(RCMAIL_CONFIG_DIR . '/main.inc.php'))
56             $this->errors[] = 'main.inc.php was not found.';
57
58         // load database config
59         if (!$this->load_from_file(RCMAIL_CONFIG_DIR . '/db.inc.php'))
60             $this->errors[] = 'db.inc.php was not found.';
61     
62         // load host-specific configuration
63         $this->load_host_config();
64
65         // set skin (with fallback to old 'skin_path' property)
66         if (empty($this->prop['skin']) && !empty($this->prop['skin_path']))
67             $this->prop['skin'] = str_replace('skins/', '', unslashify($this->prop['skin_path']));
68         else if (empty($this->prop['skin']))
69             $this->prop['skin'] = 'default';
70
71         // fix paths
72         $this->prop['log_dir'] = $this->prop['log_dir'] ? realpath(unslashify($this->prop['log_dir'])) : INSTALL_PATH . 'logs';
73         $this->prop['temp_dir'] = $this->prop['temp_dir'] ? realpath(unslashify($this->prop['temp_dir'])) : INSTALL_PATH . 'temp';
74     
75         // fix default imap folders encoding
76         foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder)
77             $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP');
78
79         if (!empty($this->prop['default_imap_folders']))
80             foreach ($this->prop['default_imap_folders'] as $n => $folder)
81                 $this->prop['default_imap_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
82
83         // set PHP error logging according to config
84         if ($this->prop['debug_level'] & 1) {
85             ini_set('log_errors', 1);
86
87             if ($this->prop['log_driver'] == 'syslog') {
88                 ini_set('error_log', 'syslog');
89             }
90             else {
91                 ini_set('error_log', $this->prop['log_dir'].'/errors');
92             }
93         }
94         if ($this->prop['debug_level'] & 4) {
95             ini_set('display_errors', 1);
96         }
97         else {
98             ini_set('display_errors', 0);
99         }
100
101         // clear output buffer
102         ob_end_clean();
103
104         // export config data
105         $GLOBALS['CONFIG'] = &$this->prop;
2471d3 106     }
1854c4 107
2eb794 108     /**
A 109      * Load a host-specific config file if configured
110      * This will merge the host specific configuration with the given one
111      */
112     private function load_host_config()
113     {
114         $fname = null;
10eedb 115
2eb794 116         if (is_array($this->prop['include_host_config'])) {
A 117             $fname = $this->prop['include_host_config'][$_SERVER['HTTP_HOST']];
118         }
119         else if (!empty($this->prop['include_host_config'])) {
120             $fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $_SERVER['HTTP_HOST']) . '.inc.php';
121         }
2471d3 122
2eb794 123         if ($fname) {
A 124             $this->load_from_file(RCMAIL_CONFIG_DIR . '/' . $fname);
125         }
83a763 126     }
T 127
2eb794 128
A 129     /**
130      * Read configuration from a file
131      * and merge with the already stored config values
132      *
133      * @param string Full path to the config file to be loaded
134      * @return booelan True on success, false on failure
135      */
136     public function load_from_file($fpath)
137     {
138         if (is_file($fpath) && is_readable($fpath)) {
139             include($fpath);
140             if (is_array($rcmail_config)) {
141                 $this->prop = array_merge($this->prop, $rcmail_config, $this->userprefs);
142                 return true;
143             }
144         }
145
146         return false;
147     }
148
149
150     /**
151      * Getter for a specific config parameter
152      *
153      * @param  string Parameter name
154      * @param  mixed  Default value if not set
155      * @return mixed  The requested config value
156      */
157     public function get($name, $def = null)
158     {
159         return isset($this->prop[$name]) ? $this->prop[$name] : $def;
160     }
161
162
163     /**
164      * Setter for a config parameter
165      *
166      * @param string Parameter name
167      * @param mixed  Parameter value
168      */
169     public function set($name, $value)
170     {
171         $this->prop[$name] = $value;
172     }
173
174
175     /**
176      * Override config options with the given values (eg. user prefs)
177      *
178      * @param array Hash array with config props to merge over
179      */
180     public function merge($prefs)
181     {
182         $this->prop = array_merge($this->prop, $prefs, $this->userprefs);
183     }
184
185
186     /**
187      * Merge the given prefs over the current config
188      * and make sure that they survive further merging.
189      *
190      * @param array  Hash array with user prefs
191      */
192     public function set_user_prefs($prefs)
193     {
194         $this->userprefs = $prefs;
195         $this->prop = array_merge($this->prop, $prefs);
196     }
197
198
199     /**
200      * Getter for all config options
201      *
202      * @return array  Hash array containg all config properties
203      */
204     public function all()
205     {
206         return $this->prop;
207     }
208
209
210     /**
211      * Return requested DES crypto key.
212      *
213      * @param string Crypto key name
214      * @return string Crypto key
215      */
216     public function get_crypto_key($key)
217     {
218         // Bomb out if the requested key does not exist
219         if (!array_key_exists($key, $this->prop)) {
220             raise_error(array(
221                 'code' => 500, 'type' => 'php',
222                 'file' => __FILE__, 'line' => __LINE__,
223                 'message' => "Request for unconfigured crypto key \"$key\""
224             ), true, true);
225         }
226
227         $key = $this->prop[$key];
228
229         // Bomb out if the configured key is not exactly 24 bytes long
230         if (strlen($key) != 24) {
231             raise_error(array(
232                 'code' => 500, 'type' => 'php',
233                 'file' => __FILE__, 'line' => __LINE__,
234                 'message' => "Configured crypto key '$key' is not exactly 24 bytes long"
235             ), true, true);
236         }
237
238         return $key;
239     }
240
241
242     /**
243      * Try to autodetect operating system and find the correct line endings
244      *
245      * @return string The appropriate mail header delimiter
246      */
247     public function header_delimiter()
248     {
249         // use the configured delimiter for headers
086767 250         if (!empty($this->prop['mail_header_delimiter'])) {
A 251             $delim = $this->prop['mail_header_delimiter'];
252             if ($delim == "\n" || $delim == "\r\n")
253                 return $delim;
254             else
255                 raise_error(array(
256                     'code' => 500, 'type' => 'php',
257                     'file' => __FILE__, 'line' => __LINE__,
258                     'message' => "Invalid mail_header_delimiter setting"
259                 ), true, false);
260         }
2eb794 261
A 262         $php_os = strtolower(substr(PHP_OS, 0, 3));
263
264         if ($php_os == 'win')
265             return "\r\n";
266
267         if ($php_os == 'mac')
268             return "\r\n";
269
270         return "\n";
271     }
272
273
274     /**
275      * Return the mail domain configured for the given host
276      *
277      * @param string IMAP host
278      * @return string Resolved SMTP host
279      */
280     public function mail_domain($host)
281     {
282         $domain = $host;
283
284         if (is_array($this->prop['mail_domain'])) {
285             if (isset($this->prop['mail_domain'][$host]))
286                 $domain = $this->prop['mail_domain'][$host];
287         }
288         else if (!empty($this->prop['mail_domain']))
bb8721 289             $domain = rcube_parse_host($this->prop['mail_domain']);
A 290
2eb794 291         return $domain;
A 292     }
bb8721 293
A 294
2eb794 295     /**
A 296      * Getter for error state
297      *
298      * @return mixed Error message on error, False if no errors
299      */
300     public function get_error()
301     {
302         return empty($this->errors) ? false : join("\n", $this->errors);
303     }
83a763 304
197601 305 }