automated search support

This commit is contained in:
SJ 2014-01-23 21:39:47 +01:00
parent fd2026b70b
commit 8f59372cf4
14 changed files with 490 additions and 85 deletions

View File

@ -4,4 +4,5 @@ The FSF.hu Foundation (http://fsf.hu/) supported and donated piler within the
Nemeth Adam reviewed the web interface, and gave lots of useful hints and insights to
improve the web ui of piler.
Remi Smith improved the restricted auditor feature for a better multitenancy.
Remi Smith improved the restricted auditor feature for a better multitenancy,
and invented the default theme.

206
util/automated-search.php Normal file
View File

@ -0,0 +1,206 @@
<?php
$webuidir = "";
$search_expression = "";
$title = "automated search";
$page = 0;
$sort = "date";
$order = 0;
$dry_run = 0;
$opts = 'w:s:dyh';
$lopts = array(
'webui:',
'search:',
'dry-run',
'yesterday',
'help'
);
$options = getopt($opts, $lopts);
if(isset($options['help']) || isset($options['h']) )
{
display_help();
exit;
}
if(isset($options['webui']))
{
$webuidir = $options['webui'];
} else
{
print "\nError: must provide path to WebUI directory\n\n";
display_help();
exit;
}
if(isset($options['search']))
{
$search_expression = $options['search'];
} else {
print "\nError: must provide a search expression\n\n";
display_help();
exit;
}
if(isset($options['dry-run']) || isset($options['d']) )
{
$dry_run = 1;
}
ini_set("session.save_path", "/tmp");
require_once($webuidir . "/config.php");
if(count($automated_search_recipients) < 1)
{
print "\nError: please set \$automated_search_recipients array in config-site.php, and define the recipients' email addresses\n\n";
exit;
}
$page_len = MAX_SEARCH_HITS;
$session->set("username", "system");
$session->set("uid", 1);
$session->set("admin_user", 2);
$session->set("email", "system@local");
$session->set("domain", "local");
$session->set("emails", array("system@local"));
$session->set("pagelen", $page_len);
require(DIR_SYSTEM . "/startup.php");
$request = new Request();
Registry::set("request", $request);
Registry::set('document', new Document());
$start = NULL;
$loader = new Loader();
Registry::set('load', $loader);
$language = new Language();
Registry::set('language', $language);
extract($language->data);
if(ENABLE_SYSLOG == 1) { openlog("piler-automated-search", LOG_PID, LOG_MAIL); }
/* check if user has authenticated himself. If not, we send him to login */
Registry::set('username', "system");
Registry::set('admin_user', 0);
Registry::set('auditor_user', 1);
Registry::set('readonly_admin', 0);
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE, DB_PREFIX);
Registry::set('DB_DATABASE', DB_DATABASE);
Registry::set('db', $db);
Registry::set('DB_DRIVER', DB_DRIVER);
$sphx = new DB(SPHINX_DRIVER, SPHINX_HOSTNAME, "", "", SPHINX_DATABASE, "");
Registry::set('sphx', $sphx);
if(MEMCACHED_ENABLED) {
$memcache = new Memcache();
foreach ($memcached_servers as $m){
$memcache->addServer($m[0], $m[1]);
}
Registry::set('memcache', $memcache);
}
Registry::set('counters', $counters);
Registry::set('langs', $langs);
Registry::set('paging', $paging);
Registry::set('themes', $themes);
Registry::set('letters', $letters);
Registry::set('ldap_types', array("AD", "iredmail", "lotus", "zimbra", LDAP_TYPE_GENERIC));
Registry::set('health_smtp_servers', $health_smtp_servers);
Registry::set('partitions_to_monitor', $partitions_to_monitor);
Registry::set('actions', $actions);
Registry::set('import_status', $import_status);
$data = array(
'page' => 0,
'sort' => $sort,
'order' => $order,
'type' => 'search',
'search' => $search_expression,
'searchtype' => 'expert'
);
$loader->model('search/search');
$loader->model('search/message');
$loader->model('mail/mail');
$search = new ModelSearchSearch();
$mail = new ModelMailMail();
$a = $search->preprocess_post_expert_request($data);
if(isset($options['yesterday']) || isset($options['y']) )
{
$a['date1'] = $a['date2'] = date("Y.m.d", time() - 86400);
}
list ($n, $total_found, $all_ids, $messages) = $search->search_messages($a, $page);
if($dry_run == 0)
{
$msg = "From: " . SMTP_FROMADDR . EOL;
$msg .= "To: " . ADMIN_EMAIL . EOL;
$msg .= "Subject: =?UTF-8?Q?" . preg_replace("/\n/", "", my_qp_encode($title)) . "?=" . EOL;
$msg .= "Message-ID: <" . generate_random_string(25) . '@' . SITE_NAME . ">" . EOL;
$msg .= "MIME-Version: 1.0" . EOL;
$msg .= "Content-Type: text/html; charset=\"utf-8\"" . EOL;
$msg .= EOL . EOL;
ob_start();
include($webuidir . "/view/theme/default/templates/search/auto.tpl");
$msg .= ob_get_contents();
ob_end_clean();
$x = $mail->send_smtp_email(SMARTHOST, SMARTHOST_PORT, SMTP_DOMAIN, SMTP_FROMADDR, $automated_search_recipients, $msg);
}
else {
print "search = $search_expression\n";
print_r($all_ids);
print EOL;
}
function display_help() {
$phpself = basename(__FILE__);
echo("\nUsage: $phpself --webui [PATH] --search '[SEARCH EXPRESSION]' [OPTIONS...]\n\n");
echo("\nThe results go to the recipients defined in \$automated_search_recipients, see config-site.php\n\n");
echo("\t--webui=\"[REQUIRED: path to the piler webui directory]\"\n");
echo("\t--search=\"[REQUIRED: the search expression]\"\n\n");
echo("options:\n");
echo("\t-y | --yesterday: Search \"yesterday\"\n");
echo("\t-d | --dry-run: Only print the found IDs\n");
echo("\t-h | --help: Prints this help screen and exits\n");
}
?>

