Allow to load config files for different environments (#1487311); keep (non-default) filename in URLs throughout the webmail app

pull/89/head
Thomas Bruederli 12 years ago
parent f6777712dc
commit deb2b8d080

@ -39,7 +39,7 @@
require_once 'program/include/iniset.php'; require_once 'program/include/iniset.php';
// init application, start session, init output class, etc. // init application, start session, init output class, etc.
$RCMAIL = rcmail::get_instance(); $RCMAIL = rcmail::get_instance($GLOBALS['env']);
// Make the whole PHP output non-cacheable (#1487797) // Make the whole PHP output non-cacheable (#1487797)
$RCMAIL->output->nocacheing_headers(); $RCMAIL->output->nocacheing_headers();

@ -51,6 +51,7 @@ class rcmail extends rcube
*/ */
public $action = ''; public $action = '';
public $comm_path = './'; public $comm_path = './';
public $filename = '';
private $address_books = array(); private $address_books = array();
private $action_map = array(); private $action_map = array();
@ -65,12 +66,13 @@ class rcmail extends rcube
/** /**
* This implements the 'singleton' design pattern * This implements the 'singleton' design pattern
* *
* @param string Environment name to run (e.g. live, dev, test)
* @return rcmail The one and only instance * @return rcmail The one and only instance
*/ */
static function get_instance() static function get_instance($env = '')
{ {
if (!self::$instance || !is_a(self::$instance, 'rcmail')) { if (!self::$instance || !is_a(self::$instance, 'rcmail')) {
self::$instance = new rcmail(); self::$instance = new rcmail($env);
self::$instance->startup(); // init AFTER object was linked with self::$instance self::$instance->startup(); // init AFTER object was linked with self::$instance
} }
@ -86,6 +88,10 @@ class rcmail extends rcube
{ {
$this->init(self::INIT_WITH_DB | self::INIT_WITH_PLUGINS); $this->init(self::INIT_WITH_DB | self::INIT_WITH_PLUGINS);
// set filename if not index.php
if (($basename = basename($_SERVER['SCRIPT_FILENAME'])) && $basename != 'index.php')
$this->filename = $basename;
// start session // start session
$this->session_init(); $this->session_init();
@ -724,7 +730,7 @@ class rcmail extends rcube
$p['_task'] = $task; $p['_task'] = $task;
unset($p['task']); unset($p['task']);
$url = './'; $url = './' . $this->filename;
$delm = '?'; $delm = '?';
foreach (array_reverse($p) as $key => $val) { foreach (array_reverse($p) as $key => $val) {
if ($val !== '' && $val !== null) { if ($val !== '' && $val !== null) {

@ -1004,7 +1004,9 @@ class rcmail_output_html extends rcmail_output
} }
return html::quote($value); return html::quote($value);
break;
case 'form':
return $this->form_tag($attrib);
} }
return ''; return '';
} }
@ -1432,7 +1434,7 @@ class rcmail_output_html extends rcmail_output
$attrib['noclose'] = true; $attrib['noclose'] = true;
return html::tag('form', return html::tag('form',
$attrib + array('action' => "./", 'method' => "get"), $attrib + array('action' => $this->app->comm_path, 'method' => "get"),
$hidden . $content, $hidden . $content,
array('id','class','style','name','method','action','enctype','onsubmit')); array('id','class','style','name','method','action','enctype','onsubmit'));
} }

@ -105,13 +105,14 @@ class rcube
* This implements the 'singleton' design pattern * This implements the 'singleton' design pattern
* *
* @param integer Options to initialize with this instance. See rcube::INIT_WITH_* constants * @param integer Options to initialize with this instance. See rcube::INIT_WITH_* constants
* @param string Environment name to run (e.g. live, dev, test)
* *
* @return rcube The one and only instance * @return rcube The one and only instance
*/ */
static function get_instance($mode = 0) static function get_instance($mode = 0, $env = '')
{ {
if (!self::$instance) { if (!self::$instance) {
self::$instance = new rcube(); self::$instance = new rcube($env);
self::$instance->init($mode); self::$instance->init($mode);
} }
@ -122,10 +123,10 @@ class rcube
/** /**
* Private constructor * Private constructor
*/ */
protected function __construct() protected function __construct($env = '')
{ {
// load configuration // load configuration
$this->config = new rcube_config; $this->config = new rcube_config($env);
$this->plugins = new rcube_dummy_plugin_api; $this->plugins = new rcube_dummy_plugin_api;
register_shutdown_function(array($this, 'shutdown')); register_shutdown_function(array($this, 'shutdown'));

@ -26,6 +26,8 @@ class rcube_config
{ {
const DEFAULT_SKIN = 'larry'; const DEFAULT_SKIN = 'larry';
private $env = '';
private $basedir = 'config/';
private $prop = array(); private $prop = array();
private $errors = array(); private $errors = array();
private $userprefs = array(); private $userprefs = array();
@ -50,9 +52,14 @@ class rcube_config
/** /**
* Object constructor * Object constructor
*
* @param string Environment suffix for config files to load
*/ */
public function __construct() public function __construct($env = '')
{ {
$this->env = $env;
$this->basedir = RCUBE_CONFIG_DIR;
$this->load(); $this->load();
// Defaults, that we do not require you to configure, // Defaults, that we do not require you to configure,
@ -70,15 +77,15 @@ class rcube_config
private function load() private function load()
{ {
// Load default settings // Load default settings
if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'defaults.inc.php')) { if (!$this->load_from_file('defaults.inc.php')) {
$this->errors[] = 'defaults.inc.php was not found.'; $this->errors[] = 'defaults.inc.php was not found.';
} }
// load main config file // load main config file
if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'config.inc.php')) { if (!$this->load_from_file('config.inc.php')) {
// Old configuration files // Old configuration files
if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'main.inc.php') || if (!$this->load_from_file('main.inc.php') ||
!$this->load_from_file(RCUBE_CONFIG_DIR . 'db.inc.php')) { !$this->load_from_file('db.inc.php')) {
$this->errors[] = 'config.inc.php was not found.'; $this->errors[] = 'config.inc.php was not found.';
} }
else if (rand(1,100) == 10) { // log warning on every 100th request (average) else if (rand(1,100) == 10) { // log warning on every 100th request (average)
@ -87,7 +94,8 @@ class rcube_config
} }
// load host-specific configuration // load host-specific configuration
$this->load_host_config(); if (!empty($_SERVER['HTTP_HOST']))
$this->load_host_config();
// set skin (with fallback to old 'skin_path' property) // set skin (with fallback to old 'skin_path' property)
if (empty($this->prop['skin'])) { if (empty($this->prop['skin'])) {
@ -164,7 +172,7 @@ class rcube_config
} }
if ($fname) { if ($fname) {
$this->load_from_file(RCUBE_CONFIG_DIR . $fname); $this->load_from_file($fname);
} }
} }
@ -173,12 +181,13 @@ class rcube_config
* Read configuration from a file * Read configuration from a file
* and merge with the already stored config values * and merge with the already stored config values
* *
* @param string $fpath Full path to the config file to be loaded * @param string $file Name of the config file to be loaded
* @return booelan True on success, false on failure * @return booelan True on success, false on failure
*/ */
public function load_from_file($fpath) public function load_from_file($file)
{ {
if (is_file($fpath) && is_readable($fpath)) { $fpath = $this->resolve_path($file);
if ($fpath && is_file($fpath) && is_readable($fpath)) {
// use output buffering, we don't need any output here // use output buffering, we don't need any output here
ob_start(); ob_start();
include($fpath); include($fpath);
@ -198,6 +207,26 @@ class rcube_config
return false; return false;
} }
/**
* Helper method to resolve the absolute path to the given config file.
* This also takes the 'env' property into account.
*/
public function resolve_path($file, $use_env = true)
{
if (strpos($file, '/') === false) {
$file = realpath($this->basedir . '/' . $file);
}
// check if <file>-env.ini exists
if ($file && $use_env && !empty($this->env)) {
$envfile = preg_replace('/\.(inc.php)$/', '-' . $this->env . '.\\1', $file);
if (is_file($envfile))
return $envfile;
}
return $file;
}
/** /**
* Getter for a specific config parameter * Getter for a specific config parameter

@ -44,7 +44,7 @@
<roundcube:button name="messageoptions" id="composemenulink" type="link" class="button messagemenu" title="messageoptions" onclick="rcmail_ui.show_popup('composemenu', true);return false" content=" " /> <roundcube:button name="messageoptions" id="composemenulink" type="link" class="button messagemenu" title="messageoptions" onclick="rcmail_ui.show_popup('composemenu', true);return false" content=" " />
</div> </div>
<form name="form" action="./" method="post"> <roundcube:form name="form" method="post">
<div id="mainscreen"> <div id="mainscreen">

@ -9,7 +9,7 @@
<div id="contact-title" class="boxtitle"><roundcube:label name="addcontact" /></div> <div id="contact-title" class="boxtitle"><roundcube:label name="addcontact" /></div>
<div id="contact-details" class="boxcontent"> <div id="contact-details" class="boxcontent">
<form name="editform" method="post" action="./"> <roundcube:form name="editform" method="post">
<roundcube:if condition="strlen(env:sourcename)" /> <roundcube:if condition="strlen(env:sourcename)" />
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:object name="sourceselector" class="hint" id="sourceselect" /></div> <div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:object name="sourceselector" class="hint" id="sourceselect" /></div>
<roundcube:endif /> <roundcube:endif />

@ -9,7 +9,7 @@
<div id="contact-title" class="boxtitle"><roundcube:label name="editcontact" /></div> <div id="contact-title" class="boxtitle"><roundcube:label name="editcontact" /></div>
<div id="contact-details" class="boxcontent"> <div id="contact-details" class="boxcontent">
<form name="editform" method="post" action="./"> <roundcube:form name="editform" method="post">
<roundcube:if condition="strlen(env:sourcename)" /> <roundcube:if condition="strlen(env:sourcename)" />
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div> <div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
<roundcube:endif /> <roundcube:endif />

@ -15,7 +15,7 @@
<div class="boxtitle"><roundcube:label name="welcome" /></div> <div class="boxtitle"><roundcube:label name="welcome" /></div>
<div class="boxcontent"> <div class="boxcontent">
<form name="form" action="./" method="post"> <roundcube:form name="form" method="post">
<roundcube:object name="loginform" form="form" /> <roundcube:object name="loginform" form="form" />
<p style="text-align:center;"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p> <p style="text-align:center;"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>

@ -65,7 +65,7 @@
<div id="composeview-right"> <div id="composeview-right">
<form name="form" action="./" method="post" id="compose-content" class="uibox"> <roundcube:form name="form" method="post" id="compose-content" class="uibox">
<!-- message headers --> <!-- message headers -->
<div id="composeheaders"> <div id="composeheaders">

@ -11,7 +11,7 @@
<roundcube:else /><roundcube:label name="editcontact" /> <roundcube:else /><roundcube:label name="editcontact" />
<roundcube:endif /></h1> <roundcube:endif /></h1>
<form name="editform" method="post" action="./" id="contact-details" class="boxcontent"> <roundcube:form name="editform" method="post" id="contact-details" class="boxcontent">
<roundcube:if condition="strlen(env:sourcename)" /> <roundcube:if condition="strlen(env:sourcename)" />
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" condition="env:action!='add'" /><roundcube:object name="sourceselector" id="sourceselect" condition="env:action=='add'" /></div> <div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" condition="env:action!='add'" /><roundcube:object name="sourceselector" id="sourceselect" condition="env:action=='add'" /></div>
<roundcube:endif /> <roundcube:endif />

@ -11,7 +11,7 @@
<div class="box-inner"> <div class="box-inner">
<roundcube:object name="logo" src="/images/roundcube_logo.png" id="logo" border="0" /> <roundcube:object name="logo" src="/images/roundcube_logo.png" id="logo" border="0" />
<form name="form" action="./" method="post"> <roundcube:form name="form" method="post">
<roundcube:object name="loginform" form="form" size="40" /> <roundcube:object name="loginform" form="form" size="40" />
<p class="formbuttons"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p> <p class="formbuttons"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>

@ -27,7 +27,7 @@ if (!defined('INSTALL_PATH')) define('INSTALL_PATH', realpath(dirname(__FILE__)
define('TESTS_DIR', dirname(__FILE__) . '/'); define('TESTS_DIR', dirname(__FILE__) . '/');
if (@is_dir(TESTS_DIR . 'config')) { if (@is_dir(TESTS_DIR . 'config')) {
define('RCMAIL_CONFIG_DIR', TESTS_DIR . 'config'); define('RCUBE_CONFIG_DIR', TESTS_DIR . 'config');
} }
require_once(INSTALL_PATH . 'program/include/iniset.php'); require_once(INSTALL_PATH . 'program/include/iniset.php');
@ -38,7 +38,7 @@ if (set_include_path($include_path) === false) {
die("Fatal error: ini_set/set_include_path does not work."); die("Fatal error: ini_set/set_include_path does not work.");
} }
$rcmail = rcube::get_instance(); $rcmail = rcube::get_instance('test');
define('TESTS_URL', $rcmail->config->get('tests_url')); define('TESTS_URL', $rcmail->config->get('tests_url'));
define('TESTS_BROWSER', $rcmail->config->get('tests_browser', 'firefox')); define('TESTS_BROWSER', $rcmail->config->get('tests_browser', 'firefox'));

@ -27,12 +27,12 @@ if (!defined('INSTALL_PATH')) define('INSTALL_PATH', realpath(dirname(__FILE__)
define('TESTS_DIR', dirname(__FILE__) . '/'); define('TESTS_DIR', dirname(__FILE__) . '/');
if (@is_dir(TESTS_DIR . 'config')) { if (@is_dir(TESTS_DIR . 'config')) {
define('RCMAIL_CONFIG_DIR', TESTS_DIR . 'config'); define('RCUBE_CONFIG_DIR', TESTS_DIR . 'config');
} }
require_once(INSTALL_PATH . 'program/include/iniset.php'); require_once(INSTALL_PATH . 'program/include/iniset.php');
rcmail::get_instance()->config->set('devel_mode', false); rcmail::get_instance('test')->config->set('devel_mode', false);
// Extend include path so some plugin test won't fail // Extend include path so some plugin test won't fail
$include_path = ini_get('include_path') . PATH_SEPARATOR . TESTS_DIR . '..'; $include_path = ini_get('include_path') . PATH_SEPARATOR . TESTS_DIR . '..';

Loading…
Cancel
Save