SF.net SVN: postfixadmin:[751] trunk
Brought to you by:
christian_boltz,
gingerdog
From: <chr...@us...> - 2009-11-02 00:24:49
|
Revision: 751 http://postfixadmin.svn.sourceforge.net/postfixadmin/?rev=751&view=rev Author: christian_boltz Date: 2009-11-02 00:24:40 +0000 (Mon, 02 Nov 2009) Log Message: ----------- 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 Modified Paths: -------------- trunk/functions.inc.php trunk/list-virtual.php trunk/templates/list-virtual.php Modified: trunk/functions.inc.php =================================================================== --- trunk/functions.inc.php 2009-11-01 23:46:42 UTC (rev 750) +++ trunk/functions.inc.php 2009-11-02 00:24:40 UTC (rev 751) @@ -1756,8 +1756,17 @@ } } +/** + * 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 // Action: Return table name for given key Modified: trunk/list-virtual.php =================================================================== --- trunk/list-virtual.php 2009-11-01 23:46:42 UTC (rev 750) +++ trunk/list-virtual.php 2009-11-02 00:24:40 UTC (rev 751) @@ -53,11 +53,13 @@ { 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 (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 @@ 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 @@ } } +# +# 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 @@ } } -# 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 @@ $tCanAddAlias = false; $tCanAddMailbox = false; +# TODO: needs reworking for $search... $limit = get_domain_properties($fDomain); if (isset ($limit)) { if ($fDisplay >= $page_size) { Modified: trunk/templates/list-virtual.php =================================================================== --- trunk/templates/list-virtual.php 2009-11-01 23:46:42 UTC (rev 750) +++ trunk/templates/list-virtual.php 2009-11-02 00:24:40 UTC (rev 751) @@ -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 @@ 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 @@ { 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 @@ ), $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 @@ # 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 @@ { $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 @@ { $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 @@ $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 @@ 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 @@ 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 ($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"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |