<?php
/***************************************
** Filename.......: class.mailaccess_pop3.inc
** Project........: V-webmail
** Last Modified..: $Date: 2006/01/25 00:04:47 $
** CVS Revision...: $Revision: 1.2 $
** Copyright......: 2001-2004 Richard Heyes
***************************************/
require_once($CONFIG['pear_dir'] . 'Net/POP3.php');
class mailaccess_pop3 extends mailaccess{
var $pop3;
var $host;
var $port;
var $type;
var $mbox;
var $user;
var $pass;
/***************************************
** Constructor
***************************************/
function mailaccess_pop3(){
$this->pop3 =& new Net_POP3();
$this->host = '';
$this->port = 110;
$this->type = 'pop3';
$this->mbox = 'INBOX';
$this->user = '';
$this->pass = '';
return TRUE;
}
/***************************************
** Connection function
** Returns TRUE/FALSE
***************************************/
function connect($host, $user, $pass, $port = 110, $type = 'pop3', $mbox = 'INBOX'){
if($this->pop3->connect($host, $port) AND $this->pop3->login($user, $pass)){
$this->host = $host;
$this->port = $port;
$this->type = $type;
$this->mbox = $mbox;
$this->user = $user;
$this->pass = $pass;
return TRUE;
}else{
return FALSE;
}
}
/***************************************
** Reconnects to server. Used for looking
** at mailboxes other than the current.
***************************************/
function reconnect($mbox = 'INBOX'){
// Don't need to actually reconnect.
return ($this->pop3->disconnect() AND $this->pop3->connect($this->host, $this->port) AND $this->pop3->login($this->user, $this->pass));
return TRUE;
}
/***************************************
** Closes a connection
***************************************/
function close(){
return $this->pop3->disconnect();
}
/***************************************
** Returns capabilities
***************************************/
function capabilities($attrib){
switch($attrib){
// Not much supported by this driver :)
default:
return FALSE;
}
}
/***************************************
** Returns structured header information
***************************************/
function headerinfo($msg_id){
global $CONFIG;
require_once($CONFIG['pear_dir'] . 'Mail/RFC822.php');
$headers = $this->pop3->getParsedHeaders($msg_id);
foreach($headers as $key => $value){
$headers[strtolower($key)] = $value;
unset($headers[$key]);
}
// Setup the return object
if(!empty($headers['from'])){
$return->fromaddress = $headers['from'];
$return->from = Mail_RFC822::parseAddressList($headers['from']);
}
if(!empty($headers['to'])){
$return->toaddress = $headers['to'];
$return->to = Mail_RFC822::parseAddressList($headers['to']);
}
if(!empty($headers['cc'])){
$return->ccaddress = $headers['cc'];
$return->cc = Mail_RFC822::parseAddressList($headers['cc']);
}
if(!empty($headers['bcc'])){
$return->bccaddress = $headers['bcc'];
$return->bcc = Mail_RFC822::parseAddressList($headers['bcc']);
}
if(!empty($headers['reply-to'])){
$return->reply_toaddress = $headers['reply-to'];
$return->reply_to = Mail_RFC822::parseAddressList($headers['reply-to']);
}
if(!empty($headers['sender'])){
$return->senderaddress = $headers['sender'];
$return->sender = Mail_RFC822::parseAddressList($headers['sender']);
}
if(!empty($headers['return-path'])){
$return->return_pathaddress = $headers['return-path'];
$return->return_path = Mail_RFC822::parseAddressList($headers['return-path']);
}
$return->date = !empty($headers['date']) ? $headers['date'] : date('r');
$return->Date = $return->date;
$return->subject = !empty($headers['subject']) ? $headers['subject'] : '';
$return->Subject = $return->subject;
$return->message_id = !empty($headers['message-id']) ? $headers['message-id'] : '';
$return->Msgno = $msg_id;
list(,$return->size,) = array_values($this->pop3->getListing($msg_id));
$return->udate = !empty($headers['date']) ? strtotime($headers['date']) : time();
return $return;
}
/***************************************
** Returns messages raw headers, as is.
** Includes a blank line at the end.
***************************************/
function get_raw_headers($msg_id, $partno = NULL){
if(!isset($partno)){
$headers = $this->pop3->getRawHeaders($msg_id);
return $headers ? $headers : FALSE;
}else{
// FIXME ...doh!
$body = imap_fetchbody($this->connection, $msg_id, $partno, FT_UID);
$headers = substr($body, 0, strpos($body, "\r\n\r\n")+4);
return $headers ? $headers : FALSE;
}
}
/***************************************
** Returns the body of a message.
***************************************/
function get_body($msg_id, $partno = NULL, $is_message = FALSE){
if(!isset($partno)){
$body = $this->pop3->getBody($msg_id);
return $body ? $body : FALSE;
}else{
$body = imap_fetchbody($this->connection, $msg_id, $partno, FT_UID);
if($body){
if($is_message)
$body = substr($body, strpos($body, "\r\n\r\n")+4);
return $body;
}else{
return FALSE;
}
}
}
/***************************************
** Returns number of messages
***************************************/
function num_msg(){
return (int)$this->pop3->numMsg();
}
/***************************************
** Marks messages for deletion. $msg_ids
** can be a single msg_id, or a comma
** seperated list of msg_ids.
***************************************/
function delete($msg_ids){
$msg_ids = explode(',', $msg_ids);
foreach($msg_ids as $value){
$this->pop3->delete($value);
}
return TRUE;
}
/***************************************
** Function to *actually* delete the
** messages currently marked for deletion
** Not really implemented in POP3. Messages
** marked for deletion get deleted upon
** closure of the connection.
***************************************/
function expunge(){
return TRUE;
}
/***************************************
** Returns msg_ids based on:
** sorting, asc/desc, start_msg, show_per_page
***************************************/
function get_msg_ids($sort, $ascdesc, $start_msg, $per_page = 0, $search = 'ALL', &$num_msgs){
$num_msgs = $this->pop3->numMsg();
if(0 == $per_page){
$per_page = $num_msgs;
}
switch($sort){
case 'size':
$list = $this->pop3->getListing();
$i = 1;
foreach($list as $value){
$return[$i++] = (int)$value['size'];
}
$return = array_flip($return);
ksort($return);
$return = array_values($return);
$return = $ascdesc ? $return : array_reverse($return);
return array_slice($return, $start_msg - 1, $per_page);
break;
case 'from':
case 'subject':
case 'to':
case 'date':
case 'arrival':
$msg_ids = $ascdesc ? array_reverse(range(1, $num_msgs)) : range(1, $num_msgs);
$msg_ids = array_slice($msg_ids, $start_msg - 1, $per_page);
return $msg_ids;
break;
}
}
/***************************************
** Returns a summary of the message for
** the listing page.
***************************************/
function get_msg_summary($msg_id){
global $LANG, $HOSTINFO;
/***************************************
** Get from cache if it's there
***************************************/
if($data = $this->cache_get($msg_id . ':' . $this->mbox)){
return $data;
}
/***************************************
** Not in the cache :(
***************************************/
$headerinfo = $this->headerinfo($msg_id);
// Any attachments?
$raw_headers = $this->pop3->getRawHeaders($msg_id);
$attachments = (strpos(strtolower($raw_headers), 'content-type: multipart/mixed') !== FALSE) ? lang('attachment_icon') : '';
// Importance header?
$importance = preg_match('/^Importance: High/im', $raw_headers) ? lang('important_icon') : '';
// Determine Size
if($size = $headerinfo->size){
if($size > 1048576) $size = round($size/1048576, 1) . ' Mb';
elseif($size > 1024) $size = round($size/1024 , 1) . ' Kb';
else $size = $size . ' b';
}else{
$size = ' ';
}
// From address
if(isset($headerinfo->from)){
$email = $headerinfo->from[0]->mailbox.'@'.$headerinfo->from[0]->host;
$name = !empty($headerinfo->from[0]->personal) ? decode_header($headerinfo->from[0]->personal) : $email;
}else{
$email = '';
$name = 'Unknown';
}
// To address
if(isset($headerinfo->to)){
$to_email = $headerinfo->to[0]->mailbox.'@'.$headerinfo->to[0]->host;
$to_name = !empty($headerinfo->to[0]->personal) ? decode_header($headerinfo->to[0]->personal) : $email;
}else{
$to_email = '';
$to_name = 'Unknown';
}
// Subject
$subject = (!empty($headerinfo->Subject) AND trim($headerinfo->Subject) != '') ? decode_header($headerinfo->Subject) : lang('[no subject]');
// FIXME Make this max subject length configurable
if(strlen($subject) > 80){
$subject = substr($subject, 0, 80).'...';
}
// Return all the info
$ret = array(
'msg_id' => $msg_id,
'date' => date('H:i jS M Y', $headerinfo->udate),
'email' => htmlspecialchars($email),
'name' => htmlspecialchars($name),
'email_urlsafe' => urlencode(sprintf('%s <%s>', $name, $email)),
'to_email' => htmlspecialchars($to_email),
'to_name' => htmlspecialchars($to_name),
'to_urlsafe' => urlencode(sprintf('%s <%s>', $to_name, $to_email)),
'subject' => htmlspecialchars($subject),
'size' => $size,
'attachments' => $attachments,
'importance' => $importance,
'deleted' => '',
'flagged' => '',
'unread' => FALSE
);
// Cache the summary information
if(@$HOSTINFO['cache_email_list']){
$this->cache_add($msg_id . ':' . $this->mbox, $ret);
}
return $ret;
}
/***************************************
** Clears the cache
***************************************/
function cache_clear(){
global $SESSION;
if(isset($SESSION['cache'])){
unset($SESSION['cache']);
}
}
/***************************************
** Cache add function
***************************************/
function cache_add($uid, $data){
global $SESSION;
$SESSION['cache'][$uid] = $data;
}
/***************************************
** Cache remove function
***************************************/
function cache_remove($uid){
global $SESSION;
if(isset($SESSION['cache'][$uid])){
unset($SESSION['cache'][$uid]);
}
}
/***************************************
** Cache get function
***************************************/
function cache_get($uid){
global $SESSION;
return isset($SESSION['cache'][$uid]) ? $SESSION['cache'][$uid] : FALSE;
}
} // End of class
?>