4 +-----------------------------------------------------------------------+
7 | This file is part of the RoundCube Webmail package |
8 | Copyright (C) 2008, RoundCube Dev. - Switzerland |
9 | Licensed under the GNU Public License |
10 +-----------------------------------------------------------------------+
18 * Class to control the installation process of the RoundCube Webmail package
22 * @author Thomas Bruederli
29 var $config = array();
30 var $configured = false;
31 var $last_error = null;
32 var $email_pattern = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9])';
33 var $config_props = array();
38 function rcube_install()
40 $this->step = intval($_REQUEST['_step']);
41 $this->is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
47 function get_instance()
52 $inst = new rcube_install();
58 * Read the default config files and store properties
60 function load_defaults()
62 $this->_load_config('.php.dist');
67 * Read the local config files and store properties
69 function load_config()
71 $this->config = array();
72 $this->_load_config('.php');
73 $this->configured = !empty($this->config);
77 * Read the default config file and store properties
80 function _load_config($suffix)
82 @include '../config/main.inc' . $suffix;
83 if (is_array($rcmail_config)) {
84 $this->config += $rcmail_config;
87 @include '../config/db.inc'. $suffix;
88 if (is_array($rcmail_config)) {
89 $this->config += $rcmail_config;
95 * Getter for a certain config property
97 * @param string Property name
98 * @param string Default value
99 * @return string The property value
101 function getprop($name, $default = '')
103 $value = $this->is_post && (isset($_POST["_$name"]) || $this->config_props[$name]) ? $_POST["_$name"] : $this->config[$name];
105 if ($name == 'des_key' && !$this->configured && !isset($_REQUEST["_$name"]))
106 $value = rcube_install::random_key(24);
108 return $value !== null && $value !== '' ? $value : $default;
113 * Take the default config file and replace the parameters
114 * with the submitted form data
116 * @param string Which config file (either 'main' or 'db')
117 * @return string The complete config file content
119 function create_config($which)
121 $out = file_get_contents("../config/{$which}.inc.php.dist");
124 return '[Warning: could not read the template file]';
126 foreach ($this->config as $prop => $default) {
127 $value = (isset($_POST["_$prop"]) || $this->config_props[$prop]) ? $_POST["_$prop"] : $default;
129 // convert some form data
130 if ($prop == 'debug_level' && is_array($value)) {
132 foreach ($value as $i => $dbgval)
133 $val += intval($dbgval);
136 else if ($prop == 'db_dsnw' && !empty($_POST['_dbtype'])) {
137 if ($_POST['_dbtype'] == 'sqlite')
138 $value = sprintf('%s://%s?mode=0646', $_POST['_dbtype'], $_POST['_dbname']{0} == '/' ? '/' . $_POST['_dbname'] : $_POST['_dbname']);
140 $value = sprintf('%s://%s:%s@%s/%s', $_POST['_dbtype'],
141 rawurlencode($_POST['_dbuser']), rawurlencode($_POST['_dbpass']),
142 $_POST['_dbhost'], $_POST['_dbname']);
144 else if ($prop == 'smtp_auth_type' && $value == '0') {
147 else if ($prop == 'default_host' && is_array($value)) {
148 $value = rcube_install::_clean_array($value);
149 if (count($value) <= 1)
152 else if ($prop == 'pagesize') {
153 $value = max(2, intval($value));
155 else if ($prop == 'smtp_user' && !empty($_POST['_smtp_user_u'])) {
158 else if ($prop == 'smtp_pass' && !empty($_POST['_smtp_user_u'])) {
161 else if (is_bool($default)) {
162 $value = (bool)$value;
164 else if (is_numeric($value)) {
165 $value = intval($value);
168 // skip this property
169 if ($value == $default)
172 // replace the matching line in config file
174 '/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie',
175 "'\\1 = ' . var_export(\$value, true) . ';'",
184 * Getter for the last error message
186 * @return string Error message or null if none exists
190 return $this->last_error['message'];
195 * Return a list with all imap hosts configured
197 * @return array Clean list with imap hosts
199 function get_hostlist()
201 $default_hosts = (array)$this->getprop('default_host');
204 foreach ($default_hosts as $key => $name) {
206 $out[] = is_numeric($key) ? $name : $key;
216 * @param string Test name
217 * @param string Confirm message
219 function pass($name, $message = '')
221 echo Q($name) . ': <span class="success">OK</span>';
222 $this->_showhint($message);
227 * Display an error status and increase failure count
229 * @param string Test name
230 * @param string Error message
231 * @param string URL for details
233 function fail($name, $message = '', $url = '')
237 echo Q($name) . ': <span class="fail">NOT OK</span>';
238 $this->_showhint($message, $url);
243 * Display warning status
245 * @param string Test name
246 * @param string Warning message
247 * @param string URL for details
249 function na($name, $message = '', $url = '')
251 echo Q($name) . ': <span class="na">NOT AVAILABLE</span>';
252 $this->_showhint($message, $url);
256 function _showhint($message, $url = '')
261 $hint .= ($hint ? '; ' : '') . 'See <a href="' . Q($url) . '" target="_blank">' . Q($url) . '</a>';
264 echo '<span class="indent">(' . $hint . ')</span>';
268 function _clean_array($arr)
272 foreach (array_unique($arr) as $i => $val)
281 * Initialize the database with the according schema
283 * @param object rcube_db Database connection
284 * @return boolen True on success, False on error
286 function init_db($DB)
288 $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql');
289 $engine = isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider;
291 // find out db version
292 if ($engine == 'mysql') {
293 $DB->query('SELECT VERSION() AS version');
294 $sql_arr = $DB->fetch_assoc();
295 $version = floatval($sql_arr['version']);
301 // read schema file from /SQL/*
302 $fname = "../SQL/$engine.initial.sql";
303 if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) {
305 foreach ($lines as $i => $line) {
306 if (eregi('^--', $line))
309 $buff .= $line . "\n";
310 if (eregi(';$', trim($line))) {
313 if ($this->get_error())
319 $this->fail('DB Schema', "Cannot read the schema file: $fname");
323 if ($err = $this->get_error()) {
324 $this->fail('DB Schema', "Error creating database schema: $err");
332 * Handler for RoundCube errors
334 function raise_error($p)
336 $this->last_error = $p;
341 * Generarte a ramdom string to be used as encryption key
343 * @param int Key length
344 * @return string The generated random string
347 function random_key($length)
349 $alpha = 'ABCDEFGHIJKLMNOPQERSTUVXYZabcdefghijklmnopqrtsuvwxyz0123456789+*%&?!$-_=';
352 for ($i=0; $i < $length; $i++)
353 $out .= $alpha{rand(0, strlen($alpha)-1)};
362 * Shortcut function for htmlentities()
364 * @param string String to quote
365 * @return string The html-encoded string
369 return htmlentities($string);
374 * Fake rinternal error handler to catch errors
376 function raise_error($p)
378 $rci = rcube_install::get_instance();
379 $rci->raise_error($p);