From e8b01985125eeac7702b2d1941347c7e4f8b763e Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Tue, 28 Oct 2014 20:05:46 +0000 Subject: [PATCH 01/27] 2.92 (aka 3.0 beta2) release git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1706 a1433add-5e2c-0410-b055-b7f2511e0802 --- CHANGELOG.TXT | 4 ++-- debian/changelog | 6 ++++++ functions.inc.php | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 7b4f91e5..5e89af14 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -9,8 +9,8 @@ # Last update: # $Id$ -SVN changes since 3.0 beta1 (2.91) ----------------------------------- +Version 3.0 beta2 (2.92) - 2014/10/28 - SVN r1706 +------------------------------------------------- - AliasHandler: don't clean goto field when making alias inactive (bug#316) - list-virtual: display quota even if $CONF[used_quotas] == NO (bug#307) diff --git a/debian/changelog b/debian/changelog index 11537845..e79e4aa9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +postfixadmin (2.92-1) unstable; urgency=low + + * New upstream release (effectively beta2 for v3.0) + + -- David Goodwin Wed, 28 Oct 2014 21:02:00 +0100 + postfixadmin (2.91-1) unstable; urgency=low * New upstream release (effectively beta for v3.0) diff --git a/functions.inc.php b/functions.inc.php index f9a1144e..881e99b5 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -15,7 +15,7 @@ * Contains re-usable code. */ -$version = '2.91'; +$version = '2.92'; /** * check_session From 22839d3695f8254c5c84a0a559aaf096bf07a8e4 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 18:05:39 +0000 Subject: [PATCH 02/27] Cli*.php: - add SVN $Id header git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1709 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/CliDelete.php | 1 + model/CliEdit.php | 1 + model/CliHelp.php | 1 + model/CliView.php | 1 + 4 files changed, 4 insertions(+) diff --git a/model/CliDelete.php b/model/CliDelete.php index 8cdb29a7..ce20d2ff 100644 --- a/model/CliDelete.php +++ b/model/CliDelete.php @@ -1,4 +1,5 @@ Date: Sat, 1 Nov 2014 18:08:11 +0000 Subject: [PATCH 03/27] Add CliScheme.php: - displays the database scheme (for usage in upgrade.php) PFAHandler: - add "Scheme" to the list of available tasks postfixadmin-cli.php: - add "scheme" to help This is the first patch of a series sponsored by Bund der Deutschen Landjugend (german rural youth) http://bdl.landjugend.info/ git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1710 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/CliScheme.php | 104 +++++++++++++++++++++++++++++++++++ model/PFAHandler.php | 2 +- scripts/postfixadmin-cli.php | 1 + 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 model/CliScheme.php diff --git a/model/CliScheme.php b/model/CliScheme.php new file mode 100644 index 00000000..1cc13321 --- /dev/null +++ b/model/CliScheme.php @@ -0,0 +1,104 @@ +handler_to_use); + $module = strtolower($module); + + $handler = new $this->handler_to_use($this->new); + $struct = $handler->getStruct(); + + foreach (array_keys($struct) as $field) { + if ($field == 'created') { + $struct[$field]['db_code'] = '{DATE}'; + } elseif ($field == 'modified') { + $struct[$field]['db_code'] = '{DATECURRENT}'; + } else { + switch ($struct[$field]['type']) { + case 'int': + $struct[$field]['db_code'] = '{BIGINT}'; + break; + case 'bool': + $struct[$field]['db_code'] = '{BOOLEAN}'; + break; + default: + $struct[$field]['db_code'] = 'VARCHAR(255) {LATIN1} NOT NULL'; + } + } + } + + $this->out("For creating a new table with upgrade.php:"); + $this->out(""); + + $this->out('db_query_parsed("'); + $this->out(' CREATE TABLE {IF_NOT_EXISTS} " . table_by_key("' . $module . '") . " ('); + # TODO: $module is not really correct - $handler->db_table would be + + foreach (array_keys($struct) as $field) { + if ($struct[$field]['not_in_db'] == 0 && $struct[$field]['dont_write_to_db'] == 0) { + $this->out(" $field " . $struct[$field]['db_code'] . ","); + } + } + + $this->out(" INDEX domain(domain,username), // <--- change as needed"); + $this->out(" PRIMARY KEY (" . $handler->getId_field() . ")"); + $this->out(' ) {MYISAM} '); + $this->out('");'); + + $this->out(''); + $this->hr(); + $this->out('For adding fields with upgrade.php:'); + $this->out(''); + + $prev_field = ''; + foreach (array_keys($struct) as $field) { + if ($struct[$field]['not_in_db'] == 0 && $struct[$field]['dont_write_to_db'] == 0) { + $this->out(" _db_add_field('$module', '$field',\t'" . $struct[$field]['db_code'] . "',\t'$prev_field');"); + $prev_field = $field; + } + } + + $this->out(''); + $this->hr(); + $this->out('Note that the above is only a template.'); + $this->out('You might need to adjust some parts.'); + return; + } + + /** + * Displays help contents + */ + public function help() { + $module = preg_replace('/Handler$/', '', $this->handler_to_use); + $module = strtolower($module); + + $this->out( +"Usage: + + postfixadmin-cli $module scheme + + Print the $module database scheme in a way that can be + pasted into upgrade.php. + +"); + + $this->_stop(); + } + +} +/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */ diff --git a/model/PFAHandler.php b/model/PFAHandler.php index a95130f2..8c7551a8 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -12,7 +12,7 @@ abstract class PFAHandler { public $infomsg = array(); # array of tasks available in CLI - public $taskNames = array('Help', 'Add', 'Update', 'Delete', 'View'); + public $taskNames = array('Help', 'Add', 'Update', 'Delete', 'View', 'Scheme'); /** * variables that must be defined in all *Handler classes diff --git a/scripts/postfixadmin-cli.php b/scripts/postfixadmin-cli.php index f7d75a1c..bea17d42 100644 --- a/scripts/postfixadmin-cli.php +++ b/scripts/postfixadmin-cli.php @@ -472,6 +472,7 @@ class PostfixAdmin { $this->stdout(" add Add an item"); $this->stdout(" update Update an item"); $this->stdout(" delete Delete an item"); + $this->stdout(" scheme Print database scheme (useful for developers only)"); $this->stdout(" help Print help output"); $this->stdout(""); $this->stdout(""); From 647aa3921865f80597151ed9d0f979b172f6f5eb Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 18:54:27 +0000 Subject: [PATCH 04/27] PFAHandler: - add validation for "enma" field type - list of options, must be given in column "options" as associative array (value => displayed value) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1711 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 8c7551a8..52b03d94 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -135,6 +135,7 @@ abstract class PFAHandler { * bool boolean (converted to 0/1, additional column _$field with yes/no) * ts timestamp (created/modified) * enum list of options, must be given in column "options" as array + * enma list of options, must be given in column "options" as associative array * list like enum, but allow multiple selections * You can use custom types, but you'll have to add handling for them in *Handler and the smarty templates * @@ -663,6 +664,15 @@ abstract class PFAHandler { return false; } + /** + * check if value of an enum field is in the list of allowed values + */ + protected function _inp_enma($field, $val) { + if(array_key_exists($val, $this->struct[$field]['options'])) return true; + $this->errormsg[$field] = Config::Lang_f('invalid_value_given', $field); + return false; + } + /** * check if a password is secure enough */ From 9093a946b4a319027efed7ea5e5af51db5a13655 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 19:19:00 +0000 Subject: [PATCH 05/27] functions.inc.php: - add functions db_quota_text() and db_quota_percent() to generate queries for used quota ("x/y" and percentage) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1712 a1433add-5e2c-0410-b055-b7f2511e0802 --- functions.inc.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/functions.inc.php b/functions.inc.php index 881e99b5..e9219fe3 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -1302,6 +1302,34 @@ function db_get_boolean($bool) { } } +/** + * Returns a query that reports the used quota ("x / y") + * @param string column containing used quota + * @param string column containing allowed quota + * @param string column that will contain "x / y" + * @return string + */ +function db_quota_text($count, $quota, $fieldname) { + return " CASE $quota + WHEN '-1' THEN coalesce($count,0) + ELSE CONCAT(coalesce($count,0), ' / ', $quota) + END AS $fieldname"; +} + +/** + * Returns a query that reports the used quota ("x / y") + * @param string column containing used quota + * @param string column containing allowed quota + * @param string column that will contain "x / y" + * @return string + */ +function db_quota_percent($count, $quota, $fieldname) { + return " CASE $quota + WHEN '-1' THEN -1 + ELSE round(100 * coalesce($count,0) / $quota) + END AS $fieldname"; +} + /** * returns true if PostgreSQL is used, false otherwise */ From f07281cdc1de6fd9102358452672bd10f71e5f2c Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 19:25:11 +0000 Subject: [PATCH 06/27] PFAHandler: - automatically skip quot, vnum and vtxt fields in store() (as if dont_write_to_db == 1) - document new field types vtxt and quot and mark field types that will never be stored in db git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1713 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 52b03d94..31a0fd7a 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -128,16 +128,20 @@ abstract class PFAHandler { * * available values for the "type" column: * text one line of text + * *vtxt "virtual" line of text, coming from JOINs etc. * pass password (will be encrypted with pacrypt()) * num number * txtl text "list" - array of one line texts - * vnum "virtual" number, coming from JOINs etc. + * *vnum "virtual" number, coming from JOINs etc. * bool boolean (converted to 0/1, additional column _$field with yes/no) * ts timestamp (created/modified) * enum list of options, must be given in column "options" as array * enma list of options, must be given in column "options" as associative array * list like enum, but allow multiple selections + * *quot used / total quota ("5 / 10") - for field "quotausage", there must also be a "_quotausage_percent" (type vnum) * You can use custom types, but you'll have to add handling for them in *Handler and the smarty templates + * + * Field types marked with * will automatically be skipped in store(). * * All database tables should have a 'created' and a 'modified' column. * @@ -373,6 +377,11 @@ abstract class PFAHandler { case 'pass': $db_values[$key] = pacrypt($db_values[$key]); break; + case 'quot': + case 'vnum': + case 'vtxt': + unset ($db_values[$key]); # virtual field, never write it + break; } if ($this->struct[$key]['not_in_db'] == 1) unset ($db_values[$key]); # remove 'not in db' columns if ($this->struct[$key]['dont_write_to_db'] == 1) unset ($db_values[$key]); # remove 'dont_write_to_db' columns From 72d9d42601fa8398247bb76d819b0e37a71ca261 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 19:30:54 +0000 Subject: [PATCH 07/27] PFAHandler: - add protected $is_superadmin = 1; will be set to 0 if $admin_username is set and is not a superadmin git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1714 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 31a0fd7a..ea2531a4 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -46,6 +46,8 @@ abstract class PFAHandler { # set in __construct() protected $admin_username = ""; + # will be set to 0 if $admin_username is set and is not a superadmin + protected $is_superadmin = 1; # the ID of the current item (where item can be an admin, domain, mailbox, alias etc.) # filled in init() @@ -93,6 +95,10 @@ abstract class PFAHandler { if ($new) $this->new = 1; $this->admin_username = $admin_username; + if ($admin_username != "" && (! authentication_has_role('global-admin') ) ) { + $this->is_superadmin = 0; + } + if ($this->domain_field == "") { $this->no_domain_field(); } else { From 3fe75c117d4c8ff1c07db24f4cfef4628280ebbe Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 19:38:28 +0000 Subject: [PATCH 08/27] PFAHandler: - add handling of users (non-admins), including permission checks git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1715 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 47 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index ea2531a4..8d42ae65 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -29,6 +29,9 @@ abstract class PFAHandler { # if a table does not contain a domain column, leave empty and override no_domain_field()) protected $domain_field = ""; + # column containing the username (if logged in as non-admin) + protected $user_field = ''; + # skip empty password fields in edit mode # enabled by default to allow changing an admin, mailbox etc. without changing the password # disable for "edit password" forms @@ -49,6 +52,12 @@ abstract class PFAHandler { # will be set to 0 if $admin_username is set and is not a superadmin protected $is_superadmin = 1; + # if set, switch to user (non-admin) mode + protected $username = ''; + + # will be set to 0 if a user (non-admin) is logged in + protected $is_admin = 1; + # the ID of the current item (where item can be an admin, domain, mailbox, alias etc.) # filled in init() protected $id = null; @@ -90,25 +99,37 @@ abstract class PFAHandler { * Constructor: fill $struct etc. * @param integer - 0 is edit mode, set to 1 to switch to create mode * @param string - if an admin_username is specified, permissions will be restricted to the domains this admin may manage + * @param integer - 0 if logged in as user, 1 if logged in as admin or superadmin */ - public function __construct($new = 0, $admin_username = "") { + public function __construct($new = 0, $username = "", $is_admin = 1) { if ($new) $this->new = 1; - $this->admin_username = $admin_username; - if ($admin_username != "" && (! authentication_has_role('global-admin') ) ) { + if ($is_admin) { + $this->admin_username = $username; + } else { + $this->username = $username; + $this->is_admin = 0; + $this->is_superadmin = 0; + } + + if ($username != "" && (! authentication_has_role('global-admin') ) ) { $this->is_superadmin = 0; } if ($this->domain_field == "") { $this->no_domain_field(); } else { - if ($admin_username != "") { - $this->allowed_domains = list_domains_for_admin($admin_username); + if ($this->admin_username != "") { + $this->allowed_domains = list_domains_for_admin($username); } else { $this->allowed_domains = list_domains(); } } + if ($this->user_field == '') { + $this->no_user_field(); + } + $this->initStruct(); $struct_hook = Config::read($this->db_table . '_struct_hook'); @@ -128,6 +149,17 @@ abstract class PFAHandler { if ($this->admin_username != "") die('Attemp to restrict domains without setting $this->domain_field!'); } + /** + * ensure a lazy programmer can't give access to all items accidently + * + * to intentionally disable the check if $this->user_field is empty, override this function + */ + protected function no_user_field() { + if ($this->username != '') die('Attemp to restrict users without setting $this->user_field!'); + } + + + /** * init $this->struct (an array of pacol() results) * see pacol() in functions.inc.php for all available parameters @@ -499,6 +531,11 @@ abstract class PFAHandler { $where .= " AND " . db_in_clause($this->domain_field, $this->allowed_domains); } + # if logged in as user, restrict to the items the user is allowed to see + if ( (!$this->is_admin) && $this->user_field != '') { + $where .= " AND " . $this->user_field . " = '" . escape_string($this->username) . "' "; + } + $query = "SELECT $cols FROM $table $extrafrom $where ORDER BY " . $this->id_field; $limit = (int) $limit; # make sure $limit and $offset are really integers From e39d13aa52db91905bca1c98a6517a8b45f1e6e4 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 19:51:25 +0000 Subject: [PATCH 09/27] PFAHandler: Add $can_edit and $can_delete flags. This makes it possible to make some, but not all items non-editable or non-deletable (based on a database column/query or read_from_db_postprocess()) - add $can_edit and $can_delete - after initStruct, check if $struct contains _can_edit and _can_delete. If not, fill with default values (allowed) - init(): set $this->can_edit and $this->can_delete (only in view/edit mode) - set(): abort if !$this->can_edit git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1716 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 8d42ae65..4b920328 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -66,6 +66,15 @@ abstract class PFAHandler { # filled in domain_from_id() via init() protected $domain = null; + # can this item be edited? + # filled in init() (only in edit mode) + protected $can_edit = 1; + + # can this item be deleted? + # filled in init() (only in edit mode) + protected $can_delete = 1; + # TODO: needs to be implemented in delete() + # structure of the database table, list, edit form etc. # filled in initStruct() protected $struct = array(); @@ -132,6 +141,22 @@ abstract class PFAHandler { $this->initStruct(); + if (!isset($this->struct['_can_edit'])) { + $this->struct['_can_edit'] = pacol( 0, 0, 1, 'vnum', '' , '' , '', '', + /*not_in_db*/ 0, + /*dont_write_to_db*/ 1, + /*select*/ '1 as _can_edit' + ); + } + + if (!isset($this->struct['_can_delete'])) { + $this->struct['_can_delete'] = pacol( 0, 0, 1, 'vnum', '' , '' , '', '', + /*not_in_db*/ 0, + /*dont_write_to_db*/ 1, + /*select*/ '1 as _can_delete' + ); + } + $struct_hook = Config::read($this->db_table . '_struct_hook'); if ( $struct_hook != 'NO' && function_exists($struct_hook) ) { $this->struct = $struct_hook($this->struct); @@ -239,11 +264,13 @@ abstract class PFAHandler { # } else { # return true; } - } else { # edit mode + } else { # view or edit mode if (!$exists) { $this->errormsg[$this->id_field] = Config::lang($this->msg['error_does_not_exist']); return false; -# } else { + } else { + $this->can_edit = $this->result['_can_edit']; + $this->can_delete = $this->result['_can_delete']; # return true; } } @@ -298,6 +325,11 @@ abstract class PFAHandler { * error messages (if any) are stored in $this->errormsg */ public function set($values) { + if ( !$this->can_edit ) { + $this->errormsg[] = Config::Lang_f('edit_not_allowed', $this->id); + return false; + } + if ($this->new == 1) { $values[$this->id_field] = $this->id; } From 1edc38a7981cbecc09bdc15e485410437b638c03 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 20:10:25 +0000 Subject: [PATCH 10/27] edit.php: - add user (non-admin) mode git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1717 a1433add-5e2c-0410-b055-b7f2511e0802 --- edit.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/edit.php b/edit.php index 824abf33..d864de3b 100644 --- a/edit.php +++ b/edit.php @@ -39,11 +39,18 @@ $edit = safepost('edit', safeget('edit')); $new = 0; if ($edit == "") $new = 1; -$handler = new $handlerclass($new, $username); +$is_admin = authentication_has_role('admin'); +$handler = new $handlerclass($new, $username, $is_admin); $formconf = $handler->webformConfig(); -authentication_require_role($formconf['required_role']); +if ($is_admin) { + authentication_require_role($formconf['required_role']); +} else { + if (empty($formconf['user_hardcoded_field'])) { + die($handlerclass . ' is not available for users'); + } +} if ($new == 0 || $formconf['early_init']) { if (!$handler->init($edit)) { From a4085d287fafebbb7b391d0f67e63c021309746e Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 20:58:01 +0000 Subject: [PATCH 11/27] DomainHandler: - initStruct: - set column write permissions depending on superadmin status - add _can_edit and _can_delete (also depending on superadmin status) - webformConfig(): reduce required permissions to 'admin' - add beforestore() - aborts writing for non-superadmins - delete: allow deletion only for superadmins *.lang: - new text 'no_delete_permissions' git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1718 a1433add-5e2c-0410-b055-b7f2511e0802 --- languages/bg.lang | 1 + languages/ca.lang | 1 + languages/cn.lang | 1 + languages/cs.lang | 1 + languages/da.lang | 1 + languages/de.lang | 1 + languages/en.lang | 1 + languages/es.lang | 1 + languages/et.lang | 1 + languages/eu.lang | 1 + languages/fi.lang | 1 + languages/fo.lang | 1 + languages/fr.lang | 1 + languages/hr.lang | 1 + languages/hu.lang | 1 + languages/is.lang | 1 + languages/it.lang | 1 + languages/ja.lang | 1 + languages/lt.lang | 1 + languages/mk.lang | 1 + languages/nb.lang | 1 + languages/nl.lang | 1 + languages/nn.lang | 1 + languages/pl.lang | 1 + languages/pt-br.lang | 1 + languages/ru.lang | 1 + languages/sk.lang | 1 + languages/sl.lang | 1 + languages/sv.lang | 1 + languages/tr.lang | 1 + languages/tw.lang | 1 + model/DomainHandler.php | 47 +++++++++++++++++++++++++++++++++-------- 32 files changed, 69 insertions(+), 9 deletions(-) diff --git a/languages/bg.lang b/languages/bg.lang index 4887de69..22cf6496 100644 --- a/languages/bg.lang +++ b/languages/bg.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Отказ'; $PALANG['save'] = 'Запази'; # XXX Text change: "Save" -> "Save Changes" $PALANG['confirm'] = 'Сигурни ли сте, че желаете да изтрието това?\n'; $PALANG['confirm_domain'] = 'Наистина ли искате да изтриете всички записи за този домейн? Това действие е необратимо!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; $PALANG['invalid_parameter'] = 'Невалиден параметър!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/ca.lang b/languages/ca.lang index 3d0abd7b..20727ffe 100644 --- a/languages/ca.lang +++ b/languages/ca.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = '¿Segur que vols esborrar-lo?\n'; $PALANG['confirm_domain'] = 'Estas segur que vols borrar tots els registres d\'aquest domini? Això no podrà ser desfet!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/cn.lang b/languages/cn.lang index 7538b82d..33cafebd 100644 --- a/languages/cn.lang +++ b/languages/cn.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = '是否确定删除?\n'; $PALANG['confirm_domain'] = '你是否确定要删除该域中的所有记录? 删除后不可恢复!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = '检查新版本'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/cs.lang b/languages/cs.lang index d06daef4..1d7b8ef7 100644 --- a/languages/cs.lang +++ b/languages/cs.lang @@ -18,6 +18,7 @@ $PALANG['cancel'] = 'Zrušit'; $PALANG['save'] = 'Uložit'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Jste si jistí?\n'; $PALANG['confirm_domain'] = 'Opravdu chcete smazat všechny záznamy v této doméně Tohle nelze vrátit!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Zkontrolovat aktualizace'; $PALANG['invalid_parameter'] = 'Neplatný parametr!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/da.lang b/languages/da.lang index c90b76db..a88a3b4e 100644 --- a/languages/da.lang +++ b/languages/da.lang @@ -17,6 +17,7 @@ $PALANG['cancel'] = 'Annuller'; $PALANG['save'] = 'Gem'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Er du sikker på du vil slette dette?\n'; $PALANG['confirm_domain'] = 'Vil du virkelig slette alle adresser for dette domæne? Dette kan ikke fortrydes!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Søg efter opdateringer'; $PALANG['invalid_parameter'] = 'Ugyldig parameter.'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/de.lang b/languages/de.lang index 4b9e3119..de18922b 100644 --- a/languages/de.lang +++ b/languages/de.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Abbrechen'; $PALANG['save'] = 'Änderungen speichern'; $PALANG['confirm'] = 'Sind Sie sicher dass Sie das löschen wollen?\n'; $PALANG['confirm_domain'] = 'Wollen Sie wirklich alle Einträge dieser Domain löschen? Dies kann NICHT rückgängig gemacht werden!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Auf Updates überprüfen'; $PALANG['invalid_parameter'] = 'Ungültiger Parameter!'; $PALANG['show'] = 'Anzeigen:'; diff --git a/languages/en.lang b/languages/en.lang index 9e11ee1c..8047eef3 100644 --- a/languages/en.lang +++ b/languages/en.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Cancel'; $PALANG['save'] = 'Save changes'; $PALANG['confirm'] = 'Are you sure you want to delete this?\n'; $PALANG['confirm_domain'] = 'Do you really want to delete all records for this domain? This can not be undone!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; $PALANG['check_update'] = 'Check for update'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; $PALANG['show'] = 'Show:'; diff --git a/languages/es.lang b/languages/es.lang index 588636d6..4c7cfe69 100644 --- a/languages/es.lang +++ b/languages/es.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Cancelar'; $PALANG['save'] = 'Salvar'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = '¿Está seguro de que desea borrarlo?\n'; $PALANG['confirm_domain'] = '¿Está seguro de que desea borrar todos los registros de este dominio? ¡Esto no puede ser deshecho!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = '¡Parámetro inválido!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/et.lang b/languages/et.lang index 54b41336..c7db5485 100644 --- a/languages/et.lang +++ b/languages/et.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Oled kindel, et soovid seda kustutada?\n'; $PALANG['confirm_domain'] = 'Oled tõesti kindel, et tahad kustutada kõik kirjed sellele domeenile? Seda tegevust ei saa tagasi võtta!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/eu.lang b/languages/eu.lang index 438f12ea..ed378525 100644 --- a/languages/eu.lang +++ b/languages/eu.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Ziur al zaude ezabatu nahi duzula?\n'; $PALANG['confirm_domain'] = 'Ziur al zaude domeinu honetako erregistro guztiak ezbatu nahi dituzula? Hau ezin izango da desegin!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/fi.lang b/languages/fi.lang index ce0cde9f..f1dcc433 100644 --- a/languages/fi.lang +++ b/languages/fi.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Peruuta'; $PALANG['save'] = 'Tallenna'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Oletko varma että haluat poistaa tämän?\n'; $PALANG['confirm_domain'] = 'Oletko varma että haluat poistaa kaikki tietueet tästä domainista? Tätä komentoa ei voi perua!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Tarkista päivitykset'; $PALANG['invalid_parameter'] = 'Viallinen parametri!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/fo.lang b/languages/fo.lang index 50b69166..866728d8 100644 --- a/languages/fo.lang +++ b/languages/fo.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Ert tú vís(ur) í at tú vilt strika hetta?\n'; $PALANG['confirm_domain'] = 'Vilt tú veruliga strika allar upplýsingar fyri hetta navnaøki? Her kann ikki vendast aftur!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/fr.lang b/languages/fr.lang index 6097ca7e..56f7ddb7 100644 --- a/languages/fr.lang +++ b/languages/fr.lang @@ -16,6 +16,7 @@ $PALANG['cancel'] = 'Annuler'; $PALANG['save'] = 'Enregistrer les modifications'; $PALANG['confirm'] = 'Etes vous sur de vouloir supprimer cet enregistrement\n'; $PALANG['confirm_domain'] = 'Etes-vous sur de vouloir effacer tous les enregistrements dans ce domaine ? Cette opération ne pourra pas être annulée.\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Vérifier les mises à jour'; $PALANG['invalid_parameter'] = 'Paramètres invalides!'; $PALANG['show'] = 'Afficher:'; diff --git a/languages/hr.lang b/languages/hr.lang index 1a41c299..3d1bd4b4 100644 --- a/languages/hr.lang +++ b/languages/hr.lang @@ -13,6 +13,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Da li ste sigurni da želite ovo pobrisati?\n'; $PALANG['confirm_domain'] = 'Da li ste sigurni da želite pobrisati sve zapise za tu domenu? Zapisi ce biti zauvijek pobrisani!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Provjeri da li postoji novija inačica'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/hu.lang b/languages/hu.lang index 9bd0be61..7aabccbd 100644 --- a/languages/hu.lang +++ b/languages/hu.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Biztos vagy benne hogy törlöd ezt?\n'; $PALANG['confirm_domain'] = 'Biztos hogy törölni akarod az összes bejegyzést ez alól a domain alól? Nem lehet visszahozni késõbb!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/is.lang b/languages/is.lang index bc73a4a6..36041b41 100644 --- a/languages/is.lang +++ b/languages/is.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Ertu viss um að þú viljir eyða þessu?\n'; $PALANG['confirm_domain'] = 'Ertu viss um að þú viljir eyða öllu sem tengist þessu léni? Það er ekki hægt að bakka með aðgerðina!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/it.lang b/languages/it.lang index 1a2de9c9..bf7120b5 100644 --- a/languages/it.lang +++ b/languages/it.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Annulla'; $PALANG['save'] = 'registra'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Sei certo di volerlo cancellare?\n'; $PALANG['confirm_domain'] = 'Sei sicuro di voler cancellare tutti gli indirizzi di questo dominio? Questa modifica sarà permanente!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Verifica gli aggiornamenti'; $PALANG['invalid_parameter'] = 'Parametro non valido!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/ja.lang b/languages/ja.lang index 9f2fffb3..9efb7bc2 100644 --- a/languages/ja.lang +++ b/languages/ja.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'キャンセル'; $PALANG['save'] = '変更を保存'; $PALANG['confirm'] = '本当に削除してもよろしいですか?\n'; $PALANG['confirm_domain'] = '本当にこのドメインのすべての情報を削除してもよろしいですか?これを元に戻すことはできません。\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = '更新の確認'; $PALANG['invalid_parameter'] = '無効なパラメータです。'; $PALANG['show'] = '閲覧:'; diff --git a/languages/lt.lang b/languages/lt.lang index fb7def28..e9053609 100644 --- a/languages/lt.lang +++ b/languages/lt.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Atšaukti'; $PALANG['save'] = 'Išsaugoti'; $PALANG['confirm'] = 'Tikrai norite šalinti?\n'; $PALANG['confirm_domain'] = 'Tikrai norite šalinti visus šios srities įrašus? Operacija negrįžtama!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Patikrinti versiją'; $PALANG['invalid_parameter'] = 'Neteisingas parametras!'; $PALANG['show'] = 'Rodyti:'; diff --git a/languages/mk.lang b/languages/mk.lang index 8feec87d..152cf564 100644 --- a/languages/mk.lang +++ b/languages/mk.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Дали сте сигурни дека сакате да го избришете ова?\n'; $PALANG['confirm_domain'] = 'Дали сакате да ги избришете сите записи од овој домен? Ова не може да се поправи покасно!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/nb.lang b/languages/nb.lang index 73cfce1d..4dff1659 100644 --- a/languages/nb.lang +++ b/languages/nb.lang @@ -16,6 +16,7 @@ $PALANG['cancel'] = 'Avbryt'; $PALANG['save'] = 'Lagre'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Er du sikker på at du ønsker å slette dette?\n'; $PALANG['confirm_domain'] = 'Ønsker du virkelig å slette alle oppføringer for dette domenet? Dette kan ikke angres!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Se etter oppdatering'; $PALANG['invalid_parameter'] = 'Ugyldig parameter!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/nl.lang b/languages/nl.lang index aa180d65..918c86b9 100644 --- a/languages/nl.lang +++ b/languages/nl.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Annuleren'; $PALANG['save'] = 'Wijzigingen opslaan'; $PALANG['confirm'] = 'Weet u het zeker dat u wilt verwijderen?\n'; $PALANG['confirm_domain'] = 'Weet u zeker dat u ALLE data van het domein wilt verwijderen? Dit kan niet ongedaan worden gemaakt!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Zoeken naar nieuwe versie'; $PALANG['invalid_parameter'] = 'ongeldige parameter!'; $PALANG['show'] = 'Toon:'; diff --git a/languages/nn.lang b/languages/nn.lang index a4f33226..5a31bb18 100644 --- a/languages/nn.lang +++ b/languages/nn.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Vil du slette dette?\n'; $PALANG['confirm_domain'] = 'Vil du virkelig slette alle poster og domenet?\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Se etter oppdatering'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/pl.lang b/languages/pl.lang index 4d750907..2938f58d 100644 --- a/languages/pl.lang +++ b/languages/pl.lang @@ -17,6 +17,7 @@ $PALANG['cancel'] = 'Anuluj'; $PALANG['save'] = 'Zapisz'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Jesteś przekonany, że chcesz to usunąć?\n'; $PALANG['confirm_domain'] = 'Czy rzeczywiście chcesz usunąć wszystkie wpisy dla tej domeny? To jest proces nieodwracalny!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Sprawdź aktualizację'; $PALANG['invalid_parameter'] = 'Błędny parametr!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/pt-br.lang b/languages/pt-br.lang index b9bd9b8d..e832eb42 100644 --- a/languages/pt-br.lang +++ b/languages/pt-br.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Cancelar'; $PALANG['save'] = 'Gravar'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Tem certeza de que deseja remover?\n'; $PALANG['confirm_domain'] = 'Tem certeza de que deseja remover todos os registros deste domínio? Essa ação não pode ser desfeita!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Checar por atualização'; $PALANG['invalid_parameter'] = 'Parâmetro inválido!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/ru.lang b/languages/ru.lang index 155d7398..808b991c 100644 --- a/languages/ru.lang +++ b/languages/ru.lang @@ -16,6 +16,7 @@ $PALANG['cancel'] = 'Отменить'; $PALANG['save'] = 'Сохранить изменения'; $PALANG['confirm'] = 'Вы уверены, что хотите удалить это?\n'; $PALANG['confirm_domain'] = 'Вы действительно хотите удалить все настройки для домена? Это действие нельзя будет отменить!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Проверить обновление'; $PALANG['invalid_parameter'] = 'Некорректный параметр!'; $PALANG['show'] = 'Показать:'; diff --git a/languages/sk.lang b/languages/sk.lang index 64069c4b..62a0d1c4 100644 --- a/languages/sk.lang +++ b/languages/sk.lang @@ -15,6 +15,7 @@ $PALANG['cancel'] = 'Zrušiť'; $PALANG['save'] = 'Uložiť'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Ste si istí?\n'; $PALANG['confirm_domain'] = 'Naozaj chcete zmazať všetky záznamy v tejto doméne? Toto nie je možné vrátiť!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Skontrolovať aktualizácie'; $PALANG['invalid_parameter'] = 'Neplatný parameter!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/sl.lang b/languages/sl.lang index 022069ea..8dc15f8c 100644 --- a/languages/sl.lang +++ b/languages/sl.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save'; # XXX # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Ali ste prepričani, da želite brisati?\n'; $PALANG['confirm_domain'] = 'Ali ste prepričani, da želite brisati vse zapise za to domeno? Zapisi bodo izgubljeni za vedno!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Preveri, če obstaja novejša različica'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/sv.lang b/languages/sv.lang index fb1a0bf5..8a5586c0 100644 --- a/languages/sv.lang +++ b/languages/sv.lang @@ -16,6 +16,7 @@ $PALANG['cancel'] = 'Avbryt'; $PALANG['save'] = 'Spara'; # XXX Text change: "Save" -> "Save changes" $PALANG['confirm'] = 'Är du säker på att du vill radera denna?\n'; $PALANG['confirm_domain'] = 'Vill du verkligen radera all data för denna domän? Kan ej ångras!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Senaste versionen?'; $PALANG['invalid_parameter'] = 'Felaktig parameter!'; $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/tr.lang b/languages/tr.lang index d89735d1..2f116fae 100644 --- a/languages/tr.lang +++ b/languages/tr.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = 'Bunu silmek istediðinizden emin misiniz?\n'; $PALANG['confirm_domain'] = 'Bu domain için tüm kayýtlarý silmek istediðinizden emin misiniz? Bu iþlem geri alýnamaz!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = 'Check for update'; # XXX $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/languages/tw.lang b/languages/tw.lang index 911f51f3..511630b2 100644 --- a/languages/tw.lang +++ b/languages/tw.lang @@ -14,6 +14,7 @@ $PALANG['cancel'] = 'Cancel'; # XXX $PALANG['save'] = 'Save changes'; # XXX $PALANG['confirm'] = '是否確定刪除?\n'; $PALANG['confirm_domain'] = '你是否確定要刪除該網域中的所有記錄? 刪除後不可恢復!\n'; +$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX $PALANG['check_update'] = '檢查新版本'; $PALANG['invalid_parameter'] = 'Invalid parameter!'; # XXX $PALANG['show'] = 'Show:'; # XXX diff --git a/model/DomainHandler.php b/model/DomainHandler.php index f13dfeb6..da04c922 100644 --- a/model/DomainHandler.php +++ b/model/DomainHandler.php @@ -30,9 +30,11 @@ class DomainHandler extends PFAHandler { protected function initStruct() { # TODO: shorter PALANG labels ;-) - $transp = Config::intbool('transport'); - $quota = Config::intbool('quota'); - $dom_q = Config::intbool('domain_quota'); + $super = $this->is_superadmin; + + $transp = min($super, Config::intbool('transport')); + $quota = min($super, Config::intbool('quota')); + $dom_q = min($super, Config::intbool('domain_quota')); # NOTE: There are dependencies between alias_count, mailbox_count and total_quota. # NOTE: If you disable "display in list" for one of them, the SQL query for the others might break. @@ -42,15 +44,15 @@ class DomainHandler extends PFAHandler { # field name allow display in... type $PALANG label $PALANG description default / options / ... # editing? form list 'domain' => pacol( $this->new, 1, 1, 'text', 'domain' , '' ), - 'description' => pacol( 1, 1, 1, 'text', 'description' , '' ), - 'aliases' => pacol( 1, 1, 1, 'num' , 'aliases' , 'pAdminEdit_domain_aliases_text' , Config::read('aliases') ), + 'description' => pacol( $super, 1, 1, 'text', 'description' , '' ), + 'aliases' => pacol( $super, $super, 1, 'num' , 'aliases' , 'pAdminEdit_domain_aliases_text' , Config::read('aliases') ), 'alias_count' => pacol( 0, 0, 1, 'vnum', '' , '' , '', '', /*not_in_db*/ 0, /*dont_write_to_db*/ 1, /*select*/ 'coalesce(__alias_count,0) - coalesce(__mailbox_count,0) as alias_count', /*extrafrom*/ 'left join ( select count(*) as __alias_count, domain as __alias_domain from ' . table_by_key('alias') . ' group by domain) as __alias on domain = __alias_domain'), - 'mailboxes' => pacol( 1, 1, 1, 'num' , 'mailboxes' , 'pAdminEdit_domain_aliases_text' , Config::read('mailboxes') ), + 'mailboxes' => pacol( $super, $super, 1, 'num' , 'mailboxes' , 'pAdminEdit_domain_aliases_text' , Config::read('mailboxes') ), 'mailbox_count' => pacol( 0, 0, 1, 'vnum', '' , '' , '', '', /*not_in_db*/ 0, /*dont_write_to_db*/ 1, @@ -65,11 +67,21 @@ class DomainHandler extends PFAHandler { 'quota' => pacol( $dom_q, $dom_q, $dom_q, 'num' , 'pAdminEdit_domain_quota' , 'pAdminEdit_domain_maxquota_text' , Config::read('domain_quota_default') ), 'transport' => pacol( $transp, $transp,$transp,'enum', 'transport' , 'pAdminEdit_domain_transport_text' , Config::read('transport_default') , /*options*/ Config::read('transport_options') ), - 'backupmx' => pacol( 1, 1, 1, 'bool', 'pAdminEdit_domain_backupmx' , '' , 0), - 'active' => pacol( 1, 1, 1, 'bool', 'active' , '' , 1 ), + 'backupmx' => pacol( $super, $super, 1, 'bool', 'pAdminEdit_domain_backupmx' , '' , 0), + 'active' => pacol( $super, $super, 1, 'bool', 'active' , '' , 1 ), 'default_aliases' => pacol( $this->new, $this->new, 0, 'bool', 'pAdminCreate_domain_defaultaliases', '' , 1,'', /*not in db*/ 1 ), 'created' => pacol( 0, 0, 1, 'ts', 'created' , '' ), 'modified' => pacol( 0, 0, 1, 'ts', 'last_modified' , '' ), + '_can_edit' => pacol( 0, 0, 1, 'int', '' , '' , 0 , + /*options*/ '', + /*not_in_db*/ 0, + /*dont_write_to_db*/ 1, + /*select*/ $this->is_superadmin . ' as _can_edit' ), + '_can_delete' => pacol( 0, 0, 1, 'int', '' , '' , 0 , + /*options*/ '', + /*not_in_db*/ 0, + /*dont_write_to_db*/ 1, + /*select*/ $this->is_superadmin . ' as _can_delete' ), ); } @@ -95,12 +107,23 @@ class DomainHandler extends PFAHandler { 'create_button' => 'pAdminCreate_domain_button', # various settings - 'required_role' => 'global-admin', + 'required_role' => 'admin', 'listview' => 'list-domain.php', 'early_init' => 0, ); } + + protected function beforestore() { + # TODO: is this function superfluous? _can_edit should already cover this + if ($this->is_superadmin) { + return true; + } + + $this->errormsg[] = Config::Lang('edit_not_allowed', $this->id); + return false; + } + /** * called by $this->store() after storing $this->values in the database * can be used to update additional tables, call scripts etc. @@ -138,6 +161,12 @@ class DomainHandler extends PFAHandler { * @return true on success false on failure */ public function delete() { + # TODO: check for _can_delete instead + if (! $this->is_superadmin) { + $this->errormsg[] = Config::Lang_f('no_delete_permissions', $this->id); + return false; + } + if ( ! $this->view() ) { $this->errormsg[] = Config::Lang('domain_does_not_exist'); # TODO: can users hit this message at all? init() should already fail... return false; From 786a7d665e25fd71e57f1724a1ed3ebf140a0f7a Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 21:11:33 +0000 Subject: [PATCH 12/27] functions.inc.php: - pacol(): - add $linkto parameter (if list mode should link to something) - replace $not_in_db with $multiopt - the remaining parameters can now be specified as associated array (backwards-compatible) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1719 a1433add-5e2c-0410-b055-b7f2511e0802 --- functions.inc.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/functions.inc.php b/functions.inc.php index e9219fe3..2bfe10e1 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -385,13 +385,23 @@ function safesession ($param, $default="") { * @param String PALANG_desc * @param any optional $default * @param array optional $options - * @param int $not_in_db + * @param int or $not_in_db - if array, can contain the remaining parameters as associated array + * @param ... * @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="") { +function pacol($allow_editing, $display_in_form, $display_in_list, $type, $PALANG_label, $PALANG_desc, $default = "", $options = array(), $multiopt=0, $dont_write_to_db=0, $select="", $extrafrom="", $linkto="") { if ($PALANG_label != '') $PALANG_label = Config::lang($PALANG_label); if ($PALANG_desc != '') $PALANG_desc = Config::lang($PALANG_desc ); + if (is_array($multiopt)) { # remaining parameters provided in named array + $not_in_db = 0; # keep default value + foreach ($multiopt as $key => $value) { + $$key = $value; # extract everything to the matching variable + } + } else { + $not_in_db = $multiopt; + } + return array( 'editable' => $allow_editing, 'display_in_form' => $display_in_form, @@ -405,6 +415,7 @@ function pacol($allow_editing, $display_in_form, $display_in_list, $type, $PALAN 'dont_write_to_db' => $dont_write_to_db, 'select' => $select, # replaces the field name after SELECT 'extrafrom' => $extrafrom, # added after FROM xy - useful for JOINs etc. + 'linkto' => $linkto, # make the value a link - %s will be replaced with the ID ); } From 3d58d1f09218e22ff683452b4d44d9a06b2cfd2d Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sat, 1 Nov 2014 21:22:30 +0000 Subject: [PATCH 13/27] editform.tpl: - add handling for 'enma' fields (see PFAHandler r1711) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1720 a1433add-5e2c-0410-b055-b7f2511e0802 --- templates/editform.tpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/editform.tpl b/templates/editform.tpl index e1339a50..2846f5b8 100644 --- a/templates/editform.tpl +++ b/templates/editform.tpl @@ -27,6 +27,10 @@ + {elseif $field.type == 'enma'} + {elseif $field.type == 'list'} + {$select_options} + + + +{#form_search#} + + + +
+ + + + {foreach key=key item=field from=$struct} + {if $field.display_in_list == 1 && $field.label}{* don't show fields without a label *} + + {/if} + {/foreach} + + + + +{foreach from=$items item=item} + {#tr_hilightoff#} + + {foreach key=key item=field from=$struct} + {if $field.display_in_list == 1 && $field.label} + + {if $table == 'foo' && $key == 'bar'} + + {else} + + {/if} + {/if} + {/foreach} + + + + +{/foreach} + +
{$field.label}  
Special handling (complete table row) for {$table} / {$key}
+ {if $table == 'foo' && $key == 'bar'} + Special handling (td content) for {$table} / {$key} +{* {elseif $table == 'domain' && $key == 'domain'} + {$item.domain} +*} + {elseif $key == 'active'} + {$item._active} + {elseif $field.type == 'bool'} + {assign "tmpkey" "_{$key}"}{$item.{$tmpkey}} + {elseif $field.type == 'list'} + {foreach key=key2 item=field2 from=$value_{$key}}

{$field2} {/foreach} + {elseif $field.type == 'pass'} + (hidden) + {elseif $field.type == 'txtl'} + {foreach key=key2 item=field2 from=$value_{$key}}

{$field2} {/foreach} + {else} +{$item.{$key}} + {/if} +

{if $item._can_edit}{$PALANG.edit}{else} {/if}{if $item._can_delete}{$PALANG.del}{else} {/if}
+ +
{$PALANG.{$formconf.create_button}}
+ +
From 1e35c579b6d7de30a1b02ff1ebdad217dcf1c418 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 21:14:16 +0000 Subject: [PATCH 16/27] list.php, list.tpl: - use smarty-style dropdown for admin dropdown instead of select_options() - only display admin dropdown if more than one admin is available (which basically means hiding it for domain admins) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1723 a1433add-5e2c-0410-b055-b7f2511e0802 --- list.php | 3 ++- templates/list.tpl | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/list.php b/list.php index 74c21cc6..f64907ad 100644 --- a/list.php +++ b/list.php @@ -48,7 +48,8 @@ authentication_require_role($formconf['required_role']); $handler->getList(''); $items = $handler->result(); -$smarty->assign ('select_options', select_options($list_admins, array ($fUsername)), false); +$smarty->assign('admin_list', $list_admins); +$smarty->assign('admin_selected', $username); #if ($is_superadmin) { $smarty->assign('smarty_template', 'list'); $smarty->assign('struct', $handler->getStruct()); diff --git a/templates/list.tpl b/templates/list.tpl index 31176f46..2c4f3529 100644 --- a/templates/list.tpl +++ b/templates/list.tpl @@ -1,9 +1,9 @@
- - + {if ($admin_list|count > 1)} + {html_options name='username' output=$admin_list values=$admin_list selected=$admin_selected onchange="this.form.submit();"} + + {/if}
{#form_search#}
From 50357d276a5f37698e122804eb6fa2ea73c928e6 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 21:19:54 +0000 Subject: [PATCH 17/27] list.php: - allow usage for users, not only admins git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1724 a1433add-5e2c-0410-b055-b7f2511e0802 --- list.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/list.php b/list.php index f64907ad..2dc4b5b1 100644 --- a/list.php +++ b/list.php @@ -36,14 +36,22 @@ $is_superadmin = 0; if (authentication_has_role('global-admin')) { # more permissions? Fine! $list_admins = array_keys(list_admins()); $is_superadmin = 1; - $username = safepost('username', safeget('username', authentication_get_username())); # prefer POST over GET variable + $username = safepost('username', safeget('username', $username)); # prefer POST over GET variable } -$handler = new $handlerclass(0, $username); +$is_admin = authentication_has_role('admin'); + +$handler = new $handlerclass(0, $username, $is_admin); $formconf = $handler->webformConfig(); -authentication_require_role($formconf['required_role']); +if ($is_admin) { + authentication_require_role($formconf['required_role']); +} else { + if (empty($formconf['user_hardcoded_field'])) { + die($handlerclass . ' is not available for users'); + } +} $handler->getList(''); $items = $handler->result(); From a8265649629c024e26ec8134c2edada465da974c Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 21:32:25 +0000 Subject: [PATCH 18/27] list.php: - add CSV export list.tpl: - add "export as CSV" link *.lang: - new text 'download_csv' git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1725 a1433add-5e2c-0410-b055-b7f2511e0802 --- languages/bg.lang | 1 + languages/ca.lang | 1 + languages/cn.lang | 1 + languages/cs.lang | 1 + languages/da.lang | 1 + languages/de.lang | 1 + languages/en.lang | 1 + languages/es.lang | 1 + languages/et.lang | 1 + languages/eu.lang | 1 + languages/fi.lang | 1 + languages/fo.lang | 1 + languages/fr.lang | 1 + languages/hr.lang | 1 + languages/hu.lang | 1 + languages/is.lang | 1 + languages/it.lang | 1 + languages/ja.lang | 1 + languages/lt.lang | 1 + languages/mk.lang | 1 + languages/nb.lang | 1 + languages/nl.lang | 1 + languages/nn.lang | 1 + languages/pl.lang | 1 + languages/pt-br.lang | 1 + languages/ru.lang | 1 + languages/sk.lang | 1 + languages/sl.lang | 1 + languages/sv.lang | 1 + languages/tr.lang | 1 + languages/tw.lang | 1 + list.php | 50 +++++++++++++++++++++++++++++++++++++------- templates/list.tpl | 2 ++ 33 files changed, 76 insertions(+), 7 deletions(-) diff --git a/languages/bg.lang b/languages/bg.lang index 22cf6496..f11bb96b 100644 --- a/languages/bg.lang +++ b/languages/bg.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/ca.lang b/languages/ca.lang index 20727ffe..24272463 100644 --- a/languages/ca.lang +++ b/languages/ca.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/cn.lang b/languages/cn.lang index 33cafebd..15b3e3ea 100644 --- a/languages/cn.lang +++ b/languages/cn.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/cs.lang b/languages/cs.lang index 1d7b8ef7..5560051f 100644 --- a/languages/cs.lang +++ b/languages/cs.lang @@ -25,6 +25,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/da.lang b/languages/da.lang index a88a3b4e..1e1a1afb 100644 --- a/languages/da.lang +++ b/languages/da.lang @@ -24,6 +24,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/de.lang b/languages/de.lang index de18922b..2b408ea9 100644 --- a/languages/de.lang +++ b/languages/de.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Anzeigen:'; $PALANG['all'] = 'Alle'; $PALANG['created'] = 'Erstellt'; $PALANG['unknown'] = 'unbekannt'; +$PALANG['download_csv'] = 'Diese Liste als CSV-Datei herunterladen'; $PALANG['missing_field'] = 'Das Feld %s fehlt'; $PALANG['must_be_numeric'] = '%s muss numerisch sein'; $PALANG['must_be_boolean'] = "%s muss ein Bool'scher Wert sein"; diff --git a/languages/en.lang b/languages/en.lang index 8047eef3..43182811 100644 --- a/languages/en.lang +++ b/languages/en.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; $PALANG['all'] = 'All'; $PALANG['created'] = 'Created'; $PALANG['unknown'] = 'unknown'; +$PALANG['download_csv'] = 'Download this list as CSV file'; $PALANG['missing_field'] = 'Field %s is missing'; $PALANG['must_be_numeric'] = '%s must be numeric'; $PALANG['must_be_boolean'] = '%s must be boolean'; diff --git a/languages/es.lang b/languages/es.lang index 4c7cfe69..8efbc3fa 100644 --- a/languages/es.lang +++ b/languages/es.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/et.lang b/languages/et.lang index c7db5485..3f6e7422 100644 --- a/languages/et.lang +++ b/languages/et.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/eu.lang b/languages/eu.lang index ed378525..bb301cd3 100644 --- a/languages/eu.lang +++ b/languages/eu.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/fi.lang b/languages/fi.lang index f1dcc433..d72be66e 100644 --- a/languages/fi.lang +++ b/languages/fi.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/fo.lang b/languages/fo.lang index 866728d8..01f14d6f 100644 --- a/languages/fo.lang +++ b/languages/fo.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/fr.lang b/languages/fr.lang index 56f7ddb7..ab97d8ab 100644 --- a/languages/fr.lang +++ b/languages/fr.lang @@ -23,6 +23,7 @@ $PALANG['show'] = 'Afficher:'; $PALANG['all'] = 'Tous'; $PALANG['created'] = 'Créé'; $PALANG['unknown'] = 'inconnu'; +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Le champ %s est manquant'; $PALANG['must_be_numeric'] = '%s doit être numérique'; $PALANG['must_be_boolean'] = '%s doit être booléen'; diff --git a/languages/hr.lang b/languages/hr.lang index 3d1bd4b4..a76353ca 100644 --- a/languages/hr.lang +++ b/languages/hr.lang @@ -20,6 +20,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/hu.lang b/languages/hu.lang index 7aabccbd..08d0d7e6 100644 --- a/languages/hu.lang +++ b/languages/hu.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/is.lang b/languages/is.lang index 36041b41..b522e84a 100644 --- a/languages/is.lang +++ b/languages/is.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/it.lang b/languages/it.lang index bf7120b5..61b983e7 100644 --- a/languages/it.lang +++ b/languages/it.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/ja.lang b/languages/ja.lang index 9efb7bc2..3ef38172 100644 --- a/languages/ja.lang +++ b/languages/ja.lang @@ -22,6 +22,7 @@ $PALANG['show'] = '閲覧:'; $PALANG['all'] = '全て'; $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/lt.lang b/languages/lt.lang index e9053609..5545137a 100644 --- a/languages/lt.lang +++ b/languages/lt.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Rodyti:'; $PALANG['all'] = 'Visi'; $PALANG['created'] = 'Sukurta'; $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/mk.lang b/languages/mk.lang index 152cf564..ea950e1a 100644 --- a/languages/mk.lang +++ b/languages/mk.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/nb.lang b/languages/nb.lang index 4dff1659..7969a917 100644 --- a/languages/nb.lang +++ b/languages/nb.lang @@ -23,6 +23,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/nl.lang b/languages/nl.lang index 918c86b9..44d923bc 100644 --- a/languages/nl.lang +++ b/languages/nl.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Toon:'; $PALANG['all'] = 'Alle'; $PALANG['created'] = 'Aangemaakt'; #XXX $PALANG['unknown'] = 'onbekend'; #XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Veld %s is niet aanwezig'; #XXX $PALANG['must_be_numeric'] = '%s moet een getal zijn'; #XXX $PALANG['must_be_boolean'] = '%s moet een boolean zijn'; #XXX diff --git a/languages/nn.lang b/languages/nn.lang index 5a31bb18..7ae8daf6 100644 --- a/languages/nn.lang +++ b/languages/nn.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/pl.lang b/languages/pl.lang index 2938f58d..feb418ff 100644 --- a/languages/pl.lang +++ b/languages/pl.lang @@ -24,6 +24,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/pt-br.lang b/languages/pt-br.lang index e832eb42..aeaaf69d 100644 --- a/languages/pt-br.lang +++ b/languages/pt-br.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/ru.lang b/languages/ru.lang index 808b991c..15cdb11d 100644 --- a/languages/ru.lang +++ b/languages/ru.lang @@ -23,6 +23,7 @@ $PALANG['show'] = 'Показать:'; $PALANG['all'] = 'Все'; $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/sk.lang b/languages/sk.lang index 62a0d1c4..bae21073 100644 --- a/languages/sk.lang +++ b/languages/sk.lang @@ -22,6 +22,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/sl.lang b/languages/sl.lang index 8dc15f8c..2ccba55d 100644 --- a/languages/sl.lang +++ b/languages/sl.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/sv.lang b/languages/sv.lang index 8a5586c0..ba8e7ac5 100644 --- a/languages/sv.lang +++ b/languages/sv.lang @@ -23,6 +23,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/tr.lang b/languages/tr.lang index 2f116fae..a0639a9c 100644 --- a/languages/tr.lang +++ b/languages/tr.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/languages/tw.lang b/languages/tw.lang index 511630b2..6a5d3a5d 100644 --- a/languages/tw.lang +++ b/languages/tw.lang @@ -21,6 +21,7 @@ $PALANG['show'] = 'Show:'; # XXX $PALANG['all'] = 'All'; # XXX $PALANG['created'] = 'Created'; # XXX $PALANG['unknown'] = 'unknown'; # XXX +$PALANG['download_csv'] = 'Download this list as CSV file'; # XXX $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX diff --git a/list.php b/list.php index 2dc4b5b1..48bea500 100644 --- a/list.php +++ b/list.php @@ -56,9 +56,46 @@ if ($is_admin) { $handler->getList(''); $items = $handler->result(); -$smarty->assign('admin_list', $list_admins); -$smarty->assign('admin_selected', $username); -#if ($is_superadmin) { +if (safeget('output') == 'csv') { + + $out = fopen('php://output', 'w'); + header( 'Content-Type: text/csv; charset=utf-8' ); + header( 'Content-Disposition: attachment;filename='.$table.'.csv'); + + print "\xEF\xBB\xBF"; # utf8 byte-order to indicate the file is utf8 encoded + # print "sep=;"; # hint that ; is used as seperator - breaks the utf8 flag in excel import! + print "\n"; + + if (!defined('ENT_HTML401')) { # for compability for PHP < 5.4.0 + define('ENT_HTML401', 0); + } + + # print column headers as csv + $header = array(); + $columns = array(); + foreach ($handler->getStruct() as $key => $field) { + if ($field['display_in_list'] && $field['label'] != '') { # don't show fields without a label + $header[] = html_entity_decode ( $field['label'], ENT_COMPAT | ENT_HTML401, 'UTF-8' ); + $columns[] = $key; + } + } + fputcsv($out, $header, ';'); + + # print items as csv + foreach ($items as $item) { + $fields = array(); + foreach ($columns as $column) { + $fields[] = $item[$column]; + } + fputcsv($out, $fields, ';'); + } + + fclose($out); + +} else { # HTML output + + $smarty->assign('admin_list', $list_admins); + $smarty->assign('admin_selected', $username); $smarty->assign('smarty_template', 'list'); $smarty->assign('struct', $handler->getStruct()); $smarty->assign('msg', $handler->getMsg()); @@ -66,11 +103,10 @@ $smarty->assign('admin_selected', $username); $smarty->assign('items', $items); $smarty->assign('id_field', $handler->getId_field()); $smarty->assign('formconf', $formconf); -#} else { -# $smarty->assign ('smarty_template', 'overview-get'); -#} -$smarty->display ('index.tpl'); + $smarty->display ('index.tpl'); + +} /* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */ ?> diff --git a/templates/list.tpl b/templates/list.tpl index 2c4f3529..2ea6243b 100644 --- a/templates/list.tpl +++ b/templates/list.tpl @@ -64,5 +64,7 @@
{$PALANG.{$formconf.create_button}}
+
+
{$PALANG.download_csv} From 7a23b3cda80a3fb77a1f2c75cbab69534a415aa4 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 21:39:13 +0000 Subject: [PATCH 19/27] list.tpl: - add handling for quota fields (visual quota indicator) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1726 a1433add-5e2c-0410-b055-b7f2511e0802 --- templates/list.tpl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/templates/list.tpl b/templates/list.tpl index 2ea6243b..dee0b468 100644 --- a/templates/list.tpl +++ b/templates/list.tpl @@ -45,6 +45,24 @@ {foreach key=key2 item=field2 from=$value_{$key}}

{$field2} {/foreach} {elseif $field.type == 'pass'} (hidden) + {elseif $field.type == 'quot'} + {assign "tmpkey" "_{$key}_percent"} + + {if $item[$tmpkey]>90} + {assign var="quota_level" value="high"} + {elseif $item[$tmpkey]>55} + {assign var="quota_level" value="mid"} + {else} + {assign var="quota_level" value="low"} + {/if} + {if $item[$tmpkey] > -1} +

+
+
{$item[$key]}
+ {else} + {$item[$key]} + {/if} + {elseif $field.type == 'txtl'} {foreach key=key2 item=field2 from=$value_{$key}}

{$field2} {/foreach} {else} From d2490f61530bfae3d5aa0061c00b5577c0297518 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 21:47:31 +0000 Subject: [PATCH 20/27] list.tpl: - add support for $struct[linkto] git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1727 a1433add-5e2c-0410-b055-b7f2511e0802 --- templates/list.tpl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/templates/list.tpl b/templates/list.tpl index dee0b468..68af8a65 100644 --- a/templates/list.tpl +++ b/templates/list.tpl @@ -28,6 +28,13 @@ {foreach key=key item=field from=$struct} {if $field.display_in_list == 1 && $field.label} + {if $field.linkto != '' && ($item.$id_field != '' || $item.$id_field > 0) } + {assign "linkto" "{$field.linkto|replace:'%s':{$item.$id_field|escape:url}}"} {* TODO: use label field instead *} + {assign "linktext" "{$item.{$key}}"} + {else} + {assign "linktext" $item.$key} + {/if} + {if $table == 'foo' && $key == 'bar'} Special handling (complete table row) for {$table} / {$key} {else} @@ -58,7 +65,7 @@ {if $item[$tmpkey] > -1}

-
{$item[$key]}
+
{$linktext}
{else} {$item[$key]} {/if} @@ -66,7 +73,7 @@ {elseif $field.type == 'txtl'} {foreach key=key2 item=field2 from=$value_{$key}}

{$field2} {/foreach} {else} -{$item.{$key}} + {$linktext} {/if} {/if} From ca76b0fb6e70a7001d5362a1109f36c97a689bda Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 21:55:56 +0000 Subject: [PATCH 21/27] PFAHandler: - add getMsg() function (needed by list.php) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1728 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 4b920328..2fd12681 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -672,6 +672,10 @@ abstract class PFAHandler { return $this->struct; } + public function getMsg() { + return $this->msg; + } + public function getId_field() { return $this->id_field; } From 6bfe6706bad7bdc2646d93ce7f943db6be9379d6 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 22:03:58 +0000 Subject: [PATCH 22/27] PFAHandler: - add $this->label_field and $this->label (defaults to $this->id_field and $this->id) to allow nicer messages - use $this->label in various messages git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1729 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 2fd12681..9e7eb1e1 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -25,6 +25,10 @@ abstract class PFAHandler { # field containing the ID protected $id_field = null; + # field containing the label + # defaults to $id_field if not set + protected $label_field = null; + # column containing the domain # if a table does not contain a domain column, leave empty and override no_domain_field()) protected $domain_field = ""; @@ -66,6 +70,10 @@ abstract class PFAHandler { # filled in domain_from_id() via init() protected $domain = null; + # the label of the current item (for usage in error/info messages) + # filled in init() (only contains the "real" label in edit mode - in new mode, it will be the same as $id) + protected $label = null; + # can this item be edited? # filled in init() (only in edit mode) protected $can_edit = 1; @@ -111,6 +119,11 @@ abstract class PFAHandler { * @param integer - 0 if logged in as user, 1 if logged in as admin or superadmin */ public function __construct($new = 0, $username = "", $is_admin = 1) { + # set label_field if not explicitely set + if (empty($this->label_field)) { + $this->label_field = $this->id_field; + } + if ($new) $this->new = 1; if ($is_admin) { @@ -251,6 +264,7 @@ abstract class PFAHandler { */ public function init($id) { $this->id = strtolower($id); + $this->label = $this->id; $exists = $this->view(false); @@ -271,6 +285,7 @@ abstract class PFAHandler { } else { $this->can_edit = $this->result['_can_edit']; $this->can_delete = $this->result['_can_delete']; + $this->label = $this->result[$this->label_field]; # return true; } } @@ -326,7 +341,7 @@ abstract class PFAHandler { */ public function set($values) { if ( !$this->can_edit ) { - $this->errormsg[] = Config::Lang_f('edit_not_allowed', $this->id); + $this->errormsg[] = Config::Lang_f('edit_not_allowed', $this->label); return false; } @@ -463,7 +478,7 @@ abstract class PFAHandler { $result = db_update($this->db_table, $this->id_field, $this->id, $db_values); } if ($result != 1) { - $this->errormsg[] = Config::lang_f($this->msg['store_error'], $this->id); + $this->errormsg[] = Config::lang_f($this->msg['store_error'], $this->label); return false; } @@ -475,7 +490,7 @@ abstract class PFAHandler { if ($result) { # return success message # TODO: add option to override the success message (for example to include autogenerated passwords) - $this->infomsg['success'] = Config::lang_f($this->msg['successmessage'], $this->id); + $this->infomsg['success'] = Config::lang_f($this->msg['successmessage'], $this->label); } return $result; From b76511628d5921f31fbfc8924f5982e8b381f556 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 22:07:20 +0000 Subject: [PATCH 23/27] PFAHandler: - add $this->order_by to allow ordering by any field(s) (defaults to $this->id_field) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1730 a1433add-5e2c-0410-b055-b7f2511e0802 --- model/PFAHandler.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 9e7eb1e1..2eef1a21 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -29,6 +29,11 @@ abstract class PFAHandler { # defaults to $id_field if not set protected $label_field = null; + # field(s) to use in the ORDER BY clause + # can contain multiple comma-separated fields + # defaults to $id_field if not set + protected $order_by = null; + # column containing the domain # if a table does not contain a domain column, leave empty and override no_domain_field()) protected $domain_field = ""; @@ -124,6 +129,11 @@ abstract class PFAHandler { $this->label_field = $this->id_field; } + # set order_by if not explicitely set + if (empty($this->order_by)) { + $this->order_by = $this->id_field; + } + if ($new) $this->new = 1; if ($is_admin) { @@ -582,8 +592,7 @@ abstract class PFAHandler { if ( (!$this->is_admin) && $this->user_field != '') { $where .= " AND " . $this->user_field . " = '" . escape_string($this->username) . "' "; } - - $query = "SELECT $cols FROM $table $extrafrom $where ORDER BY " . $this->id_field; + $query = "SELECT $cols FROM $table $extrafrom $where ORDER BY " . $this->order_by; $limit = (int) $limit; # make sure $limit and $offset are really integers $offset = (int) $offset; From 13f1a28b6ef9c6bc82ab257cef7af4686f53933c Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 22:45:22 +0000 Subject: [PATCH 24/27] PFAHandler: - read_from_db(), getList(): - add $searchmode parameter (_before_ $limit and $offset!) to be able to use query different query modes, not only "=" - add a warning that $condition will be changed to array only in the future - getList(): filter $condition for fields that are available to the user to avoid information leaks by using search parameters (filter is only applied if $condition is an array!) functions.inc.php: - db_where_clause(): - add $additional_raw_where parameter for additional query parameters - add $searchmode parameter to be able to use query different query modes, not only "=" (see $allowed_operators) - check for allowed operators in $searchmode - split query into WHERE and HAVING (if a parameter has $struct[select] set, HAVING is used) list-virtual.php: - adopt getList() call to the new syntax AliasHandler: - adopt getList() definition and call to the new syntax git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1731 a1433add-5e2c-0410-b055-b7f2511e0802 --- functions.inc.php | 39 +++++++++++++++++++++++++++++++++--- list-virtual.php | 2 +- model/AliasHandler.php | 4 ++-- model/PFAHandler.php | 45 +++++++++++++++++++++++++++++++----------- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/functions.inc.php b/functions.inc.php index 2bfe10e1..4ba9ba0b 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -1617,21 +1617,54 @@ function db_in_clause($field, $values) { * Call: db_where_clause (array $conditions, array $struct) * param array $conditios: array('field' => 'value', 'field2' => 'value2, ...) * param array $struct - field structure, used for automatic bool conversion + * param string $additional_raw_where - raw sniplet to include in the WHERE part - typically needs to start with AND + * param array $searchmode - operators to use (=, <, > etc.) - defaults to = if not specified for a field (see + * $allowed_operators for available operators) */ -function db_where_clause($condition, $struct) { +function db_where_clause($condition, $struct, $additional_raw_where = '', $searchmode = array()) { if (!is_array($condition)) { die('db_where_cond: parameter $cond is not an array!'); + } elseif(!is_array($searchmode)) { + die('db_where_cond: parameter $searchmode is not an array!'); } elseif (count($condition) == 0) { die("db_where_cond: parameter is an empty array!"); # die() might sound harsh, but can prevent information leaks } elseif(!is_array($struct)) { die('db_where_cond: parameter $struct is not an array!'); } + $allowed_operators = explode(' ', '< > >= <= = != <> CONT LIKE'); + $where_parts = array(); + $having_parts = array(); + foreach($condition as $field => $value) { if (isset($struct[$field]) && $struct[$field]['type'] == 'bool') $value = db_get_boolean($value); - $parts[] = "$field='" . escape_string($value) . "'"; + $operator = '='; + if (isset($searchmode[$field])) { + if (in_array($searchmode[$field], $allowed_operators)) { + $operator = $searchmode[$field]; + + if ($operator == 'CONT') { # CONT - as in "contains" + $operator = ' LIKE '; # add spaces + $value = '%' . $value . '%'; + } elseif ($operator == 'LIKE') { # LIKE -without adding % wildcards (the search value can contain %) + $operator = ' LIKE '; # add spaces + } + } else { + die('db_where_clause: Invalid searchmode for ' . $field); + } + } + $querypart = $field . $operator . "'" . escape_string($value) . "'"; + if($struct[$field]['select'] != '') { + $having_parts[$field] = $querypart; + } else { + $where_parts[$field] = $querypart; + } } - $query = " WHERE ( " . join(" AND ", $parts) . " ) "; + $query = ' WHERE 1=1 '; + $query .= " $additional_raw_where "; + if (count($where_parts) > 0) $query .= " AND ( " . join(" AND ", $where_parts) . " ) "; + if (count($having_parts) > 0) $query .= " HAVING ( " . join(" AND ", $having_parts) . " ) "; + return $query; } diff --git a/list-virtual.php b/list-virtual.php index 21fc6892..f5487af6 100644 --- a/list-virtual.php +++ b/list-virtual.php @@ -126,7 +126,7 @@ $alias_pagebrowser_query = " "; $handler = new AliasHandler(0, $admin_username); -$handler->getList($list_param, $page_size, $fDisplay); +$handler->getList($list_param, array(), $page_size, $fDisplay); $tAlias = $handler->result(); diff --git a/model/AliasHandler.php b/model/AliasHandler.php index ab96b78a..ec71127f 100644 --- a/model/AliasHandler.php +++ b/model/AliasHandler.php @@ -287,10 +287,10 @@ class AliasHandler extends PFAHandler { return $db_result; } - public function getList($condition, $limit=-1, $offset=-1) { + public function getList($condition, $searchmode = array(), $limit=-1, $offset=-1) { # only list aliases that do not belong to mailboxes # TODO: breaks if $condition is an array - return parent::getList( "__mailbox_username IS NULL AND ( $condition )", $limit, $offset); + return parent::getList( "__mailbox_username IS NULL AND ( $condition )", $searchmode, $limit, $offset); } protected function _validate_goto($field, $val) { diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 2eef1a21..9456a022 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -533,11 +533,13 @@ abstract class PFAHandler { * * @param array or string - condition (an array will be AND'ed using db_where_clause, a string will be directly used) * (if you use a string, make sure it is correctly escaped!) + * - WARNING: will be changed to array only in the future, with an option to include a raw string inside the array + * @param array searchmode - operators to use (=, <, >) if $condition is an array. Defaults to = if not specified for a field. * @param integer limit - maximum number of rows to return * @param integer offset - number of first row to return * @return array - rows (as associative array, with the ID as key) */ - protected function read_from_db($condition, $limit=-1, $offset=-1) { + protected function read_from_db($condition, $searchmode = array(), $limit=-1, $offset=-1) { $select_cols = array(); $yes = escape_string(Config::lang('YES')); @@ -577,21 +579,23 @@ abstract class PFAHandler { $cols = join(',', $select_cols); $table = table_by_key($this->db_table); - if (is_array($condition)) { - $where = db_where_clause($condition, $this->struct); - } else { - if ($condition == "") $condition = '1=1'; - $where = " WHERE ( $condition ) "; - } - + $additional_where = ''; if ($this->domain_field != "") { - $where .= " AND " . db_in_clause($this->domain_field, $this->allowed_domains); + $additional_where .= " AND " . db_in_clause($this->domain_field, $this->allowed_domains); } # if logged in as user, restrict to the items the user is allowed to see if ( (!$this->is_admin) && $this->user_field != '') { - $where .= " AND " . $this->user_field . " = '" . escape_string($this->username) . "' "; + $additional_where .= " AND " . $this->user_field . " = '" . escape_string($this->username) . "' "; + } + + if (is_array($condition)) { + $where = db_where_clause($condition, $this->struct, $additional_where, $searchmode); + } else { + if ($condition == "") $condition = '1=1'; + $where = " WHERE ( $condition ) $additional_where"; } + $query = "SELECT $cols FROM $table $extrafrom $where ORDER BY " . $this->order_by; $limit = (int) $limit; # make sure $limit and $offset are really integers @@ -644,13 +648,30 @@ abstract class PFAHandler { /** * get a list of one or more items with all values * @param array or string $condition - see read_from_db for details + * WARNING: will be changed to array only in the future, with an option to include a raw string inside the array + * @param array - modes to use if $condition is an array - see read_from_db for details * @param integer limit - maximum number of rows to return * @param integer offset - number of first row to return * @return bool - always true, no need to check ;-) (if $result is not an array, getList die()s) * The data is stored in $this->result (as array of rows, each row is an associative array of column => value) */ - public function getList($condition, $limit=-1, $offset=-1) { - $result = $this->read_from_db($condition, $limit, $offset); + public function getList($condition, $searchmode = array(), $limit=-1, $offset=-1) { + if (is_array($condition)) { + $real_condition = array(); + foreach ($condition as $key => $value) { + # allow only access to fields the user can access to avoid information leaks via search parameters + if (isset($this->struct[$key]) && ($this->struct[$key]['display_in_list'] || $this->struct[$key]['display_in_form']) ) { + $real_condition[$key] = $value; + } else { + $this->errormsg[] = "Ignoring unknown search field $key"; + } + } + } else { + # warning: no sanity checks are applied if $condition is not an array! + $real_condition = $condition; + } + + $result = $this->read_from_db($real_condition, $searchmode, $limit, $offset); if (!is_array($result)) { error_log('getList: read_from_db didn\'t return an array. table: ' . $this->db_table . ' - condition: $condition - limit: $limit - offset: $offset'); From 03b0c869ddb977ad53b83dc7343363ec806727ab Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 23:04:15 +0000 Subject: [PATCH 25/27] list.php: - add search support: - new parameters: - search[$field] - value to search for - searchmode[$field] - search mode (=, <, > etc.) - reset_search - if given, empty $search and $searchmode - remember $search and $searchmode via session - display errormsg and infomsg from $handler, if any list.tpl: - display current search parameters and a "[x]" link to remove all search parameters This change doesn't add a search form, but you can use ?search[field]= and ?searchmode[field]= URL parameters git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1732 a1433add-5e2c-0410-b055-b7f2511e0802 --- list.php | 27 ++++++++++++++++++++++++++- templates/list.tpl | 13 +++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/list.php b/list.php index 48bea500..40e8f38e 100644 --- a/list.php +++ b/list.php @@ -53,9 +53,32 @@ if ($is_admin) { } } -$handler->getList(''); +$search = safeget('search', safesession("search_$table", array())); +$searchmode = safeget('searchmode', safesession("searchmode_$table", array())); + +if (!is_array($search) || !is_array($searchmode)) { + # avoid injection of raw SQL if $search is a string instead of an array + die("Invalid parameter"); +} + +if (safeget('reset_search', 0)) { + $search = array(); + $searchmode = array(); +} +$_SESSION["search_$table"] = $search; +$_SESSION["searchmode_$table"] = $searchmode; + +if (count($search)) { + $handler->getList($search, $searchmode); +} else { + $handler->getList(''); +} $items = $handler->result(); +if (count($handler->errormsg)) flash_error($handler->errormsg); +if (count($handler->infomsg)) flash_error($handler->infomsg); + + if (safeget('output') == 'csv') { $out = fopen('php://output', 'w'); @@ -103,6 +126,8 @@ if (safeget('output') == 'csv') { $smarty->assign('items', $items); $smarty->assign('id_field', $handler->getId_field()); $smarty->assign('formconf', $formconf); + $smarty->assign('search', $search); + $smarty->assign('searchmode', $searchmode); $smarty->display ('index.tpl'); diff --git a/templates/list.tpl b/templates/list.tpl index 68af8a65..2620d4e3 100644 --- a/templates/list.tpl +++ b/templates/list.tpl @@ -8,6 +8,19 @@ {#form_search#} + {if ($search|count > 0)} +

+

{$PALANG.searchparams} + {foreach key=key item=field from=$search} + {if $struct.$key.label}{$struct.$key.label}{else}{$key}{/if} + {if isset($searchmode.$key)}{$searchmode.$key}{else}={/if} {$field} + + {/foreach} + [x] +

+ {/if} + +
From eee25272a681ee9f0c411ae884e05235d90ab623 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 23:06:13 +0000 Subject: [PATCH 26/27] delete.php: - allow users (non-admins) to use delete.php git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1733 a1433add-5e2c-0410-b055-b7f2511e0802 --- delete.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/delete.php b/delete.php index 62296a0b..6d09677b 100644 --- a/delete.php +++ b/delete.php @@ -32,11 +32,18 @@ if ( !preg_match('/^[a-z]+$/', $table) || !file_exists("model/$handlerclass.php" die ("Invalid table name given!"); } -$handler = new $handlerclass(0, $username); +$is_admin = authentication_has_role('admin'); +$handler = new $handlerclass(0, $username, $is_admin); $formconf = $handler->webformConfig(); -authentication_require_role($formconf['required_role']); +if ($is_admin) { + authentication_require_role($formconf['required_role']); +} else { + if (empty($formconf['user_hardcoded_field'])) { + die($handlerclass . ' is not available for users'); + } +} if ($handler->init($id)) { # errors will be displayed as last step anyway, no need for duplicated code ;-) $handler->delete(); From 3916ae4104bbb79b1489111008cd480ef0064c05 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 2 Nov 2014 23:13:35 +0000 Subject: [PATCH 27/27] *.lang: - add 'edit_not_allowed' (needed by PFAHandler) - add 'searchparams' (needed by list.tpl) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1734 a1433add-5e2c-0410-b055-b7f2511e0802 --- languages/bg.lang | 2 ++ languages/ca.lang | 2 ++ languages/cn.lang | 2 ++ languages/cs.lang | 2 ++ languages/da.lang | 2 ++ languages/de.lang | 2 ++ languages/en.lang | 2 ++ languages/es.lang | 2 ++ languages/et.lang | 2 ++ languages/eu.lang | 2 ++ languages/fi.lang | 2 ++ languages/fo.lang | 2 ++ languages/fr.lang | 2 ++ languages/hr.lang | 2 ++ languages/hu.lang | 2 ++ languages/is.lang | 2 ++ languages/it.lang | 2 ++ languages/ja.lang | 2 ++ languages/lt.lang | 2 ++ languages/mk.lang | 2 ++ languages/nb.lang | 2 ++ languages/nl.lang | 2 ++ languages/nn.lang | 2 ++ languages/pl.lang | 2 ++ languages/pt-br.lang | 2 ++ languages/ru.lang | 2 ++ languages/sk.lang | 2 ++ languages/sl.lang | 2 ++ languages/sv.lang | 2 ++ languages/tr.lang | 2 ++ languages/tw.lang | 2 ++ 31 files changed, 62 insertions(+) diff --git a/languages/bg.lang b/languages/bg.lang index f11bb96b..5e317ed6 100644 --- a/languages/bg.lang +++ b/languages/bg.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Потребител %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Администратора може да се логне оттук за администриране на домейн.'; diff --git a/languages/ca.lang b/languages/ca.lang index 24272463..e7cfb881 100644 --- a/languages/ca.lang +++ b/languages/ca.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Login d\'administrador per l\'administració de dominis.'; diff --git a/languages/cn.lang b/languages/cn.lang index 15b3e3ea..ab1c6a9d 100644 --- a/languages/cn.lang +++ b/languages/cn.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = '邮件管理员请从这里登录以管理你的域名.'; diff --git a/languages/cs.lang b/languages/cs.lang index 5560051f..13e3f291 100644 --- a/languages/cs.lang +++ b/languages/cs.lang @@ -30,6 +30,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Přihlášen jako %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) diff --git a/languages/da.lang b/languages/da.lang index 1e1a1afb..1a54395b 100644 --- a/languages/da.lang +++ b/languages/da.lang @@ -29,6 +29,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Indlogget som %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) diff --git a/languages/de.lang b/languages/de.lang index 2b408ea9..89053db8 100644 --- a/languages/de.lang +++ b/languages/de.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Das Feld %s fehlt'; $PALANG['must_be_numeric'] = '%s muss numerisch sein'; $PALANG['must_be_boolean'] = "%s muss ein Bool'scher Wert sein"; $PALANG['invalid_value_given'] = 'Ungültiger Wert für %s angegeben'; +$PALANG['edit_not_allowed'] = 'Sie dülrfen %s nicht bearbeiten!'; +$PALANG['searchparams'] = 'Suchparameter:'; $PALANG['pFooter_logged_as'] = 'Angemeldet als %s'; diff --git a/languages/en.lang b/languages/en.lang index 43182811..e201c0d9 100644 --- a/languages/en.lang +++ b/languages/en.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; $PALANG['must_be_numeric'] = '%s must be numeric'; $PALANG['must_be_boolean'] = '%s must be boolean'; $PALANG['invalid_value_given'] = 'Invalid value given for %s'; +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; +$PALANG['searchparams'] = 'Search parameters:'; $PALANG['pFooter_logged_as'] = 'Logged in as %s'; diff --git a/languages/es.lang b/languages/es.lang index 8efbc3fa..d8b2f593 100644 --- a/languages/es.lang +++ b/languages/es.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Autenticado como %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Login de administrador para administración de dominios.'; diff --git a/languages/et.lang b/languages/et.lang index 3f6e7422..c5dbdf9e 100644 --- a/languages/et.lang +++ b/languages/et.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'E-posti haldaja, logi siit domeeni administreerimiseks sisse.'; diff --git a/languages/eu.lang b/languages/eu.lang index bb301cd3..ee5bac30 100644 --- a/languages/eu.lang +++ b/languages/eu.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Kudeatzailearen logina domeinuak kudeatzeko.'; diff --git a/languages/fi.lang b/languages/fi.lang index d72be66e..b2014f4b 100644 --- a/languages/fi.lang +++ b/languages/fi.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Kirjautunut sisään tunnuksella %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Kirjautuminen'; diff --git a/languages/fo.lang b/languages/fo.lang index 01f14d6f..7dc1113c 100644 --- a/languages/fo.lang +++ b/languages/fo.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Umsitarar kunnu logga inn her fyri at umsita tykkara navnaøki.'; diff --git a/languages/fr.lang b/languages/fr.lang index ab97d8ab..374b794a 100644 --- a/languages/fr.lang +++ b/languages/fr.lang @@ -28,6 +28,8 @@ $PALANG['missing_field'] = 'Le champ %s est manquant'; $PALANG['must_be_numeric'] = '%s doit être numérique'; $PALANG['must_be_boolean'] = '%s doit être booléen'; $PALANG['invalid_value_given'] = 'Valeur incorrecte pour %s'; +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Connecté en tant que %s'; $PALANG['pLogin_welcome'] = 'Entrez votre adresse courriel pour administrer votre domaine.'; diff --git a/languages/hr.lang b/languages/hr.lang index a76353ca..ba7bd055 100644 --- a/languages/hr.lang +++ b/languages/hr.lang @@ -25,6 +25,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Administratori prijavite se ovdje.'; diff --git a/languages/hu.lang b/languages/hu.lang index 08d0d7e6..b41fcdb2 100644 --- a/languages/hu.lang +++ b/languages/hu.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = '%s-ként bejelentkezve'; # XXX Text change: 'logged in as %s' (the 'in' was missing) diff --git a/languages/is.lang b/languages/is.lang index b522e84a..bff94192 100644 --- a/languages/is.lang +++ b/languages/is.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Póst kerfisstjóri tengist hér til að viðhalda póstkerfi lénsins þins.'; diff --git a/languages/it.lang b/languages/it.lang index 61b983e7..3df04413 100644 --- a/languages/it.lang +++ b/languages/it.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Collegato come %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Gli amministratori di posta devono effettuare il login qui per amministrare il proprio dominio.'; diff --git a/languages/ja.lang b/languages/ja.lang index 3ef38172..c312b6a1 100644 --- a/languages/ja.lang +++ b/languages/ja.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'ログイン名 %s'; diff --git a/languages/lt.lang b/languages/lt.lang index 5545137a..bd6af686 100644 --- a/languages/lt.lang +++ b/languages/lt.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Prisijungęs kaip %s'; $PALANG['pLogin_welcome'] = 'Pašto srities administratorius.'; diff --git a/languages/mk.lang b/languages/mk.lang index ea950e1a..911871ce 100644 --- a/languages/mk.lang +++ b/languages/mk.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Логин за администрирање на домени (Само за администратори!)'; diff --git a/languages/nb.lang b/languages/nb.lang index 7969a917..2d71b805 100644 --- a/languages/nb.lang +++ b/languages/nb.lang @@ -28,6 +28,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logget inn som %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'E-postadministratorer kan logge inn her for å administrere sine domener'; diff --git a/languages/nl.lang b/languages/nl.lang index 44d923bc..26769025 100644 --- a/languages/nl.lang +++ b/languages/nl.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Veld %s is niet aanwezig'; #XXX $PALANG['must_be_numeric'] = '%s moet een getal zijn'; #XXX $PALANG['must_be_boolean'] = '%s moet een boolean zijn'; #XXX $PALANG['invalid_value_given'] = 'Foutief waarde ingevooerd %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'aangemeld als %s'; $PALANG['pLogin_welcome'] = 'Mail beheerders log hier in om uw domeinen te beheren.'; diff --git a/languages/nn.lang b/languages/nn.lang index 7ae8daf6..d4acb062 100644 --- a/languages/nn.lang +++ b/languages/nn.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Postadministrator; Logg inn her for å administrere ditt domene'; diff --git a/languages/pl.lang b/languages/pl.lang index feb418ff..3a876ea6 100644 --- a/languages/pl.lang +++ b/languages/pl.lang @@ -29,6 +29,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Zalogowano jako %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Sekcja przeznaczona dla administratorów domen.'; diff --git a/languages/pt-br.lang b/languages/pt-br.lang index aeaaf69d..e3dd50ce 100644 --- a/languages/pt-br.lang +++ b/languages/pt-br.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Autenticado como %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) diff --git a/languages/ru.lang b/languages/ru.lang index 15cdb11d..6d573fb9 100644 --- a/languages/ru.lang +++ b/languages/ru.lang @@ -28,6 +28,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Вошли как %s'; diff --git a/languages/sk.lang b/languages/sk.lang index bae21073..566aee08 100644 --- a/languages/sk.lang +++ b/languages/sk.lang @@ -27,6 +27,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Prihlásený ako %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Prihlásenie administrátorov pre správu domén'; diff --git a/languages/sl.lang b/languages/sl.lang index 2ccba55d..38bd572d 100644 --- a/languages/sl.lang +++ b/languages/sl.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Administratorji se prijavite tukaj.'; diff --git a/languages/sv.lang b/languages/sv.lang index ba8e7ac5..977b8a04 100644 --- a/languages/sv.lang +++ b/languages/sv.lang @@ -28,6 +28,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Inloggad som %s'; # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = 'Mail administratörer loggar in här för att sköta er domän.'; diff --git a/languages/tr.lang b/languages/tr.lang index a0639a9c..1dec448b 100644 --- a/languages/tr.lang +++ b/languages/tr.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged in as %s'; # XXX $PALANG['pLogin_welcome'] = 'Posta Yöneticileri buradan domainlerinizi yönetmek için giriþ yapabilirsiniz.'; diff --git a/languages/tw.lang b/languages/tw.lang index 6a5d3a5d..6b839456 100644 --- a/languages/tw.lang +++ b/languages/tw.lang @@ -26,6 +26,8 @@ $PALANG['missing_field'] = 'Field %s is missing'; # XXX $PALANG['must_be_numeric'] = '%s must be numeric'; # XXX $PALANG['must_be_boolean'] = '%s must be boolean'; # XXX $PALANG['invalid_value_given'] = 'Invalid value given for %s'; # XXX +$PALANG['edit_not_allowed'] = 'You are not allowed to edit %s'; # XXX +$PALANG['searchparams'] = 'Search parameters:'; # XXX $PALANG['pFooter_logged_as'] = 'Logged as %s'; # XXX # XXX Text change: 'logged in as %s' (the 'in' was missing) $PALANG['pLogin_welcome'] = '郵件管理員請從這裡登錄以管理你的網域名.';