]> git.donarmstrong.com Git - roundcube.git/blob - program/include/rcube_config.php
66d7b675d96f45aa3bbbda26a21675ce7e3d2192
[roundcube.git] / program / include / rcube_config.php
1 <?php
2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_config.php                                      |
6  |                                                                       |
7  | This file is part of the Roundcube Webmail client                     |
8  | Copyright (C) 2008-2010, Roundcube Dev. - Switzerland                 |
9  | Licensed under the GNU GPL                                            |
10  |                                                                       |
11  | PURPOSE:                                                              |
12  |   Class to read configuration settings                                |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
18  $Id: rcube_config.php 4363 2010-12-22 19:17:47Z alec $
19
20 */
21
22 /**
23  * Configuration class for Roundcube
24  *
25  * @package Core
26  */
27 class rcube_config
28 {
29     private $prop = array();
30     private $errors = array();
31     private $userprefs = array();
32
33
34     /**
35      * Object constructor
36      */
37     public function __construct()
38     {
39         $this->load();
40     }
41
42
43     /**
44      * Load config from local config file
45      *
46      * @todo Remove global $CONFIG
47      */
48     private function load()
49     {
50         // load main config file
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.';
57     
58         // load host-specific configuration
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';
70     
71         // fix default imap folders encoding
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         }
90         if ($this->prop['debug_level'] & 4) {
91             ini_set('display_errors', 1);
92         }
93         else {
94             ini_set('display_errors', 0);
95         }
96
97         // export config data
98         $GLOBALS['CONFIG'] = &$this->prop;
99     }
100
101     /**
102      * Load a host-specific config file if configured
103      * This will merge the host specific configuration with the given one
104      */
105     private function load_host_config()
106     {
107         $fname = null;
108
109         if (is_array($this->prop['include_host_config'])) {
110             $fname = $this->prop['include_host_config'][$_SERVER['HTTP_HOST']];
111         }
112         else if (!empty($this->prop['include_host_config'])) {
113             $fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $_SERVER['HTTP_HOST']) . '.inc.php';
114         }
115
116         if ($fname) {
117             $this->load_from_file(RCMAIL_CONFIG_DIR . '/' . $fname);
118         }
119     }
120
121
122     /**
123      * Read configuration from a file
124      * and merge with the already stored config values
125      *
126      * @param string $fpath Full path to the config file to be loaded
127      * @return booelan True on success, false on failure
128      */
129     public function load_from_file($fpath)
130     {
131         if (is_file($fpath) && is_readable($fpath)) {
132             // use output buffering, we don't need any output here 
133             ob_start();
134             include($fpath);
135             ob_end_clean();
136
137             if (is_array($rcmail_config)) {
138                 $this->prop = array_merge($this->prop, $rcmail_config, $this->userprefs);
139                 return true;
140             }
141         }
142
143         return false;
144     }
145
146
147     /**
148      * Getter for a specific config parameter
149      *
150      * @param  string $name Parameter name
151      * @param  mixed  $def  Default value if not set
152      * @return mixed  The requested config value
153      */
154     public function get($name, $def = null)
155     {
156         return isset($this->prop[$name]) ? $this->prop[$name] : $def;
157     }
158
159
160     /**
161      * Setter for a config parameter
162      *
163      * @param string $name  Parameter name
164      * @param mixed  $value Parameter value
165      */
166     public function set($name, $value)
167     {
168         $this->prop[$name] = $value;
169     }
170
171
172     /**
173      * Override config options with the given values (eg. user prefs)
174      *
175      * @param array $prefs Hash array with config props to merge over
176      */
177     public function merge($prefs)
178     {
179         $this->prop = array_merge($this->prop, $prefs, $this->userprefs);
180     }
181
182
183     /**
184      * Merge the given prefs over the current config
185      * and make sure that they survive further merging.
186      *
187      * @param array $prefs Hash array with user prefs
188      */
189     public function set_user_prefs($prefs)
190     {
191         $this->userprefs = $prefs;
192         $this->prop = array_merge($this->prop, $prefs);
193     }
194
195
196     /**
197      * Getter for all config options
198      *
199      * @return array  Hash array containg all config properties
200      */
201     public function all()
202     {
203         return $this->prop;
204     }
205
206
207     /**
208      * Return requested DES crypto key.
209      *
210      * @param string $key Crypto key name
211      * @return string Crypto key
212      */
213     public function get_crypto_key($key)
214     {
215         // Bomb out if the requested key does not exist
216         if (!array_key_exists($key, $this->prop)) {
217             raise_error(array(
218                 'code' => 500, 'type' => 'php',
219                 'file' => __FILE__, 'line' => __LINE__,
220                 'message' => "Request for unconfigured crypto key \"$key\""
221             ), true, true);
222         }
223
224         $key = $this->prop[$key];
225
226         // Bomb out if the configured key is not exactly 24 bytes long
227         if (strlen($key) != 24) {
228             raise_error(array(
229                 'code' => 500, 'type' => 'php',
230                     'file' => __FILE__, 'line' => __LINE__,
231                 'message' => "Configured crypto key '$key' is not exactly 24 bytes long"
232             ), true, true);
233         }
234
235         return $key;
236     }
237
238
239     /**
240      * Try to autodetect operating system and find the correct line endings
241      *
242      * @return string The appropriate mail header delimiter
243      */
244     public function header_delimiter()
245     {
246         // use the configured delimiter for headers
247         if (!empty($this->prop['mail_header_delimiter'])) {
248             $delim = $this->prop['mail_header_delimiter'];
249             if ($delim == "\n" || $delim == "\r\n")
250                 return $delim;
251             else
252                 raise_error(array(
253                     'code' => 500, 'type' => 'php',
254                         'file' => __FILE__, 'line' => __LINE__,
255                     'message' => "Invalid mail_header_delimiter setting"
256                 ), true, false);
257         }
258
259         $php_os = strtolower(substr(PHP_OS, 0, 3));
260
261         if ($php_os == 'win')
262             return "\r\n";
263
264         if ($php_os == 'mac')
265             return "\r\n";
266
267         return "\n";
268     }
269
270
271     /**
272      * Return the mail domain configured for the given host
273      *
274      * @param string  $host   IMAP host
275      * @param boolean $encode If true, domain name will be converted to IDN ASCII
276      * @return string Resolved SMTP host
277      */
278     public function mail_domain($host, $encode=true)
279     {
280         $domain = $host;
281
282         if (is_array($this->prop['mail_domain'])) {
283             if (isset($this->prop['mail_domain'][$host]))
284                 $domain = $this->prop['mail_domain'][$host];
285         }
286         else if (!empty($this->prop['mail_domain']))
287             $domain = rcube_parse_host($this->prop['mail_domain']);
288
289         if ($encode)
290             $domain = idn_to_ascii($domain);
291
292         return $domain;
293     }
294
295
296     /**
297      * Getter for error state
298      *
299      * @return mixed Error message on error, False if no errors
300      */
301     public function get_error()
302     {
303         return empty($this->errors) ? false : join("\n", $this->errors);
304     }
305
306 }