]> git.donarmstrong.com Git - roundcube.git/blob - installer/rcube_install.php
Imported Upstream version 0.1
[roundcube.git] / installer / rcube_install.php
1 <?php
2
3 /*
4  +-----------------------------------------------------------------------+
5  | rcube_install.php                                                     |
6  |                                                                       |
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  +-----------------------------------------------------------------------+
11
12  $Id:  $
13
14 */
15
16
17 /**
18  * Class to control the installation process of the RoundCube Webmail package
19  *
20  * @category Install
21  * @package  RoundCube
22  * @author Thomas Bruederli
23  */
24 class rcube_install
25 {
26   var $step;
27   var $is_post = false;
28   var $failures = 0;
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();
34   
35   /**
36    * Constructor
37    */
38   function rcube_install()
39   {
40     $this->step = intval($_REQUEST['_step']);
41     $this->is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
42   }
43   
44   /**
45    * Singleton getter
46    */
47   function get_instance()
48   {
49     static $inst;
50     
51     if (!$inst)
52       $inst = new rcube_install();
53     
54     return $inst;
55   }
56   
57   /**
58    * Read the default config files and store properties
59    */
60   function load_defaults()
61   {
62     $this->_load_config('.php.dist');
63   }
64
65
66   /**
67    * Read the local config files and store properties
68    */
69   function load_config()
70   {
71     $this->config = array();
72     $this->_load_config('.php');
73     $this->configured = !empty($this->config);
74   }
75
76   /**
77    * Read the default config file and store properties
78    * @access private
79    */
80   function _load_config($suffix)
81   {
82     @include '../config/main.inc' . $suffix;
83     if (is_array($rcmail_config)) {
84       $this->config += $rcmail_config;
85     }
86       
87     @include '../config/db.inc'. $suffix;
88     if (is_array($rcmail_config)) {
89       $this->config += $rcmail_config;
90     }
91   }
92   
93   
94   /**
95    * Getter for a certain config property
96    *
97    * @param string Property name
98    * @param string Default value
99    * @return string The property value
100    */
101   function getprop($name, $default = '')
102   {
103     $value = $this->is_post && (isset($_POST["_$name"]) || $this->config_props[$name]) ? $_POST["_$name"] : $this->config[$name];
104     
105     if ($name == 'des_key' && !isset($_REQUEST["_$name"]))
106       $value = rcube_install::random_key(24);
107     
108     return $value !== null && $value !== '' ? $value : $default;
109   }
110   
111   
112   /**
113    * Take the default config file and replace the parameters
114    * with the submitted form data
115    *
116    * @param string Which config file (either 'main' or 'db')
117    * @return string The complete config file content
118    */
119   function create_config($which)
120   {
121     $out = file_get_contents("../config/{$which}.inc.php.dist");
122     
123     if (!$out)
124       return '[Warning: could not read the template file]';
125     
126     foreach ($this->config as $prop => $default) {
127       $value = (isset($_POST["_$prop"]) || $this->config_props[$prop]) ? $_POST["_$prop"] : $default;
128       
129       // convert some form data
130       if ($prop == 'debug_level' && is_array($value)) {
131         $val = 0;
132         foreach ($value as $i => $dbgval)
133           $val += intval($dbgval);
134         $value = $val;
135       }
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']);
139         else
140           $value = sprintf('%s://%s:%s@%s/%s', $_POST['_dbtype'], $_POST['_dbuser'], $_POST['_dbpass'], $_POST['_dbhost'], $_POST['_dbname']);
141       }
142       else if ($prop == 'smtp_auth_type' && $value == '0') {
143         $value = '';
144       }
145       else if ($prop == 'default_host' && is_array($value)) {
146         $value = rcube_install::_clean_array($value);
147         if (count($value) <= 1)
148           $value = $value[0];
149       }
150       else if ($prop == 'smtp_user' && !empty($_POST['_smtp_user_u'])) {
151         $value = '%u';
152       }
153       else if ($prop == 'smtp_pass' && !empty($_POST['_smtp_user_u'])) {
154         $value = '%p';
155       }
156       else if (is_bool($default)) {
157         $value = (bool)$value;
158       }
159       else if (is_numeric($value)) {
160         $value = intval($value);
161       }
162       
163       // skip this property
164       if ($value == $default)
165         continue;
166       
167       // replace the matching line in config file
168       $out = preg_replace(
169         '/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie',
170         "'\\1 = ' . var_export(\$value, true) . ';'",
171         $out);
172     }
173     
174     return $out;
175   }
176   
177   
178   /**
179    * Getter for the last error message
180    *
181    * @return string Error message or null if none exists
182    */
183   function get_error()
184   {
185       return $this->last_error['message'];
186   }
187   
188   
189   /**
190    * Return a list with all imap hosts configured
191    *
192    * @return array Clean list with imap hosts
193    */
194   function get_hostlist()
195   {
196     $default_hosts = (array)$this->getprop('default_host');
197     $out = array();
198     
199     foreach ($default_hosts as $key => $name) {
200       if (!empty($name))
201         $out[] = is_numeric($key) ? $name : $key;
202     }
203     
204     return $out;
205   }
206   
207   
208   /**
209    * Display OK status
210    *
211    * @param string Test name
212    * @param string Confirm message
213    */
214   function pass($name, $message = '')
215   {
216     echo Q($name) . ':&nbsp; <span class="success">OK</span>';
217     $this->_showhint($message);
218   }
219   
220   
221   /**
222    * Display an error status and increase failure count
223    *
224    * @param string Test name
225    * @param string Error message
226    * @param string URL for details
227    */
228   function fail($name, $message = '', $url = '')
229   {
230     $this->failures++;
231     
232     echo Q($name) . ':&nbsp; <span class="fail">NOT OK</span>';
233     $this->_showhint($message, $url);
234   }
235   
236   
237   /**
238    * Display warning status
239    *
240    * @param string Test name
241    * @param string Warning message
242    * @param string URL for details
243    */
244   function na($name, $message = '', $url = '')
245   {
246     echo Q($name) . ':&nbsp; <span class="na">NOT AVAILABLE</span>';
247     $this->_showhint($message, $url);
248   }
249   
250   
251   function _showhint($message, $url = '')
252   {
253     $hint = Q($message);
254     
255     if ($url)
256       $hint .= ($hint ? '; ' : '') . 'See <a href="' . Q($url) . '" target="_blank">' . Q($url) . '</a>';
257       
258     if ($hint)
259       echo '<span class="indent">(' . $hint . ')</span>';
260   }
261   
262   
263   function _clean_array($arr)
264   {
265     $out = array();
266     
267     foreach (array_unique($arr) as $i => $val)
268       if (!empty($val))
269         $out[] = $val;
270     
271     return $out;
272   }
273   
274   
275   /**
276    * Initialize the database with the according schema
277    *
278    * @param object rcube_db Database connection
279    * @return boolen True on success, False on error
280    */
281   function init_db($DB)
282   {
283     $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql');
284     $engine = isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider;
285     
286     // find out db version
287     if ($engine == 'mysql') {
288       $DB->query('SELECT VERSION() AS version');
289       $sql_arr = $DB->fetch_assoc();
290       $version = floatval($sql_arr['version']);
291       
292       if ($version >= 4.1)
293         $engine = 'mysql5';
294     }
295     
296     // read schema file from /SQL/*
297     $fname = "../SQL/$engine.initial.sql";
298     if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) {
299       $buff = '';
300       foreach ($lines as $i => $line) {
301         if (eregi('^--', $line))
302           continue;
303           
304         $buff .= $line . "\n";
305         if (eregi(';$', trim($line))) {
306           $DB->query($buff);
307           $buff = '';
308         }
309       }
310     }
311     else {
312       $this->fail('DB Schema', "Cannot read the schema file: $fname");
313       return false;
314     }
315     
316     if ($err = $this->get_error()) {
317       $this->fail('DB Schema', "Error creating database schema: $err");
318       return false;
319     }
320
321     return true;
322   }
323   
324   /**
325    * Handler for RoundCube errors
326    */
327   function raise_error($p)
328   {
329       $this->last_error = $p;
330   }
331   
332   
333   /**
334    * Generarte a ramdom string to be used as encryption key
335    *
336    * @param int Key length
337    * @return string The generated random string
338    * @static
339    */
340   function random_key($length)
341   {
342     $alpha = 'ABCDEFGHIJKLMNOPQERSTUVXYZabcdefghijklmnopqrtsuvwxyz0123456789+*%&?!$-_=';
343     $out = '';
344     
345     for ($i=0; $i < $length; $i++)
346       $out .= $alpha{rand(0, strlen($alpha)-1)};
347     
348     return $out;
349   }
350   
351 }
352
353
354 /**
355  * Shortcut function for htmlentities()
356  *
357  * @param string String to quote
358  * @return string The html-encoded string
359  */
360 function Q($string)
361 {
362   return htmlentities($string);
363 }
364
365
366 /**
367  * Fake rinternal error handler to catch errors
368  */
369 function raise_error($p)
370 {
371   $rci = rcube_install::get_instance();
372   $rci->raise_error($p);
373 }
374