View File

@ -259,6 +259,8 @@ $paging = array(
50
);
$automated_search_recipients = array();
$letters = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
@ -287,7 +289,7 @@ if(MOBILE_DEVICE == 1 || OUTLOOK == 1) { $config['THEME'] = 'mobile'; }
// make sure auditors are restricted in a saas environment
if($config['ENABLE_SAAS'] == 1) { $config['RESTRICTED_AUDITOR'] = 1; }
if($session->get("username") == 'auditor@local') { $config['RESTRICTED_AUDITOR'] = 0; }
if($session->get("username") == 'auditor@local' || isset($_SERVER['argv'][2]) ) { $config['RESTRICTED_AUDITOR'] = 0; }

View File

@ -32,6 +32,12 @@ class ControllerMessageView extends Controller {
$this->data['search'] = $this->request->post['search'];
}
if(substr($this->data['id'], 0, 1) == 'a') {
$this->template = "message/auto.tpl";
$this->data['id'] = substr($this->data['id'], 1, 200);
}
if(!verify_piler_id($this->data['id'])) {
AUDIT(ACTION_UNKNOWN, '', '', $this->data['id'], 'unknown id: ' . $this->data['id']);
die("invalid id: " . $this->data['id']);

View File

@ -35,7 +35,6 @@ class ControllerSearchHelper extends Controller {
$this->load->model('search/message');
$this->load->model('user/user');
$this->data['page'] = 0;
if(isset($this->request->post['page'])) { $this->data['page'] = $this->request->post['page']; }
@ -46,7 +45,7 @@ class ControllerSearchHelper extends Controller {
if($this->request->post['searchtype'] == 'expert'){
if(isset($this->request->post['search']) && preg_match("/(from|to|subject|body|direction|d|size|date1|date2|attachment|a|tag|note|id)\:/", $this->request->post['search'])) {
$this->preprocess_post_expert_request($this->request->post);
$this->a = $this->model_search_search->preprocess_post_expert_request($this->request->post);
}
else {
$this->naive_preprocess_post_expert_request($this->request->post);
@ -164,87 +163,6 @@ class ControllerSearchHelper extends Controller {
}
private function preprocess_post_expert_request($data = array()) {
$token = 'match';
$ndate = 0;
$match = array();
if(!isset($data['search'])) { return; }
$s = preg_replace("/:/", ": ", $data['search']);
$s = preg_replace("/,/", " ", $s);
$s = preg_replace("/\(/", "( ", $s);
$s = preg_replace("/\)/", ") ", $s);
$s = preg_replace("/OR/", "|", $s);
$s = preg_replace("/AND/", "", $s);
$s = preg_replace("/\s{1,}/", " ", $s);
$b = explode(" ", $s);
while(list($k, $v) = each($b)) {
if($v == '') { continue; }
if($v == 'from:') { $token = 'match'; $this->a['match'][] = '@from'; continue; }
else if($v == 'to:') { $token = 'match'; $this->a['match'][] = '@to'; continue; }
else if($v == 'subject:') { $token = 'match'; $this->a['match'][] = '@subject'; continue; }
else if($v == 'body:') { $token = 'match'; $this->a['match'][] = '@body'; continue; }
else if($v == 'direction:' || $v == 'd:') { $token = 'direction'; continue; }
else if($v == 'size:') { $token = 'size'; continue; }
else if($v == 'date1:') { $token = 'date1'; continue; }
else if($v == 'date2:') { $token = 'date2'; continue; }
else if($v == 'attachment:' || $v == 'a:') { $token = 'match'; $this->a['match'][] = '@attachment_types'; continue; }
else if($v == 'size') { $token = 'size'; continue; }
else if($v == 'tag:') { $token = 'tag'; continue; }
else if($v == 'note:') { $token = 'note'; continue; }
else if($v == 'ref:') { $token = 'ref'; continue; }
else if($v == 'id:') { $token = 'id'; continue; }
else {
if(preg_match("/\d{4}\-\d{1,2}\-\d{1,2}/", $v) || preg_match("/\d{1,2}\/\d{1,2}\/\d{4}/", $v)) {
$ndate++;
$this->a["date$ndate"] = $v;
}
}
if($token == 'match') { $this->a['match'][] = $v; }
else if($token == 'date1') { $this->a['date1'] = ' ' . $v; }
else if($token == 'date2') { $this->a['date2'] = ' ' . $v; }
else if($token == 'tag') { $this->a['tag'] .= ' ' . $v; }
else if($token == 'note') { $this->a['note'] .= ' ' . $v; }
else if($token == 'ref') { $this->a['ref'] = ' ' . $v; }
else if($token == 'id') { $this->a['id'] .= ' ' . $v; }
else if($token == 'direction') {
if($v == 'inbound') { $this->a['direction'] = "0"; }
else if($v == 'outbound') { $this->a['direction'] = 2; }
else if($v == 'internal') { $this->a['direction'] = 1; }
}
else if($token == 'size') {
$o = substr($v, 0, 1);
if($o == '<' || $o == '>') {
$v = substr($v, 1, strlen($v));
$o1 = substr($v, 0, 1);
if($o1 == '=') {
$v = substr($v, 1, strlen($v));
$o .= $o1;
}
}
else { $o = ''; }
$s = explode("k", $v);
if($s[0] != $v) { $v = $s[0] * 1000; }
$s = explode("M", $v);
if($s[0] != $v) { $v = $s[0] * 1000000; }
$this->a['size'] .= ' ' . $o . $v;
}
}
}
}
?>

View File

@ -471,5 +471,6 @@ $_['text_qr_code'] = "QR";
$_['text_refresh_qr_code'] = "Refresh QR code";
$_['text_print_message'] = "Print";
$_['text_forward_selected_emails_to'] = "Forward selected emails to";
$_['text_search_expression'] = "Search expression";
?>

View File

@ -303,6 +303,7 @@ $_['text_search'] = "Search";
$_['text_search2'] = "search";
$_['text_search_emails'] = "Search email addresses";
$_['text_search_email_to_add'] = "Search email to add";
$_['text_search_expression'] = "Search expression";
$_['text_search_folders'] = "Search folders";
$_['text_search_folder_to_add'] = "Search folder to add";
$_['text_search_groups'] = "Search groups";

View File

@ -470,5 +470,6 @@ $_['text_qr_code'] = "QR";
$_['text_refresh_qr_code'] = "Refresh QR code";
$_['text_print_message'] = "Print";
$_['text_forward_selected_emails_to'] = "Forward selected emails to";
$_['text_search_expression'] = "Search expression";
?>

View File

@ -305,6 +305,7 @@ $_['text_search'] = "Keres
$_['text_search2'] = "keresés";
$_['text_search_emails'] = "Email címek keresése";
$_['text_search_email_to_add'] = "írja be az email cím elejét";
$_['text_search_expression'] = "Keresési kifejezés";
$_['text_search_folders'] = "Mappák keresése";
$_['text_search_folder_to_add'] = "Írja be a mappa elejét";
$_['text_search_groups'] = "Csoportok keresése";

View File

@ -305,6 +305,7 @@ $_['text_search'] = "Keresés";
$_['text_search2'] = "keresés";
$_['text_search_emails'] = "Email címek keresése";
$_['text_search_email_to_add'] = "írja be az email cím elejét";
$_['text_search_expression'] = "Keresési kifejezés";
$_['text_search_folders'] = "Mappák keresése";
$_['text_search_folder_to_add'] = "Írja be a mappa elejét";
$_['text_search_groups'] = "Csoportok keresése";

View File

@ -460,5 +460,6 @@ $_['text_invalid_pin_code'] = "Pin code inválido";
$_['text_qr_code'] = "QR";
$_['text_refresh_qr_code'] = "Renovar código QR";
$_['text_forward_selected_emails_to'] = "Forward selected emails to";
$_['text_search_expression'] = "Search expression";
?>

View File

@ -307,6 +307,105 @@ class ModelSearchSearch extends Model {
}
public function preprocess_post_expert_request($data = array()) {
$token = 'match';
$ndate = 0;
$match = array();
$a = array(
'date1' => '',
'date2' => '',
'direction' => '',
'size' => '',
'attachment_type' => '',
'tag' => '',
'note' => '',
'ref' => '',
'folders' => '',
'extra_folders' => '',
'id' => '',
'match' => array()
);
if(!isset($data['search'])) { return $a; }
$s = preg_replace("/:/", ": ", $data['search']);
$s = preg_replace("/,/", " ", $s);
$s = preg_replace("/\(/", "( ", $s);
$s = preg_replace("/\)/", ") ", $s);
$s = preg_replace("/OR/", "|", $s);
$s = preg_replace("/AND/", "", $s);
$s = preg_replace("/\s{1,}/", " ", $s);
$b = explode(" ", $s);
while(list($k, $v) = each($b)) {
if($v == '') { continue; }
if($v == 'from:') { $token = 'match'; $a['match'][] = '@from'; continue; }
else if($v == 'to:') { $token = 'match'; $a['match'][] = '@to'; continue; }
else if($v == 'subject:') { $token = 'match'; $a['match'][] = '@subject'; continue; }
else if($v == 'body:') { $token = 'match'; $a['match'][] = '@body'; continue; }
else if($v == 'direction:' || $v == 'd:') { $token = 'direction'; continue; }
else if($v == 'size:') { $token = 'size'; continue; }
else if($v == 'date1:') { $token = 'date1'; continue; }
else if($v == 'date2:') { $token = 'date2'; continue; }
else if($v == 'attachment:' || $v == 'a:') { $token = 'match'; $a['match'][] = '@attachment_types'; continue; }
else if($v == 'size') { $token = 'size'; continue; }
else if($v == 'tag:') { $token = 'tag'; continue; }
else if($v == 'note:') { $token = 'note'; continue; }
else if($v == 'ref:') { $token = 'ref'; continue; }
else if($v == 'id:') { $token = 'id'; continue; }
else {
if(preg_match("/\d{4}\-\d{1,2}\-\d{1,2}/", $v) || preg_match("/\d{1,2}\/\d{1,2}\/\d{4}/", $v)) {
$ndate++;
$a["date$ndate"] = $v;
}
}
if($token == 'match') { $a['match'][] = $v; }
else if($token == 'date1') { $a['date1'] = ' ' . $v; }
else if($token == 'date2') { $a['date2'] = ' ' . $v; }
else if($token == 'tag') { $a['tag'] .= ' ' . $v; }
else if($token == 'note') { $a['note'] .= ' ' . $v; }
else if($token == 'ref') { $a['ref'] = ' ' . $v; }
else if($token == 'id') { $a['id'] .= ' ' . $v; }
else if($token == 'direction') {
if($v == 'inbound') { $a['direction'] = "0"; }
else if($v == 'outbound') { $a['direction'] = 2; }
else if($v == 'internal') { $a['direction'] = 1; }
}
else if($token == 'size') {
$o = substr($v, 0, 1);
if($o == '<' || $o == '>') {
$v = substr($v, 1, strlen($v));
$o1 = substr($v, 0, 1);
if($o1 == '=') {
$v = substr($v, 1, strlen($v));
$o .= $o1;
}
}
else { $o = ''; }
$s = explode("k", $v);
if($s[0] != $v) { $v = $s[0] * 1000; }
$s = explode("M", $v);
if($s[0] != $v) { $v = $s[0] * 1000000; }
$a['size'] .= ' ' . $o . $v;
}
}
$a['sort'] = $data['sort'];
$a['order'] = $data['order'];
return $a;
}
private function get_sphinx_id_list($s = '', $sphx_table = '', $field = '') {
$id_list = '';

View File

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?php print $title; ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php if(SITE_KEYWORDS) { ?><meta name="keywords" content="<?php print SITE_KEYWORDS; ?>" /><?php } ?>
<?php if(SITE_DESCRIPTION) { ?><meta name="description" content="<?php print SITE_DESCRIPTION; ?>" /><?php } ?>
<?php if(PROVIDED_BY) { ?><meta name="author" content="<?php print PROVIDED_BY; ?>" /><?php } ?>
<base href="<?php print SITE_URL; ?>" />
<link href="/view/theme/default/assets/css/metro-bootstrap.css" rel="stylesheet">
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!-- original location: http://html5shim.googlecode.com/svn/trunk/html5.js -->
<!--[if lt IE 9]>
<script src="/view/theme/default/assets/js/html5.js"></script>
<![endif]-->
<!-- Fav and touch icons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/view/theme/default/assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/view/theme/default/assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/view/theme/default/assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="/view/theme/default/assets/ico/apple-touch-icon-57-precomposed.png">
<?php if(BRANDING_FAVICON) { ?><link rel="shortcut icon" href="<?php print BRANDING_FAVICON; ?>" /><?php } ?>
<script type="text/javascript" src="/view/javascript/jquery.min.js"></script>
<script type="text/javascript" src="/view/javascript/jquery-ui-custom.min.js"></script>
<!--script type="text/javascript" src="/view/javascript/rc-splitter.js"></script-->
<script type="text/javascript" src="/view/theme/default/assets/js/bootstrap.js"></script>
<script type="text/javascript" src="/view/javascript/piler.js"></script>
</head>
<body>
<div id="piler1" class="container">
<div class="messageheader">
<p>
<a class="messagelink" href="index.php?route=message/download&amp;id=<?php print $id; ?>"><i class="icon-cloud-download"></i>&nbsp;<?php print $text_download_message; ?></a> |
<?php if(SMARTHOST || ENABLE_IMAP_AUTH == 1) { if(Registry::get('auditor_user') == 1) { ?>
<a class="messagelink" href="#" onclick="$('#restorebox').show();"><i class="icon-reply"></i>&nbsp;<?php print $text_restore_to_mailbox; ?></a> |
<?php } else { ?>
<!--a class="messagelink" href="#" onclick="Piler.restore_message(<?php print $id; ?>);"><i class="icon-reply"></i>&nbsp;<?php print $text_restore_to_mailbox; ?></a--> |
<?php } } ?>
<a class="messagelink" href="#" onclick="Piler.view_headers(<?php print $id; ?>);"><i class="icon-envelope-alt"></i>&nbsp;<?php print $text_view_headers; ?></a>
<?php if($message['has_journal'] == 1 && Registry::get('auditor_user') == 1 && SHOW_ENVELOPE_JOURNAL == 1) { ?>
| <a class="messagelink" href="#" onclick="Piler.view_journal(<?php print $id; ?>);"><i class="icon-envelope-alt"></i>&nbsp;<?php print $text_view_journal_envelope; ?></a>
<?php } ?>
<?php if($spam == 1) { ?>
| <a class="messagelink" href="#" onclick="Piler.not_spam(<?php print $id; ?>);"><i class="icon-exclamation-sign"></i>&nbsp;<?php print $text_not_spam; ?></a>
<?php } ?>
| <a href="#" onclick="Piler.print_div('messageblock');"><i class="icon-print"></i>&nbsp;<?php print $text_print_message; ?></a>
<?php if(ENABLE_ON_THE_FLY_VERIFICATION == 0) {
if ($message['verification'] == 1) { ?><?php print $text_verified_flag; ?> <i class="verified icon-ok-sign icon-large" title="<?php print $text_verified_flag; ?>"></i><?php } else { ?><?php print $text_unverified_flag; ?> <i class="unverified icon-remove-sign icon-large" title="<?php print $text_unverified_flag; ?>"></i><?php }
} ?>
</p>
</div>
<div id="notesbox" class="input-prepend input-append">
<span class="add-on"><i class="icon-file-alt icon-large"></i>&nbsp;<?php print $text_notes; ?>:</span>
<input type="text" size="60" id="note" name="note" class="mynote" value="<?php print preg_replace("/\"/", "&quot;", $message['note']); ?>" />
<input type="button" class="btn btn-info" value="<?php print $text_save; ?>" class="message_button" onclick="Piler.add_note_to_message(<?php print $id; ?>, '<?php print $text_saved; ?>'); " />
</div>
<div id="messageblock">
<div class="messageheader">
<strong><?php if($message['subject'] == "" || $message['subject'] == "Subject:") { print "&lt;" . $text_no_subject . "&gt;"; } else { print $message['subject']; } ?></strong><br />
<strong><?php print $message['from']; ?></strong><br />
<strong><?php print $message['to']; ?></strong><br />
<strong><?php print $message['date']; ?></strong><br />
<?php foreach($attachments as $a) { ?>
<span><i class="attachment icon-paper-clip icon-large" title="Message Attachment"></i>&nbsp;<a href="index.php?route=message/attachment&id=<?php print $a['id']; ?>"><?php print $a['name']; ?></a></span>
<?php } ?><?php if(count($attachments) > 1) { ?>| <a href="index.php?route=message/attachments&id=<?php print $id; ?>"><i class="icon-briefcase"></i></a><?php } ?><br/>
</div>
<div class="messagecontents">
<?php print $message['message']; ?>
</div>
<?php foreach($images as $img) { ?>
<p><img src="<?php print SITE_URL; ?>/tmp/<?php print $img['name']; ?>" alt="" /></p>
<?php } ?>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?php print $title; ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php if(SITE_KEYWORDS) { ?><meta name="keywords" content="<?php print SITE_KEYWORDS; ?>" /><?php } ?>
<?php if(SITE_DESCRIPTION) { ?><meta name="description" content="<?php print SITE_DESCRIPTION; ?>" /><?php } ?>
<?php if(PROVIDED_BY) { ?><meta name="author" content="<?php print PROVIDED_BY; ?>" /><?php } ?>
</head>
<body>
<p style="font-weight: bold; font-size: 18px;"><?php print $text_search_expression; ?>: <?php print $search_expression; ?><br />
<?php print $text_date; ?>: <?php print $a['date1']; ?></p>
<?php if($n > 0) { ?>
<table id="results" class="table table-striped table-condensed">
<thead>
<tr>
<th align="left" id="id-header">&nbsp;</th>
<th align="left" id="date-header">
<?php print $text_date; ?>
</th>
<th align="left" id="from-header">
<?php print $text_from; ?>
</th>
<th align="left" id="to-header">
<?php print $text_to; ?>
</th>
<th align="left" id="subject-header">
<?php print $text_subject; ?>
</th>
<th align="left" id="size-header">
<?php print $text_size; ?>
</th>
<th align="left" id="spam-header"><?php print $text_spam; ?></th>
<th align="left" id="attachment-header"><?php print $text_attachment; ?></th>
</tr>
</thead>
<tbody>
<?php $i=0; foreach ($messages as $message) { ?>
<tr id="e_<?php print $message['id']; ?>" class="resultrow new">
<td id="c2_r<?php print $i; ?>" class="resultcell id"><?php print ($page*$page_len) + $i + 1; ?>.</td>
<td id="c3_r<?php print $i; ?>" class="resultcell date"><?php print $message['date']; ?></td>
<td id="c4_r<?php print $i; ?>" class="resultcell from"><?php if($message['from'] != $message['shortfrom']) { ?><span title="<?php print $message['from']; ?>"><?php print $message['shortfrom']; ?></span><?php } else { print $message['from']; } ?></td>
<td id="c5_r<?php print $i; ?>" class="resultcell to"><?php if($message['to'] != $message['shortto']) { ?><span title="<?php print $message['to']; ?>"><?php print $message['shortto']; ?>&nbsp;<i class=" muted icon-group"></i></span><?php } else { print $message['to']; } ?></td>
<td id="c6_r<?php print $i; ?>" class="resultcell subject"><a href="<?php print SITE_URL; ?>/message.php/a<?php print $message['id']; ?>"><?php print $message['subject']; ?></a></td>
<td id="c7_r<?php print $i; ?>" class="resultcell size"><?php print $message['size']; ?></td>
<td align="center" id="c8_r<?php print $i; ?>" class="resultcell end"><?php if($message['spam'] == 1) { ?>!<?php } else { ?>&nbsp;<?php } ?></td>
<td align="center" id="c9_r<?php print $i; ?>" class="resultcell end"><?php if($message['attachments'] > 0) { ?>+<?php } else { ?>&nbsp;<?php } ?></td>
</tr>
<?php $i++; } ?>
</tbody>
</table>
<?php } else if($n == 0) { ?>
<div class="alert alert-block alert-error lead"><i class="icon-exclamation-sign icon-2x pull-left"></i> <?php print $text_empty_search_result; ?></div>
<?php } ?>
</body>
</html>