/', $_html, -1, PREG_SPLIT_OFFSET_CAPTURE);
foreach($quoteParts as $quotePart) {
if($quotePart[1] > 0) {
$indent++;
$indentString .= '>';
}
$quoteParts2 = preg_split('/<\/blockquote>/', $quotePart[0], -1, PREG_SPLIT_OFFSET_CAPTURE);
foreach($quoteParts2 as $quotePart2) {
if($quotePart2[1] > 0) {
$indent--;
$indentString = substr($indentString, 0, $indent);
}
$quoteParts3 = explode("\r\n", $quotePart2[0]);
foreach($quoteParts3 as $quotePart3) {
$allowedLength = 76-strlen("\r\n$indentString");
if (strlen($quotePart3) > $allowedLength) {
$s=explode(" ", $quotePart3);
$quotePart3 = "";
$linecnt = 0;
foreach ($s as $k=>$v) {
$cnt = strlen($v);
// only break long words within the wordboundaries,
if($cnt > $allowedLength) {
$v=wordwrap($v, $allowedLength, "\r\n$indentString", true);
}
// the rest should be broken at the start of the new word that exceeds the limit
if ($linecnt+$cnt > $allowedLength) {
$v="\r\n$indentString$v";
$linecnt = 0;
} else {
$linecnt += $cnt;
}
if (strlen($v)) $quotePart3 .= (strlen($quotePart3) ? " " : "").$v;
}
}
$asciiTextBuff[] = $indentString . $quotePart3 ;
}
}
}
return implode("\r\n",$asciiTextBuff);
}
}
/**
* retrieve a attachment
*
* @param int _uid the uid of the message
* @param string _partID the id of the part, which holds the attachment
* @param int _winmail_nr winmail.dat attachment nr.
*
* @returns array
*/
function getAttachment($_uid, $_partID, $_winmail_nr=0)
{
// parse message structure
$structure = $this->icServer->getStructure($_uid, true);
if($_partID != '') {
$structure = $this->_getSubStructure($structure, $_partID);
}
$filename = self::getFileNameFromStructure($structure);
$attachment = $this->icServer->getBodyPart($_uid, $_partID, true);
switch ($structure->encoding) {
case 'BASE64':
// use imap_base64 to decode
$attachment = imap_base64($attachment);
break;
case 'QUOTED-PRINTABLE':
// use imap_qprint to decode
#$attachment = imap_qprint($attachment);
$attachment = quoted_printable_decode($attachment);
break;
default:
// it is either not encoded or we don't know about it
}
$attachmentData = array(
'type' => $structure->type .'/'. $structure->subType,
'filename' => $filename,
'attachment' => $attachment
);
# if the attachment holds a winmail number and is a winmail.dat then we have to handle that.
if ( $filename == 'winmail.dat' && $_winmail_nr > 0 &&
( $wmattach = $this->decode_winmail( $_uid, $_partID, $_winmail_nr ) ) )
{
$attachmentData = array(
'type' => $wmattach['type'],
'filename' => $wmattach['name'],
'attachment' => $wmattach['attachment'],
);
}
return $attachmentData;
}
// this function is based on a on "Building A PHP-Based Mail Client"
// http://www.devshed.com
// fetch a specific attachment from a message
function getAttachmentByCID($_uid, $_cid, $_part)
{
$partID = false;
#error_log("getAttachmentByCID:$_uid, $_cid, $_part");
$attachments = $this->getMessageAttachments($_uid, $_part);
foreach($attachments as $attachment) {
#error_log(print_r($attachment,true));
if(strpos($attachment['cid'], $_cid) !== false || strpos($cid, $attachment['cid']) !== false) {
$partID = $attachment['partID'];
break;
}
}
#error_log( "PARTID:$_cid $partID
"); #exit;
if($partID == false) {
return false;
}
// parse message structure
$structure = $this->icServer->getStructure($_uid, true);
$structure = $this->_getSubStructure($structure, $partID);
$filename = self::getFileNameFromStructure($structure);
$attachment = $this->icServer->getBodyPart($_uid, $partID, true);
switch ($structure->encoding) {
case 'BASE64':
// use imap_base64 to decode
$attachment = imap_base64($attachment);
break;
case 'QUOTED-PRINTABLE':
// use imap_qprint to decode
#$attachment = imap_qprint($attachment);
$attachment = quoted_printable_decode($attachment);
break;
default:
// it is either not encoded or we don't know about it
}
$attachmentData = array(
'type' => $structure->type .'/'. $structure->subType,
'filename' => $filename,
'attachment' => $attachment
);
return $attachmentData;
}
function getEMailProfile()
{
$config =& CreateObject('phpgwapi.config','felamimail');
$config->read_repository();
$felamimailConfig = $config->config_data;
#_debug_array($felamimailConfig);
if(!isset($felamimailConfig['profileID'])){
return -1;
} else {
return intval($felamimailConfig['profileID']);
}
}
function getErrorMessage()
{
return $this->icServer->_connectionErrorObject->message;
}
/**
* get IMAP folder status
*
* returns an array information about the imap folder
*
* @param _folderName string the foldername
*
* @returns array
*/
function getFolderStatus($_folderName)
{
$retValue = array();
$retValue['subscribed'] = false;
if(!$icServer = $this->mailPreferences->getIncomingServer(0)) {
return false;
}
// does the folder exist???
$folderInfo = $this->icServer->getMailboxes('', $_folderName, true);
if(is_a($folderInfo, 'PEAR_Error') || !is_array($folderInfo[0])) {
if (self::$debug) error_log(__METHOD__." returned Info for folder $_folderName:".print_r($folderInfo->message,true));
return false;
}
#if(!is_array($folderInfo[0])) {
# return false;
#}
$subscribedFolders = $this->icServer->listsubscribedMailboxes('', $_folderName);
if(is_array($subscribedFolders) && count($subscribedFolders) == 1) {
$retValue['subscribed'] = true;
}
$retValue['delimiter'] = $folderInfo[0]['HIERACHY_DELIMITER'];
$retValue['attributes'] = $folderInfo[0]['ATTRIBUTES'];
$shortNameParts = explode($retValue['delimiter'], $_folderName);
$retValue['shortName'] = array_pop($shortNameParts);
$retValue['displayName'] = $this->encodeFolderName($_folderName);
$retValue['shortDisplayName'] = $this->encodeFolderName($retValue['shortName']);
if(strtoupper($retValue['shortName']) == 'INBOX') {
$retValue['displayName'] = lang('INBOX');
$retValue['shortDisplayName'] = lang('INBOX');
}
// translate the automatic Folders (Sent, Drafts, ...) like the INBOX
elseif (in_array($retValue['shortName'],$this->autoFolders))
{
$retValue['displayName'] = $retValue['shortDisplayName'] = lang($retValue['shortName']);
}
if ( PEAR::isError($folderStatus = $this->icServer->getStatus($_folderName)) ) {
/*if ($folderStatus = $this->bofelamimail->getMailBoxCounters($_folderName)) {
$retValue['messages'] = $folderStatus->messages;
$retValue['recent'] = $folderStatus->recent;
$retValue['uidnext'] = $folderStatus->uidnext;
$retValue['unseen'] = $folderStatus->unseen;
$retValue['uidvalidity']= $folderStatus->uidvalidity;
*/
//_debug_array($folderStatus);
if (self::$debug) error_log(__METHOD__." returned folderStatus for Folder $_folderName:".print_r($folderStatus->message,true));
} else {
$retValue['messages'] = $folderStatus['MESSAGES'];
$retValue['recent'] = $folderStatus['RECENT'];
$retValue['uidnext'] = $folderStatus['UIDNEXT'];
$retValue['uidvalidity'] = $folderStatus['UIDVALIDITY'];
$retValue['unseen'] = $folderStatus['UNSEEN'];
}
return $retValue;
}
/**
* get IMAP folder objects
*
* returns an array of IMAP folder objects. Put INBOX folder in first
* position. Preserves the folder seperator for later use. The returned
* array is indexed using the foldername.
*
* @param _subscribedOnly boolean get subscribed or all folders
* @param _getCounters boolean get get messages counters
*
* @returns array with folder objects. eg.: INBOX => {inbox object}
*/
function getFolderObjects($_subscribedOnly=false, $_getCounters=false)
{
$isUWIMAP = false;
$delimiter = $this->getHierarchyDelimiter();
$inboxData = new stdClass;
$inboxData->name = 'INBOX';
$inboxData->folderName = 'INBOX';
$inboxData->displayName = lang('INBOX');
$inboxData->delimiter = $delimiter;
$inboxData->shortFolderName = 'INBOX';
$inboxData->shortDisplayName = lang('INBOX');
$inboxData->subscribed = true;
if($_getCounters == true) {
/*
$folderStatus = $this->icServer->getStatus('INBOX');
$status = new stdClass;
$status->messages = $folderStatus['MESSAGES'];
$status->unseen = $folderStatus['UNSEEN'];
$status->recent = $folderStatus['RECENT'];
$inboxData->counter = $status;
*/
$inboxData->counter = self::getMailBoxCounters('INBOX');
}
#$inboxData->attributes = 64;
$folders = array('INBOX' => $inboxData);
#_debug_array($folders);
$nameSpace = $this->icServer->getNameSpaces();
#_debug_array($nameSpace);
#_debug_array($delimiter);
if(isset($nameSpace['#mh/'])) {
// removed the uwimap code
// but we need to reintroduce him later
// uw imap does not return the attribute of a folder, when requesting subscribed folders only
// dovecot has the same problem too
} else {
if (is_array($nameSpace)) {
foreach($nameSpace as $type => $singleNameSpace) {
if($type == 'personal' && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && $this->icServer->mailboxExist('Mail')) {
// uw-imap server with mailbox prefix or dovecot maybe
$foldersNameSpace[$type]['prefix'] = 'Mail';
} elseif($type == 'personal' && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && $this->icServer->mailboxExist('mail')) {
// uw-imap server with mailbox prefix or dovecot maybe
$foldersNameSpace[$type]['prefix'] = 'mail';
} else {
$foldersNameSpace[$type]['prefix'] = $singleNameSpace[0]['name'];
}
#echo "############## ".print_r($singleNameSpace,true)." ###################
";
$foldersNameSpace[$type]['delimiter'] = $delimiter;
if(is_array($singleNameSpace[0])) {
// fetch and sort the subscribed folders
$subscribedMailboxes = $this->icServer->listsubscribedMailboxes($foldersNameSpace[$type]['prefix']);
if (empty($subscribedMailboxes) && $type == 'shared') $subscribedMailboxes = $this->icServer->listsubscribedMailboxes('',0);
#echo "subscribedMailboxes";_debug_array($subscribedMailboxes);
if( PEAR::isError($subscribedMailboxes) ) {
continue;
}
$foldersNameSpace[$type]['subscribed'] = $subscribedMailboxes;
if (is_array($foldersNameSpace[$type]['subscribed'])) sort($foldersNameSpace[$type]['subscribed']);
#_debug_array($foldersNameSpace);
if ($_subscribedOnly == true) {
$foldersNameSpace[$type]['all'] = (is_array($foldersNameSpace[$type]['subscribed']) ? $foldersNameSpace[$type]['subscribed'] :array());
continue;
}
// only check for Folder in FolderMaintenance for Performance Reasons
if(!$_subscribedOnly) {
foreach ((array)$foldersNameSpace[$type]['subscribed'] as $folderName)
{
//echo __METHOD__."Checking $folderName for existence
";
if (!self::folderExists($folderName)) {
echo("eMail Folder $folderName failed to exist; should be unsubscribed; Trying ...");
error_log(__METHOD__."-> $folderName failed to be here; should be unsubscribed");
if (self::subscribe($folderName, false))
{
echo " success."."
" ;
} else {
echo " failed."."
";
}
}
}
}
// fetch and sort all folders
#echo $type.'->'.$foldersNameSpace[$type]['prefix'].'->'.($type=='shared'?0:2)."
";
$allMailboxesExt = $this->icServer->getMailboxes($foldersNameSpace[$type]['prefix'],2,true);
if (empty($allMailboxesExt) && $type == 'shared') $allMailboxesExt = $this->icServer->getMailboxes('',0,true);
if( PEAR::isError($allMailboxesExt) ) {
#echo __METHOD__;_debug_array($allMailboxesExt);
continue;
}
foreach ($allMailboxesExt as $mbx) {
#echo __METHOD__;_debug_array($mbx);
$allMailBoxesExtSorted[$mbx['MAILBOX']] = $mbx;
}
if (is_array($allMailBoxesExtSorted)) ksort($allMailBoxesExtSorted);
#_debug_array($allMailBoxesExtSorted);
$allMailboxes = array();
foreach ((array)$allMailBoxesExtSorted as $mbx) {
#echo $mbx['MAILBOX']."
";
if (in_array('\HasChildren',$mbx["ATTRIBUTES"]) || in_array('\Haschildren',$mbx["ATTRIBUTES"])) {
unset($buff);
//$buff = $this->icServer->getMailboxes($mbx['MAILBOX'].$delimiter,0,false);
if (!in_array($mbx['MAILBOX'],$allMailboxes)) $buff = self::getMailBoxesRecursive($mbx['MAILBOX'],$delimiter,$foldersNameSpace[$type]['prefix'],1);
if( PEAR::isError($buff) ) {
continue;
}
#_debug_array($buff);
if (is_array($buff)) $allMailboxes = array_merge($allMailboxes,$buff);
}
if (!in_array($mbx['MAILBOX'],$allMailboxes)) $allMailboxes[] = $mbx['MAILBOX'];
#echo "Result:";_debug_array($allMailboxes);
}
$foldersNameSpace[$type]['all'] = $allMailboxes;
if (is_array($foldersNameSpace[$type]['all'])) sort($foldersNameSpace[$type]['all']);
}
}
}
// check for autocreated folders
if(isset($foldersNameSpace['personal']['prefix'])) {
$personalPrefix = $foldersNameSpace['personal']['prefix'];
$personalDelimiter = $foldersNameSpace['personal']['delimiter'];
if(!empty($personalPrefix)) {
if(substr($personalPrefix, -1) != $personalDelimiter) {
$folderPrefix = $personalPrefix . $personalDelimiter;
} else {
$folderPrefix = $personalPrefix;
}
}
if ($this->mailPreferences->preferences['notavailableautofolders'] && !empty($this->mailPreferences->preferences['notavailableautofolders']))
{
$foldersToCheck = array_diff($this->autoFolders,explode(',',$this->mailPreferences->preferences['notavailableautofolders']));
} else {
$foldersToCheck = $this->autoFolders;
}
#echo "foldersToCheck:";_debug_array($foldersToCheck);
foreach($foldersToCheck as $personalFolderName) {
$folderName = (!empty($personalPrefix)) ? $folderPrefix.$personalFolderName : $personalFolderName;
if(!is_array($foldersNameSpace['personal']['all']) || !in_array($folderName, $foldersNameSpace['personal']['all'])) {
$createfolder = true;
switch($folderName)
{
case 'Drafts': // => Entwürfe
if ($this->mailPreferences->preferences['draftFolder'] && $this->mailPreferences->preferences['draftFolder']=='none')
$createfolder=false;
break;
case 'Junk': //] => Spammails
if ($this->mailPreferences->preferences['junkFolder'] && $this->mailPreferences->preferences['junkFolder']=='none')
$createfolder=false;
break;
case 'Sent': //] => Gesendet
if ($this->mailPreferences->preferences['sentFolder'] && $this->mailPreferences->preferences['sentFolder']=='none')
$createfolder=false;
break;
case 'Trash': //] => Papierkorb
if ($this->mailPreferences->preferences['trashFolder'] && $this->mailPreferences->preferences['trashFolder']=='none')
$createfolder=false;
break;
case 'Templates': //] => Vorlagen
if ($this->mailPreferences->preferences['templateFolder'] && $this->mailPreferences->preferences['templateFolder']=='none')
$createfolder=false;
break;
}
if($createfolder === true && $this->createFolder('', $folderName, true)) {
$foldersNameSpace['personal']['all'][] = $folderName;
$foldersNameSpace['personal']['subscribed'][] = $folderName;
} else {
#print "FOLDERNAME failed: $folderName
";
}
}
}
}
}
#echo "
FolderNameSpace To Process:";_debug_array($foldersNameSpace);
foreach( array('personal', 'others', 'shared') as $type) {
if(isset($foldersNameSpace[$type])) {
if($_subscribedOnly) {
if( !PEAR::isError($foldersNameSpace[$type]['subscribed']) ) $listOfFolders = $foldersNameSpace[$type]['subscribed'];
} else {
if( !PEAR::isError($foldersNameSpace[$type]['all'])) $listOfFolders = $foldersNameSpace[$type]['all'];
}
foreach((array)$listOfFolders as $folderName) {
//echo "
FolderToCheck:$folderName
";
if($_subscribedOnly && !in_array($folderName, $foldersNameSpace[$type]['all'])) {
#echo "$folderName failed to be here
";
continue;
}
$folderParts = explode($delimiter, $folderName);
$shortName = array_pop($folderParts);
$folderObject = new stdClass;
$folderObject->delimiter = $delimiter;
$folderObject->folderName = $folderName;
$folderObject->shortFolderName = $shortName;
if(!$_subscribedOnly) {
#echo $folderName."->".$type."
";
#_debug_array($foldersNameSpace[$type]['subscribed']);
$folderObject->subscribed = in_array($folderName, $foldersNameSpace[$type]['subscribed']);
}
if($_getCounters == true) {
/*
$folderStatus = $this->icServer->getStatus($folderName);
#echo "
FolderStatus:";_debug_array($folderStatus);
if(is_array($folderStatus)) {
$status = new stdClass;
$status->messages = $folderStatus['MESSAGES'];
$status->unseen = $folderStatus['UNSEEN'];
$status->recent = $folderStatus['RECENT'];
$folderObject->counter = $status;
}
*/
$folderObject->counter = $this->bofelamimail->getMailBoxCounters($folderName);
}
if(strtoupper($folderName) == 'INBOX') {
$folderName = 'INBOX';
$folderObject->folderName = 'INBOX';
$folderObject->shortFolderName = 'INBOX';
$folderObject->displayName = lang('INBOX');
$folderObject->shortDisplayName = lang('INBOX');
$folderObject->subscribed = true;
// translate the automatic Folders (Sent, Drafts, ...) like the INBOX
} elseif (in_array($shortName,$this->autoFolders)) {
$folderObject->displayName = $folderObject->shortDisplayName = lang($shortName);
} else {
$folderObject->displayName = $this->encodeFolderName($folderObject->folderName);
$folderObject->shortDisplayName = $this->encodeFolderName($shortName);
}
$folderName = $folderName;
$folders[$folderName] = $folderObject;
}
}
}
#_debug_array($folders); #exit;
return $folders;
}
function getMailBoxCounters($folderName)
{
$folderStatus = $this->icServer->getStatus($folderName);
#echo "
FolderStatus:";_debug_array($folderStatus);
if ( PEAR::isError($folderStatus)) {
if (self::$debug) error_log(__METHOD__." returned FolderStatus for Folder $folderName:".print_r($folderStatus->message,true));
return false;
}
if(is_array($folderStatus)) {
$status = new stdClass;
$status->messages = $folderStatus['MESSAGES'];
$status->unseen = $folderStatus['UNSEEN'];
$status->recent = $folderStatus['RECENT'];
$status->uidnext = $folderStatus['UIDNEXT'];
$status->uidvalidity = $folderStatus['UIDVALIDITY'];
return $status;
}
return false;
}
function getMailBoxesRecursive($_mailbox, $delimiter, $prefix, $reclevel=0)
{
#echo __METHOD__." retrieve SubFolders for $_mailbox$delimiter
";
$maxreclevel=25;
if ($reclevel > $maxreclevel) {
error_log( __METHOD__." Recursion Level Exeeded ($reclevel) while looking up $_mailbox$delimiter ");
return array();
}
$reclevel++;
// clean up douple delimiters
$_mailbox = preg_replace('~'.($delimiter == '.' ? "\\".$delimiter:$delimiter).'+~s',$delimiter,$_mailbox);
//get that mailbox in question
$mbx = $this->icServer->getMailboxes($_mailbox,1,true);
#_debug_array($mbx);
if (is_array($mbx[0]["ATTRIBUTES"]) && (in_array('\HasChildren',$mbx[0]["ATTRIBUTES"]) || in_array('\Haschildren',$mbx[0]["ATTRIBUTES"]))) {
// if there are children fetch them
#echo $mbx[0]['MAILBOX']."
";
unset($buff);
$buff = $this->icServer->getMailboxes($mbx[0]['MAILBOX'].($mbx[0]['MAILBOX'] == $prefix ? '':$delimiter),2,false);
//$buff = $this->icServer->getMailboxes($mbx[0]['MAILBOX'],2,false);
#_debug_array($buff);
if( PEAR::isError($buff) ) {
if (self::$debug) error_log(__METHOD__." Error while retrieving Mailboxes for:".$mbx[0]['MAILBOX'].$delimiter.".");
return array();
} else {
$allMailboxes = array();
foreach ($buff as $mbxname) {
$mbxname = preg_replace('~'.($delimiter == '.' ? "\\".$delimiter:$delimiter).'+~s',$delimiter,$mbxname);
#echo "About to recur in level $reclevel:".$mbxname."
";
if ( $mbxname != $mbx[0]['MAILBOX'] && $mbxname != $prefix) $allMailboxes = array_merge($allMailboxes, self::getMailBoxesRecursive($mbxname, $delimiter, $prefix, $reclevel));
}
if (!(in_array('\NoSelect',$mbx[0]["ATTRIBUTES"]) || in_array('\Noselect',$mbx[0]["ATTRIBUTES"]))) $allMailboxes[] = $mbx[0]['MAILBOX'];
return $allMailboxes;
}
} else {
return array($_mailbox);
}
}
function getMimePartCharset($_mimePartObject)
{
$charSet = 'iso-8859-1';
if(is_array($_mimePartObject->parameters)) {
if(isset($_mimePartObject->parameters['CHARSET'])) {
$charSet = $_mimePartObject->parameters['CHARSET'];
}
}
return $charSet;
}
function getMultipartAlternative($_uid, $_structure, $_htmlMode)
{
// a multipart/alternative has exactly 2 parts (text and html OR text and something else)
$partText = false;
$partHTML = false;
foreach($_structure as $mimePart) {
if($mimePart->type == 'TEXT' && $mimePart->subType == 'PLAIN' && $mimePart->bytes > 0) {
$partText = $mimePart;
} elseif($mimePart->type == 'TEXT' && $mimePart->subType == 'HTML' && $mimePart->bytes > 0) {
$partHTML = $mimePart;
} elseif ($mimePart->type == 'MULTIPART' && $mimePart->subType == 'RELATED' && is_array($mimePart->subParts)) {
// in a multipart alternative we treat the multipart/related as html part
#$partHTML = array($mimePart);
error_log(__METHOD__." process MULTIPART/RELATED with array as subparts");
$partHTML = $mimePart;
}
}
switch($_htmlMode) {
case 'always_display':
if(is_object($partHTML)) {
if($partHTML->subType == 'RELATED') {
return $this->getMultipartRelated($_uid, $partHTML, 'always_display');
} else {
return $this->getTextPart($_uid, $partHTML, 'always_display');
}
} elseif(is_object($partText)) {
return $this->getTextPart($_uid, $partText);
}
break;
case 'only_if_no_text':
if(is_object($partText)) {
return $this->getTextPart($_uid, $partText);
} elseif(is_object($partHTML)) {
if($partHTML->type) {
return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode);
} else {
return $this->getTextPart($_uid, $partHTML, 'always_display');
}
}
break;
default:
if(is_object($partText)) {
return $this->getTextPart($_uid, $partText);
} else {
$bodyPart = array(
'body' => lang("no plain text part found"),
'mimeType' => 'text/plain',
'charSet' => self::$displayCharset,
);
}
break;
}
return $bodyPart;
}
function getMultipartMixed($_uid, $_structure, $_htmlMode)
{
if (self::$debug) echo __METHOD__."$_uid, $_htmlMode
";
$bodyPart = array();
if (self::$debug) _debug_array($_structure);
if (!is_array($_structure)) $_structure = array($_structure);
foreach($_structure as $part) {
if (self::$debug) echo $part->type."/".$part->subType."
";
switch($part->type) {
case 'MULTIPART':
switch($part->subType) {
case 'ALTERNATIVE':
$bodyPart[] = $this->getMultipartAlternative($_uid, $part->subParts, $_htmlMode);
break;
case 'MIXED':
case 'SIGNED':
$bodyPart = array_merge($bodyPart, $this->getMultipartMixed($_uid, $part->subParts, $_htmlMode));
break;
case 'RELATED':
$bodyPart = array_merge($bodyPart, $this->getMultipartRelated($_uid, $part->subParts, $_htmlMode));
break;
}
break;
case 'TEXT':
switch($part->subType) {
case 'PLAIN':
case 'HTML':
if($part->disposition != 'ATTACHMENT') {
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode);
}
break;
}
break;
case 'MESSAGE':
if($part->subType == 'delivery-status') {
$bodyPart[] = $this->getTextPart($_uid, $part);
}
break;
default:
// do nothing
// the part is a attachment
#$bodyPart[] = $this->getMessageBody($_uid, $_htmlMode, $part->partID, $part);
#if (!($part->type == 'TEXT' && ($part->subType == 'PLAIN' || $part->subType == 'HTML'))) {
# $bodyPart[] = $this->getMessageAttachments($_uid, $part->partID, $part);
#}
}
}
return $bodyPart;
}
function getMultipartRelated($_uid, $_structure, $_htmlMode)
{
return $this->getMultipartMixed($_uid, $_structure, $_htmlMode);
}
function getTextPart($_uid, $_structure, $_htmlMode = '')
{
$bodyPart = array();
#_debug_array($_structure);
$partID = $_structure->partID;
$mimePartBody = $this->icServer->getBodyPart($_uid, $partID, true);
#_debug_array($mimePartBody);
#_debug_array(preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding)));
if($_structure->subType == 'HTML' && $_htmlMode != 'always_display' && $_htmlMode != 'only_if_no_text') {
$bodyPart = array(
'body' => lang("displaying html messages is disabled"),
'mimeType' => 'text/html',
'charSet' => self::$displayCharset,
);
} else {
// some Servers append PropertyFile___ ; strip that here for display
$bodyPart = array(
'body' => preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding, $this->getMimePartCharset($_structure))),
'mimeType' => ($_structure->type == 'TEXT' && $_structure->subType == 'HTML') ? 'text/html' : 'text/plain',
'charSet' => $this->getMimePartCharset($_structure),
);
}
return $bodyPart;
}
function getNameSpace($_icServer)
{
$this->icServer->getNameSpaces();
}
function getHierarchyDelimiter()
{
$HierarchyDelimiter = $this->icServer->getHierarchyDelimiter();
if (PEAR::isError($HierarchyDelimiter)) $HierarchyDelimiter = '/';
return $HierarchyDelimiter;
}
/**
* fetches a sorted list of messages from the imap server
* private function
*
* @todo implement sort based on Net_IMAP
* @param string $_folderName the name of the folder in which the messages get searched
* @param integer $_sort the primary sort key
* @param bool $_reverse sort the messages ascending or descending
* @param array $_filter the search filter
* @return bool
*/
function getSortedList($_folderName, $_sort, $_reverse, $_filter)
{
if(PEAR::isError($folderStatus = $this->icServer->examineMailbox($_folderName))) {
return false;
}
if(is_array($this->sessionData['folderStatus'][0][$_folderName]) &&
$this->sessionData['folderStatus'][0][$_folderName]['uidValidity'] === $folderStatus['UIDVALIDITY'] &&
$this->sessionData['folderStatus'][0][$_folderName]['messages'] === $folderStatus['EXISTS'] &&
$this->sessionData['folderStatus'][0][$_folderName]['uidnext'] === $folderStatus['UIDNEXT'] &&
$this->sessionData['folderStatus'][0][$_folderName]['filter'] === $_filter &&
$this->sessionData['folderStatus'][0][$_folderName]['sort'] === $_sort
) {
#error_log("USE CACHE");
$sortResult = $this->sessionData['folderStatus'][0][$_folderName]['sortResult'];
} else {
#error_log("USE NO CACHE");
$filter = $this->createIMAPFilter($_folderName, $_filter);
if($this->icServer->hasCapability('SORT')) {
$sortOrder = $this->_getSortString($_sort);
if (!empty(self::$displayCharset)) {
$sortResult = $this->icServer->sort($sortOrder, strtoupper( self::$displayCharset ), $filter, true);
}
if (PEAR::isError($sortResult) || empty(self::$displayCharset)) {
$sortResult = $this->icServer->sort($sortOrder, 'US-ASCII', $filter, true);
}
} else {
$advFilter = 'CHARSET '. strtoupper(self::$displayCharset) .' '.$filter;
$sortResult = $this->icServer->search($advFilter, true);
if (PEAR::isError($sortResult)) $sortResult = $this->icServer->search($filter, true);
if(is_array($sortResult)) {
sort($sortResult, SORT_NUMERIC);
}
}
$this->sessionData['folderStatus'][0][$_folderName]['uidValidity'] = $folderStatus['UIDVALIDITY'];
$this->sessionData['folderStatus'][0][$_folderName]['messages'] = $folderStatus['EXISTS'];
$this->sessionData['folderStatus'][0][$_folderName]['uidnext'] = $folderStatus['UIDNEXT'];
$this->sessionData['folderStatus'][0][$_folderName]['filter'] = $_filter;
$this->sessionData['folderStatus'][0][$_folderName]['sortResult'] = $sortResult;
$this->sessionData['folderStatus'][0][$_folderName]['sort'] = $_sort;
}
$this->sessionData['folderStatus'][0][$_folderName]['reverse'] = $_reverse;
$this->saveSessionData();
return $sortResult;
}
function getMessageEnvelope($_uid, $_partID = '')
{
if($_partID == '') {
if( PEAR::isError($envelope = $this->icServer->getEnvelope('', $_uid, true)) ) {
return false;
}
return $envelope[0];
} else {
if( PEAR::isError($headers = $this->icServer->getParsedHeaders($_uid, true, $_partID, true)) ) {
return false;
}
#_debug_array($headers);
$newData = array(
'DATE' => $headers['DATE'],
'SUBJECT' => $headers['SUBJECT'],
'MESSAGE_ID' => $headers['MESSAGE-ID']
);
$recepientList = array('FROM', 'TO', 'CC', 'BCC', 'SENDER', 'REPLY_TO');
foreach($recepientList as $recepientType) {
if(isset($headers[$recepientType])) {
$addresses = imap_rfc822_parse_adrlist($headers[$recepientType], '');
foreach($addresses as $singleAddress) {
$addressData = array(
'PERSONAL_NAME' => $singleAddress->personal ? $singleAddress->personal : 'NIL',
'AT_DOMAIN_LIST' => $singleAddress->adl ? $singleAddress->adl : 'NIL',
'MAILBOX_NAME' => $singleAddress->mailbox ? $singleAddress->mailbox : 'NIL',
'HOST_NAME' => $singleAddress->host ? $singleAddress->host : 'NIL',
'EMAIL' => $singleAddress->host ? $singleAddress->mailbox.'@'.$singleAddress->host : $singleAddress->mailbox,
);
if($addressData['PERSONAL_NAME'] != 'NIL') {
$addressData['RFC822_EMAIL'] = imap_rfc822_write_address($singleAddress->mailbox, $singleAddress->host, $singleAddress->personal);
} else {
$addressData['RFC822_EMAIL'] = 'NIL';
}
$newData[$recepientType][] = $addressData;
}
} else {
if($recepientType == 'SENDER' || $recepientType == 'REPLY_TO') {
$newData[$recepientType] = $newData['FROM'];
} else {
$newData[$recepientType] = array();
}
}
}
#_debug_array($newData);
return $newData;
}
}
function getHeaders($_folderName, $_startMessage, $_numberOfMessages, $_sort, $_reverse, $_filter)
{
$reverse = (bool)$_reverse;
// get the list of messages to fetch
$this->reopen($_folderName);
//$this->icServer->selectMailbox($_folderName);
#print "";
#$this->icServer->setDebug(true);
$sortResult = $this->getSortedList($_folderName, $_sort, $_reverse, $_filter);
#$this->icServer->setDebug(false);
#print "
";
// nothing found
if(!is_array($sortResult) || empty($sortResult)) {
$retValue = array();
$retValue['info']['total'] = 0;
$retValue['info']['first'] = 0;
$retValue['info']['last'] = 0;
return $retValue;
}
$total = count($sortResult);
#_debug_array($sortResult);
#_debug_array(array_slice($sortResult, -5, -2));
#error_log("REVERSE: $reverse");
if($reverse === true) {
$startMessage = $_startMessage-1;
if($startMessage > 0) {
$sortResult = array_slice($sortResult, -($_numberOfMessages+$startMessage), -$startMessage);
} else {
$sortResult = array_slice($sortResult, -($_numberOfMessages+($_startMessage-1)));
}
$sortResult = array_reverse($sortResult);
} else {
$sortResult = array_slice($sortResult, $_startMessage-1, $_numberOfMessages);
}
$queryString = implode(',', $sortResult);
// fetch the data for the selected messages
$headersNew = $this->icServer->getSummary($queryString, true);
$count = 0;
foreach((array)$sortResult as $uid) {
$sortOrder[$uid] = $count++;
}
$count = 0;
if (is_array($headersNew)) {
foreach((array)$headersNew as $headerObject) {
#if($count == 0) _debug_array($headerObject);
if (empty($headerObject['UID'])) continue;
$uid = $headerObject['UID'];
// make dates like "Mon, 23 Apr 2007 10:11:06 UT" working with strtotime
if(substr($headerObject['DATE'],-2) === 'UT') {
$headerObject['DATE'] .= 'C';
}
$retValue['header'][$sortOrder[$uid]]['subject'] = $this->decode_subject($headerObject['SUBJECT']);
$retValue['header'][$sortOrder[$uid]]['size'] = $headerObject['SIZE'];
$retValue['header'][$sortOrder[$uid]]['date'] = strtotime($headerObject['DATE']);
$retValue['header'][$sortOrder[$uid]]['mimetype'] = $headerObject['MIMETYPE'];
$retValue['header'][$sortOrder[$uid]]['id'] = $headerObject['MSG_NUM'];
$retValue['header'][$sortOrder[$uid]]['uid'] = $headerObject['UID'];
$retValue['header'][$sortOrder[$uid]]['priority'] = ($headerObject['PRIORITY']?$headerObject['PRIORITY']:3);
if (is_array($headerObject['FLAGS'])) {
$retValue['header'][$sortOrder[$uid]]['recent'] = in_array('\\Recent', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['flagged'] = in_array('\\Flagged', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['answered'] = in_array('\\Answered', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['forwarded'] = in_array('$Forwarded', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['deleted'] = in_array('\\Deleted', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['seen'] = in_array('\\Seen', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['draft'] = in_array('\\Draft', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['mdnsent'] = in_array('MDNSent', $headerObject['FLAGS']);
$retValue['header'][$sortOrder[$uid]]['mdnnotsent'] = in_array('MDNnotSent', $headerObject['FLAGS']);
}
if(is_array($headerObject['FROM']) && is_array($headerObject['FROM'][0])) {
if($headerObject['FROM'][0]['HOST_NAME'] != 'NIL') {
$retValue['header'][$sortOrder[$uid]]['sender_address'] = $headerObject['FROM'][0]['EMAIL'];
} else {
$retValue['header'][$sortOrder[$uid]]['sender_address'] = $headerObject['FROM'][0]['MAILBOX_NAME'];
}
if($headerObject['FROM'][0]['PERSONAL_NAME'] != 'NIL') {
$retValue['header'][$sortOrder[$uid]]['sender_name'] = $this->decode_header($headerObject['FROM'][0]['PERSONAL_NAME']);
}
}
if(is_array($headerObject['TO']) && is_array($headerObject['TO'][0])) {
if($headerObject['TO'][0]['HOST_NAME'] != 'NIL') {
$retValue['header'][$sortOrder[$uid]]['to_address'] = $headerObject['TO'][0]['EMAIL'];
} else {
$retValue['header'][$sortOrder[$uid]]['to_address'] = $headerObject['TO'][0]['MAILBOX_NAME'];
}
if($headerObject['TO'][0]['PERSONAL_NAME'] != 'NIL') {
$retValue['header'][$sortOrder[$uid]]['to_name'] = $this->decode_header($headerObject['TO'][0]['PERSONAL_NAME']);
}
}
$count++;
}
// sort the messages to the requested displayorder
if(is_array($retValue['header'])) {
ksort($retValue['header']);
$retValue['info']['total'] = $total;
$retValue['info']['first'] = $_startMessage;
$retValue['info']['last'] = $_startMessage + $count - 1 ;
return $retValue;
} else {
$retValue = array();
$retValue['info']['total'] = 0;
$retValue['info']['first'] = 0;
$retValue['info']['last'] = 0;
return $retValue;
}
} else {
error_log("bofelamimail::getHeaders -> retrieval of Message Details failed: ".print_r($headersNew,TRUE));
$retValue = array();
$retValue['info']['total'] = 0;
$retValue['info']['first'] = 0;
$retValue['info']['last'] = 0;
return $retValue;
}
}
function getNextMessage($_foldername, $_id)
{
#_debug_array($this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult']);
#_debug_array($this->sessionData['folderStatus'][$this->profileID]);
#print "ID: $_id
";
$position=false;
if (is_array($this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'])) {
$position = array_search($_id, $this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult']);
}
#print "POS: $position
";
if($position !== false) {
$retValue = array();
if($this->sessionData['folderStatus'][$this->profileID][$_foldername]['reverse'] == true) {
#print "is reverse
";
if(isset($this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position-1])) {
$retValue['next'] = $this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position-1];
}
if(isset($this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position+1])) {
$retValue['previous'] = $this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position+1];
}
} else {
#print "is not reverse";
if(isset($this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position-1])) {
$retValue['previous'] = $this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position-1];
}
if(isset($this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position+1])) {
$retValue['next'] = $this->sessionData['folderStatus'][$this->profileID][$_foldername]['sortResult'][$position+1];
}
}
return $retValue;
}
return false;
}
function getIMAPACL($_folderName, $user='')
{
if(($this->hasCapability('ACL'))) {
if ( PEAR::isError($acl = $this->icServer->getACL($_folderName)) ) {
return false;
}
if ($user=='') {
return $acl;
}
foreach ($acl as $i => $userACL) {
if ($userACL['USER'] == $user) {
return $userACL['RIGHTS'];
}
}
return '';
}
return false;
}
/**
* checks if the imap server supports a given capability
*
* @param string $_capability the name of the capability to check for
* @return bool
*/
function hasCapability($_capability)
{
return $this->icServer->hasCapability(strtoupper($_capability));
}
function getMailPreferences()
{
return $this->mailPreferences;
}
function getMessageAttachments($_uid, $_partID='', $_structure='')
{
if (self::$debug) echo __METHOD__."$_uid, $_partID
";
if(is_object($_structure)) {
$structure = $_structure;
} else {
$structure = $this->icServer->getStructure($_uid, true);
if($_partID != '' && $_partID !=0) {
$structure = $this->_getSubStructure($structure, $_partID);
}
}
if (self::$debug) _debug_array($structure);
$attachments = array();
// this kind of messages contain only the attachment and no body
if($structure->type == 'APPLICATION' || $structure->type == 'AUDIO' || $structure->type == 'IMAGE')
{
$newAttachment = array();
$newAttachment['size'] = $structure->bytes;
$newAttachment['mimeType'] = $structure->type .'/'. $structure->subType;
$newAttachment['partID'] = $structure->partID;
$newAttachment['encoding'] = $structure->encoding;
if(isset($structure->cid)) {
$newAttachment['cid'] = $structure->cid;
}
$newAttachment['name'] = self::getFileNameFromStructure($structure);
# if the new attachment is a winmail.dat, we have to decode that first
if ( $newAttachment['name'] == 'winmail.dat' &&
( $wmattachments = $this->decode_winmail( $_uid, $newAttachment['partID'] ) ) )
{
$attachments = array_merge( $attachments, $wmattachments );
} else {
$attachments[] = $newAttachment;
}
//$attachments[] = $newAttachment;
#return $attachments;
}
// this kind of message can have no attachments
if(($structure->type == 'TEXT' && !($structure->disposition == 'INLINE' && $structure->dparameters['FILENAME'])) ||
($structure->type == 'MULTIPART' && $structure->subType == 'ALTERNATIVE' && !is_array($structure->subParts)) ||
!is_array($structure->subParts))
{
if (count($attachments) == 0) return array();
}
#$attachments = array();
foreach($structure->subParts as $subPart) {
// skip all non attachment parts
if(($subPart->type == 'TEXT' && ($subPart->subType == 'PLAIN' || $subPart->subType == 'HTML') && ($subPart->disposition != 'ATTACHMENT' &&
!($subPart->disposition == 'INLINE' && $subPart->dparameters['FILENAME']))) ||
($subPart->type == 'MULTIPART' && $subPart->subType == 'ALTERNATIVE') ||
($subPart->type == 'MULTIPART' && $subPart->subType == 'APPLEFILE') ||
($subPart->type == 'MESSAGE' && $subPart->subType == 'delivery-status'))
{
if ($subPart->type == 'MULTIPART' && $subPart->subType == 'ALTERNATIVE')
{
$attachments = array_merge($this->getMessageAttachments($_uid, '', $subPart), $attachments);
}
continue;
}
// fetch the subparts for this part
if($subPart->type == 'MULTIPART' &&
($subPart->subType == 'RELATED' ||
$subPart->subType == 'MIXED' ||
$subPart->subType == 'SIGNED' ||
$subPart->subType == 'APPLEDOUBLE'))
{
$attachments = array_merge($this->getMessageAttachments($_uid, '', $subPart), $attachments);
} else {
$newAttachment = array();
$newAttachment['size'] = $subPart->bytes;
$newAttachment['mimeType'] = $subPart->type .'/'. $subPart->subType;
$newAttachment['partID'] = $subPart->partID;
$newAttachment['encoding'] = $subPart->encoding;
if(isset($subPart->cid)) {
$newAttachment['cid'] = $subPart->cid;
}
$newAttachment['name'] = self::getFileNameFromStructure($subPart);
# if the new attachment is a winmail.dat, we have to decode that first
if ( $newAttachment['name'] == 'winmail.dat' &&
( $wmattachments = $this->decode_winmail( $_uid, $newAttachment['partID'] ) ) )
{
$attachments = array_merge( $attachments, $wmattachments );
} else {
$attachments[] = $newAttachment;
}
//$attachments[] = $newAttachment;
}
}
//_debug_array($attachments); exit;
return $attachments;
}
static function getFileNameFromStructure(&$structure)
{
if(isset($structure->parameters['NAME'])) {
return self::decode_header($structure->parameters['NAME']);
} elseif(isset($structure->dparameters['FILENAME'])) {
return self::decode_header($structure->dparameters['FILENAME']);
} elseif(isset($structure->dparameters['FILENAME*'])) {
return self::decode_header($structure->dparameters['FILENAME*']);
} elseif ( isset($structure->filename) && !empty($structure->filename) && $structure->filename != 'NIL') {
return self::decode_header($structure->filename);
} else {
return lang("unknown").($structure->subType ? ".".$structure->subType : "");
}
}
function getMessageBody($_uid, $_htmlOptions='', $_partID='', $_structure = '')
{
if (self::$debug) echo __METHOD__."$_uid, $_htmlOptions, $_partID
";
if($_htmlOptions != '') {
$this->htmlOptions = $_htmlOptions;
}
if(is_object($_structure)) {
$structure = $_structure;
} else {
$structure = $this->icServer->getStructure($_uid, true);
if($_partID != '') {
$structure = $this->_getSubStructure($structure, $_partID);
}
}
if (self::$debug) _debug_array($structure);
switch($structure->type) {
case 'APPLICATION':
return array(
array(
'body' => '',
'mimeType' => 'text/plain',
'charSet' => 'iso-8859-1',
)
);
break;
case 'MULTIPART':
switch($structure->subType) {
case 'ALTERNATIVE':
return array($this->getMultipartAlternative($_uid, $structure->subParts, $this->htmlOptions));
break;
case 'MIXED':
case 'REPORT':
case 'SIGNED':
return $this->getMultipartMixed($_uid, $structure->subParts, $this->htmlOptions);
break;
case 'RELATED':
return $this->getMultipartRelated($_uid, $structure->subParts, $this->htmlOptions);
break;
}
break;
case 'AUDIO': // some servers send audiofiles and imagesfiles directly, without any stuff surround it
case 'IMAGE': // they are displayed as Attachment NOT INLINE
return array(
array(
'body' => '',
'mimeType' => $structure->subType,
),
);
break;
case 'TEXT':
$bodyPart = array();
if ( $structure->disposition != 'ATTACHMENT') {
switch($structure->subType) {
case 'CALENDAR':
// maybe opening an egw_calendar object, ... in the future
#$calobj =& CreateObject('calendar.calendar_ical');
#$bodyPart = $this->getTextPart($_uid, $structure, $this->htmlOptions);
#$calobj->importVCal($bodyPart['body']);
#break;
case 'HTML':
case 'PLAIN':
default:
$bodyPart = array($this->getTextPart($_uid, $structure, $this->htmlOptions));
}
} else {
// what if the structure->disposition is attachment ,...
}
return $bodyPart;
break;
case 'MESSAGE':
switch($structure->subType) {
case 'RFC822':
$newStructure = array_shift($structure->subParts);
return $this->getMessageBody($_uid, $_htmlOptions, $newStructure->partID, $newStructure);
break;
}
break;
default:
return array(
array(
'body' => lang('The mimeparser can not parse this message.'),
'mimeType' => 'text/plain',
'charSet' => 'iso-8859-1',
)
);
break;
}
}
function getMessageHeader($_uid, $_partID = '')
{
$retValue = $this->icServer->getParsedHeaders($_uid, true, $_partID, true);
return $retValue;
}
function getMessageRawBody($_uid, $_partID = '')
{
if($_partID != '') {
$body = $this->icServer->getBody($_uid, true);
} else {
$body = $this->icServer->getBodyPart($_uid, $_partID, true);
}
return $body;
}
function getMessageRawHeader($_uid, $_partID = '')
{
$retValue = $this->icServer->getRawHeaders($_uid, $_partID, true);
return $retValue;
}
// return the qouta of the users INBOX
function getQuotaRoot()
{
if(!$this->icServer->hasCapability('QUOTA')) {
return false;
}
$quota = $this->icServer->getStorageQuotaRoot('INBOX');
if(is_array($quota)) {
return array(
'usage' => $quota['USED'],
'limit' => $quota['QMAX'],
);
} else {
return false;
}
}
# function imapGetQuota($_username)
# {
# $quota_value = @imap_get_quota($this->mbox, "user.".$_username);
#
# if(is_array($quota_value) && count($quota_value) > 0)
# {
# return array('limit' => $quota_value['limit']/1024);
# }
# else
# {
# return false;
# }
# }
# function imap_get_quotaroot($_folderName)
# {
# return @imap_get_quotaroot($this->mbox, $_folderName);
# }
# function imapSetQuota($_username, $_quotaLimit)
# {
# if(is_numeric($_quotaLimit) && $_quotaLimit >= 0)
# {
# // enable quota
# $quota_value = @imap_set_quota($this->mbox, "user.".$_username, $_quotaLimit*1024);
# }
# else
# {
# // disable quota
# $quota_value = @imap_set_quota($this->mbox, "user.".$_username, -1);
# }
# }
function isSentFolder($_folderName)
{
if(empty($this->mailPreferences->preferences['sentFolder'])) {
return false;
}
// does the folder exist???
if (!self::folderExists($_folderName)) {
return false;
}
if(false !== stripos($_folderName, $this->mailPreferences->preferences['sentFolder'])) {
return true;
} else {
return false;
}
}
function isDraftFolder($_folderName)
{
if(empty($this->mailPreferences->preferences['draftFolder'])) {
return false;
}
// does the folder exist???
if (!self::folderExists($_folderName)) {
return false;
}
if(false !== stripos($_folderName, $this->mailPreferences->preferences['draftFolder'])) {
return true;
} else {
return false;
}
}
function isTemplateFolder($_folderName)
{
if(empty($this->mailPreferences->preferences['templateFolder'])) {
return false;
}
// does the folder exist???
if (!self::folderExists($_folderName)) {
return false;
}
if(false !== stripos($_folderName, $this->mailPreferences->preferences['templateFolder'])) {
return true;
} else {
return false;
}
}
function folderExists($_folder, $forceCheck=false)
{
#echo __METHOD__." called; check for $_folder
";
// does the folder exist???
#error_log("bofelamimail::folderExists->Connected?".$this->icServer->_connected.", ".$_folder.", ".$forceCheck);
if ((!($this->icServer->_connected == 1)) && $forceCheck) {
#error_log("bofelamimail::folderExists->NotConnected and forceCheck");
return false;
}
$folderInfo = $this->icServer->getMailboxes('', $_folder, true);
#error_log(print_r($folderInfo,true));
if(is_a($folderInfo, 'PEAR_Error') || !is_array($folderInfo[0])) {
return false;
} else {
return true;
}
}
function moveMessages($_foldername, $_messageUID)
{
$msglist = '';
$deleteOptions = $GLOBALS['egw_info']["user"]["preferences"]["felamimail"]["deleteOptions"];
if ( PEAR::isError($this->icServer->copyMessages($_foldername, $_messageUID, $this->sessionData['mailbox'], true)) ) {
return false;
}
// mark messages as deleted
if ( PEAR::isError($this->icServer->deleteMessages($_messageUID, true))) {
return false;
}
if($deleteOptions != "mark_as_deleted") {
// delete the messages finaly
$this->icServer->expunge();
}
return true;
}
function openConnection($_icServerID=0, $_adminConnection=false)
{
#if (!is_object($this->mailPreferences)) echo function_backtrace();
if(!$this->icServer = $this->mailPreferences->getIncomingServer((int)$_icServerID)) {
$this->errorMessage .= lang('No active IMAP server found!!');
return false;
}
if ($this->icServer && empty($this->icServer->host)) {
$errormessage = lang('No IMAP server host configured!!');
if ($GLOBALS['egw_info']['user']['apps']['emailadmin']) {
$errormessage .= "
".lang("Configure a valid IMAP Server in emailadmin for the profile you are using.");
} else {
$errormessage .= "
".lang('Please ask the administrator to correct the emailadmin IMAP Server Settings for you.');
}
$this->icServer->_connectionErrorObject->message .= $this->errorMessage .= $errormessage;
return false;
}
#error_log( "---------------------------open connection
");
#error_log(print_r($this->icServer,true));
if ($this->icServer->_connected == 1) {
$tretval = $this->icServer->selectMailbox($this->icServer->currentMailbox);
#error_log(__METHOD__." using existing Connection ".print_r($this->icServer->_connected,true));
} else {
$tretval = $this->icServer->openConnection($_adminConnection);
#error_log(__METHOD__." open new Connection ".print_r($this->icServer->_connected,true));
}
#error_log(print_r($this->icServer->_connected,true));
return $tretval;
}
/**
* rename a folder
*
* @param string _oldFolderName the old foldername
* @param string _parent the parent foldername
* @param string _folderName the new foldername
*
* @returns mixed name of the newly created folder or false on error
*/
function renameFolder($_oldFolderName, $_parent, $_folderName)
{
$oldFolderName = $this->_encodeFolderName($_oldFolderName);
$parent = $this->_encodeFolderName($_parent);
$folderName = $this->_encodeFolderName($_folderName);
if(empty($parent)) {
$newFolderName = $folderName;
} else {
$HierarchyDelimiter = $this->getHierarchyDelimiter();
$newFolderName = $parent . $HierarchyDelimiter . $folderName;
}
if (self::$debug) error_log("create folder: $newFolderName");
$rv = $this->icServer->renameMailbox($oldFolderName, $newFolderName);
if ( PEAR::isError($rv) ) {
if (self::$debug) error_log(__METHOD__." failed for $oldFolderName, $newFolderName with error: ".print_r($rv->message,true));
return false;
}
return $newFolderName;
}
function reopen($_foldername)
{
#error_log( "------------------------reopen-
");
#error_log(print_r($this->icServer->_connected,true));
if ($this->icServer->_connected == 1) {
$tretval = $this->icServer->selectMailbox($_foldername);
} else {
$tretval = $this->icServer->openConnection(false);
$tretval = $this->icServer->selectMailbox($_foldername);
}
}
function restoreSessionData()
{
$GLOBALS['egw_info']['flags']['autoload'] = array(__CLASS__,'autoload');
$this->sessionData = $GLOBALS['egw']->session->appsession('session_data','felamimail');
}
function saveFilter($_formData)
{
if(!empty($_formData['from']))
$data['from'] = $_formData['from'];
if(!empty($_formData['to']))
$data['to'] = $_formData['to'];
if(!empty($_formData['subject']))
$data['subject']= $_formData['subject'];
if($_formData['filterActive'] == "true")
{
$data['filterActive']= "true";
}
$this->sessionData['filter'] = $data;
$this->saveSessionData();
}
function saveSessionData()
{
$GLOBALS['egw']->session->appsession('session_data','felamimail',$this->sessionData);
}
function setEMailProfile($_profileID)
{
$config =& CreateObject('phpgwapi.config','felamimail');
$config->read_repository();
$config->value('profileID',$_profileID);
$config->save_repository();
}
function subscribe($_folderName, $_status)
{
if (self::$debug) error_log("bofelamimail::".($_status?"":"un")."subscribe:".$_folderName);
if($_status === true) {
if ( PEAR::isError($this->icServer->subscribeMailbox($_folderName))) {
error_log("bofelamimail::".($_status?"":"un")."subscribe:".$_folderName." failed");
return false;
}
} else {
if ( PEAR::isError($this->icServer->unsubscribeMailbox($_folderName))) {
error_log("bofelamimail::".($_status?"":"un")."subscribe:".$_folderName." failed");
return false;
}
}
return true;
}
function toggleFilter()
{
if($this->sessionData['filter']['filterActive'] == 'true') {
$this->sessionData['filter']['filterActive'] = 'false';
} else {
$this->sessionData['filter']['filterActive'] = 'true';
}
$this->saveSessionData();
}
function updateAccount($_hookValues)
{
$icServer = $this->mailPreferences->getIncomingServer(0);
if(is_a($icServer,'defaultimap')) {
$icServer->updateAccount($_hookValues);
}
$ogServer = $this->mailPreferences->getOutgoingServer(0);
if(is_a($ogServer,'defaultsmtp')) {
$ogServer->updateAccount($_hookValues);
}
}
function updateSingleACL($_folderName, $_accountName, $_aclType, $_aclStatus)
{
$userACL = $this->getIMAPACL($_folderName, $_accountName);
if($_aclStatus == 'true') {
if(strpos($userACL, $_aclType) === false) {
$userACL .= $_aclType;
$this->setACL($_folderName, $_accountName, $userACL);
}
} elseif($_aclStatus == 'false') {
if(strpos($userACL, $_aclType) !== false) {
$userACL = str_replace($_aclType,'',$userACL);
$this->setACL($_folderName, $_accountName, $userACL);
}
}
return $userACL;
}
static function wordwrap($str, $cols, $cut)
{
$lines = explode("\n", $str);
$newStr = '';
foreach($lines as $line)
{
// replace tabs by 8 space chars, or any tab only counts one char
//$line = str_replace("\t"," ",$line);
//$newStr .= wordwrap($line, $cols, $cut);
$allowedLength = $cols-strlen($cut);
if (strlen($line) > $allowedLength) {
$s=explode(" ", $line);
$line = "";
$linecnt = 0;
foreach ($s as $k=>$v) {
$cnt = strlen($v);
// only break long words within the wordboundaries,
if($cnt > $allowedLength) {
$v=wordwrap($v, $allowedLength, $cut, true);
}
// the rest should be broken at the start of the new word that exceeds the limit
if ($linecnt+$cnt > $allowedLength) {
$v=$cut.$v;
#$linecnt = 0;
$linecnt =strlen($v)-strlen($cut);
} else {
$linecnt += $cnt;
}
if (strlen($v)) $line .= (strlen($line) ? " " : "").$v;
}
}
$newStr .= $line . "\n";
}
return $newStr;
}
/**
* convert the foldername from display charset to UTF-7
*
* @param string _parent the parent foldername
* @returns ISO-8859-1 / UTF7-IMAP encoded string
*/
function _encodeFolderName($_folderName) {
return $GLOBALS['egw']->translation->convert($_folderName, self::$displayCharset, 'ISO-8859-1');
#return $GLOBALS['egw']->translation->convert($_folderName, self::$displayCharset, 'UTF7-IMAP');
}
/**
* convert the foldername from UTF-7 to display charset
*
* @param string _parent the parent foldername
* @returns ISO-8859-1 / self::$displayCharset encoded string
*/
function _decodeFolderName($_folderName) {
return $GLOBALS['egw']->translation->convert($_folderName, self::$displayCharset, 'ISO-8859-1');
#return $GLOBALS['egw']->translation->convert($_folderName, 'UTF7-IMAP', self::$displayCharset);
}
/**
* convert the sort value from the gui(integer) into a string
*
* @param int _sort the integer sort order
* @returns the ascii sort string
*/
function _getSortString($_sort)
{
switch($_sort) {
case 2:
$retValue = 'FROM';
break;
case 3:
$retValue = 'SUBJECT';
break;
case 6:
$retValue = 'SIZE';
break;
case 0:
default:
$retValue = 'DATE';
break;
}
return $retValue;
}
function sendMDN($uid) {
$identities = $this->mailPreferences->getIdentity();
$headers = $this->getMessageHeader($uid);
$send = & CreateObject('phpgwapi.send');
$send->ClearAddresses();
$send->ClearAttachments();
$send->IsHTML(False);
$send->IsSMTP();
$array_to = explode(",",$headers['TO']);
foreach($identities as $identity) {
if ( preg_match('/\b'.$identity->emailAddress.'\b/',$headers['TO']) ) {
$send->From = $identity->emailAddress;
$send->FromName = $identity->realName;
error_log('Not Default '.$send->From);
break;
}
if($identity->default) {
$send->From = $identity->emailAddress;
$send->FromName = $identity->realName;
}
}
if (isset($headers['DISPOSITION-NOTIFICATION-TO'])) {
$send->AddAddress( $headers['DISPOSITION-NOTIFICATION-TO'] );
} else if ( isset($headers['RETURN-RECEIPT-TO']) ) {
$send->AddAddress( $headers['RETURN-RECEIPT-TO']);
} else if ( isset($headers['X-CONFIRM-READING-TO']) ) {
$send->AddAddress( $headers['X-CONFIRM-READING-TO']);
} else return false;
$send->AddCustomHeader('References: '.$headers['MESSAGE-ID']);
$send->Subject = $send->encode_subject( lang('Read')." : ".$headers['SUBJECT'] );
$sep = "-----------mdn".$uniq_id = md5(uniqid(time()));
$body = "--".$sep."\r\n".
"Content-Type: text/plain; charset=ISO-8859-1\r\n".
"Content-Transfer-Encoding: 7bit\r\n\r\n".
$send->EncodeString(lang("Your message to %1 was displayed." ,$send->From),"7bit").
"\r\n";
$body .= "--".$sep."\r\n".
"Content-Type: message/disposition-notification; name=\"MDNPart2.txt\"\r\n" .
"Content-Disposition: inline\r\n".
"Content-Transfer-Encoding: 7bit\r\n\r\n";
$body.= $send->EncodeString("Reporting-UA: eGroupWare\r\n" .
"Final-Recipient: rfc822;".$send->From."\r\n" .
"Original-Message-ID: ".$headers['MESSAGE-ID']."\r\n".
"Disposition: manual-action/MDN-sent-manually; displayed",'7bit')."\r\n";
$body .= "--".$sep."\r\n".
"Content-Type: text/rfc822-headers; name=\"MDNPart3.txt\"\r\n" .
"Content-Transfer-Encoding: 7bit\r\n" .
"Content-Disposition: inline\r\n\r\n";
$body .= $send->EncodeString($this->getMessageRawHeader($uid),'7bit')."\r\n";
$body .= "--".$sep."--";
$header = rtrim($send->CreateHeader())."\r\n"."Content-Type: multipart/report; report-type=disposition-notification;\r\n".
"\tboundary=\"".$sep."\"\r\n\r\n";
return $send->SmtpSend($header,$body);
}
/**
* Merges a given content with contact data
*
* @param string $content
* @param array $ids array with contact id(s)
* @param string &$err error-message on error
* @return string/boolean merged content or false on error
*/
function merge($content,$ids)
{
$contacts =& new addressbook_bo();
$mergeobj =& new addressbook_merge();
foreach ($ids as $id)
{
// generate replacements
if (!($replacements = $mergeobj->contact_replacements($id)))
{
$err = lang('Contact not found!');
#return false;
continue;
}
if (strpos($content,'$$user/') !== null && ($user = $GLOBALS['egw']->accounts->id2name($GLOBALS['egw_info']['user']['account_id'],'person_id')))
{
$replacements += $mergeobj->contact_replacements($user,'user');
}
$replacements['$$date$$'] = date($GLOBALS['egw_info']['user']['preferences']['common']['dateformat'],time()+$this->contacts->tz_offset_s);
$content = str_replace(array_keys($replacements),array_values($replacements),$content);
$this->replacements = $replacements;
if (strpos($content,'$$IF'))
{ //Example use to use: $$IF n_prefix~Herr~Sehr geehrter~Sehr geehrte$$
$content = preg_replace_callback('/\$\$IF ([0-9a-z_-]+)~(.*)~(.*)~(.*)\$\$/imU',Array($this,'replace_callback'),$content);
}
}
return $content;
}
/**
* Tests if string contains 8bit symbols.
*
* If charset is not set, function defaults to default_charset.
* $default_charset global must be set correctly if $charset is
* not used.
* @param string $string tested string
* @param string $charset charset used in a string
* @return bool true if 8bit symbols are detected
*/
static function is8bit(&$string,$charset='') {
if ($charset=='') $charset= self::$displayCharset;
/**
* Don't use \240 in ranges. Sometimes RH 7.2 doesn't like it.
* Don't use \200-\237 for iso-8859-x charsets. This ranges
* stores control symbols in those charsets.
* Use preg_match instead of ereg in order to avoid problems
* with mbstring overloading
*/
if (preg_match("/^iso-8859/i",$charset)) {
$needle='/\240|[\241-\377]/';
} else {
$needle='/[\200-\237]|\240|[\241-\377]/';
}
return preg_match("$needle",$string);
}
static function detect_qp(&$sting) {
$needle = '/(=[0-9][A-F])|(=[A-F][0-9])|(=[A-F][A-F])|(=[0-9][0-9])/';
return preg_match("$needle",$string);
}
}