From 4d9a338eb21da4054b3275e5f9a1510cad149432 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 13 Oct 2013 18:11:18 +0000 Subject: [PATCH] After hunting an "undefined index transport" error in list-domain, I found out that the 'Config' class is too static - it shares its static data with the 'Lang' child class. This caused a conflict because we have $CONF[transport] and $PALANG[transport], and Config::read('transport') returned the $PALANG text. To fix this, all texts are now stored as $CONF[__LANG]. I also dropped the 'Lang' class. model/Config.php: - mark the 'Config' class as final to ensure we don't trap into the "too static" problem again. - bool(): display and log an error message if a $CONF option does not contain YES or NO (that would have uncovered this bug much earlier) - add lang() and lang_f() wrapper functions to get $PALANG texts - remove unused $__cache and $__objects model/Lang.php: - deleted common.php: - store $PALANG as $CONF[__LANG] lots of files: - replace Lang::read() and Lang::read_f() calls with Config::lang() and Config::lang_f() git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1536 a1433add-5e2c-0410-b055-b7f2511e0802 --- common.php | 7 +++-- edit.php | 8 ++--- functions.inc.php | 16 +++++----- model/AdminHandler.php | 2 +- model/AdminpasswordHandler.php | 2 +- model/AliasHandler.php | 10 +++---- model/AliasdomainHandler.php | 4 +-- model/Config.php | 54 +++++++++++++++++++++++----------- model/DomainHandler.php | 4 +-- model/Lang.php | 8 ----- model/MailboxHandler.php | 22 +++++++------- model/PFAHandler.php | 20 ++++++------- setup.php | 2 +- 13 files changed, 86 insertions(+), 73 deletions(-) delete mode 100644 model/Lang.php diff --git a/common.php b/common.php index e52afaa7..f38fca4a 100644 --- a/common.php +++ b/common.php @@ -64,8 +64,6 @@ if(isset($CONF['configured'])) { } } -Config::write($CONF); - require_once("$incpath/languages/language.php"); require_once("$incpath/functions.inc.php"); @@ -83,7 +81,10 @@ if($CONF['language_hook'] != '' && function_exists($CONF['language_hook'])) { $PALANG = $hook_func ($PALANG, $language); } -Lang::write($PALANG); +$CONF['__LANG'] = $PALANG; + +Config::write($CONF); + if (!defined('POSTFIXADMIN_CLI')) { if(!is_file("$incpath/smarty.inc.php")) { diff --git a/edit.php b/edit.php index b00cc1c5..efc63163 100644 --- a/edit.php +++ b/edit.php @@ -190,12 +190,12 @@ if (count($errormsg)) flash_error($errormsg); # display the remaining error mess if ($new) { $smarty->assign ('mode', 'create'); - $smarty->assign('formtitle', Lang::read($formconf['formtitle_create'])); - $smarty->assign('submitbutton', Lang::read($formconf['create_button'])); + $smarty->assign('formtitle', Config::lang($formconf['formtitle_create'])); + $smarty->assign('submitbutton', Config::lang($formconf['create_button'])); } else { $smarty->assign ('mode', 'edit'); - $smarty->assign('formtitle', Lang::read($formconf['formtitle_edit'])); - $smarty->assign('submitbutton', Lang::read('save')); + $smarty->assign('formtitle', Config::lang($formconf['formtitle_edit'])); + $smarty->assign('submitbutton', Config::lang('save')); } $smarty->assign ('struct', $form_fields); diff --git a/functions.inc.php b/functions.inc.php index 6f3b21e7..2b849d4a 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -199,7 +199,7 @@ function language_selector() { */ function check_domain ($domain) { if (!preg_match ('/^([-0-9A-Z]+\.)+' . '([0-9A-Z]){2,6}$/i', ($domain))) { - return sprintf(Lang::read('pInvalidDomainRegex'), htmlentities($domain)); + return sprintf(Config::lang('pInvalidDomainRegex'), htmlentities($domain)); } if (Config::bool('emailcheck_resolve_domain') && 'WINDOWS'!=(strtoupper(substr(php_uname('s'), 0, 7)))) { @@ -213,7 +213,7 @@ function check_domain ($domain) { } if (checkdnsrr($domain,'A')) return ''; if (checkdnsrr($domain,'MX')) return ''; - return sprintf(Lang::Read('pInvalidDomainDNS'), htmlentities($domain)); + return sprintf(Config::lang('pInvalidDomainDNS'), htmlentities($domain)); } else { return 'emailcheck_resolve_domain is enabled, but function (checkdnsrr) missing!'; } @@ -243,13 +243,13 @@ function check_email ($email) { // Perform non-domain-part sanity checks if (!preg_match ('/^[-!#$%&\'*+\\.\/0-9=?A-Z^_{|}~]+' . '@' . '[^@]+$/i', $ce_email)) { - return Lang::read_f('pInvalidMailRegex', $email); + return Config::lang_f('pInvalidMailRegex', $email); } // Determine domain name $matches=array(); if (!preg_match('|@(.+)$|',$ce_email,$matches)) { - return Lang::read_f('pInvalidMailRegex', $email); + return Config::lang_f('pInvalidMailRegex', $email); } $domain=$matches[1]; @@ -375,8 +375,8 @@ function safecookie ($param, $default="") { * @return array for $struct */ function pacol($allow_editing, $display_in_form, $display_in_list, $type, $PALANG_label, $PALANG_desc, $default = "", $options = array(), $not_in_db=0, $dont_write_to_db=0, $select="", $extrafrom="") { - if ($PALANG_label != '') $PALANG_label = Lang::Read($PALANG_label); - if ($PALANG_desc != '') $PALANG_desc = Lang::Read($PALANG_desc ); + if ($PALANG_label != '') $PALANG_label = Config::lang($PALANG_label); + if ($PALANG_desc != '') $PALANG_desc = Config::lang($PALANG_desc ); return array( 'editable' => $allow_editing, @@ -807,9 +807,9 @@ function validate_password($password) { if (!preg_match($regex, $password)) { $msgparts = preg_split("/ /", $message, 2); if (count($msgparts) == 1) { - $result[] = Lang::read($msgparts[0]); + $result[] = Config::lang($msgparts[0]); } else { - $result[] = sprintf(Lang::read($msgparts[0]), $msgparts[1]); + $result[] = sprintf(Config::lang($msgparts[0]), $msgparts[1]); } } } diff --git a/model/AdminHandler.php b/model/AdminHandler.php index 4f0b51ad..cb690a87 100644 --- a/model/AdminHandler.php +++ b/model/AdminHandler.php @@ -13,7 +13,7 @@ class AdminHandler extends PFAHandler { return true; } else { $this->errormsg[] = $email_check; - $this->errormsg[$this->id_field] = Lang::read('pAdminCreate_admin_username_text_error1'); + $this->errormsg[$this->id_field] = Config::lang('pAdminCreate_admin_username_text_error1'); return false; } } diff --git a/model/AdminpasswordHandler.php b/model/AdminpasswordHandler.php index 32a01215..9eac9b5e 100644 --- a/model/AdminpasswordHandler.php +++ b/model/AdminpasswordHandler.php @@ -82,7 +82,7 @@ class AdminpasswordHandler extends PFAHandler { return true; } - $this->errormsg[$field] = Lang::read('pPassword_password_current_text_error'); + $this->errormsg[$field] = Config::lang('pPassword_password_current_text_error'); return false; } diff --git a/model/AliasHandler.php b/model/AliasHandler.php index d2be4c4e..07db3df2 100644 --- a/model/AliasHandler.php +++ b/model/AliasHandler.php @@ -138,20 +138,20 @@ class AliasHandler extends PFAHandler { protected function validate_new_id() { if ($this->id == '') { - $this->errormsg[$this->id_field] = Lang::read('pCreate_alias_address_text_error1'); + $this->errormsg[$this->id_field] = Config::lang('pCreate_alias_address_text_error1'); return false; } list($local_part,$domain) = explode ('@', $this->id); if(!$this->create_allowed($domain)) { - $this->errormsg[$this->id_field] = Lang::read('pCreate_alias_address_text_error3'); + $this->errormsg[$this->id_field] = Config::lang('pCreate_alias_address_text_error3'); return false; } # TODO: already checked in set() - does it make sense to check it here also? Only advantage: it's an early check # if (!in_array($domain, $this->allowed_domains)) { -# $this->errormsg[] = Lang::read('pCreate_alias_address_text_error1'); +# $this->errormsg[] = Config::lang('pCreate_alias_address_text_error1'); # return false; # } @@ -235,7 +235,7 @@ class AliasHandler extends PFAHandler { $values['goto'][] = $this->id; # if the alias points to the mailbox, don't display the "empty goto" error message - if (isset($this->errormsg['goto']) && $this->errormsg['goto'] == Lang::read('pEdit_alias_goto_text_error1') ) { + if (isset($this->errormsg['goto']) && $this->errormsg['goto'] == Config::lang('pEdit_alias_goto_text_error1') ) { unset($this->errormsg['goto']); } } @@ -291,7 +291,7 @@ class AliasHandler extends PFAHandler { protected function _field_goto($field, $val) { if (count($val) == 0) { # empty is ok for mailboxes - this is checked in setmore() which can clear the error message - $this->errormsg[$field] = Lang::read('pEdit_alias_goto_text_error1'); + $this->errormsg[$field] = Config::lang('pEdit_alias_goto_text_error1'); return false; } diff --git a/model/AliasdomainHandler.php b/model/AliasdomainHandler.php index 02c12ff5..137d2e22 100644 --- a/model/AliasdomainHandler.php +++ b/model/AliasdomainHandler.php @@ -54,7 +54,7 @@ class AliasdomainHandler extends PFAHandler { $success = parent::init($id); if ($success) { if (count($this->struct['alias_domain']['options']) == 0 && $this->new) { - $this->errormsg[] = Lang::read('pCreate_alias_domain_error4'); + $this->errormsg[] = Config::lang('pCreate_alias_domain_error4'); return false; } # TODO: check if target domains are available (in new and edit mode) @@ -125,7 +125,7 @@ class AliasdomainHandler extends PFAHandler { */ protected function _field_target_domain($field, $val) { if ($val == $this->id) { - $this->errormsg[$field] = Lang::read('pCreate_alias_domain_error2'); # TODO: error message could be better... + $this->errormsg[$field] = Config::lang('pCreate_alias_domain_error2'); # TODO: error message could be better... return false; } return true; diff --git a/model/Config.php b/model/Config.php index 5fbb2af5..0993477b 100644 --- a/model/Config.php +++ b/model/Config.php @@ -1,23 +1,12 @@ value array of objects type - * - * @var array - * @access private - */ - private $__objects = array(); +# This class is too static - if you inherit a class from it, it will share the static $instance and all its contents +# Therefore the class is marked as final to prevent someone accidently does this ;-) +final class Config { private static $instance = null; + /** * Return a singleton instance of Configure. * @@ -152,8 +141,13 @@ class Config { if (strtoupper($value) == 'YES') { # YES return true; - } else { # NO, unknown value - # TODO: show/log error message on unknown value? + } elseif (strtoupper($value) == 'NO') { # NO + return false; + } else { # unknown value + # show and log error message on unknown value + $msg = "\$CONF['$var'] has an invalid value, should be 'YES' or 'NO'"; + flash_error($msg); + error_log("$msg (value: $value)"); return false; } } @@ -168,6 +162,32 @@ class Config { +/** + * Get translated text from $PALANG + * (wrapper for self::read(), see also the comments there) + * + * @param string $var Variable to obtain + * @return string value of $PALANG[$var] + * @access public + */ + public static function lang($var) { + return self::read(array('__LANG', $var)); + } + + /** + * Get translated text from $PALANG and apply sprintf on it + * (wrapper for self::read_f(), see also the comments there) + * + * @param string $var Text (from $PALANG) to obtain + * @param string $value Value to use as sprintf parameter + * @return string value of $PALANG[$var], parsed by sprintf + * @access public + */ + public static function lang_f($var, $value) { + return self::read_f(array('__LANG', $var), $value); + } + + function getAll() { $output = $this->config; return $output; diff --git a/model/DomainHandler.php b/model/DomainHandler.php index 155ccc90..b670326c 100644 --- a/model/DomainHandler.php +++ b/model/DomainHandler.php @@ -116,14 +116,14 @@ class DomainHandler extends PFAHandler { } } if ($this->new) { - $tMessage = Lang::read('pAdminCreate_domain_result_success') . " (" . $this->id . ")"; # TODO: tMessage is not used/returned anywhere + $tMessage = Config::lang('pAdminCreate_domain_result_success') . " (" . $this->id . ")"; # TODO: tMessage is not used/returned anywhere } else { # TODO: success message for edit } if ($this->new) { if (!domain_postcreation($this->id)) { - $this->errormsg[] = Lang::read('pAdminCreate_domain_error'); + $this->errormsg[] = Config::lang('pAdminCreate_domain_error'); } } else { # we don't have domain_postedit() diff --git a/model/Lang.php b/model/Lang.php deleted file mode 100644 index a4e5cd46..00000000 --- a/model/Lang.php +++ /dev/null @@ -1,8 +0,0 @@ -struct['quota']['desc'] = Lang::read_f('mb_max', $maxquota); + $this->struct['quota']['desc'] = Config::lang_f('mb_max', $maxquota); } } @@ -120,7 +120,7 @@ class MailboxHandler extends PFAHandler { protected function validate_new_id() { if ($this->id == '') { - $this->errormsg[$this->id_field] = Lang::read('pCreate_mailbox_username_text_error1'); + $this->errormsg[$this->id_field] = Config::lang('pCreate_mailbox_username_text_error1'); return false; } @@ -133,14 +133,14 @@ class MailboxHandler extends PFAHandler { list(/*NULL*/,$domain) = explode ('@', $this->id); if(!$this->create_allowed($domain)) { - $this->errormsg[] = Lang::read('pCreate_mailbox_username_text_error3'); + $this->errormsg[] = Config::lang('pCreate_mailbox_username_text_error3'); return false; } # check if an alias with this name already exists - if yes, don't allow to create the mailbox $handler = new AliasHandler(1); if (!$handler->init($this->id)) { - $this->errormsg[] = Lang::read('email_address_already_exists'); + $this->errormsg[] = Config::lang('email_address_already_exists'); return false; } @@ -236,10 +236,10 @@ class MailboxHandler extends PFAHandler { if ( !$this->create_mailbox_subfolders() ) { # TODO: implement $tShowpass - $this->infomsg[] = Lang::read_f('pCreate_mailbox_result_succes_nosubfolders', "$fUsername$tShowpass"); + $this->infomsg[] = Config::lang_f('pCreate_mailbox_result_succes_nosubfolders', "$fUsername$tShowpass"); } else { # everything ok # TODO: implement $tShowpass - # $this->infomsg[] = Lang::read_f('pCreate_mailbox_result_success'], "$fUsername$tShowpass"); + # $this->infomsg[] = Config::lang_f('pCreate_mailbox_result_success'], "$fUsername$tShowpass"); # TODO: currently edit.php displays the default success message from webformConfig } @@ -293,7 +293,7 @@ class MailboxHandler extends PFAHandler { */ protected function _field_quota($field, $val) { if ( !$this->check_quota ($val) ) { - $this->errormsg[$field] = Lang::Read('pEdit_mailbox_quota_text_error'); + $this->errormsg[$field] = Config::lang('pEdit_mailbox_quota_text_error'); return false; } return true; @@ -376,11 +376,11 @@ class MailboxHandler extends PFAHandler { $fTo = $this->id; $fFrom = smtp_get_admin_email(); if(empty($fFrom) || $fFrom == 'CLI') $fFrom = $this->id; - $fSubject = Lang::read('pSendmail_subject_text'); + $fSubject = Config::lang('pSendmail_subject_text'); $fBody = Config::read('welcome_text'); if (!smtp_mail ($fTo, $fFrom, $fSubject, $fBody)) { - $this->errormsg[] = Lang::read('pSendmail_result_error'); + $this->errormsg[] = Config::lang('pSendmail_result_error'); return false; } else { # TODO flash_info($PALANG['pSendmail_result_success']); @@ -641,7 +641,7 @@ class MailboxHandler extends PFAHandler { if ($result != 1) { db_log ($domain, 'edit_password', "FAILURE: " . $this->id); - $this->errormsg[] = Lang::read('pEdit_mailbox_result_error'); + $this->errormsg[] = Config::lang('pEdit_mailbox_result_error'); return false; } @@ -706,7 +706,7 @@ class MailboxHandler extends PFAHandler { $postdel_res=mailbox_postdeletion($username,$domain); if ($result != 1 || !$postdel_res) { - $tMessage = Lang::read('pDelete_delete_error') . "$username ("; + $tMessage = Config::lang('pDelete_delete_error') . "$username ("; if ($result['rows']!=1) { # TODO: invalid test, $result is from db_delete and only contains the number of deleted rows $tMessage.='mailbox'; if (!$postdel_res) $tMessage.=', '; diff --git a/model/PFAHandler.php b/model/PFAHandler.php index b968e033..2efe1db4 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -142,7 +142,7 @@ abstract class PFAHandler { /** * init $this->msg[] with messages used in various functions. * - * always list the key to hand over to Lang::read + * always list the key to hand over to Config::lang * the only exception is 'logname' which uses the key for db_log * * The values can depend on $this->new @@ -181,7 +181,7 @@ abstract class PFAHandler { if ($this->new) { if ($exists) { - $this->errormsg[$this->id_field] = Lang::read($this->msg['error_already_exists']); + $this->errormsg[$this->id_field] = Config::lang($this->msg['error_already_exists']); return false; } elseif (!$this->validate_new_id() ) { # errormsg filled by validate_new_id() @@ -191,7 +191,7 @@ abstract class PFAHandler { } } else { # edit mode if (!$exists) { - $this->errormsg[$this->id_field] = Lang::read($this->msg['error_does_not_exist']); + $this->errormsg[$this->id_field] = Config::lang($this->msg['error_does_not_exist']); return false; } else { return true; @@ -292,7 +292,7 @@ abstract class PFAHandler { } } } elseif ($this->new) { # new, field not set in input data - $this->errormsg[$key] = Lang::read_f('missing_field', $key); + $this->errormsg[$key] = Config::lang_f('missing_field', $key); } else { # edit, field unchanged # echo "skipped / not set: $key\n"; } @@ -356,7 +356,7 @@ abstract class PFAHandler { $result = db_update($this->db_table, $this->id_field, $this->id, $db_values); } if ($result != 1) { - $this->errormsg[] = Lang::read($this->msg['store_error']) . "\n(" . $this->id . ")\n"; # TODO: change message + use sprintf + $this->errormsg[] = Config::lang($this->msg['store_error']) . "\n(" . $this->id . ")\n"; # TODO: change message + use sprintf return false; } @@ -369,7 +369,7 @@ abstract class PFAHandler { # return success message # TODO: use sprintf to add $this->id # TODO: add option to override the success message (for example to include autogenerated passwords) - $this->infomsg['success'] = sprintf(Lang::read($this->msg['successmessage']), $this->id); + $this->infomsg['success'] = sprintf(Config::lang($this->msg['successmessage']), $this->id); } return $result; @@ -409,8 +409,8 @@ abstract class PFAHandler { protected function read_from_db($condition, $limit=-1, $offset=-1) { $select_cols = array(); - $yes = escape_string(Lang::read('YES')); - $no = escape_string(Lang::read('NO')); + $yes = escape_string(Config::lang('YES')); + $no = escape_string(Config::lang('NO')); # TODO: replace hardcoded %Y-%m-%d with a country-specific date format via *.lang? # TODO: (not too easy because pgsql uses a different formatstring format :-/ ) @@ -503,7 +503,7 @@ abstract class PFAHandler { return true; } - if ($errors) $this->errormsg[] = Lang::read($this->msg['error_does_not_exist']); + if ($errors) $this->errormsg[] = Config::lang($this->msg['error_does_not_exist']); # $this->errormsg[] = $result['error']; return false; } @@ -587,7 +587,7 @@ abstract class PFAHandler { return true; } - $this->errormsg[$field2] = Lang::read('pEdit_mailbox_password_text_error'); + $this->errormsg[$field2] = Config::lang('pEdit_mailbox_password_text_error'); return false; } diff --git a/setup.php b/setup.php index c552102c..17e7c92a 100644 --- a/setup.php +++ b/setup.php @@ -515,7 +515,7 @@ function create_admin($values) { return array( 0, - Lang::read($formconf['successmessage']), + Config::lang($formconf['successmessage']), array(), ); }