Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2518211
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/installer/config.php b/installer/config.php
index 0697cc124..c110276aa 100644
--- a/installer/config.php
+++ b/installer/config.php
@@ -1,434 +1,437 @@
<form action="index.php" method="post">
<input type="hidden" name="_step" value="2" />
<?php
ini_set('display_errors', 1);
require_once 'include/rcube_html.inc';
+$RCI->load_config();
$RCI->load_defaults();
if (!empty($_POST['submit'])) {
echo '<p class="notice">Copy the following configurations and save them in two files (names above the text box)';
echo ' within the <tt>config/</tt> directory of your RoundCube installation.</p>';
$textbox = new textarea(array('rows' => 16, 'cols' => 60, 'class' => "configfile"));
echo '<div><em>main.inc.php</em></div>';
echo $textbox->show($RCI->create_config('main'));
echo '<div style="margin-top:1em"><em>db.inc.php</em></div>';
echo $textbox->show($RCI->create_config('db'));
echo '<p><input type="button" onclick="location.href=\'./index.php?_step=3\'" value="CONTINUE" /></p>';
// echo '<style type="text/css"> .configblock { display:none } </style>';
echo "\n<hr style='margin-bottom:1.6em' />\n";
}
?>
<fieldset>
<legend>General configuration</legend>
<dl class="configblock">
<!--
<dt id="cgfblockgeneral" class="propname">debug_level</dt>
<dd>
<?php
/*
$value = $RCI->getprop('debug_level');
$check_debug = new checkbox(array('name' => '_debug_level[]'));
echo $check_debug->show(($value & 1) ? 1 : 0 , array('value' => 1, 'id' => 'cfgdebug1'));
echo '<label for="cfgdebug1">Log errors</label><br />';
echo $check_debug->show(($value & 4) ? 4 : 0, array('value' => 4, 'id' => 'cfgdebug4'));
echo '<label for="cfgdebug4">Display errors</label><br />';
echo $check_debug->show(($value & 8) ? 8 : 0, array('value' => 8, 'id' => 'cfgdebug8'));
echo '<label for="cfgdebug8">Verbose display</label><br />';
*/
?>
</dd>
-->
<dt class="propname">product_name</dt>
<dd>
<?php
$input_prodname = new textfield(array('name' => '_product_name', 'size' => 30, 'id' => "cfgprodname"));
echo $input_prodname->show($RCI->getprop('product_name'));
?>
<div>The name of your service (used to compose page titles)</div>
</dd>
<dt class="propname">skin_path</dt>
<dd>
<?php
$input_skinpath = new textfield(array('name' => '_skin_path', 'size' => 30, 'id' => "cfgskinpath"));
echo $input_skinpath->show($RCI->getprop('skin_path'));
?>
<div>Relative path to the skin folder</div>
</dd>
<dt class="propname">temp_dir</dt>
<dd>
<?php
$input_tempdir = new textfield(array('name' => '_temp_dir', 'size' => 30, 'id' => "cfgtempdir"));
echo $input_tempdir->show($RCI->getprop('temp_dir'));
?>
<div>Use this folder to store temp files (must be writebale for webserver)</div>
</dd>
<dt class="propname">log_dir</dt>
<dd>
<?php
$input_logdir = new textfield(array('name' => '_log_dir', 'size' => 30, 'id' => "cfglogdir"));
echo $input_logdir->show($RCI->getprop('log_dir'));
?>
<div>Use this folder to store log files (must be writebale for webserver)</div>
</dd>
<dt class="propname">ip_check</dt>
<dd>
<?php
$check_ipcheck = new checkbox(array('name' => '_ip_check', 'id' => "cfgipcheck"));
echo $check_ipcheck->show(intval($RCI->getprop('ip_check')), array('value' => 1));
?>
<label for="cfgipcheck">Check client IP in session authorization</label><br />
<p class="hint">This increases security but can cause sudden logouts when someone uses a proxy with changeing IPs.</p>
</dd>
<dt class="propname">des_key</dt>
<dd>
<?php
$input_deskey = new textfield(array('name' => '_des_key', 'size' => 30, 'id' => "cfgdeskey"));
echo $input_deskey->show($RCI->getprop('des_key'));
?>
<div>This key is used to encrypt the users imap password before storing in the session record</div>
<p class="hint">It's a random generated string to ensure that every installation has it's own key.
If you enter it manually please provide a string of exactly 24 chars.</p>
</dd>
<dt class="propname">enable_caching</dt>
<dd>
<?php
$check_caching = new checkbox(array('name' => '_enable_caching', 'id' => "cfgcache"));
echo $check_caching->show(intval($RCI->getprop('enable_caching')), array('value' => 1));
?>
<label for="cfgcache">Cache messages in local database</label><br />
</dd>
<dt class="propname">enable_spellcheck</dt>
<dd>
<?php
$check_caching = new checkbox(array('name' => '_enable_spellcheck', 'id' => "cfgspellcheck"));
echo $check_caching->show(intval($RCI->getprop('enable_spellcheck')), array('value' => 1));
?>
<label for="cfgspellcheck">Make use of the built-in spell checker</label><br />
<p class="hint">It is based on GoogieSpell what implies that the message content will be sent to Google in order to check the spelling.</p>
</dd>
<dt class="propname">mdn_requests</dt>
<dd>
<?php
$select_mdnreq = new select(array('name' => '_mdn_requests', 'id' => "cfgmdnreq"));
$select_mdnreq->add(array('ask the user', 'send automatically', 'ignore'), array(0, 1, 2));
echo $select_mdnreq->show(intval($RCI->getprop('mdn_requests')));
?>
<div>Behavior if a received message requests a message delivery notification (read receipt)</div>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>Database setup</legend>
<dl class="configblock" id="cgfblockdb">
<dt class="propname">db_dsnw</dt>
<dd>
<p>Database settings for read/write operations:</p>
<?php
+require_once 'DB.php';
+
$supported_dbs = array('MySQL' => 'mysql', 'MySQLi' => 'mysqli',
'PgSQL' => 'pgsql', 'SQLite' => 'sqlite');
$select_dbtype = new select(array('name' => '_dbtype', 'id' => "cfgdbtype"));
foreach ($supported_dbs AS $database => $ext) {
if (extension_loaded($ext)) {
$select_dbtype->add($database, $ext);
}
}
$input_dbhost = new textfield(array('name' => '_dbhost', 'size' => 20, 'id' => "cfgdbhost"));
$input_dbname = new textfield(array('name' => '_dbname', 'size' => 20, 'id' => "cfgdbname"));
$input_dbuser = new textfield(array('name' => '_dbuser', 'size' => 20, 'id' => "cfgdbuser"));
$input_dbpass = new textfield(array('name' => '_dbpass', 'size' => 20, 'id' => "cfgdbpass"));
-$dsnw = parse_url($RCI->getprop('db_dsnw'));
+$dsnw = DB::parseDSN($RCI->getprop('db_dsnw'));
-echo $select_dbtype->show($_POST['_dbtype'] ? $_POST['_dbtype'] : $dsnw['scheme']);
+echo $select_dbtype->show($_POST['_dbtype'] ? $_POST['_dbtype'] : $dsnw['phptype']);
echo '<label for="cfgdbtype">Database type</label><br />';
-echo $input_dbhost->show($_POST['_dbhost'] ? $_POST['_dbhost'] : $dsnw['host']);
+echo $input_dbhost->show($_POST['_dbhost'] ? $_POST['_dbhost'] : $dsnw['hostspec']);
echo '<label for="cfgdbhost">Database server</label><br />';
-echo $input_dbname->show($_POST['_dbname'] ? $_POST['_dbname'] : preg_replace('/^\//', '', $dsnw['path']));
+echo $input_dbname->show($_POST['_dbname'] ? $_POST['_dbname'] : $dsnw['database']);
echo '<label for="cfgdbname">Database name</label><br />';
-echo $input_dbuser->show($_POST['_dbuser'] ? $_POST['_dbuser'] : $dsnw['user']);
+echo $input_dbuser->show($_POST['_dbuser'] ? $_POST['_dbuser'] : $dsnw['username']);
echo '<label for="cfgdbuser">Database user name (needs write permissions)</label><br />';
-echo $input_dbpass->show($_POST['_dbpass'] ? $_POST['_dbpass'] : $dsnw['pass']);
+echo $input_dbpass->show($_POST['_dbpass'] ? $_POST['_dbpass'] : $dsnw['password']);
echo '<label for="cfgdbpass">Database password</label><br />';
?>
</dd>
<dt class="propname">db_backend</dt>
<dd>
<?php
// check for existing PEAR classes
@include_once 'DB.php';
@include_once 'MDB2.php';
$select_dbba = new select(array('name' => '_db_backend', 'id' => "cfgdbba"));
if (class_exists('DB'))
$select_dbba->add('DB', 'db');
if (class_exists('MDB2'))
$select_dbba->add('MDB2', 'mdb2');
echo $select_dbba->show($RCI->getprop('db_backend'));
?>
<div>PEAR Database backend to use</div>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>IMAP Settings</legend>
<dl class="configblock" id="cgfblockimap">
<dt class="propname">default_host</dt>
<dd>
<div>The IMAP host(s) chosen to perform the log-in</div>
<div id="defaulthostlist">
<?php
$default_hosts = array_unique((array)$RCI->getprop('default_host'));
$text_imaphost = new textfield(array('name' => '_default_host[]', 'size' => 30));
for ($i=0; $i < count($default_hosts); $i++) {
echo '<div id="defaulthostentry'.$i.'">' . $text_imaphost->show($default_hosts[$i]);
if ($i > 0)
echo '<a href="#" onclick="removehostfield(this.parentNode);return false" class="removelink" title="Remove this entry">remove</a>';
echo '</div>';
}
?>
</div>
<div><a href="javascript:addhostfield()" class="addlink" title="Add another field">add</a></div>
<p class="hint">Leave blank to show a textbox at login</p>
</dd>
<dt class="propname">default_port</dt>
<dd>
<?php
$text_imapport = new textfield(array('name' => '_default_port', 'size' => 6, 'id' => "cfgimapport"));
echo $text_imapport->show($RCI->getprop('default_port'));
?>
<div>TCP port used for IMAP connections</div>
</dd>
<dt class="propname">username_domain</dt>
<dd>
<?php
$text_userdomain = new textfield(array('name' => '_username_domain', 'size' => 30, 'id' => "cfguserdomain"));
echo $text_userdomain->show($RCI->getprop('username_domain'));
?>
<div>Automatically add this domain to user names for login</div>
<p class="hint">Only for IMAP servers that require full e-mail addresses for login</p>
</dd>
<dt class="propname">auto_create_user</dt>
<dd>
<?php
$check_autocreate = new checkbox(array('name' => '_auto_create_user', 'id' => "cfgautocreate"));
echo $check_autocreate->show(intval($RCI->getprop('auto_create_user')), array('value' => 1));
?>
<label for="cfgautocreate">Automatically create a new RoundCube user when log-in the first time</label><br />
<p class="hint">A user is authenticated by the IMAP server but it requires a local record to store settings
and contacts. With this option enabled a new user record will automatically be created once the IMAP login succeeds.</p>
<p class="hint">If this option is disabled, the login only succeeds if there's a matching user-record in the local RoundCube database
what means that you have to create those records manually or disable this option after the first login.</p>
</dd>
<dt class="propname">sent_mbox</dt>
<dd>
<?php
$text_sentmbox = new textfield(array('name' => '_sent_mbox', 'size' => 20, 'id' => "cfgsentmbox"));
echo $text_sentmbox->show($RCI->getprop('sent_mbox'));
?>
<div>Store sent messages is this folder</div>
<p class="hint">Leave blank if sent messages should not be stored</p>
</dd>
<dt class="propname">trash_mbox</dt>
<dd>
<?php
$text_trashmbox = new textfield(array('name' => '_trash_mbox', 'size' => 20, 'id' => "cfgtrashmbox"));
echo $text_trashmbox->show($RCI->getprop('trash_mbox'));
?>
<div>Move messages to this folder when deleting them</div>
<p class="hint">Leave blank if they should be deleted directly</p>
</dd>
<dt class="propname">drafts_mbox</dt>
<dd>
<?php
$text_draftsmbox = new textfield(array('name' => '_drafts_mbox', 'size' => 20, 'id' => "cfgdraftsmbox"));
echo $text_draftsmbox->show($RCI->getprop('drafts_mbox'));
?>
<div>Store draft messages is this folder</div>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>SMTP Settings</legend>
<dl class="configblock" id="cgfblocksmtp">
<dt class="propname">smtp_server</dt>
<dd>
<?php
$text_smtphost = new textfield(array('name' => '_smtp_server', 'size' => 30, 'id' => "cfgsmtphost"));
echo $text_smtphost->show($RCI->getprop('smtp_server'));
?>
<div>Use this host for sending mails</div>
<p class="hint">To use SSL connection, set ssl://smtp.host.com. If left blank, the PHP mail() function is used</p>
</dd>
<dt class="propname">smtp_port</dt>
<dd>
<?php
$text_smtpport = new textfield(array('name' => '_smtp_port', 'size' => 6, 'id' => "cfgsmtpport"));
echo $text_smtpport->show($RCI->getprop('smtp_port'));
?>
<div>SMTP port (default is 25; 465 for SSL)</div>
</dd>
<dt class="propname">smtp_user/smtp_pass</dt>
<dd>
<?php
$text_smtpuser = new textfield(array('name' => '_smtp_user', 'size' => 20, 'id' => "cfgsmtpuser"));
$text_smtppass = new textfield(array('name' => '_smtp_pass', 'size' => 20, 'id' => "cfgsmtppass"));
echo $text_smtpuser->show($RCI->getprop('smtp_user'));
echo $text_smtppass->show($RCI->getprop('smtp_pass'));
?>
<div>SMTP username and password (if required)</div>
<p>
<?php
$check_smtpuser = new checkbox(array('name' => '_smtp_user_u', 'id' => "cfgsmtpuseru"));
echo $check_smtpuser->show($RCI->getprop('smtp_user') == '%u' || $_POST['_smtp_user_u'] ? 1 : 0, array('value' => 1));
?>
<label for="cfgsmtpuseru">Use the current IMAP username and password for SMTP authentication</label>
</p>
</dd>
<!--
<dt class="propname">smtp_auth_type</dt>
<dd>
<?php
/*
$select_smtpauth = new select(array('name' => '_smtp_auth_type', 'id' => "cfgsmtpauth"));
$select_smtpauth->add(array('(auto)', 'PLAIN', 'DIGEST-MD5', 'CRAM-MD5', 'LOGIN'), array('0', 'PLAIN', 'DIGEST-MD5', 'CRAM-MD5', 'LOGIN'));
echo $select_smtpauth->show(intval($RCI->getprop('smtp_auth_type')));
*/
?>
<div>Method to authenticate at the SMTP server. Choose (auto) if you don't know what this is</div>
</dd>
-->
<dt class="propname">smtp_log</dt>
<dd>
<?php
$check_smtplog = new checkbox(array('name' => '_smtp_log', 'id' => "cfgsmtplog"));
echo $check_smtplog->show(intval($RCI->getprop('smtp_log')), array('value' => 1));
?>
<label for="cfgsmtplog">Log sent messages in <tt>logs/sendmail</tt></label><br />
</dd>
</dl>
</fieldset>
<fieldset>
<legend>Display settings</legend>
<dl class="configblock" id="cgfblockdisplay">
<dt class="propname">locale_string</dt>
<dd>
<?php
$input_locale = new textfield(array('name' => '_locale_string', 'size' => 6, 'id' => "cfglocale"));
echo $input_locale->show($RCI->getprop('locale_string'));
?>
<div>The default locale setting. This also defines the language of the login screen.</div>
<p class="hint">Enter a <a href="http://www.faqs.org/rfcs/rfc1766">RFC1766</a> formatted locale name. Examples: en_US, de, de_CH, fr, pt_BR</p>
</dd>
</dl>
</fieldset>
<?php
echo '<p><input type="submit" name="submit" value="UPDATE" ' . ($RCI->failures ? 'disabled' : '') . ' /></p>';
?>
</form>
diff --git a/installer/index.php b/installer/index.php
index d62f6cb9d..aab406e98 100644
--- a/installer/index.php
+++ b/installer/index.php
@@ -1,70 +1,71 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>RoundCube Webmail Installer</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script type="text/javascript" src="client.js"></script>
</head>
<body>
<div id="banner">
<div id="header">
<div class="banner-logo"><a href="http://www.roundcube.net"><img src="images/banner_logo.gif" width="200" height="56" border="0" alt="RoundCube Webmal Project" /></a></div>
<div class="banner-right"><img src="images/banner_right.gif" width="10" height="56" alt="" /></div>
</div>
<div id="topnav">
<a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a>
</div>
</div>
<div id="content">
<h1>RoundCube Webmail Installer</h1>
<?php
ini_set('display_errors', 1);
$docroot = realpath(dirname(__FILE__) . '/../');
$include_path = $docroot . '/program/lib' . PATH_SEPARATOR . $docroot . '/program' . PATH_SEPARATOR . ini_get('include_path');
set_include_path($include_path);
require_once 'rcube_install.php';
$RCI = rcube_install::get_instance();
?>
<ol id="progress">
<?php
foreach (array('Check environment', 'Create config', 'Test config') as $i => $item) {
$j = $i + 1;
$link = $RCI->step > $j ? '<a href="./index.php?_step='.$j.'">' . Q($item) . '</a>' : Q($item);
printf('<li class="step%d%s">%s</li>', $j+1, $RCI->step > $j ? ' passed' : ($RCI->step == $j ? ' current' : ''), $link);
}
?>
</ol>
<?php
$include_steps = array('welcome.html', 'check.php', 'config.php', 'test.php');
if ($include_steps[$RCI->step]) {
include $include_steps[$RCI->step];
}
else {
header("HTTP/1.0 404 Not Found");
echo '<h2 class="error">Invalid step</h2>';
}
?>
</div>
<div id="footer">
- Installer by the RoundCube Dev Team. Copyright © 2008 - Published under the GNU Public License
+ Installer by the RoundCube Dev Team. Copyright © 2008 - Published under the GNU Public License;
+ Icons by <a href="http://famfamfam.com">famfamfam</a>
</div>
</body>
</html>
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
index f2ab394a1..8ff220357 100644
--- a/installer/rcube_install.php
+++ b/installer/rcube_install.php
@@ -1,341 +1,343 @@
<?php
/*
+-----------------------------------------------------------------------+
| rcube_install.php |
| |
| This file is part of the RoundCube Webmail package |
| Copyright (C) 2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU Public License |
+-----------------------------------------------------------------------+
$Id: $
*/
/**
* Class to control the installation process of the RoundCube Webmail package
*
* @category Install
* @package RoundCube
* @author Thomas Bruederli
*/
class rcube_install
{
var $step;
var $failures = 0;
var $config = array();
var $last_error = null;
+ var $email_pattern = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9])';
/**
* Constructor
*/
function rcube_install()
{
$this->step = intval($_REQUEST['_step']);
}
/**
* Singleton getter
*/
function get_instance()
{
static $inst;
if (!$inst)
$inst = new rcube_install();
return $inst;
}
/**
* Read the default config files and store properties
*/
function load_defaults()
{
$this->_load_config('.php.dist');
}
/**
* Read the local config files and store properties
*/
function load_config()
{
$this->_load_config('.php');
}
/**
* Read the default config file and store properties
* @access private
*/
function _load_config($suffix)
{
include '../config/main.inc' . $suffix;
if (is_array($rcmail_config)) {
$this->config += $rcmail_config;
}
@include '../config/db.inc'. $suffix;
if (is_array($rcmail_config)) {
$this->config += $rcmail_config;
}
}
/**
* Getter for a certain config property
*
* @param string Property name
+ * @param string Default value
* @return string The property value
*/
- function getprop($name)
+ function getprop($name, $default = null)
{
$value = isset($_REQUEST["_$name"]) ? $_REQUEST["_$name"] : $this->config[$name];
if ($name == 'des_key' && !isset($_REQUEST["_$name"]))
$value = self::random_key(24);
- return $value;
+ return $value !== null ? $value : $default;
}
/**
* Take the default config file and replace the parameters
* with the submitted form data
*
* @param string Which config file (either 'main' or 'db')
* @return string The complete config file content
*/
function create_config($which)
{
$out = file_get_contents("../config/{$which}.inc.php.dist");
if (!$out)
return '[Warning: could not read the template file]';
foreach ($this->config as $prop => $default) {
$value = $_POST["_$prop"] ? $_POST["_$prop"] : $default;
// convert some form data
if ($prop == 'debug_level' && is_array($value)) {
$val = 0;
foreach ($value as $i => $dbgval)
$val += intval($dbgval);
$value = $val;
}
else if ($prop == 'db_dsnw' && !empty($_POST['_dbtype'])) {
$value = sprintf('%s://%s:%s@%s/%s', $_POST['_dbtype'], $_POST['_dbuser'], $_POST['_dbpass'], $_POST['_dbhost'], $_POST['_dbname']);
}
else if ($prop == 'smtp_auth_type' && $value == '0') {
$value = '';
}
else if ($prop == 'default_host' && is_array($value)) {
$value = self::_clean_array($value);
if (count($value) <= 1)
$value = $value[0];
}
else if ($prop == 'smtp_user' && !empty($_POST['_smtp_user_u'])) {
$value = '%u';
}
else if ($prop == 'smtp_pass' && !empty($_POST['_smtp_user_u'])) {
$value = '%p';
}
else if (is_bool($default)) {
$value = is_numeric($value) ? (bool)$value : $value;
}
// skip this property
if ($value == $default)
continue;
// replace the matching line in config file
$out = preg_replace(
'/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie',
"'\\1 = ' . var_export(\$value, true) . ';'",
$out);
}
return $out;
}
/**
* Getter for the last error message
*
* @return string Error message or null if none exists
*/
function get_error()
{
return $this->last_error['message'];
}
/**
* Display OK status
*
* @param string Test name
* @param string Confirm message
*/
function pass($name, $message = '')
{
echo Q($name) . ': <span class="success">OK</span>';
$this->_showhint($message);
}
/**
* Display an error status and increase failure count
*
* @param string Test name
* @param string Error message
* @param string URL for details
*/
function fail($name, $message = '', $url = '')
{
$this->failures++;
echo Q($name) . ': <span class="fail">NOT OK</span>';
$this->_showhint($message, $url);
}
/**
* Display warning status
*
* @param string Test name
* @param string Warning message
* @param string URL for details
*/
function na($name, $message = '', $url = '')
{
echo Q($name) . ': <span class="na">NOT AVAILABLE</span>';
$this->_showhint($message, $url);
}
function _showhint($message, $url = '')
{
$hint = Q($message);
if ($url)
$hint .= ($hint ? '; ' : '') . 'See <a href="' . Q($url) . '" target="_blank">' . Q($url) . '</a>';
if ($hint)
echo '<span class="indent">(' . $hint . ')</span>';
}
function _clean_array($arr)
{
$out = array();
foreach (array_unique($arr) as $i => $val)
if (!empty($val))
$out[] = $val;
return $out;
}
/**
* Initialize the database with the according schema
*
* @param object rcube_db Database connection
* @return boolen True on success, False on error
*/
function init_db($DB)
{
$db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql');
$engine = isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider;
// find out db version
if ($engine == 'mysql') {
$DB->query('SELECT VERSION() AS version');
$sql_arr = $DB->fetch_assoc();
$version = floatval($sql_arr['version']);
if ($version >= 4.1)
$engine = 'mysql5';
}
// read schema file from /SQL/*
$fname = "../SQL/$engine.initial.sql";
if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) {
$buff = '';
foreach ($lines as $i => $line) {
if (eregi('^--', $line))
continue;
$buff .= $line . "\n";
if (eregi(';$', trim($line))) {
$DB->query($buff);
$buff = '';
}
}
}
else {
$this->fail('DB Schema', "Cannot read the schema file: $fname");
return false;
}
if ($err = $this->get_error()) {
$this->fail('DB Schema', "Error creating database schema: $err");
return false;
}
return true;
}
/**
* Handler for RoundCube errors
*/
function raise_error($p)
{
$this->last_error = $p;
}
/**
* Generarte a ramdom string to be used as encryption key
*
* @param int Key length
* @return string The generated random string
* @static
*/
function random_key($length)
{
$alpha = 'ABCDEFGHIJKLMNOPQERSTUVXYZabcdefghijklmnopqrtsuvwxyz0123456789+*%&?!$-_=';
$out = '';
for ($i=0; $i < $length; $i++)
$out .= $alpha{rand(0, strlen($alpha)-1)};
return $out;
}
}
/**
* Shortcut function for htmlentities()
*
* @param string String to quote
* @return string The html-encoded string
*/
function Q($string)
{
return htmlentities($string);
}
/**
* Fake rinternal error handler to catch errors
*/
function raise_error($p)
{
$rci = rcube_install::get_instance();
$rci->raise_error($p);
}
diff --git a/installer/styles.css b/installer/styles.css
index 1290696f8..0260b6741 100644
--- a/installer/styles.css
+++ b/installer/styles.css
@@ -1,221 +1,221 @@
body {
margin: 1em 2em 2em 2em;
background-color: #fff;
}
body, td, th, div, p {
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-size: small;
color: #000;
}
#banner {
position: relative;
}
#header {
position: relative;
height: 56px;
background: url('images/banner_bg.gif') top left repeat-x #fff;
}
#header div.banner-logo {
position: absolute;
top: 0px;
left: 0px;
width: 200px;
height: 56px;
}
#header div.banner-right {
position: absolute;
right: 0px;
top: 0px;
width: 10px;
height: 56px;
}
#topnav {
position: absolute;
right: 20px;
bottom: 8px;
text-align: right;
color: #ebebeb;
font-size: smaller;
}
#topnav a {
color: #ebebeb;
font-size: 11px;
text-decoration: none;
}
#topnav a:hover {
text-decoration: underline;
}
#content {
margin: 8px 20px;
}
#footer {
margin: 2em 20px 1em 20px;
padding-top: 0.6em;
font-size: smaller;
text-align: center;
border-top: 1px dotted #999;
}
#progress {
margin-bottom: 2em;
border: 1px solid #aaa;
background-color: #f9f9f9;
}
#progress:after {
content: ".";
display: block;
height: 0;
font-size: 0;
clear: both;
visibility: hidden;
}
#progress li {
float: left;
color: #999;
padding: 1em 5em 1em 0.2em;
}
#progress li.current {
color: #000;
font-weight: bold;
}
#progress li.passed,
#progress li.passed a {
color: #333;
text-decoration: none;
}
#progress li.passed a:hover {
text-decoration: underline;
}
fieldset {
margin-bottom: 1.5em;
border: 1px solid #aaa;
background-color: #f9f9f9;
}
fieldset p.hint {
margin-top: 0.5em;
}
legend {
font-size: 1.1em;
font-weight: bold;
}
textarea.configfile {
background-color: #f9f9f9;
font-family: monospace;
font-size: 9pt;
width: 100%;
height: 30em;
}
dt.propname {
font-family: monospace;
font-size: 9pt;
margin-top: 1em;
margin-bottom: 0.6em;
}
dd div {
margin-top: 0.3em;
}
-label {
+dd label {
padding-left: 0.5em;
}
th {
text-align: left;
}
ul li {
margin: 0.3em 0 0.4em -1em;
}
ul li ul li {
margin-bottom: 0.2em;
}
h3 {
font-size: 1.1em;
margin-top: 1.5em;
margin-bottom: 0.6em;
}
h4 {
margin-bottom: 0.2em;
}
a.blocktoggle {
color: #666;
text-decoration: none;
}
a.addlink {
color: #999;
font-size: 0.9em;
padding: 1px 0 1px 20px;
background: url('images/add.png') top left no-repeat;
text-decoration: none;
}
a.removelink {
color: #999;
font-size: 0.9em;
padding: 1px 0 1px 24px;
background: url('images/delete.png') 4px 0 no-repeat;
text-decoration: none;
}
.hint {
color: #666;
font-size: 0.95em;
}
.success {
color: #006400;
font-weight: bold !important;
}
.fail {
color: #ff0000 !important;
font-weight: bold !important;
}
.na {
color: #f60;
font-weight: bold;
}
.indent {
padding-left: 0.8em;
}
.notice {
padding: 1em;
background-color: #f7fdcb;
border: 2px solid #c2d071;
}
.warning {
padding: 1em;
background-color: #ef9398;
border: 2px solid #dc5757;
}
diff --git a/installer/test.php b/installer/test.php
index b782a5c44..0f499eba3 100644
--- a/installer/test.php
+++ b/installer/test.php
@@ -1,139 +1,204 @@
<form action="index.php?_step=3" method="post">
<h3>Check config files</h3>
<?php
// load local config files
$RCI->load_config();
$read_main = is_readable('../config/main.inc.php');
$read_db = is_readable('../config/db.inc.php');
if ($read_main && !empty($RCI->config)) {
$RCI->pass('main.inc.php');
}
else if ($read_main) {
$RCI->fail('main.inc.php', 'Syntax error');
}
else if (!$read_main) {
$RCI->fail('main.inc.php', 'Unable to read file. Did you create the config files?');
}
echo '<br />';
if ($read_db && !empty($RCI->config['db_table_users'])) {
$RCI->pass('db.inc.php');
}
else if ($read_db) {
$RCI->fail('db.inc.php', 'Syntax error');
}
else if (!$read_db) {
$RCI->fail('db.inc.php', 'Unable to read file. Did you create the config files?');
}
?>
<h3>Check configured database settings</h3>
<?php
$db_working = false;
if (!empty($RCI->config)) {
if (!empty($RCI->config['db_backend']) && !empty($RCI->config['db_dsnw'])) {
echo 'Backend: ';
echo 'PEAR::' . strtoupper($RCI->config['db_backend']) . '<br />';
$_class = 'rcube_' . strtolower($RCI->config['db_backend']);
require_once 'include/' . $_class . '.inc';
$DB = new $_class($RCI->config['db_dsnw'], '', false);
$DB->db_connect('w');
if (!($db_error_msg = $DB->is_error())) {
$RCI->pass('DSN (write)');
echo '<br />';
$db_working = true;
}
else {
$RCI->fail('DSN (write)', $db_error_msg);
echo '<p class="hint">Make sure that the configured database extists and that the user as write privileges<br />';
echo 'DSN: ' . $RCI->config['db_dsnw'] . '</p>';
}
}
else {
$RCI->fail('DSN (write)', 'not set');
}
}
else {
$RCI->fail('Config', 'Could not read config files');
}
// initialize db with schema found in /SQL/*
if ($db_working && $_POST['initdb']) {
if (!($success = $RCI->init_db($DB))) {
$db_working = false;
echo '<p class="warning">Please try to inizialize the database manually as described in the INSTALL guide.
Make sure that the configured database extists and that the user as write privileges</p>';
}
}
// test database
if ($db_working) {
$db_read = $DB->query("SELECT count(*) FROM {$RCI->config['db_table_users']}");
if (!$db_read) {
$RCI->fail('DB Schema', "Database not initialized");
$db_working = false;
echo '<p><input type="submit" name="initdb" value="Initialize database" /></p>';
}
else {
$RCI->pass('DB Schema');
}
echo '<br />';
}
// more database tests
if ($db_working) {
// write test
$db_write = $DB->query("INSERT INTO {$RCI->config['db_table_cache']} (session_id, cache_key, data, user_id) VALUES (?, ?, ?, 0)", '1234567890abcdef', 'test', 'test');
$insert_id = $DB->insert_id($RCI->config['db_sequence_cache']);
if ($db_write && $insert_id) {
$RCI->pass('DB Write');
$DB->query("DELETE FROM {$RCI->config['db_table_cache']} WHERE cache_id=?", $insert_id);
}
else {
$RCI->fail('DB Write', $RCI->get_error());
}
echo '<br />';
// check timezone settings
$tz_db = 'SELECT ' . $DB->unixtimestamp($DB->now()) . ' AS tz_db';
$tz_db = $DB->query($tz_db);
$tz_db = $DB->fetch_assoc($tz_db);
$tz_db = (int) $tz_db['tz_db'];
$tz_local = (int) time();
$tz_diff = $tz_local - $tz_db;
// sometimes db and web servers are on separate hosts, so allow a 30 minutes delta
if (abs($tz_diff) > 1800) {
$RCI->fail('DB Time', "Database time differs {$td_ziff}s from PHP time");
}
else {
$RCI->pass('DB Time');
}
}
?>
-<p>[@todo Add tests for IMAP and SMTP settings]</p>
+<h3>Test SMTP settings</h3>
+
+<p>
+Server: <?php echo $RCI->getprop('smtp_server', 'PHP mail()'); ?><br />
+Port: <?php echo $RCI->getprop('smtp_port'); ?><br />
+User: <?php echo $RCI->getprop('smtp_user', '(none)'); ?><br />
+Password: <?php echo $RCI->getprop('smtp_pass', '(none)'); ?><br />
+</p>
+
+<?php
+
+if (isset($_POST['sendmail']) && !empty($_POST['_from']) && !empty($_POST['_to'])) {
+
+ require_once 'lib/rc_mail_mime.inc';
+ require_once 'include/rcube_smtp.inc';
+
+ echo '<p>Trying to send email...<br />';
+
+ if (preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_from'])) &&
+ preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_to']))) {
+
+ $recipients = trim($_POST['_to']);
+
+ $headers = array(
+ 'From' => trim($_POST['_from']),
+ 'To' => $recipients,
+ 'Subject' => 'Test message from RoundCube',
+ );
+
+ $body = 'This is a test to confirm that RoundCube can send email.';
+
+ $mail_object = new rc_mail_mime();
+ $send_headers = $mail_object->headers($headers);
+
+ $smtp_response = array();
+ $status = smtp_mail($headers['From'], $recipients,
+ ($foo = $mail_object->txtHeaders($send_headers)),
+ $body, $smtp_response);
+
+ if ($status) {
+ $RCI->pass('SMTP send');
+ }
+ else {
+ $RCI->fail('SMTP send', join('; ', $smtp_response));
+ }
+ }
+ else {
+ $RCI->fail('SMTP send', 'Invalid sender or recipient');
+ }
+}
+
+echo '</p>';
+
+?>
+
+<table>
+<tbody>
+ <tr><td><label for="sendmailfrom">Sender</label></td><td><input type="text" name="_from" value="" id="sendmailfrom" /></td></tr>
+ <tr><td><label for="sendmailto">Recipient</label></td><td><input type="text" name="_to" value="" id="sendmailto" /></td></tr>
+</tbody>
+</table>
+
+<p><input type="submit" name="sendmail" value="Send test mail" /></p>
+
+
+<p>[@todo Add tests for IMAP settings]</p>
</form>
<p class="warning">
After completing the installation and the final tests please <b>remove</b> the whole
installer folder from the document root of the webserver.<br />
<br />
These files may expose sensitive configuration data like server passwords and encryption keys
to the public. Make sure you cannot access this installer from your browser.
</p>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Dec 18, 10:36 AM (24 m, 39 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
418723
Default Alt Text
(34 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment