after a long weekend...

list-virtual.php:
- merge search functionality into list-virtual.php (even more performant
  for domain admins now - search.php checked domain ownership after
  querying all domains...)
  (Use list-virtual.php?search=searchterm to test searching)
- allow to display mailbox alias targets in mailbox list
  Fields added to the mailbox list array:
  * goto_mailbox (mailbox (=1) or forward-only (=0))
  * goto_other (array with aliases not pointing to the mailbox)
  * (vacation alias is skipped)
  open question: is $display_mailbox_aliases = boolconf('special_alias_control')
  correct? I'm slightly confused with alias_control, alias_control_admin
  and special_alias_control...
- build mailbox query step by step instead of having several variants
  which overlap 90% (and include a high bug potential, as already
  demonstrated by me ;-)

templates/list-virtual.php
- added search result highlighting
- added displaying of mailbox aliases (goto_mailbox and goto_other)
- removed ?domain= parameter for edit-alias.php, other edit-*.php have
  to follow (otherwise we'll have to extract the domain from the address
  to avoid incorrect parameters in search mode)

functions.inc.php
- added db_in_clause() which builds a "field in(x, y)" clause for
  database queries



git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@751 a1433add-5e2c-0410-b055-b7f2511e0802
pull/2/head
Christian Boltz 16 years ago
parent 7ea19f84ef
commit 6220b6d85c

@ -1756,7 +1756,16 @@ function db_log ($username,$domain,$action,$data)
}
}
/**
* db_in_clause
* Action: builds and returns the "field in(x, y)" clause for database queries
* Call: db_in_clause (string field, array values)
*/
function db_in_clause($field, $values) {
return " $field IN ('"
. implode("','",escape_string(array_values($values)))
. "') ";
}
//
// table_by_key

@ -53,11 +53,13 @@ if ($_SERVER['REQUEST_METHOD'] == "GET")
{
if (isset ($_GET['domain'])) $fDomain = escape_string ($_GET['domain']);
if (isset ($_GET['limit'])) $fDisplay = intval ($_GET['limit']);
$search = escape_string(safeget('search'));
}
else
{
if (isset ($_POST['fDomain'])) $fDomain = escape_string ($_POST['fDomain']);
if (isset ($_POST['limit'])) $fDisplay = intval ($_POST['limit']);
$search = escape_string(safepost('search'));
}
// store fDomain in $_SESSION so after adding/editing aliases/mailboxes we can
@ -69,6 +71,7 @@ if($fDomain) {
if (count($list_domains) == 0) {
# die("no domains");
header("Location: list-domain.php"); # no domains (for this admin at least) - redirect to domain list
exit;
}
if ((is_array ($list_domains) and sizeof ($list_domains) > 0)) if (empty ($fDomain)) $fDomain = $list_domains[0];
@ -79,6 +82,11 @@ if (!check_owner(authentication_get_username(), $fDomain)) {
exit(0);
}
#
# alias domain
#
# TODO: add search support for alias domains
if (boolconf('alias_domain')) {
# Alias-Domains
# first try to get a list of other domains pointing
@ -124,23 +132,36 @@ if (boolconf('alias_domain')) {
}
}
#
# aliases
#
if ($search == "") {
$sql_domain = " $table_alias.domain='$fDomain' ";
$sql_where = "";
} else {
$sql_domain = db_in_clause("$table_alias.domain", $list_domains);
$sql_where = " AND ( address LIKE '%$search%' OR goto LIKE '%$search%' ) ";
}
$query = "SELECT $table_alias.address,
$table_alias.goto,
$table_alias.modified,
$table_alias.active
FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username
WHERE ($table_alias.domain='$fDomain' AND $table_mailbox.maildir IS NULL)
WHERE ($sql_domain AND $table_mailbox.maildir IS NULL $sql_where)
ORDER BY $table_alias.address LIMIT $fDisplay, $page_size";
if ('pgsql'==$CONF['database_type'])
{
# TODO: is the different query for pgsql really needed? The mailbox query below also works with both...
$query = "SELECT address,
goto,
extract(epoch from modified) as modified,
active
FROM $table_alias
WHERE domain='$fDomain' AND NOT EXISTS(SELECT 1 FROM $table_mailbox WHERE username=$table_alias.address)
WHERE $sql_domain AND NOT EXISTS(SELECT 1 FROM $table_mailbox WHERE username=$table_alias.address $sql_where)
ORDER BY address LIMIT $page_size OFFSET $fDisplay";
}
$result = db_query ($query);
if ($result['rows'] > 0)
{
@ -158,66 +179,75 @@ if ($result['rows'] > 0)
}
}
# TODO: reduce number of different queries by not depending on too much config options
# (it probably won't hurt to include a field in the resultset that is not displayed later)
if ($CONF['vacation_control_admin'] == 'YES')
{
if (boolconf('used_quotas'))
{
if (boolconf('new_quota_table'))
{
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active, $table_quota2.bytes as current FROM $table_mailbox
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
LEFT JOIN $table_quota2 ON $table_mailbox.username=$table_quota2.username
WHERE $table_mailbox.domain='$fDomain'
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
}
else
{
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active, $table_quota.current FROM $table_mailbox
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
LEFT JOIN $table_quota ON $table_mailbox.username=$table_quota.username
WHERE $table_mailbox.domain='$fDomain' AND
( $table_quota.path='quota/storage' OR $table_quota.path IS NULL )
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
}
}
else # $CONF[used_quotas] = NO
{
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active FROM $table_mailbox
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
WHERE $table_mailbox.domain='$fDomain' ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
}
#
# mailboxes
#
$display_mailbox_aliases = boolconf('special_alias_control'); # TODO: is this condition correct? - I'm slightly confused with alias_control, alias_control_admin and special_alias_control
# build the sql query
$sql_select = " SELECT $table_mailbox.* ";
$sql_from = " FROM $table_mailbox ";
$sql_join = "";
$sql_where = " WHERE 1 ";
$sql_order = " ORDER BY $table_mailbox.username ";
$sql_limit = " LIMIT $page_size OFFSET $fDisplay";
if ($search == "") {
$sql_where .= " AND $table_mailbox.domain='$fDomain' ";
} else {
$sql_where .= " AND " . db_in_clause("$table_mailbox.domain", $list_domains) . " ";
$sql_where .= " AND ( $table_mailbox.username LIKE '%$search%' OR $table_mailbox.name LIKE '%$search%' ";
if ($display_mailbox_aliases) {
$sql_where .= " OR $table_alias.goto LIKE '%$search%' ";
}
$sql_where .= " ) "; # $search is already escaped
}
else # $CONF['vacation_control_admin'] == 'NO'
{
if (boolconf('used_quotas'))
{
if (boolconf('new_quota_table'))
{
$query = "SELECT $table_mailbox.*, $table_quota2.bytes as current FROM $table_mailbox
LEFT JOIN $table_quota2 ON $table_mailbox.username=$table_quota2.username
WHERE $table_mailbox.domain='$fDomain' ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
}
else
{
$query = "SELECT $table_mailbox.*, $table_quota.current FROM $table_mailbox
LEFT JOIN $table_quota ON $table_mailbox.username=$table_quota.username
WHERE $table_mailbox.domain='$fDomain' AND
( $table_quota.path='quota/storage' OR $table_quota.path IS NULL )
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
}
}
else # $CONF[used_quotas] = NO
{
$query = "SELECT * FROM $table_mailbox WHERE domain='$fDomain' ORDER BY username LIMIT $page_size OFFSET $fDisplay";
}
if ($display_mailbox_aliases) {
$sql_select .= ", $table_alias.goto ";
$sql_join .= " LEFT JOIN $table_alias ON $table_mailbox.username=$table_alias.address ";
}
if (boolconf('vacation_control_admin')) {
$sql_select .= ", $table_vacation.active AS v_active ";
$sql_join .= " LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email ";
}
if (boolconf('used_quotas') && boolconf('new_quota_table')) {
$sql_select .= ", $table_quota2.bytes as current ";
$sql_join .= " LEFT JOIN $table_quota2 ON $table_mailbox.username=$table_quota2.username ";
}
if (boolconf('used_quotas') && ( ! boolconf('new_quota_table') ) ) {
$sql_select .= ", $table_quota.current ";
$sql_join .= " LEFT JOIN $table_quota ON $table_mailbox.username=$table_quota.username ";
$sql_where .= " AND ( $table_quota.path='quota/storage' OR $table_quota.path IS NULL ) ";
}
$query = "$sql_select\n$sql_from\n$sql_join\n$sql_where\n$sql_order\n$sql_limit";
$result = db_query ($query);
if ($result['rows'] > 0)
{
while ($row = db_array ($result['result']))
{
if ($display_mailbox_aliases) {
$goto_split = split(",", $row['goto']);
$row['goto_mailbox'] = 0;
$row['goto_other'] = array();
foreach ($goto_split as $goto_single) {
if ($goto_single == $row['username']) { # delivers to mailbox
$row['goto_mailbox'] = 1;
} elseif (boolconf('vacation') && strstr($goto_single, '@' . $CONF['vacation_domain']) ) { # vacation alias - TODO: check for full vacation alias
# skip the vacation alias, vacation status is detected otherwise
} else { # forwarding to other alias
$row['goto_other'][] = $goto_single;
}
}
}
if ('pgsql'==$CONF['database_type'])
{
// XXX
@ -236,6 +266,7 @@ if ($result['rows'] > 0)
$tCanAddAlias = false;
$tCanAddMailbox = false;
# TODO: needs reworking for $search...
$limit = get_domain_properties($fDomain);
if (isset ($limit)) {
if ($fDisplay >= $page_size) {

@ -6,6 +6,17 @@
$file = 'list-virtual.php';
# search highlighting
function searchhl($text) {
global $search;
if ($search == "") {
return $text;
} else {
return str_ireplace($search, "<span class='searchresult' style='background:lightgreen'>" . $search . "</span>", $text);
# TODO: find out why .searchresult class in css file doesn't work
}
}
if ($limit['aliases'] < 0) $limit['aliases'] = $PALANG['pOverview_disabled'];
if ($limit['mailboxes'] < 0) $limit['mailboxes'] = $PALANG['pOverview_disabled'];
if ($limit['maxquota'] < 0) $limit['maxquota'] = $PALANG['pOverview_disabled'];
@ -94,6 +105,9 @@ if ((sizeof ($tAliasDomains) > 0) || (is_array ($tTargetDomain) ))
print " <td><a href=\"$file?domain=" . urlencode ($tAliasDomains[$i]['alias_domain']) . "&limit=" . $current_limit . "\">" . $tAliasDomains[$i]['alias_domain'] . "</a></td>\n";
print " <td>" . $tAliasDomains[$i]['modified'] . "</td>\n";
$active = ($tAliasDomains[$i]['active'] == 1) ? $PALANG['YES'] : $PALANG['NO'];
# TODO: change all edit-*.php scripts not to require the domain parameter (and extract it from the address). This avoids superflous problems when using search.
print " <td><a href=\"edit-active.php?alias_domain=true&domain=" . urlencode ($tAliasDomains[$i]['alias_domain']) . "&return=$file" . urlencode ( "?domain=" . $fDomain . "&limit=" . $current_limit) . "\">" . $active . "</a></td>\n";
print " <td><a href=\"delete.php?table=alias_domain&delete=" . urlencode ($tAliasDomains[$i]['alias_domain']) . "&domain=$fDomain" . "\"onclick=\"return confirm ('" . $PALANG['confirm'] . $PALANG['pOverview_get_alias_domains'] . ": ". $tAliasDomains[$i]['alias_domain'] . "')\">" . $PALANG['del'] . "</a></td>\n";
print " </tr>\n";
@ -151,10 +165,9 @@ if (sizeof ($tAlias) > 0)
{
print " <td>" . gen_show_status($tAlias[$i]['address']) . "</td>\n";
}
print " <td>" . $tAlias[$i]['address'] . "</td>\n";
print " <td>" . searchhl($tAlias[$i]['address']) . "</td>\n";
if ($CONF['alias_goto_limit'] > 0) {
print " <td>" . preg_replace (
print " <td>" . searchhl(preg_replace (
"/,/",
"<br>",
preg_replace(
@ -165,9 +178,9 @@ if (sizeof ($tAlias) > 0)
),
$tAlias[$i]['goto']
)
) . "</td>\n";
)) . "</td>\n";
} else {
print " <td>" . preg_replace ("/,/", "<br>", $tAlias[$i]['goto']) . "</td>\n";
print " <td>" . searchhl(preg_replace ("/,/", "<br>", $tAlias[$i]['goto'])) . "</td>\n";
}
print " <td>" . $tAlias[$i]['modified'] . "</td>\n";
@ -177,7 +190,7 @@ if (sizeof ($tAlias) > 0)
# superadmin code
$active = ($tAlias[$i]['active'] == 1) ? $PALANG['YES'] : $PALANG['NO'];
print " <td><a href=\"edit-active.php?alias=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain&return=$file?domain=$fDomain" . urlencode ("&limit=" . $current_limit) . "\">" . $active . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\">" . $PALANG['edit'] . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tAlias[$i]['address']) . "\">" . $PALANG['edit'] . "</a></td>\n";
print " <td><a href=\"delete.php?table=alias" . "&delete=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\"onclick=\"return confirm ('" . $PALANG['confirm'] . $PALANG['pOverview_get_aliases'] . ": ". $tAlias[$i]['address'] . "')\">" . $PALANG['del'] . "</a></td>\n";
} else {
@ -186,7 +199,7 @@ if (sizeof ($tAlias) > 0)
{
$active = ($tAlias[$i]['active'] == 1) ? $PALANG['YES'] : $PALANG['NO'];
print " <td><a href=\"edit-active.php?alias=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\">" . $active . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\">" . $PALANG['edit'] . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tAlias[$i]['address']) . "\">" . $PALANG['edit'] . "</a></td>\n";
print " <td><a href=\"delete.php?table=alias&delete=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\"onclick=\"return confirm ('" . $PALANG['confirm'] . $PALANG['pOverview_get_aliases'] . ": ". $tAlias[$i]['address'] . "')\">" . $PALANG['del'] . "</a></td>\n";
}
else
@ -195,7 +208,7 @@ if (sizeof ($tAlias) > 0)
{
$active = ($tAlias[$i]['active'] == 1) ? $PALANG['YES'] : $PALANG['NO'];
print " <td><a href=\"edit-active.php?alias=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\">" . $active . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\">" . $PALANG['edit'] . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tAlias[$i]['address']) . "\">" . $PALANG['edit'] . "</a></td>\n";
print " <td><a href=\"delete.php?table=alias&delete=" . urlencode ($tAlias[$i]['address']) . "&domain=$fDomain" . "\"onclick=\"return confirm ('" . $PALANG['confirm'] . $PALANG['pOverview_get_aliases'] . ": ". $tAlias[$i]['address'] . "')\">" . $PALANG['del'] . "</a></td>\n";
}
else
@ -254,6 +267,8 @@ if (sizeof ($tMailbox) > 0) {
$colspan=8;
if ($CONF['vacation_control_admin'] == 'YES') $colspan=$colspan+1;
if ($CONF['alias_control_admin'] == 'YES') $colspan=$colspan+1;
if ($display_mailbox_aliases) $colspan=$colspan+1;
print "<table id=\"mailbox_table\">\n";
print " <tr>\n";
print " <td colspan=\"$colspan\"><h3>" . $PALANG['pOverview_mailbox_title'] . "</h3></td>";
@ -261,6 +276,7 @@ if (sizeof ($tMailbox) > 0) {
print " <tr class=\"header\">\n";
if ($CONF['show_status'] == 'YES') { print "<td></td>\n"; }
print " <td>" . $PALANG['pOverview_mailbox_username'] . "</td>\n";
if ($display_mailbox_aliases) print " <td>" . $PALANG['pOverview_alias_goto'] . "</td>\n";
print " <td>" . $PALANG['pOverview_mailbox_name'] . "</td>\n";
if ($CONF['quota'] == 'YES') print " <td>" . $PALANG['pOverview_mailbox_quota'] . "</td>\n";
print " <td>" . $PALANG['pOverview_mailbox_modified'] . "</td>\n";
@ -280,7 +296,22 @@ if (sizeof ($tMailbox) > 0) {
print " <td>" . gen_show_status($tMailbox[$i]['username']) . "</td>\n";
}
print " <td>" . $tMailbox[$i]['username'] . "</td>\n";
print " <td>" . searchhl($tMailbox[$i]['username']) . "</td>\n";
if ($display_mailbox_aliases) {
# print " <td>" . searchhl($tMailbox[$i]['goto']) . "</td>\n";
print " <td>";
if ($tMailbox[$i]['goto_mailbox'] == 1) {
print "Mailbox"; # TODO: make translatable
} else {
print "Forward only"; # TODO: make translatable
}
if (count($tMailbox[$i]['goto_other']) > 0) print "<br>";
print searchhl(join("<br>", $tMailbox[$i]['goto_other'])); # TODO: honor $CONF['alias_goto_limit']
print "</td>\n";
}
print " <td>" . $tMailbox[$i]['name'] . "</td>\n";
if ($CONF['quota'] == 'YES')
{
@ -328,7 +359,7 @@ if (sizeof ($tMailbox) > 0) {
if ($edit_aliases == 1)
{
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tMailbox[$i]['username']) . "&domain=$fDomain" . "\">" . $PALANG['pOverview_alias_edit'] . "</a></td>\n";
print " <td><a href=\"edit-alias.php?address=" . urlencode ($tMailbox[$i]['username']) . "\">" . $PALANG['pOverview_alias_edit'] . "</a></td>\n";
}
print " <td><a href=\"edit-mailbox.php?username=" . urlencode ($tMailbox[$i]['username']) . "&domain=$fDomain" . "\">" . $PALANG['edit'] . "</a></td>\n";

Loading…
Cancel
Save