2010-09-06 15:31:00 +02:00
< ? php
/*************************************************************************** \
* eGroupWare - FeLaMiMail *
* http :// www . linux - at - work . de *
* http :// www . phpgw . de *
* http :// www . egroupware . org *
* Written by : Lars Kneschke [ lkneschke @ linux - at - work . de ] *
* ------------------------------------------------- *
* This program is free software ; you can redistribute it and / or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation ; either version 2 of the License , or ( at your *
* option ) any later version . *
\ ***************************************************************************/
/* $Id$ */
/**
* the core logic of FeLaMiMail
*
* This class contains all logic of FeLaMiMail .
* @ package FeLaMiMail
* @ author Lars Kneschke
* @ version 1.35
* @ copyright Lars Kneschke 2002 , 2003 , 2004
* @ license http :// opensource . org / licenses / gpl - license . php GPL
*/
class bofelamimail
{
var $public_functions = array
(
'flagMessages' => True ,
);
var $mbox ; // the mailbox identifier any function should use
static $debug = false ; //true; // sometimes debuging is quite handy, to see things. check with the error log to see results
// define some constants
// message types
var $type = array ( " text " , " multipart " , " message " , " application " , " audio " , " image " , " video " , " other " );
2012-03-13 09:59:29 +01:00
/**
* static used to configure tidy - if tidy is loadable , this config is used with tidy to straighten out html , instead of using purifiers tidy mode
*
* @ array
*/
static $tidy_config = array ( 'clean' => true , 'output-html' => true , 'join-classes' => true , 'join-styles' => true , 'show-body-only' => " auto " , 'word-2000' => true , 'wrap' => 0 );
2010-09-06 15:31:00 +02:00
// message encodings
var $encoding = array ( " 7bit " , " 8bit " , " binary " , " base64 " , " quoted-printable " , " other " );
static $displayCharset ;
var $bopreferences ;
var $mailPreferences ;
// set to true, if php is compiled with multi byte string support
var $mbAvailable = FALSE ;
// what type of mimeTypes do we want from the body(text/html, text/plain)
var $htmlOptions ;
var $sessionData ;
// the current selected user profile
var $profileID = 0 ;
/**
* Folders that get automatic created AND get translated to the users language
* their creation is also controlled by users mailpreferences . if set to none / dont use folder
* the folder will not be automatically created . This is controlled in bofelamimail -> getFolderObjects
* so changing names here , must include a change of keywords there as well . Since these
* foldernames are subject to translation , keep that in mind too , if you change names here .
* @ var array
*/
2010-11-02 15:03:31 +01:00
static $autoFolders = array ( 'Drafts' , 'Templates' , 'Sent' , 'Trash' , 'Junk' );
2010-09-06 15:31:00 +02:00
2013-07-26 15:12:32 +02:00
/**
* Array to cache the specialUseFolders , if existing
* @ var array2string
*/
static $specialUseFolders ;
2010-09-06 15:31:00 +02:00
/**
* Autoload classes from emailadmin , ' til they get autoloading conform names
*
* @ param string $class
*/
static function autoload ( $class )
{
if ( file_exists ( $file = EGW_INCLUDE_ROOT . '/emailadmin/inc/class.' . $class . '.inc.php' ))
{
include_once ( $file );
//error_log(__METHOD__."($class) included $file");
}
elseif ( file_exists ( $file = EGW_INCLUDE_ROOT . '/felamimail/inc/class.' . $class . '.inc.php' ))
{
include_once ( $file );
}
else
{
#error_log(__METHOD__."($class) failed!");
}
}
function bofelamimail ( $_displayCharset = 'iso-8859-1' , $_restoreSession = true )
{
2012-04-17 11:12:01 +02:00
if ( $_restoreSession )
2010-09-06 15:31:00 +02:00
{
//error_log(__METHOD__." Session restore ".function_backtrace());
$this -> restoreSessionData ();
}
else
{
$this -> restoreSessionData ();
$lv_mailbox = $this -> sessionData [ 'mailbox' ];
$firstMessage = $this -> sessionData [ 'previewMessage' ];
$this -> sessionData = array ();
$this -> forcePrefReload ();
}
// FIXME: this->foldername seems to be unused
//$this->foldername = $this->sessionData['mailbox'];
$this -> accountid = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
$this -> bopreferences = CreateObject ( 'felamimail.bopreferences' , $_restoreSession );
2010-09-15 21:19:53 +02:00
//$this->sofelamimail = new sofelamimail;
2010-09-06 15:31:00 +02:00
$this -> mailPreferences = $this -> bopreferences -> getPreferences ();
2013-06-13 16:13:01 +02:00
2010-09-06 15:31:00 +02:00
if ( $this -> mailPreferences ) {
$this -> icServer = $this -> mailPreferences -> getIncomingServer ( 0 );
$this -> ogServer = $this -> mailPreferences -> getOutgoingServer ( 0 );
$this -> htmlOptions = $this -> mailPreferences -> preferences [ 'htmlOptions' ];
}
2013-06-13 16:13:01 +02:00
//_debug_array($this->mailPreferences->preferences);
2010-09-06 15:31:00 +02:00
$this -> imapBaseDir = '' ;
self :: $displayCharset = $_displayCharset ;
if ( function_exists ( mb_decode_mimeheader )) {
mb_internal_encoding ( self :: $displayCharset );
}
// set some defaults
2012-04-17 11:12:01 +02:00
if ( empty ( $this -> sessionData ))
2010-09-06 15:31:00 +02:00
{
// this should be under user preferences
// sessionData empty
// no filter active
$this -> sessionData [ 'activeFilter' ] = " -1 " ;
// default mailbox INBOX
$this -> sessionData [ 'mailbox' ] = (( $lv_mailbox && self :: folderExists ( $lv_mailbox , true )) ? $lv_mailbox : " INBOX " );
2012-04-17 11:12:01 +02:00
$this -> sessionData [ 'previewMessage' ] = ( $firstMessage > 0 ? $firstMessage : 0 );
2010-09-06 15:31:00 +02:00
// default start message
$this -> sessionData [ 'startMessage' ] = 1 ;
// default mailbox for preferences pages
$this -> sessionData [ 'preferences' ][ 'mailbox' ] = " INBOX " ;
$this -> sessionData [ 'messageFilter' ] = array (
'string' => '' ,
'type' => 'quick' ,
'status' => 'any' ,
);
// default sorting
switch ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'felamimail' ][ 'sortOrder' ]) {
case 1 :
$this -> sessionData [ 'sort' ] = SORTDATE ;
$this -> sessionData [ 'sortReverse' ] = false ;
break ;
case 2 :
$this -> sessionData [ 'sort' ] = SORTFROM ;
$this -> sessionData [ 'sortReverse' ] = true ;
break ;
case 3 :
$this -> sessionData [ 'sort' ] = SORTFROM ;
$this -> sessionData [ 'sortReverse' ] = false ;
break ;
case 4 :
$this -> sessionData [ 'sort' ] = SORTSUBJECT ;
$this -> sessionData [ 'sortReverse' ] = true ;
break ;
case 5 :
$this -> sessionData [ 'sort' ] = SORTSUBJECT ;
$this -> sessionData [ 'sortReverse' ] = false ;
break ;
case 6 :
$this -> sessionData [ 'sort' ] = SORTSIZE ;
$this -> sessionData [ 'sortReverse' ] = true ;
break ;
case 7 :
$this -> sessionData [ 'sort' ] = SORTSIZE ;
$this -> sessionData [ 'sortReverse' ] = false ;
break ;
default :
$this -> sessionData [ 'sort' ] = SORTDATE ;
$this -> sessionData [ 'sortReverse' ] = true ;
break ;
}
$this -> saveSessionData ();
}
if ( function_exists ( 'mb_convert_encoding' )) {
$this -> mbAvailable = TRUE ;
}
}
function forcePrefReload ()
{
// unset the fm_preferences session object, to force the reload/rebuild
$GLOBALS [ 'egw' ] -> session -> appsession ( 'fm_preferences' , 'felamimail' , serialize ( array ()));
$GLOBALS [ 'egw' ] -> session -> appsession ( 'session_data' , 'emailadmin' , serialize ( array ()));
}
function setACL ( $_folderName , $_accountName , $_acl )
{
if ( PEAR :: isError ( $this -> icServer -> setACL ( $_folderName , $_accountName , $_acl )) ) {
return false ;
}
return TRUE ;
}
function deleteACL ( $_folderName , $_accountName )
{
if ( PEAR :: isError ( $this -> icServer -> deleteACL ( $_folderName , $_accountName )) ) {
return false ;
}
return TRUE ;
}
/**
* hook to add account
*
* this function is a wrapper function for emailadmin
*
* @ param _hookValues contains the hook values as array
* @ returns nothing
*/
function addAccount ( $_hookValues )
{
2010-11-10 19:01:15 +01:00
if ( $this -> mailPreferences ) {
$icServer = $this -> mailPreferences -> getIncomingServer ( 0 );
2011-09-12 17:31:35 +02:00
if (( $icServer instanceof defaultimap )) {
2010-11-10 19:01:15 +01:00
$icServer -> addAccount ( $_hookValues );
}
2010-09-06 15:31:00 +02:00
2010-11-10 19:01:15 +01:00
$ogServer = $this -> mailPreferences -> getOutgoingServer ( 0 );
2011-09-12 17:31:35 +02:00
if (( $ogServer instanceof defaultsmtp )) {
2010-11-10 19:01:15 +01:00
$ogServer -> addAccount ( $_hookValues );
}
2010-09-06 15:31:00 +02:00
}
}
function adminMenu ()
{
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'account_repository' ] == " ldap " )
{
$data = Array
(
'description' => 'email settings' ,
'url' => '/index.php' ,
'extradata' => 'menuaction=emailadmin.uiuserdata.editUserData'
);
//Do not modify below this line
global $menuData ;
$menuData [] = $data ;
}
}
/**
* save a message in folder
*
* @ todo set flags again
*
* @ param string _folderName the foldername
* @ param string _header the header of the message
* @ param string _body the body of the message
* @ param string _flags the imap flags to set for the saved message
*
* @ returns the id of the message appended or false
*/
function appendMessage ( $_folderName , $_header , $_body , $_flags )
{
$header = ltrim ( str_replace ( " \n " , " \r \n " , $_header ));
$body = str_replace ( " \n " , " \r \n " , $_body );
$messageid = $this -> icServer -> appendMessage ( " $header " . " $body " , $_folderName , $_flags );
if ( PEAR :: isError ( $messageid )) {
if ( self :: $debug ) error_log ( " Could not append Message: " . print_r ( $messageid -> message , true ));
return false ;
}
2012-10-18 12:52:53 +02:00
//error_log(__METHOD__.__LINE__.' appended UID:'.$messageid);
2012-10-18 12:55:19 +02:00
//$messageid = true; // for debug reasons only
2012-10-18 12:52:53 +02:00
if ( $messageid === true ) // try to figure out the message uid
{
$list = $this -> getHeaders ( $_folderName , $_startMessage = 1 , $_numberOfMessages = 1 , $_sort = 'INTERNALDATE' , $_reverse = true , $_filter = array (), $_thisUIDOnly = null );
if ( $list )
{
if ( self :: $debug ) error_log ( __METHOD__ . __LINE__ . ' MessageUid:' . $messageid . ' but found:' . array2string ( $list ));
$messageid = $list [ 'header' ][ 0 ][ 'uid' ];
}
}
2010-09-06 15:31:00 +02:00
return $messageid ;
}
function closeConnection () {
$this -> icServer -> disconnect ();
}
/**
* remove any messages which are marked as deleted or
* remove any messages from the trashfolder
*
* @ param string _folderName the foldername
* @ returns nothing
*/
function compressFolder ( $_folderName = false )
{
$folderName = ( $_folderName ? $_folderName : $this -> sessionData [ 'mailbox' ]);
$deleteOptions = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'felamimail' ][ 'deleteOptions' ];
2013-07-26 15:12:32 +02:00
$trashFolder = $this -> getTrashFolder (); //$GLOBALS['egw_info']['user']['preferences']['felamimail']['trashFolder'];
2010-09-06 15:31:00 +02:00
$this -> icServer -> selectMailbox ( $folderName );
if ( $folderName == $trashFolder && $deleteOptions == " move_to_trash " ) {
$this -> icServer -> deleteMessages ( '1:*' );
$this -> icServer -> expunge ();
} else {
$this -> icServer -> expunge ();
}
}
/**
* create a new folder under given parent folder
*
* @ param string _parent the parent foldername
* @ param string _folderName the new foldername
* @ param bool _subscribe subscribe to the new folder
*
* @ returns mixed name of the newly created folder or false on error
*/
function createFolder ( $_parent , $_folderName , $_subscribe = false )
{
$parent = $this -> _encodeFolderName ( $_parent );
$folderName = $this -> _encodeFolderName ( $_folderName );
if ( empty ( $parent )) {
$newFolderName = $folderName ;
} else {
$HierarchyDelimiter = $this -> getHierarchyDelimiter ();
$newFolderName = $parent . $HierarchyDelimiter . $folderName ;
}
if ( PEAR :: isError ( $this -> icServer -> createMailbox ( $newFolderName ) ) ) {
return false ;
}
if ( PEAR :: isError ( $this -> icServer -> subscribeMailbox ( $newFolderName ) ) ) {
return false ;
}
return $newFolderName ;
}
function createIMAPFilter ( $_folder , $_criterias )
{
2012-11-08 16:43:15 +01:00
$all = 'ALL UNDELETED' ; //'ALL'
//_debug_array($_criterias);
if ( self :: $debug ) error_log ( __METHOD__ . __LINE__ . ' Criterias:' . ( ! is_array ( $_criterias ) ? " none -> returning $all " : array2string ( $_criterias )));
2010-09-06 15:31:00 +02:00
if ( ! is_array ( $_criterias )) {
2012-11-08 16:43:15 +01:00
return $all ;
2010-09-06 15:31:00 +02:00
}
2012-11-08 16:43:15 +01:00
#error_log(print_r($_criterias, true));
2010-09-06 15:31:00 +02:00
$imapFilter = '' ;
#foreach($_criterias as $criteria => $parameter) {
if ( ! empty ( $_criterias [ 'string' ])) {
$criteria = strtoupper ( $_criterias [ 'type' ]);
switch ( $criteria ) {
case 'QUICK' :
if ( $this -> isSentFolder ( $_folder )) {
$imapFilter .= 'OR SUBJECT "' . $_criterias [ 'string' ] . '" TO "' . $_criterias [ 'string' ] . '" ' ;
} else {
$imapFilter .= 'OR SUBJECT "' . $_criterias [ 'string' ] . '" FROM "' . $_criterias [ 'string' ] . '" ' ;
}
break ;
case 'BCC' :
case 'BODY' :
case 'CC' :
case 'FROM' :
case 'KEYWORD' :
case 'SUBJECT' :
case 'TEXT' :
case 'TO' :
$imapFilter .= $criteria . ' "' . $_criterias [ 'string' ] . '" ' ;
break ;
2012-11-08 16:43:15 +01:00
case 'SINCE' :
case 'BEFORE' :
case 'ON' :
$imapFilter .= $criteria . ' ' . $_criterias [ 'string' ] . ' ' ;
break ;
2010-09-06 15:31:00 +02:00
}
}
2012-11-08 16:43:15 +01:00
foreach (( array ) $_criterias [ 'status' ] as $k => $criteria ) {
$criteria = strtoupper ( $criteria );
2010-09-06 15:31:00 +02:00
switch ( $criteria ) {
case 'ANSWERED' :
case 'DELETED' :
case 'FLAGGED' :
case 'NEW' :
case 'OLD' :
case 'RECENT' :
case 'SEEN' :
case 'UNANSWERED' :
case 'UNDELETED' :
case 'UNFLAGGED' :
case 'UNSEEN' :
$imapFilter .= $criteria . ' ' ;
break ;
2012-11-08 16:43:15 +01:00
case 'KEYWORD1' :
case 'KEYWORD2' :
case 'KEYWORD3' :
case 'KEYWORD4' :
case 'KEYWORD5' :
$imapFilter .= " KEYWORD " . '$label' . substr ( trim ( $criteria ), strlen ( 'KEYWORD' )) . ' ' ;
2010-09-06 15:31:00 +02:00
break ;
}
2012-11-08 16:43:15 +01:00
}
if ( isset ( $_criterias [ 'range' ]) && ! empty ( $_criterias [ 'range' ]))
{
$imapFilter .= $_criterias [ 'range' ] . ' ' ;
}
if ( self :: $debug ) error_log ( __METHOD__ . __LINE__ . " Filter: " . ( $imapFilter ? $imapFilter : $all ));
2010-09-06 15:31:00 +02:00
if ( $imapFilter == '' ) {
2012-11-08 16:43:15 +01:00
return $all ;
2010-09-06 15:31:00 +02:00
} else {
return trim ( $imapFilter );
#return 'CHARSET '. strtoupper(self::$displayCharset) .' '. trim($imapFilter);
}
}
/**
* convert a mailboxname from displaycharset to urf7 - imap
*
* @ param string _folderName the foldername
*
* @ returns string the converted foldername
*/
function decodeFolderName ( $_folderName )
{
return $GLOBALS [ 'egw' ] -> translation -> convert ( $_folderName , self :: $displayCharset , 'UTF7-IMAP' );
}
function decodeMimePart ( $_mimeMessage , $_encoding , $_charset = '' )
{
// decode the part
if ( self :: $debug ) error_log ( " bofelamimail::decodeMimePart with $_encoding and $_charset : " . print_r ( $_mimeMessage , true ));
switch ( $_encoding )
{
case 'BASE64' :
// use imap_base64 to decode, not any longer, as it is strict, and fails if it encounters invalid chars
return base64_decode ( $_mimeMessage ); //imap_base64($_mimeMessage);
break ;
case 'QUOTED-PRINTABLE' :
// use imap_qprint to decode
return quoted_printable_decode ( $_mimeMessage );
break ;
default :
// it is either not encoded or we don't know about it
return $_mimeMessage ;
break ;
}
}
2010-09-10 15:21:05 +02:00
/**
* decode header ( or envelope information
2012-04-17 11:12:01 +02:00
* if array given , note that only values will be converted
2010-09-10 15:21:05 +02:00
* @ param $_string mixed input to be converted , if array call decode_header recursively on each value
* @ returns mixed - based on the input type
*/
2010-09-06 15:31:00 +02:00
static function decode_header ( $_string )
{
2010-09-10 15:21:05 +02:00
if ( is_array ( $_string ))
{
foreach ( $_string as $k => $v )
{
$_string [ $k ] = self :: decode_header ( $v );
}
return $_string ;
}
else
{
return $GLOBALS [ 'egw' ] -> translation -> decodeMailHeader ( $_string , self :: $displayCharset );
}
2010-09-06 15:31:00 +02:00
}
2010-09-10 15:21:05 +02:00
function decode_subject ( $_string , $decode = true )
2010-09-06 15:31:00 +02:00
{
#$string = $_string;
if ( $_string == 'NIL' )
{
2010-09-10 15:21:05 +02:00
return 'No Subject' ;
2010-09-06 15:31:00 +02:00
}
2010-09-10 15:21:05 +02:00
if ( $decode ) $_string = self :: decode_header ( $_string );
2010-09-06 15:31:00 +02:00
return $_string ;
}
/**
* decodes winmail . dat attachments
*
* @ param int $_uid
* @ param string $_partID
* @ param int $_filenumber
* @ return array
*/
function decode_winmail ( $_uid , $_partID , $_filenumber = 0 )
{
$attachment = $this -> getAttachment ( $_uid , $_partID );
2011-07-19 12:07:26 +02:00
$dirname = $this -> accountid . '_' . $this -> profileID . '_' . $this -> sessionData [ 'mailbox' ] . '_' . $_uid . '_' . $_partID ;
if ( self :: $debug ) error_log ( __METHOD__ . __LINE__ . ' Dirname:' . $dirname );
$dirname = md5 ( $dirname );
$dir = $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] . " /fmail_winmail/ $dirname " ;
2010-09-06 15:31:00 +02:00
$mime = CreateObject ( 'phpgwapi.mime_magic' );
if ( $attachment [ 'type' ] == 'APPLICATION/MS-TNEF' && $attachment [ 'filename' ] == 'winmail.dat' )
{
// decode winmail.dat
if ( ! file_exists ( " $dir /winmail.dat " ) )
{
@ mkdir ( $dir , 0700 , true );
file_put_contents ( " $dir /winmail.dat " , $attachment [ 'attachment' ] );
}
2011-02-22 14:17:52 +01:00
if ( file_exists ( '/usr/bin/tnef' ))
{
exec ( " cd $dir && /usr/bin/tnef --save-body --overwrite -C $dir -f ./winmail.dat " );
}
elseif ( exec ( " which tnef " )) // use tnef if exsting, as it gives better results..
2010-09-06 15:31:00 +02:00
{
exec ( " cd $dir && tnef --save-body --overwrite -C $dir -f ./winmail.dat " );
2012-04-17 11:12:01 +02:00
}
2010-09-06 15:31:00 +02:00
elseif ( exec ( " which ytnef " ))
{
exec ( " cd $dir && ytnef -f . winmail.dat " );
}
// list contents
$files = scandir ( $dir );
foreach ( $files as $num => $file )
{
if ( filetype ( " $dir / $file " ) != 'file' || $file == 'winmail.dat' ) continue ;
if ( $_filenumber > 0 && $_filenumber != $num ) continue ;
$type = $mime -> filename2mime ( $file );
$attachments [] = array (
'is_winmail' => $num ,
'name' => self :: decode_header ( $file ),
'size' => filesize ( " $dir / $file " ),
'partID' => $_partID ,
'mimeType' => $type ,
'type' => $type ,
'attachment' => $_filenumber > 0 ? file_get_contents ( " $dir / $file " ) : '' ,
);
unlink ( $dir . " / " . $file );
}
if ( file_exists ( $dir . " /winmail.dat " )) unlink ( $dir . " /winmail.dat " );
if ( file_exists ( $dir )) @ rmdir ( $dir );
return $_filenumber > 0 ? $attachments [ 0 ] : $attachments ;
}
return false ;
}
function deleteAccount ( $_hookValues )
{
2010-11-10 19:01:15 +01:00
if ( $this -> mailPreferences ) {
$icServer = $this -> mailPreferences -> getIncomingServer ( 0 );
2011-09-12 17:31:35 +02:00
if (( $icServer instanceof defaultimap )) {
2010-11-10 19:01:15 +01:00
$icServer -> deleteAccount ( $_hookValues );
}
2010-09-06 15:31:00 +02:00
2010-11-10 19:01:15 +01:00
$ogServer = $this -> mailPreferences -> getOutgoingServer ( 0 );
2011-09-12 17:31:35 +02:00
if (( $ogServer instanceof defaultsmtp )) {
2010-11-10 19:01:15 +01:00
$ogServer -> deleteAccount ( $_hookValues );
}
2010-09-06 15:31:00 +02:00
}
}
/**
* delete a existing folder
*
* @ param string _folderName the name of the folder to be deleted
*
* @ returns bool true on success , false on failure
*/
function deleteFolder ( $_folderName )
{
$folderName = $this -> _encodeFolderName ( $_folderName );
$this -> icServer -> unsubscribeMailbox ( $folderName );
if ( PEAR :: isError ( $this -> icServer -> deleteMailbox ( $folderName )) ) {
return false ;
}
return true ;
}
function deleteMessages ( $_messageUID , $_folder = NULL )
{
$msglist = '' ;
$oldMailbox = '' ;
if ( is_null ( $_folder ) || empty ( $_folder )) $_folder = $this -> sessionData [ 'mailbox' ];
2012-04-17 11:12:01 +02:00
if ( ! is_array ( $_messageUID ) || count ( $_messageUID ) === 0 )
2010-09-06 15:31:00 +02:00
{
if ( $_messageUID == 'all' )
{
$_messageUID = null ;
}
else
{
if ( self :: $debug ) error_log ( __METHOD__ . " no messages Message(s): " . implode ( ',' , $_messageUID ));
2012-04-17 11:12:01 +02:00
return false ;
2010-09-06 15:31:00 +02:00
}
}
$deleteOptions = $this -> mailPreferences -> preferences [ 'deleteOptions' ];
2013-07-26 15:12:32 +02:00
$trashFolder = $this -> getTrashFolder ();
$draftFolder = $this -> getDraftFolder (); //$GLOBALS['egw_info']['user']['preferences']['felamimail']['draftFolder'];
$templateFolder = $this -> getTemplateFolder (); //$GLOBALS['egw_info']['user']['preferences']['felamimail']['templateFolder'];
2010-09-06 15:31:00 +02:00
if (( $this -> sessionData [ 'mailbox' ] == $trashFolder && $deleteOptions == " move_to_trash " ) ||
( $this -> sessionData [ 'mailbox' ] == $draftFolder )) {
$deleteOptions = " remove_immediately " ;
}
if ( $this -> icServer -> getCurrentMailbox () != $_folder ) {
$oldMailbox = $this -> icServer -> getCurrentMailbox ();
$this -> icServer -> selectMailbox ( $_folder );
}
switch ( $deleteOptions ) {
case " move_to_trash " :
if ( ! empty ( $trashFolder )) {
if ( self :: $debug ) error_log ( implode ( ' : ' , $_messageUID ));
if ( self :: $debug ) error_log ( " $trashFolder <= " . $this -> sessionData [ 'mailbox' ]);
// copy messages
if ( PEAR :: isError ( $this -> icServer -> copyMessages ( $trashFolder , $_messageUID , $_folder , true )) ) {
if ( self :: $debug ) error_log ( __METHOD__ . " failed to copy Message(s) to $trashFolder : " . implode ( ',' , $_messageUID ));
return false ;
}
// mark messages as deleted
if ( PEAR :: isError ( $this -> icServer -> deleteMessages ( $_messageUID , true ))) {
if ( self :: $debug ) error_log ( __METHOD__ . " failed to delete Message(s): " . implode ( ',' , $_messageUID ));
return false ;
}
// delete the messages finaly
$this -> icServer -> expunge ();
}
break ;
case " mark_as_deleted " :
// mark messages as deleted
if ( PEAR :: isError ( $this -> icServer -> deleteMessages ( $_messageUID , true ))) {
if ( self :: $debug ) error_log ( __METHOD__ . " failed to mark as deleted for Message(s): " . implode ( ',' , $_messageUID ));
return false ;
}
break ;
case " remove_immediately " :
// mark messages as deleted
if ( PEAR :: isError ( $this -> icServer -> deleteMessages ( $_messageUID , true ))) {
if ( self :: $debug ) error_log ( __METHOD__ . " failed to remove immediately Message(s): " . implode ( ',' , $_messageUID ));
return false ;
}
// delete the messages finaly
$this -> icServer -> expunge ();
break ;
}
if ( $oldMailbox != '' ) {
$this -> icServer -> selectMailbox ( $oldMailbox );
}
return true ;
}
/**
* convert a mailboxname from utf7 - imap to displaycharset
*
* @ param string _folderName the foldername
*
* @ returns string the converted string
*/
function encodeFolderName ( $_folderName )
{
return $GLOBALS [ 'egw' ] -> translation -> convert ( $_folderName , 'UTF7-IMAP' , self :: $displayCharset );
}
# function encodeHeader($_string, $_encoding='q')
# {
# switch($_encoding) {
# case "q":
# if(!preg_match("/[\x80-\xFF]/",$_string)) {
# // nothing to quote, only 7 bit ascii
# return $_string;
# }
#
# $string = imap_8bit($_string);
# $stringParts = explode("=\r\n",$string);
# while(list($key,$value) = each($stringParts)) {
# if(!empty($retString)) $retString .= " ";
# $value = str_replace(" ","_",$value);
# // imap_8bit does not convert "?"
# // it does not need, but it should
# $value = str_replace("?","=3F",$value);
# $retString .= "=?".strtoupper(self::$displayCharset). "?Q?". $value. "?=";
# }
# #exit;
# return $retString;
# break;
# default:
# return $_string;
# }
# }
function getFlags ( $_messageUID ) {
$flags = $this -> icServer -> getFlags ( $_messageUID , true );
if ( PEAR :: isError ( $flags )) {
return null ;
}
return $flags ;
}
2012-04-17 11:12:01 +02:00
function getNotifyFlags ( $_messageUID , $flags = null )
{
if ( $flags === null ) $flags = $this -> icServer -> getFlags ( $_messageUID , true );
2010-09-06 15:31:00 +02:00
if ( PEAR :: isError ( $flags )) {
return null ;
}
if ( in_array ( 'MDNSent' , $flags [ 0 ]) )
return true ;
if ( in_array ( 'MDNnotSent' , $flags [ 0 ]) )
return false ;
return null ;
}
function flagMessages ( $_flag , $_messageUID )
{
#error_log("felamimail::bocompose::flagMessages");
if ( ! is_array ( $_messageUID )) {
#return false;
if ( $_messageUID == 'all' )
{
//all is an allowed value to be passed
}
else
{
$_messageUID = array ( $_messageUID );
}
}
$this -> icServer -> selectMailbox ( $this -> sessionData [ 'mailbox' ]);
switch ( $_flag ) {
case " flagged " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , '\\Flagged' , 'add' , true );
2010-09-06 15:31:00 +02:00
break ;
case " read " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , '\\Seen' , 'add' , true );
2010-09-06 15:31:00 +02:00
break ;
case " forwarded " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , '$Forwarded' , 'add' , true );
2010-09-06 15:31:00 +02:00
case " answered " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , '\\Answered' , 'add' , true );
2010-09-06 15:31:00 +02:00
break ;
case " unflagged " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , '\\Flagged' , 'remove' , true );
2010-09-06 15:31:00 +02:00
break ;
case " unread " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , '\\Seen' , 'remove' , true );
$ret = $this -> icServer -> setFlags ( $_messageUID , '\\Answered' , 'remove' , true );
$ret = $this -> icServer -> setFlags ( $_messageUID , '$Forwarded' , 'remove' , true );
2010-09-06 15:31:00 +02:00
break ;
case " mdnsent " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , 'MDNSent' , 'add' , true );
2010-09-06 15:31:00 +02:00
break ;
case " mdnnotsent " :
2012-07-10 16:47:53 +02:00
$ret = $this -> icServer -> setFlags ( $_messageUID , 'MDNnotSent' , 'add' , true );
2010-09-06 15:31:00 +02:00
break ;
}
2012-07-10 16:47:53 +02:00
if ( PEAR :: isError ( $ret ))
{
if ( stripos ( $ret -> message , 'Too long argument' ))
{
$c = count ( $_messageUID );
$h = ceil ( $c / 2 );
error_log ( __METHOD__ . __LINE__ . $ret -> message . " $c messages given for flagging. Trying with chunks of $h " );
$this -> flagMessages ( $_flag , array_slice ( $_messageUID , 0 , $h ));
$this -> flagMessages ( $_flag , array_slice ( $_messageUID , $h ));
}
}
2010-09-06 15:31:00 +02:00
$this -> sessionData [ 'folderStatus' ][ $this -> profileID ][ $this -> sessionData [ 'mailbox' ]][ 'uidValidity' ] = 0 ;
$this -> saveSessionData ();
}
function _getSubStructure ( $_structure , $_partID )
{
$tempID = '' ;
$structure = $_structure ;
if ( empty ( $_partID )) $_partID = 1 ;
$imapPartIDs = explode ( '.' , $_partID );
#error_log(print_r($structure,true));
#error_log(print_r($_partID,true));
if ( $_partID != 1 ) {
foreach ( $imapPartIDs as $imapPartID ) {
if ( ! empty ( $tempID )) {
$tempID .= '.' ;
}
$tempID .= $imapPartID ;
#error_log(print_r( "TEMPID: $tempID<br>",true));
//_debug_array($structure);
if ( $structure -> subParts [ $tempID ] -> type == 'MESSAGE' && $structure -> subParts [ $tempID ] -> subType == 'RFC822' &&
count ( $structure -> subParts [ $tempID ] -> subParts ) == 1 &&
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> type == 'MULTIPART' &&
( $structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'MIXED' ||
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'ALTERNATIVE' ||
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'RELATED' ||
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'REPORT' ))
{
$structure = $structure -> subParts [ $tempID ] -> subParts [ $tempID ];
} else {
$structure = $structure -> subParts [ $tempID ];
}
}
}
if ( $structure -> partID != $_partID ) {
foreach ( $imapPartIDs as $imapPartID ) {
if ( ! empty ( $tempID )) {
$tempID .= '.' ;
}
$tempID .= $imapPartID ;
//print "TEMPID: $tempID<br>";
//_debug_array($structure);
if ( $structure -> subParts [ $tempID ] -> type == 'MESSAGE' && $structure -> subParts [ $tempID ] -> subType == 'RFC822' &&
count ( $structure -> subParts [ $tempID ] -> subParts ) == 1 &&
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> type == 'MULTIPART' &&
( $structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'MIXED' ||
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'ALTERNATIVE' ||
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'RELATED' ||
$structure -> subParts [ $tempID ] -> subParts [ $tempID ] -> subType == 'REPORT' )) {
$structure = $structure -> subParts [ $tempID ] -> subParts [ $tempID ];
} else {
$structure = $structure -> subParts [ $tempID ];
}
}
if ( $structure -> partID != $_partID ) {
error_log ( " bofelamimail::_getSubStructure( " . __LINE__ . " ) partID's don't match " );
return false ;
}
}
return $structure ;
}
/*
* strip tags out of the message completely with their content
* param $_body is the text to be processed
* param $tag is the tagname which is to be removed . Note , that only the name of the tag is to be passed to the function
* without the enclosing brackets
* param $endtag can be different from tag but should be used only , if begin and endtag are known to be different e . g .: <!-- -->
*/
static function replaceTagsCompletley ( & $_body , $tag , $endtag = '' , $addbracesforendtag = true )
{
translation :: replaceTagsCompletley ( $_body , $tag , $endtag , $addbracesforendtag );
}
2012-01-31 17:44:43 +01:00
static function getCleanHTML ( & $_html , $usepurify = false , $cleanTags = true )
2010-09-06 15:31:00 +02:00
{
// remove CRLF and TAB as it is of no use in HTML.
// but they matter in <pre>, so we rather don't
//$_html = str_replace("\r\n",' ',$_html);
//$_html = str_replace("\t",' ',$_html);
//error_log($_html);
self :: replaceTagsCompletley ( $_html , 'style' ); // clean out empty or pagewide style definitions / left over tags
2012-04-17 11:12:01 +02:00
self :: replaceTagsCompletley ( $_html , 'head' ); // Strip out stuff in head
self :: replaceTagsCompletley ( $_html , '!\[if' , '<!\[endif\]>' , false ); // Strip out stuff in ifs
self :: replaceTagsCompletley ( $_html , '!--\[if' , '<!\[endif\]-->' , false ); // Strip out stuff in ifs
2010-09-06 15:31:00 +02:00
//error_log($_html);
// force the use of kses, as it is still have the edge over purifier with some stuff
$usepurify = false ;
if ( $usepurify )
{
// we may need a customized config, as we may allow external images, $GLOBALS['egw_info']['user']['preferences']['felamimail']['allowExternalIMGs']
$config = html :: purifyCreateDefaultConfig ();
2012-04-17 11:12:01 +02:00
2010-09-06 15:31:00 +02:00
$config -> set ( 'Core.Encoding' , ( self :: $displayCharset ? self :: $displayCharset : 'UTF-8' ));
// maybe the two following lines are useful for caching???
$config -> set ( 'HTML.DefinitionID' , 'felamimail' );
$config -> set ( 'HTML.DefinitionRev' , 1 );
// doctype and tidylevel
$config -> set ( 'HTML.Doctype' , 'XHTML 1.0 Transitional' );
$config -> set ( 'HTML.TidyLevel' , 'light' );
// EnableID is needed for anchor tags
$config -> set ( 'Attr.EnableID' , true );
// actual allowed tags and attributes
$config -> set ( 'URI.AllowedSchemes' , array ( 'http' => true , 'https' => true , 'ftp' => true , 'file' => true , 'mailto' => true , 'cid' => true ));
$config -> set ( 'AutoFormat.RemoveEmpty' , true );
$config -> set ( 'HTML.Allowed' , 'br,p[align],b,i,u,s,em,pre,tt,strong,strike,center,div[align],hr[class|style],' .
'font[size|color],' .
'ul[type],ol[type|start],li,' .
'h1,h2,h3,' .
'span[class|style],' .
'table[class|border|cellpadding|cellspacing|width|style|align|bgcolor|align],' .
'tbody,thead,tfoot,colgroup,' .
'col[width|span],' .
'blockquote[class|cite|dir],' .
'tr[class|style|align|bgcolor|align|valign],' .
'td[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],' .
'th[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],' .
'a[href|target|name|title],' .
'img[src|alt|title]' );
$DisableExternalResources = true ;
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'felamimail' ][ 'allowExternalIMGs' ]) $DisableExternalResources = false ;
$config -> set ( 'URI.DisableExternalResources' , $DisableExternalResources );
$config -> set ( 'Core.RemoveInvalidImg' , false );
//$config->set('Attr.DefaultInvalidImage', 'Image removed by htmlpurify');
$config -> set ( 'Core.HiddenElements' , array ( 'script' , 'style' , 'head' )); // strips script, style, head copletely
$config -> set ( 'Cache.SerializerPath' , ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] ? $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] : sys_get_temp_dir ()));
//$config->set('HTML.MaxImgLength',null);
$config -> set ( 'Cache.DefinitionImpl' , null ); // remove this later!
//$purifier = new HTMLPurifier($config);
//$_html = $purifier->purify( $_html );
if ( get_magic_quotes_gpc () === 1 ) $_html = stripslashes ( $_html );
$_html = html :: purify ( $_html , $config );
// no scripts allowed
// clean out comments , should not be needed as purify should do the job.
$search = array (
'@url\(http:\/\/[^\)].*?\)@si' , // url calls e.g. in style definitions
2012-04-17 11:12:01 +02:00
'@<!--[\s\S]*?[ \t\n\r]*-->@' , // Strip multi-line comments including CDATA
2010-09-06 15:31:00 +02:00
);
//$_html = preg_replace($search,"",$_html);
// remove non printable chars
$_html = preg_replace ( '/([\000-\012])/' , '' , $_html );
//error_log($_html);
}
else
{
//echo $_html;exit;
$kses = new kses ();
$kses -> AddProtocol ( 'cid' );
// since check protocoll is called for every value associated to an attribute we have to add color and background-color to the valid protocolls
$kses -> AddProtocol ( 'color' );
$kses -> AddProtocol ( 'font-size' );
$kses -> AddProtocol ( 'background-color' );
#$kses->AddHTML('html', array(
# 'xmlns' => array(),
# 'lang' => array(),
# )
#);
#$kses->AddHTML('head');
#$kses->AddHTML('body', array(
# 'class' => array(),
# 'id' => array(),
# )
#);
#$kses->AddHTML('meta', array(
# 'http-equiv' => array(),
# 'content' => array(),
# )
#);
#$kses->AddHTML('link',array(
# 'rel' => array(), // ="stylesheet"
# 'type' => array(), //="text/css"
# 'href' => array(),
# 'media' => array(),
# )
#);
$kses -> AddHTML (
'p' , array (
'align' => array ( 'minlen' => 1 , 'maxlen' => 10 )
)
);
$kses -> AddHTML ( " tbody " );
$kses -> AddHTML ( " thead " );
$kses -> AddHTML ( " tt " );
$kses -> AddHTML ( " br " );
$kses -> AddHTML ( " b " );
$kses -> AddHTML ( " u " );
$kses -> AddHTML ( " s " );
$kses -> AddHTML ( " i " );
$kses -> AddHTML ( 'em' );
$kses -> AddHTML ( " strong " );
$kses -> AddHTML ( " strike " );
$kses -> AddHTML ( " center " );
$kses -> AddHTML (
" font " , array (
" color " => array ( 'maxlen' => 20 ),
" size " => array ( 'maxlen' => 2 )
)
);
$kses -> AddHTML (
" hr " , array (
" class " => array ( 'maxlen' => 20 ),
" style " => array ( 'minlen' => 1 ),
)
);
$kses -> AddHTML (
" div " , array (
# 'class' => array(),
'align' => array ( 'maxlen' => 10 )
)
);
$kses -> AddHTML ( " ul " );
$kses -> AddHTML (
" ol " , array (
" type " => array ( 'maxlen' => 20 )
)
);
$kses -> AddHTML ( " li " );
$kses -> AddHTML ( " h1 " );
$kses -> AddHTML ( " h2 " );
$kses -> AddHTML ( " h3 " );
$kses -> AddHTML (
" style " , array (
" type " => array ( 'maxlen' => 20 ),
" color " => array ( 'maxlen' => 20 ),
" background-color " => array ( 'maxlen' => 20 ),
" background " => array ( 'maxlen' => 5 ),
)
);
$kses -> AddHTML ( " select " );
$kses -> AddHTML (
" option " , array (
" value " => array ( 'maxlen' => 45 ),
" selected " => array ()
)
);
$kses -> AddHTML (
" a " , array (
" href " => array ( 'maxlen' => 348 , 'minlen' => 10 ),
" name " => array ( 'minlen' => 2 ),
'target' => array ( 'maxlen' => 10 )
)
);
$kses -> AddHTML (
" pre " , array (
" wrap " => array ( 'maxlen' => 10 )
)
);
// Allows 'td' tag with colspan|rowspan|class|style|width|nowrap attributes,
// colspan has minval of 2 and maxval of 5
// rowspan has minval of 3 and maxval of 6
// class has minlen of 1 char and maxlen of 10 chars
2011-08-17 15:28:50 +02:00
// style has minlen of 5 chars and maxlen of 100 chars
2010-09-06 15:31:00 +02:00
// width has maxval of 100
// nowrap is valueless
$kses -> AddHTML (
" table " , array (
" class " => array ( " minlen " => 1 , 'maxlen' => 20 ),
" border " => array ( " minlen " => 1 , 'maxlen' => 10 ),
" cellpadding " => array ( " minlen " => 0 , 'maxlen' => 10 ),
" cellspacing " => array ( " minlen " => 0 , 'maxlen' => 10 ),
" width " => array ( " maxlen " => 5 ),
2011-08-17 15:28:50 +02:00
" style " => array ( 'minlen' => 5 , 'maxlen' => 100 ),
2010-09-06 15:31:00 +02:00
" bgcolor " => array ( 'maxlen' => 10 ),
" align " => array ( 'maxlen' => 10 ),
" valign " => array ( 'maxlen' => 10 ),
" bordercolor " => array ( 'maxlen' => 10 )
)
);
$kses -> AddHTML (
" tr " , array (
" colspan " => array ( 'minval' => 2 , 'maxval' => 5 ),
" rowspan " => array ( 'minval' => 3 , 'maxval' => 6 ),
" class " => array ( " minlen " => 1 , 'maxlen' => 20 ),
" width " => array ( " maxlen " => 5 ),
2011-08-17 15:28:50 +02:00
" style " => array ( 'minlen' => 5 , 'maxlen' => 100 ),
2010-09-06 15:31:00 +02:00
" align " => array ( 'maxlen' => 10 ),
'bgcolor' => array ( 'maxlen' => 10 ),
" valign " => array ( 'maxlen' => 10 ),
" nowrap " => array ( 'valueless' => 'y' )
)
);
$kses -> AddHTML (
" td " , array (
" colspan " => array ( 'minval' => 2 , 'maxval' => 5 ),
" rowspan " => array ( 'minval' => 3 , 'maxval' => 6 ),
" class " => array ( " minlen " => 1 , 'maxlen' => 20 ),
" width " => array ( " maxlen " => 5 ),
2011-08-17 15:28:50 +02:00
" style " => array ( 'minlen' => 5 , 'maxlen' => 100 ),
2010-09-06 15:31:00 +02:00
" align " => array ( 'maxlen' => 10 ),
'bgcolor' => array ( 'maxlen' => 10 ),
" valign " => array ( 'maxlen' => 10 ),
" nowrap " => array ( 'valueless' => 'y' )
)
);
$kses -> AddHTML (
" th " , array (
" colspan " => array ( 'minval' => 2 , 'maxval' => 5 ),
" rowspan " => array ( 'minval' => 3 , 'maxval' => 6 ),
" class " => array ( " minlen " => 1 , 'maxlen' => 20 ),
" width " => array ( " maxlen " => 5 ),
2011-08-17 15:28:50 +02:00
" style " => array ( 'minlen' => 5 , 'maxlen' => 100 ),
2010-09-06 15:31:00 +02:00
" align " => array ( 'maxlen' => 10 ),
" valign " => array ( 'maxlen' => 10 ),
" nowrap " => array ( 'valueless' => 'y' )
)
);
$kses -> AddHTML (
" span " , array (
" class " => array ( " minlen " => 1 , 'maxlen' => 20 ),
" style " => array ( 'minlen' => 5 , 'maxlen' => 100 )
)
);
$kses -> AddHTML (
" blockquote " , array (
" class " => array ( " minlen " => 1 , 'maxlen' => 20 ),
" style " => array ( " minlen " => 1 ),
" cite " => array ( 'maxlen' => 30 ),
" type " => array ( 'maxlen' => 10 ),
" dir " => array ( " minlen " => 1 , 'maxlen' => 10 )
)
);
$kses -> AddHTML (
'img' , array (
" src " => array ( " minlen " => 4 , 'maxlen' => 384 , $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'felamimail' ][ 'allowExternalIMGs' ] ? '' : 'match' => '/^cid:.*/' ),
" align " => array ( " minlen " => 1 ),
" border " => array ( 'maxlen' => 30 ),
" width " => array ( " minlen " => 1 , 'maxlen' => 3 ),
" height " => array ( " minlen " => 1 , 'maxlen' => 3 ),
)
);
// no scripts allowed
// clean out comments
$search = array (
2012-04-17 11:12:01 +02:00
'@<!--[\s\S]*?[ \t\n\r]*-->@' , // Strip multi-line comments including CDATA
2010-09-06 15:31:00 +02:00
'@url\(http:\/\/[^\)].*?\)@si' , // url calls e.g. in style definitions
);
//error_log(__METHOD__.$_html);
$_html = preg_replace ( $search , " " , $_html );
// do the kses clean out first, to avoid general problems with content later on
$_html = $kses -> Parse ( $_html );
// remove non printable chars
$_html = preg_replace ( '/([\000-\012])/' , '' , $_html );
//error_log($_html);
}
2012-04-17 11:12:01 +02:00
// using purify above should have tidied the tags already sufficiently
2012-02-03 13:57:19 +01:00
if ( $usepurify == false && $cleanTags == true )
{
if ( extension_loaded ( 'tidy' ))
{
$tidy = new tidy ();
2012-03-13 09:59:29 +01:00
$cleaned = $tidy -> repairString ( $_html , self :: $tidy_config , 'utf8' );
2012-02-03 13:57:19 +01:00
// Found errors. Strip it all so there's some output
if ( $tidy -> getStatus () == 2 )
{
error_log ( __METHOD__ . __LINE__ . ' ->' . $tidy -> errorBuffer );
}
else
{
$_html = $cleaned ;
}
}
else
{
$_html = html :: purify ( $_html , html :: purifyCreateHTMLTidyConfig ());
}
}
2010-09-06 15:31:00 +02:00
}
/**
* replace emailaddresses enclosed in <> ( eg .: < me @ you . de > ) with the emailaddress only ( e . g : me @ you . de )
* always returns 1
*/
static function replaceEmailAdresses ( & $text )
{
return translation :: replaceEmailAdresses ( $text );
}
static function convertHTMLToText ( $_html , $stripcrl = false , $stripalltags = true )
{
return translation :: convertHTMLToText ( $_html , self :: $displayCharset , $stripcrl , $stripalltags );
}
/**
* 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 );
2012-07-10 16:47:53 +02:00
$attachment = $this -> icServer -> getBodyPart ( $_uid , $_partID , true , true );
2010-09-06 15:31:00 +02:00
2010-11-05 15:03:45 +01:00
if ( PEAR :: isError ( $attachment ))
{
error_log ( __METHOD__ . __LINE__ . ' failed:' . $attachment -> message );
return array ( 'type' => 'text/plain' ,
'filename' => 'error.txt' ,
'attachment' => __METHOD__ . ' failed:' . $attachment -> message
);
}
2010-09-06 15:31:00 +02:00
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
}
2011-11-10 16:20:58 +01:00
if ( $structure -> type === 'TEXT' && isset ( $structure -> parameters [ 'CHARSET' ]) && stripos ( 'UTF-16' , $structure -> parameters [ 'CHARSET' ]) !== false )
{
$attachment = translation :: convert ( $attachment , $structure -> parameters [ 'CHARSET' ], self :: $displayCharset );
}
2010-09-06 15:31:00 +02:00
$attachmentData = array (
'type' => $structure -> type . '/' . $structure -> subType ,
'filename' => $filename ,
'attachment' => $attachment
);
// try guessing the mimetype, if we get the application/octet-stream
if ( strtolower ( $attachmentData [ 'type' ]) == 'application/octet-stream' ) $attachmentData [ 'type' ] = mime_magic :: filename2mime ( $attachmentData [ 'filename' ]);
# 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 )
{
2011-06-09 15:54:17 +02:00
// some static variables to avoid fetching the same mail multiple times
static $uid , $part , $attachments , $structure ;
if ( $_uid != $uid || $_part != $part )
{
$attachments = $this -> getMessageAttachments ( $uid = $_uid , $part = $_part );
$structure = null ;
}
2010-09-06 15:31:00 +02:00
$partID = false ;
2011-06-09 15:54:17 +02:00
//list($cidname,$cidrest) = explode('@',$_cid,2);
//error_log("getAttachmentByCID:$_uid ($cidname -> $cidrest), $_cid, $_part");
foreach ( $attachments as $attachment )
{
//error_log(print_r($attachment,true));
if ( isset ( $attachment [ 'cid' ]) && ( strpos ( $attachment [ 'cid' ], $_cid ) !== false || strpos ( $_cid , $attachment [ 'cid' ]) !== false ))
{
2010-09-06 15:31:00 +02:00
$partID = $attachment [ 'partID' ];
break ;
}
}
2011-06-09 15:54:17 +02:00
if ( $partID == false )
{
foreach ( $attachments as $attachment )
{
// if the former did not match try matching the cid to the name of the attachment
if ( isset ( $attachment [ 'cid' ]) && isset ( $attachment [ 'name' ]) && ( strpos ( $attachment [ 'name' ], $_cid ) !== false || strpos ( $_cid , $attachment [ 'name' ]) !== false ))
{
$partID = $attachment [ 'partID' ];
break ;
}
}
}
2011-06-10 11:21:55 +02:00
if ( $partID == false )
{
foreach ( $attachments as $attachment )
{
// if the former did not match try matching the cid to the name of the attachment, AND there is no mathing attachment with cid
if ( isset ( $attachment [ 'name' ]) && ( strpos ( $attachment [ 'name' ], $_cid ) !== false || strpos ( $_cid , $attachment [ 'name' ]) !== false ))
{
$partID = $attachment [ 'partID' ];
break ;
}
}
}
2011-06-09 15:54:17 +02:00
//error_log( "Cid:$_cid PARTID:$partID<bR>"); #exit;
2010-09-06 15:31:00 +02:00
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 );
2010-11-05 15:03:45 +01:00
if ( PEAR :: isError ( $attachment ))
{
error_log ( __METHOD__ . __LINE__ . ' failed:' . $attachment -> message );
return array ( 'type' => 'text/plain' ,
'filename' => 'error.txt' ,
'attachment' => __METHOD__ . ' failed:' . $attachment -> message
);
}
2010-09-06 15:31:00 +02:00
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
);
// try guessing the mimetype, if we get the application/octet-stream
if ( strtolower ( $attachmentData [ 'type' ]) == 'application/octet-stream' ) $attachmentData [ 'type' ] = mime_magic :: filename2mime ( $attachmentData [ 'filename' ]);
2012-04-17 11:12:01 +02:00
2010-09-06 15:31:00 +02:00
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 )
{
if ( self :: $debug ) error_log ( __METHOD__ . " called with: " . $_folderName );
$retValue = array ();
$retValue [ 'subscribed' ] = false ;
if ( ! $icServer = $this -> mailPreferences -> getIncomingServer ( 0 )) {
return false ;
}
// does the folder exist???
$folderInfo = $this -> icServer -> getMailboxes ( '' , $_folderName , true );
2011-09-12 17:31:35 +02:00
if (( $folderInfo instanceof PEAR_Error ) || ! is_array ( $folderInfo [ 0 ])) {
2010-09-06 15:31:00 +02:00
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
2010-11-02 15:03:31 +01:00
elseif ( in_array ( $retValue [ 'shortName' ], self :: $autoFolders ))
2010-09-06 15:31:00 +02:00
{
$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' );
}
// force unsubscribed by preference showAllFoldersInFolderPane
2012-04-17 11:12:01 +02:00
if ( $_subscribedOnly == true &&
isset ( $this -> mailPreferences -> preferences [ 'showAllFoldersInFolderPane' ]) &&
2010-09-06 15:31:00 +02:00
$this -> mailPreferences -> preferences [ 'showAllFoldersInFolderPane' ] == 1 )
{
$_subscribedOnly = false ;
2012-04-17 11:12:01 +02:00
}
2010-09-06 15:31:00 +02:00
#$inboxData->attributes = 64;
2010-11-02 15:03:31 +01:00
$inboxFolderObject = array ( 'INBOX' => $inboxData );
2010-09-06 15:31:00 +02:00
#_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)." ###################<br>";
$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<br>";
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. " . " <br> " ;
} else {
echo " failed. " . " <br> " ;
}
}
}
}
// fetch and sort all folders
#echo $type.'->'.$foldersNameSpace[$type]['prefix'].'->'.($type=='shared'?0:2)."<br>";
$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']."<br>";
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' ]))
{
2010-11-02 15:03:31 +01:00
$foldersToCheck = array_diff ( self :: $autoFolders , explode ( ',' , $this -> mailPreferences -> preferences [ 'notavailableautofolders' ]));
2010-09-06 15:31:00 +02:00
} else {
2010-11-02 15:03:31 +01:00
$foldersToCheck = self :: $autoFolders ;
2010-09-06 15:31:00 +02:00
}
#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 ;
2013-07-26 15:12:32 +02:00
switch ( $personalFolderName )
2010-09-06 15:31:00 +02:00
{
case 'Drafts' : // => Entwürfe
2013-07-26 15:12:32 +02:00
$draftFolder = $this -> getDraftFolder ();
if ( $draftFolder && $draftFolder == 'none' )
2010-09-06 15:31:00 +02:00
$createfolder = false ;
break ;
case 'Junk' : //] => Spammails
if ( $this -> mailPreferences -> preferences [ 'junkFolder' ] && $this -> mailPreferences -> preferences [ 'junkFolder' ] == 'none' )
$createfolder = false ;
break ;
case 'Sent' : //] => Gesendet
2013-07-26 15:12:32 +02:00
// ToDo: we may need more sophistcated checking here
$sentFolder = $this -> getSentFolder ();
if ( $sentFolder && $sentFolder == 'none' )
2010-09-06 15:31:00 +02:00
$createfolder = false ;
break ;
case 'Trash' : //] => Papierkorb
2013-07-26 15:12:32 +02:00
$trashFolder = $this -> getTrashFolder ();
if ( $trashFolder && $trashFolder == 'none' )
2010-09-06 15:31:00 +02:00
$createfolder = false ;
break ;
case 'Templates' : //] => Vorlagen
2013-07-26 15:12:32 +02:00
$templateFolder = $this -> getTemplateFolder ();
if ( $templateFolder && $templateFolder == 'none' )
$createfolder = false ;
break ;
case 'Outbox' : // Nokia Outbox for activesync
//if ($this->mailPreferences->preferences['outboxFolder'] && $this->mailPreferences->preferences['outboxFolder']=='none')
2010-09-06 15:31:00 +02:00
$createfolder = false ;
2013-07-26 15:12:32 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'activesync' ]) $createfolder = true ;
2010-09-06 15:31:00 +02:00
break ;
}
2013-07-26 15:12:32 +02:00
// check for the foldername as constructed with prefix (or not)
if ( $createfolder && self :: folderExists ( $folderName ))
{
$createfolder = false ;
}
// check for the folder as it comes (no prefix)
if ( $createfolder && $personalFolderName != $folderName && self :: folderExists ( $personalFolderName ))
{
$createfolder = false ;
$folderName = $personalFolderName ;
}
// check for the folder as it comes with INBOX prefixed
$folderWithInboxPrefixed = $folderPrefixAsInbox . $personalFolderName ;
if ( $createfolder && $folderWithInboxPrefixed != $folderName && self :: folderExists ( $folderWithInboxPrefixed ))
{
$createfolder = false ;
$folderName = $folderWithInboxPrefixed ;
}
// now proceed with the folderName that may be altered in the progress of testing for existence
if ( $createfolder === false && $_alwaysGetDefaultFolders )
{
if ( ! in_array ( $folderName , $foldersNameSpace [ 'personal' ][ 'all' ])) $foldersNameSpace [ 'personal' ][ 'all' ][] = $folderName ;
if ( ! in_array ( $folderName , $foldersNameSpace [ 'personal' ][ 'subscribed' ])) $foldersNameSpace [ 'personal' ][ 'subscribed' ][] = $folderName ;
}
2010-09-06 15:31:00 +02:00
if ( $createfolder === true && $this -> createFolder ( '' , $folderName , true )) {
$foldersNameSpace [ 'personal' ][ 'all' ][] = $folderName ;
$foldersNameSpace [ 'personal' ][ 'subscribed' ][] = $folderName ;
} else {
#print "FOLDERNAME failed: $folderName<br>";
}
}
}
}
}
#echo "<br>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 "<br>FolderToCheck:$folderName<br>";
if ( $_subscribedOnly && ! in_array ( $folderName , $foldersNameSpace [ $type ][ 'all' ])) {
#echo "$folderName failed to be here <br>";
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."<br>";
#_debug_array($foldersNameSpace[$type]['subscribed']);
$folderObject -> subscribed = in_array ( $folderName , $foldersNameSpace [ $type ][ 'subscribed' ]);
}
if ( $_getCounters == true ) {
/*
$folderStatus = $this -> icServer -> getStatus ( $folderName );
#echo "<br> 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 ;
2010-11-02 15:03:31 +01:00
2010-09-06 15:31:00 +02:00
// translate the automatic Folders (Sent, Drafts, ...) like the INBOX
2010-11-02 15:03:31 +01:00
} elseif ( in_array ( $shortName , self :: $autoFolders )) {
2010-09-06 15:31:00 +02:00
$tmpfolderparts = explode ( $delimiter , $folderObject -> folderName );
array_pop ( $tmpfolderparts );
2010-11-09 10:06:44 +01:00
$folderObject -> displayName = implode ( $delimiter , $tmpfolderparts ) . $delimiter . lang ( $shortName );
2010-09-06 15:31:00 +02:00
$folderObject -> shortDisplayName = lang ( $shortName );
unset ( $tmpfolderparts );
} else {
$folderObject -> displayName = $this -> encodeFolderName ( $folderObject -> folderName );
$folderObject -> shortDisplayName = $this -> encodeFolderName ( $shortName );
}
$folderName = $folderName ;
2010-11-02 15:03:31 +01:00
if ( in_array ( $shortName , self :: $autoFolders )) {
$autoFolderObjects [ $folderName ] = $folderObject ;
} else {
$folders [ $folderName ] = $folderObject ;
}
2010-09-06 15:31:00 +02:00
}
}
}
2010-11-02 15:03:31 +01:00
if ( is_array ( $autoFolderObjects )) {
uasort ( $autoFolderObjects , array ( $this , " sortByAutoFolderPos " ));
}
if ( is_array ( $folders )) uasort ( $folders , array ( $this , " sortByDisplayName " ));
2010-12-06 17:20:05 +01:00
//$folders2return = array_merge($autoFolderObjects,$folders);
2010-11-02 15:03:31 +01:00
//_debug_array($folders2return); #exit;
return array_merge ( $inboxFolderObject ,( array ) $autoFolderObjects ,( array ) $folders );
2010-09-06 15:31:00 +02:00
}
function sortByDisplayName ( $a , $b )
{
// 0, 1 und -1
return strcasecmp ( $a -> displayName , $b -> displayName );
}
2010-11-02 15:03:31 +01:00
function sortByAutoFolderPos ( $a , $b )
{
// 0, 1 und -1
$pos1 = array_search ( $a -> shortFolderName , self :: $autoFolders );
$pos2 = array_search ( $b -> shortFolderName , self :: $autoFolders );
if ( $pos1 == $pos2 ) return 0 ;
return ( $pos1 < $pos2 ) ? - 1 : 1 ;
}
2010-09-06 15:31:00 +02:00
function getMailBoxCounters ( $folderName )
{
$folderStatus = $this -> icServer -> getStatus ( $folderName );
#echo "<br> 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 <br>";
$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']."<br>";
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."<br>";
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 ;
}
2012-07-10 16:47:53 +02:00
function getMultipartAlternative ( $_uid , $_structure , $_htmlMode , $_preserveSeen = false )
2010-09-06 15:31:00 +02:00
{
// a multipart/alternative has exactly 2 parts (text and html OR text and something else)
$partText = false ;
$partHTML = false ;
if ( self :: $debug ) _debug_array ( array ( " METHOD " => __METHOD__ , " LINE " => __LINE__ , " STRUCTURE " => $_structure ));
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 ;
2013-01-15 13:07:07 +01:00
} elseif ( $mimePart -> type == 'MULTIPART' && ( $mimePart -> subType == 'RELATED' || $mimePart -> subType == 'MIXED' ) && is_array ( $mimePart -> subParts )) {
2010-09-06 15:31:00 +02:00
// 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 ;
} elseif ( $mimePart -> type == 'MULTIPART' && $mimePart -> subType == 'ALTERNATIVE' && is_array ( $mimePart -> subParts )) {
//cascading multipartAlternative structure, assuming only the first one is to be used
2012-07-10 16:47:53 +02:00
return $this -> getMultipartAlternative ( $_uid , $mimePart -> subParts , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
}
switch ( $_htmlMode ) {
case 'always_display' :
if ( is_object ( $partHTML )) {
if ( $partHTML -> subType == 'RELATED' ) {
2012-07-10 16:47:53 +02:00
return $this -> getMultipartRelated ( $_uid , $partHTML , 'always_display' , $_preserveSeen );
2013-01-15 13:07:07 +01:00
} elseif ( $partHTML -> subType == 'MIXED' ) {
return $this -> getMultipartMixed ( $_uid , $partHTML , 'always_display' , $_preserveSeen );
2010-09-06 15:31:00 +02:00
} else {
2012-07-10 16:47:53 +02:00
return $this -> getTextPart ( $_uid , $partHTML , 'always_display' , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
} elseif ( is_object ( $partText )) {
2012-07-10 16:47:53 +02:00
return $this -> getTextPart ( $_uid , $partTexti , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
break ;
case 'only_if_no_text' :
if ( is_object ( $partText )) {
2012-07-10 16:47:53 +02:00
return $this -> getTextPart ( $_uid , $partText , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
} elseif ( is_object ( $partHTML )) {
if ( $partHTML -> type ) {
2012-07-10 16:47:53 +02:00
return $this -> getMultipartRelated ( $_uid , $partHTML , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
} else {
2012-07-10 16:47:53 +02:00
return $this -> getTextPart ( $_uid , $partHTML , 'always_display' , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
}
break ;
default :
if ( is_object ( $partText )) {
2012-07-10 16:47:53 +02:00
return $this -> getTextPart ( $_uid , $partText , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
} else {
$bodyPart = array (
'body' => lang ( " no plain text part found " ),
'mimeType' => 'text/plain' ,
'charSet' => self :: $displayCharset ,
);
}
break ;
}
return $bodyPart ;
}
2012-07-10 16:47:53 +02:00
function getMultipartMixed ( $_uid , $_structure , $_htmlMode , $_preserveSeen = false )
2010-09-06 15:31:00 +02:00
{
if ( self :: $debug ) echo __METHOD__ . " $_uid , $_htmlMode <br> " ;
$bodyPart = array ();
2012-04-17 11:12:01 +02:00
if ( self :: $debug ) _debug_array ( $_structure );
2010-09-06 15:31:00 +02:00
if ( ! is_array ( $_structure )) $_structure = array ( $_structure );
foreach ( $_structure as $part ) {
if ( self :: $debug ) echo $part -> type . " / " . $part -> subType . " <br> " ;
switch ( $part -> type ) {
case 'MULTIPART' :
switch ( $part -> subType ) {
case 'ALTERNATIVE' :
2012-07-10 16:47:53 +02:00
$bodyPart [] = $this -> getMultipartAlternative ( $_uid , $part -> subParts , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
break ;
case 'MIXED' :
case 'SIGNED' :
2012-07-10 16:47:53 +02:00
$bodyPart = array_merge ( $bodyPart , $this -> getMultipartMixed ( $_uid , $part -> subParts , $_htmlMode , $_preserveSeen ));
2010-09-06 15:31:00 +02:00
break ;
case 'RELATED' :
2012-07-10 16:47:53 +02:00
$bodyPart = array_merge ( $bodyPart , $this -> getMultipartRelated ( $_uid , $part -> subParts , $_htmlMode , $_preserveSeen ));
2010-09-06 15:31:00 +02:00
break ;
}
break ;
case 'TEXT' :
switch ( $part -> subType ) {
case 'PLAIN' :
case 'HTML' :
if ( $part -> disposition != 'ATTACHMENT' ) {
2012-07-10 16:47:53 +02:00
$bodyPart [] = $this -> getTextPart ( $_uid , $part , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
break ;
}
break ;
case 'MESSAGE' :
if ( $part -> subType == 'delivery-status' ) {
2012-07-10 16:47:53 +02:00
$bodyPart [] = $this -> getTextPart ( $_uid , $part , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
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 ;
}
2012-07-10 16:47:53 +02:00
function getMultipartRelated ( $_uid , $_structure , $_htmlMode , $_preserveSeen = false )
2010-09-06 15:31:00 +02:00
{
2012-07-10 16:47:53 +02:00
return $this -> getMultipartMixed ( $_uid , $_structure , $_htmlMode , $_preserveSeen );
2010-09-06 15:31:00 +02:00
}
2012-07-10 16:47:53 +02:00
function getTextPart ( $_uid , $_structure , $_htmlMode = '' , $_preserveSeen = false )
2010-09-06 15:31:00 +02:00
{
$bodyPart = array ();
#_debug_array($_structure);
$partID = $_structure -> partID ;
2012-07-10 16:47:53 +02:00
$mimePartBody = $this -> icServer -> getBodyPart ( $_uid , $partID , true , $_preserveSeen );
2010-11-05 15:03:45 +01:00
if ( PEAR :: isError ( $mimePartBody ))
{
error_log ( __METHOD__ . __LINE__ . ' failed:' . $mimePartBody -> message );
return false ;
}
//_debug_array($mimePartBody);
//_debug_array(preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding)));
2010-09-06 15:31:00 +02:00
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 ),
);
2013-02-26 15:58:12 +01:00
if ( $_structure -> type == 'TEXT' && $_structure -> subType == 'PLAIN' &&
is_array ( $_structure -> parameters ) && isset ( $_structure -> parameters [ 'FORMAT' ]) &&
trim ( strtolower ( $_structure -> parameters [ 'FORMAT' ])) == 'flowed'
)
{
if ( self :: $debug ) error_log ( __METHOD__ . __LINE__ . " detected TEXT/PLAIN Format:flowed -> removing leading blank (' \r \n ') per line " );
$bodyPart [ 'body' ] = str_replace ( " \r \n " , " \r \n " , $bodyPart [ 'body' ]);
}
2010-09-06 15:31:00 +02:00
}
//_debug_array($bodyPart);
return $bodyPart ;
}
2013-07-26 15:12:32 +02:00
function _getNameSpaces ()
{
static $nameSpace ;
$foldersNameSpace = array ();
$delimiter = $this -> getHierarchyDelimiter ();
// TODO: cache by $this->icServer->ImapServerId
if ( is_null ( $nameSpace )) $nameSpace = $this -> icServer -> getNameSpaces ();
if ( is_array ( $nameSpace )) {
foreach ( $nameSpace as $type => $singleNameSpace ) {
$prefix_present = false ;
if ( $type == 'personal' && ( $singleNameSpace [ 2 ][ 'name' ] == '#mh/' || count ( $nameSpace ) == 1 ) && ( $this -> folderExists ( 'Mail' ) || $this -> folderExists ( 'INBOX' )))
{
$foldersNameSpace [ $type ][ 'prefix_present' ] = 'forced' ;
// uw-imap server with mailbox prefix or dovecot maybe
$foldersNameSpace [ $type ][ 'prefix' ] = ( $this -> folderExists ( 'Mail' ) ? 'Mail' : ( ! empty ( $singleNameSpace [ 0 ][ 'name' ]) ? $singleNameSpace [ 0 ][ 'name' ] : '' ));
}
elseif ( $type == 'personal' && ( $singleNameSpace [ 2 ][ 'name' ] == '#mh/' || count ( $nameSpace ) == 1 ) && $this -> folderExists ( 'mail' ))
{
$foldersNameSpace [ $type ][ 'prefix_present' ] = 'forced' ;
// uw-imap server with mailbox prefix or dovecot maybe
$foldersNameSpace [ $type ][ 'prefix' ] = 'mail' ;
} else {
$foldersNameSpace [ $type ][ 'prefix_present' ] = true ;
$foldersNameSpace [ $type ][ 'prefix' ] = $singleNameSpace [ 0 ][ 'name' ];
}
$foldersNameSpace [ $type ][ 'delimiter' ] = $delimiter ;
//echo "############## $type->".print_r($foldersNameSpace[$type],true)." ###################<br>";
}
}
//error_log(__METHOD__.__LINE__.array2string($foldersNameSpace));
return $foldersNameSpace ;
}
function getFolderPrefixFromNamespace ( $nameSpace , $folderName )
2010-09-06 15:31:00 +02:00
{
2013-07-26 15:12:32 +02:00
foreach ( $nameSpace as $type => $singleNameSpace )
{
//if (substr($singleNameSpace['prefix'],0,strlen($folderName))==$folderName) return $singleNameSpace['prefix'];
if ( substr ( $folderName , 0 , strlen ( $singleNameSpace [ 'prefix' ])) == $singleNameSpace [ 'prefix' ]) return $singleNameSpace [ 'prefix' ];
}
return " " ;
2010-09-06 15:31:00 +02:00
}
2013-07-26 15:12:32 +02:00
2010-09-06 15:31:00 +02:00
function getHierarchyDelimiter ()
{
$HierarchyDelimiter = '/' ;
2012-04-17 11:12:01 +02:00
if (( $this -> icServer instanceof defaultimap ))
2010-09-06 15:31:00 +02:00
{
$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 &&
! empty ( $this -> sessionData [ 'folderStatus' ][ 0 ][ $_folderName ][ 'sortResult' ])
) {
if ( self :: $debug ) error_log ( __METHOD__ . " USE CACHE " );
$sortResult = $this -> sessionData [ 'folderStatus' ][ 0 ][ $_folderName ][ 'sortResult' ];
} else {
if ( self :: $debug ) error_log ( __METHOD__ . " USE NO CACHE " );
$filter = $this -> createIMAPFilter ( $_folderName , $_filter );
if ( $this -> icServer -> hasCapability ( 'SORT' )) {
if ( self :: $debug ) error_log ( __METHOD__ . " Mailserver has SORT Capability " );
$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 );
// if there is an PEAR Error, we assume that the server is not capable of sorting
if ( PEAR :: isError ( $sortResult )) {
$advFilter = 'CHARSET ' . strtoupper ( self :: $displayCharset ) . ' ' . $filter ;
2012-04-17 11:12:01 +02:00
if ( PEAR :: isError ( $sortResult ))
2010-09-06 15:31:00 +02:00
{
$sortResult = $this -> icServer -> search ( $filter , false );
if ( PEAR :: isError ( $sortResult ))
{
$sortResult = $this -> sessionData [ 'folderStatus' ][ 0 ][ $_folderName ][ 'sortResult' ];
}
}
}
}
if ( self :: $debug ) error_log ( __METHOD__ . print_r ( $sortResult , true ));
} else {
if ( self :: $debug ) error_log ( __METHOD__ . " Mailserver has NO SORT Capability " );
$advFilter = 'CHARSET ' . strtoupper ( self :: $displayCharset ) . ' ' . $filter ;
2012-11-08 16:43:15 +01:00
$resultByUid = true ;
$sortResult = $this -> icServer -> search ( $advFilter , $resultByUid );
if ( PEAR :: isError ( $sortResult ))
{
$sortResult = $this -> icServer -> search ( $filter , $resultByUid );
if ( PEAR :: isError ( $sortResult ))
{
// some servers are not replying on a search for uids, so try this one
$resultByUid = false ;
$sortResult = $this -> icServer -> search ( '*' , $resultByUid );
if ( PEAR :: isError ( $sortResult ))
{
error_log ( __METHOD__ . __LINE__ . ' PEAR_Error:' . array2string ( $sortResult -> message ));
$sortResult = null ;
}
}
}
2010-09-06 15:31:00 +02:00
if ( is_array ( $sortResult )) {
sort ( $sortResult , SORT_NUMERIC );
}
if ( self :: $debug ) error_log ( __METHOD__ . " using Filter: " . print_r ( $filter , true ) . " -> " . print_r ( $sortResult , true ));
}
$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 ;
}
2010-09-10 15:21:05 +02:00
function getMessageEnvelope ( $_uid , $_partID = '' , $decode = false )
2010-09-06 15:31:00 +02:00
{
if ( $_partID == '' ) {
if ( PEAR :: isError ( $envelope = $this -> icServer -> getEnvelope ( '' , $_uid , true )) ) {
return false ;
}
2010-09-10 15:21:05 +02:00
return ( $decode ? self :: decode_header ( $envelope [ 0 ]) : $envelope [ 0 ]);
2010-09-06 15:31:00 +02:00
} else {
if ( PEAR :: isError ( $headers = $this -> icServer -> getParsedHeaders ( $_uid , true , $_partID , true )) ) {
return false ;
}
#_debug_array($headers);
$newData = array (
'DATE' => $headers [ 'DATE' ],
2010-09-10 16:02:16 +02:00
'SUBJECT' => ( $decode ? self :: decode_header ( $headers [ 'SUBJECT' ]) : $headers [ 'SUBJECT' ]),
2010-09-06 15:31:00 +02:00
'MESSAGE_ID' => $headers [ 'MESSAGE-ID' ]
);
$recepientList = array ( 'FROM' , 'TO' , 'CC' , 'BCC' , 'SENDER' , 'REPLY_TO' );
foreach ( $recepientList as $recepientType ) {
if ( isset ( $headers [ $recepientType ])) {
2010-09-10 15:21:05 +02:00
if ( $decode ) $headers [ $recepientType ] = self :: decode_header ( $headers [ $recepientType ]);
2010-09-06 15:31:00 +02:00
$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 , $_thisUIDOnly = null )
{
$reverse = ( bool ) $_reverse ;
// get the list of messages to fetch
$this -> reopen ( $_folderName );
//$this->icServer->selectMailbox($_folderName);
#print "<pre>";
#$this->icServer->setDebug(true);
if ( $_thisUIDOnly === null )
{
$sortResult = $this -> getSortedList ( $_folderName , $_sort , $_reverse , $_filter );
#$this->icServer->setDebug(false);
#print "</pre>";
// 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 );
2012-10-18 12:52:53 +02:00
//_debug_array($sortResult);
2010-09-06 15:31:00 +02:00
#_debug_array(array_slice($sortResult, -5, -2));
2012-10-18 12:52:53 +02:00
//error_log("REVERSE: $reverse".count($sortResult));
2010-09-06 15:31:00 +02:00
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 );
}
}
else
{
$sortResult = ( is_array ( $_thisUIDOnly ) ? $_thisUIDOnly : ( array ) $_thisUIDOnly );
}
$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 ) {
2010-09-24 14:41:57 +02:00
//if($count == 0) error_log(__METHOD__.array2string($headerObject));
2010-09-06 15:31:00 +02:00
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' ];
2012-10-18 12:52:53 +02:00
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'date' ] = self :: _strtotime (( $headerObject [ 'DATE' ] ? $headerObject [ 'DATE' ] : $headerObject [ 'INTERNALDATE' ]), 'ts' , true );
2010-09-06 15:31:00 +02:00
$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' ) {
2010-09-24 14:41:57 +02:00
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'sender_address' ] = self :: decode_header ( $headerObject [ 'FROM' ][ 0 ][ 'EMAIL' ]);
2010-09-06 15:31:00 +02:00
} else {
2010-09-24 14:41:57 +02:00
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'sender_address' ] = self :: decode_header ( $headerObject [ 'FROM' ][ 0 ][ 'MAILBOX_NAME' ]);
2010-09-06 15:31:00 +02:00
}
if ( $headerObject [ 'FROM' ][ 0 ][ 'PERSONAL_NAME' ] != 'NIL' ) {
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'sender_name' ] = self :: decode_header ( $headerObject [ 'FROM' ][ 0 ][ 'PERSONAL_NAME' ]);
}
}
if ( is_array ( $headerObject [ 'TO' ]) && is_array ( $headerObject [ 'TO' ][ 0 ])) {
if ( $headerObject [ 'TO' ][ 0 ][ 'HOST_NAME' ] != 'NIL' ) {
2010-09-24 14:41:57 +02:00
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'to_address' ] = self :: decode_header ( $headerObject [ 'TO' ][ 0 ][ 'EMAIL' ]);
2010-09-06 15:31:00 +02:00
} else {
2010-09-24 14:41:57 +02:00
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'to_address' ] = self :: decode_header ( $headerObject [ 'TO' ][ 0 ][ 'MAILBOX_NAME' ]);
2010-09-06 15:31:00 +02:00
}
if ( $headerObject [ 'TO' ][ 0 ][ 'PERSONAL_NAME' ] != 'NIL' ) {
$retValue [ 'header' ][ $sortOrder [ $uid ]][ 'to_name' ] = self :: 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<br>";
$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<br>";
if ( $position !== false ) {
$retValue = array ();
if ( $this -> sessionData [ 'folderStatus' ][ $this -> profileID ][ $_foldername ][ 'reverse' ] == true ) {
#print "is reverse<br>";
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 ;
}
2011-07-19 12:07:26 +02:00
function getMessageAttachments ( $_uid , $_partID = '' , $_structure = '' , $resolveTNEF = true )
2010-09-06 15:31:00 +02:00
{
if ( self :: $debug ) echo __METHOD__ . " $_uid , $_partID <br> " ;
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
2012-04-17 11:12:01 +02:00
if ( $structure -> type == 'APPLICATION' || $structure -> type == 'AUDIO' || $structure -> type == 'IMAGE' )
2010-09-06 15:31:00 +02:00
{
$newAttachment = array ();
$newAttachment [ 'name' ] = self :: getFileNameFromStructure ( $structure );
$newAttachment [ 'size' ] = $structure -> bytes ;
$newAttachment [ 'mimeType' ] = $structure -> type . '/' . $structure -> subType ;
$newAttachment [ 'partID' ] = $structure -> partID ;
$newAttachment [ 'encoding' ] = $structure -> encoding ;
// try guessing the mimetype, if we get the application/octet-stream
if ( strtolower ( $newAttachment [ 'mimeType' ]) == 'application/octet-stream' ) $newAttachment [ 'mimeType' ] = mime_magic :: filename2mime ( $newAttachment [ 'name' ]);
2012-04-17 11:12:01 +02:00
2010-09-06 15:31:00 +02:00
if ( isset ( $structure -> cid )) {
$newAttachment [ 'cid' ] = $structure -> cid ;
}
# if the new attachment is a winmail.dat, we have to decode that first
2011-07-19 12:07:26 +02:00
if ( $resolveTNEF && $newAttachment [ 'name' ] == 'winmail.dat' &&
2010-09-06 15:31:00 +02:00
( $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 )) ||
2012-04-17 11:12:01 +02:00
! is_array ( $structure -> subParts ))
2010-09-06 15:31:00 +02:00
{
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' )
{
2011-07-19 12:07:26 +02:00
$attachments = array_merge ( $this -> getMessageAttachments ( $_uid , '' , $subPart , $resolveTNEF ), $attachments );
2010-09-06 15:31:00 +02:00
}
if ( ! ( $subPart -> type == 'TEXT' && $subPart -> disposition == 'INLINE' && $subPart -> filename )) continue ;
}
// fetch the subparts for this part
if ( $subPart -> type == 'MULTIPART' &&
( $subPart -> subType == 'RELATED' ||
$subPart -> subType == 'MIXED' ||
$subPart -> subType == 'SIGNED' ||
$subPart -> subType == 'APPLEDOUBLE' ))
{
2011-07-19 12:07:26 +02:00
$attachments = array_merge ( $this -> getMessageAttachments ( $_uid , '' , $subPart , $resolveTNEF ), $attachments );
2010-09-06 15:31:00 +02:00
} else {
$newAttachment = array ();
$newAttachment [ 'name' ] = self :: getFileNameFromStructure ( $subPart );
$newAttachment [ 'size' ] = $subPart -> bytes ;
$newAttachment [ 'mimeType' ] = $subPart -> type . '/' . $subPart -> subType ;
$newAttachment [ 'partID' ] = $subPart -> partID ;
$newAttachment [ 'encoding' ] = $subPart -> encoding ;
// try guessing the mimetype, if we get the application/octet-stream
if ( strtolower ( $newAttachment [ 'mimeType' ]) == 'application/octet-stream' ) $newAttachment [ 'mimeType' ] = mime_magic :: filename2mime ( $newAttachment [ 'name' ]);
2012-04-17 11:12:01 +02:00
2010-09-06 15:31:00 +02:00
if ( isset ( $subPart -> cid )) {
$newAttachment [ 'cid' ] = $subPart -> cid ;
}
# if the new attachment is a winmail.dat, we have to decode that first
2011-07-19 12:07:26 +02:00
if ( $resolveTNEF && $newAttachment [ 'name' ] == 'winmail.dat' &&
2010-09-06 15:31:00 +02:00
( $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 )
{
2011-06-09 13:15:53 +02:00
static $namecounter ;
if ( is_null ( $namecounter )) $namecounter = 0 ;
2010-09-06 15:31:00 +02:00
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 {
2011-06-09 13:15:53 +02:00
$namecounter ++ ;
return lang ( " unknown " ) . $namecounter . ( $structure -> subType ? " . " . $structure -> subType : " " );
2010-09-06 15:31:00 +02:00
}
}
2012-07-10 16:47:53 +02:00
function getMessageBody ( $_uid , $_htmlOptions = '' , $_partID = '' , $_structure = '' , $_preserveSeen = false )
2010-09-06 15:31:00 +02:00
{
if ( self :: $debug ) echo __METHOD__ . " $_uid , $_htmlOptions , $_partID <br> " ;
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' :
2012-07-10 16:47:53 +02:00
$bodyParts = array ( $this -> getMultipartAlternative ( $_uid , $structure -> subParts , $this -> htmlOptions , $_preserveSeen ));
2010-09-06 15:31:00 +02:00
break ;
2013-02-26 15:58:12 +01:00
case 'NIL' :
2010-09-06 15:31:00 +02:00
case 'MIXED' :
case 'REPORT' :
case 'SIGNED' :
2012-07-10 16:47:53 +02:00
$bodyParts = $this -> getMultipartMixed ( $_uid , $structure -> subParts , $this -> htmlOptions , $_preserveSeen );
2010-09-06 15:31:00 +02:00
break ;
case 'RELATED' :
2012-07-10 16:47:53 +02:00
$bodyParts = $this -> getMultipartRelated ( $_uid , $structure -> subParts , $this -> htmlOptions , $_preserveSeen );
2010-09-06 15:31:00 +02:00
break ;
}
2010-09-15 16:12:17 +02:00
return self :: normalizeBodyParts ( $bodyParts );
2010-09-06 15:31:00 +02:00
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 :
2012-07-10 16:47:53 +02:00
$bodyPart = array ( $this -> getTextPart ( $_uid , $structure , $this -> htmlOptions , $_preserveSeen ));
2010-09-06 15:31:00 +02:00
}
} else {
// what if the structure->disposition is attachment ,...
}
2010-09-15 16:12:17 +02:00
return self :: normalizeBodyParts ( $bodyPart );
2010-09-06 15:31:00 +02:00
break ;
case 'MESSAGE' :
switch ( $structure -> subType ) {
case 'RFC822' :
$newStructure = array_shift ( $structure -> subParts );
2010-09-15 16:12:17 +02:00
return self :: normalizeBodyParts ( $this -> getMessageBody ( $_uid , $_htmlOptions , $newStructure -> partID , $newStructure ));
2010-09-06 15:31:00 +02:00
break ;
}
break ;
default :
return array (
array (
'body' => lang ( 'The mimeparser can not parse this message.' ),
'mimeType' => 'text/plain' ,
'charSet' => 'iso-8859-1' ,
)
);
break ;
}
}
2010-09-15 16:12:17 +02:00
/**
* normalizeBodyParts - function to gather and normalize all body Information
* @ param _bodyParts - Body Array
* @ returns array - a normalized Bodyarray
*/
2012-04-17 11:12:01 +02:00
static function normalizeBodyParts ( $_bodyParts )
2010-09-15 16:12:17 +02:00
{
if ( is_array ( $_bodyParts ))
{
2012-04-17 11:12:01 +02:00
foreach ( $_bodyParts as $singleBodyPart )
2010-09-15 16:12:17 +02:00
{
if ( ! isset ( $singleBodyPart [ 'body' ])) {
$buff = self :: normalizeBodyParts ( $singleBodyPart );
foreach ( $buff as $val ) $body2return [] = $val ;
continue ;
}
$body2return [] = $singleBodyPart ;
}
}
else
{
$body2return = $_bodyParts ;
}
return $body2return ;
}
2010-09-10 15:21:05 +02:00
function getMessageHeader ( $_uid , $_partID = '' , $decode = false )
2010-09-06 15:31:00 +02:00
{
$retValue = $this -> icServer -> getParsedHeaders ( $_uid , true , $_partID , true );
2010-09-10 15:21:05 +02:00
return ( $decode ? self :: decode_header ( $retValue ) : $retValue );
2010-09-06 15:31:00 +02:00
}
function getMessageRawBody ( $_uid , $_partID = '' )
{
if ( $_partID != '' ) {
$body = $this -> icServer -> getBody ( $_uid , true );
} else {
$body = $this -> icServer -> getBodyPart ( $_uid , $_partID , true );
}
2010-11-05 15:03:45 +01:00
if ( PEAR :: isError ( $body ))
{
error_log ( __METHOD__ . __LINE__ . ' failed:' . $body -> message );
return false ;
}
2010-09-06 15:31:00 +02:00
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 ;
}
}
2013-07-26 15:12:32 +02:00
/**
* _getSpecialUseFolder
* abstraction layer for getDraftFolder , getTemplateFolder , getTrashFolder and getSentFolder
* @ var $type string the type to fetch ( Drafts | Template | Trash | Sent )
* @ return mixed strin or false
*/
function _getSpecialUseFolder ( $_type , $_checkexistance = TRUE )
{
static $types = array (
'Drafts' => array ( 'prefName' => 'draftFolder' , 'profileKey' => 'draftfolder' , 'autoFolderName' => 'Drafts' ),
'Template' => array ( 'prefName' => 'templateFolder' , 'profileKey' => 'templatefolder' , 'autoFolderName' => 'Templates' ),
'Trash' => array ( 'prefName' => 'trashFolder' , 'profileKey' => 'trashfolder' , 'autoFolderName' => 'Trash' ),
'Sent' => array ( 'prefName' => 'sentFolder' , 'profileKey' => 'sentfolder' , 'autoFolderName' => 'Sent' ),
);
if ( ! isset ( $types [ $_type ]))
{
error_log ( __METHOD__ . __LINE__ . ' ' . $_type . ' not supported for ' . __METHOD__ );
return false ;
}
if ( is_null ( self :: $specialUseFolders ) || empty ( self :: $specialUseFolders )) self :: $specialUseFolders = $this -> getSpecialUseFolders ();
//highest precedence
$_folderName = $this -> mailPreferences -> ic_server [ $this -> profileID ] -> $types [ $_type ][ 'profileKey' ];
//check prefs next
if ( empty ( $_folderName )) $_folderName = $this -> mailPreferences -> preferences [ $types [ $_type ][ 'prefName' ]];
// does the folder exist???
if ( $_checkexistance && $_folderName != 'none' && ! self :: folderExists ( $_folderName )) {
$_folderName = false ;
}
//no (valid) folder found yet; try specialUseFolders
if ( empty ( $_folderName ) && is_array ( self :: $specialUseFolders ) && ( $f = array_search ( $_type , self :: $specialUseFolders ))) $_folderName = $f ;
//no specialUseFolder; try some Defaults
if ( empty ( $_folderName ) && isset ( $types [ $_type ]))
{
$nameSpace = $this -> _getNameSpaces ();
$prefix = '' ;
if ( isset ( $nameSpace [ 'personal' ])) $prefix = $nameSpace [ 'personal' ][ 'prefix' ];
if ( self :: folderExists ( $prefix . $types [ $_type ][ 'autoFolderName' ])) $_folderName = $prefix . $types [ $_type ][ 'autoFolderName' ];
}
return $_folderName ;
}
function getDraftFolder ( $_checkexistance = TRUE )
{
return $this -> _getSpecialUseFolder ( 'Drafts' , $_checkexistance );
}
function getTemplateFolder ( $_checkexistance = TRUE )
{
return $this -> _getSpecialUseFolder ( 'Template' , $_checkexistance );
}
function getTrashFolder ( $_checkexistance = TRUE )
{
return $this -> _getSpecialUseFolder ( 'Trash' , $_checkexistance );
}
function getSentFolder ( $_checkexistance = TRUE )
{
return $this -> _getSpecialUseFolder ( 'Sent' , $_checkexistance );
}
function isSentFolder ( $_folderName , $_checkexistance = TRUE )
{
$sentFolder = $this -> getSentFolder ();
if ( empty ( $sentFolder )) {
return false ;
}
// does the folder exist???
if ( $_checkexistance && ! self :: folderExists ( $_folderName )) {
return false ;
}
if ( false !== stripos ( $_folderName , $sentFolder )) {
return true ;
} else {
return false ;
}
}
/**
* checks if the Outbox folder exists and is port of the foldername to be checked
*/
function isOutbox ( $_folderName , $_checkexistance = TRUE )
{
if ( stripos ( $_folderName , 'Outbox' ) === false ) {
return false ;
}
// does the folder exist???
if ( $_checkexistance && ! self :: folderExists ( $_folderName )) {
return false ;
}
return true ;
}
function isDraftFolder ( $_folderName , $_checkexistance = TRUE )
{
$draftFolder = $this -> getDraftFolder ();
if ( empty ( $draftFolder )) {
2010-09-06 15:31:00 +02:00
return false ;
}
// does the folder exist???
2013-07-26 15:12:32 +02:00
if ( $_checkexistance && ! self :: folderExists ( $_folderName )) {
2010-09-06 15:31:00 +02:00
return false ;
}
2013-07-26 15:12:32 +02:00
if ( false !== stripos ( $_folderName , $draftFolder )) {
2010-09-06 15:31:00 +02:00
return true ;
} else {
return false ;
}
}
2013-07-26 15:12:32 +02:00
function isTrashFolder ( $_folderName , $_checkexistance = TRUE )
2010-09-06 15:31:00 +02:00
{
2013-07-26 15:12:32 +02:00
$trashFolder = $this -> getTrashFolder ();
if ( empty ( $trashFolder )) {
2010-09-06 15:31:00 +02:00
return false ;
}
// does the folder exist???
2013-07-26 15:12:32 +02:00
if ( $_checkexistance && ! self :: folderExists ( $_folderName )) {
2010-09-06 15:31:00 +02:00
return false ;
}
2013-07-26 15:12:32 +02:00
if ( false !== stripos ( $_folderName , $trashFolder )) {
2010-09-06 15:31:00 +02:00
return true ;
} else {
return false ;
}
}
2013-07-26 15:12:32 +02:00
function isTemplateFolder ( $_folderName , $_checkexistance = TRUE )
2010-09-06 15:31:00 +02:00
{
2013-07-26 15:12:32 +02:00
$templateFolder = $this -> getTemplateFolder ();
if ( empty ( $templateFolder )) {
2010-09-06 15:31:00 +02:00
return false ;
}
// does the folder exist???
2013-07-26 15:12:32 +02:00
if ( $_checkexistance && ! self :: folderExists ( $_folderName )) {
2010-09-06 15:31:00 +02:00
return false ;
}
2013-07-26 15:12:32 +02:00
if ( false !== stripos ( $_folderName , $templateFolder )) {
2010-09-06 15:31:00 +02:00
return true ;
} else {
return false ;
}
}
2013-07-26 15:12:32 +02:00
function folderExists ( $_folder , $_forceCheck = false )
2010-09-06 15:31:00 +02:00
{
2011-03-28 10:55:09 +02:00
static $folderInfo ;
2013-07-26 15:12:32 +02:00
$forceCheck = $_forceCheck ;
2011-03-28 10:55:09 +02:00
if ( empty ( $_folder ))
{
2013-07-26 15:12:32 +02:00
// this error is more or less without significance, unless we force the check
if ( $_forceCheck === true ) error_log ( __METHOD__ . __LINE__ . ' Called with empty Folder:' . $_folder . function_backtrace ());
2011-03-28 10:55:09 +02:00
return false ;
}
2013-07-26 15:12:32 +02:00
// reduce traffic within the Instance per User; Expire every 5 Minutes
2011-03-28 10:55:09 +02:00
//error_log(__METHOD__.__LINE__.' Called with Folder:'.$_folder.function_backtrace());
2013-07-26 15:12:32 +02:00
if ( is_null ( $folderInfo )) $folderInfo = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'icServerFolderExistsInfo' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), $expiration = 60 * 5 );
//error_log(__METHOD__.__LINE__.'Cached Info on Folder:'.$_folder.' for Profile:'.$this->profileID.($forceCheck?'(forcedCheck)':'').':'.array2string($folderInfo));
if ( ! empty ( $folderInfo ) && isset ( $folderInfo [ $this -> profileID ]) && isset ( $folderInfo [ $this -> profileID ][ $_folder ]) && $forceCheck === false )
{
//error_log(__METHOD__.__LINE__.' Using cached Info on Folder:'.$_folder.' for Profile:'.$this->profileID);
return $folderInfo [ $this -> profileID ][ $_folder ];
}
else
{
if ( $forceCheck === false )
{
//error_log(__METHOD__.__LINE__.' No cached Info on Folder:'.$_folder.' for Profile:'.$this->profileID.' FolderExistsInfoCache:'.array2string($folderInfo[$this->profileID]));
$forceCheck = true ; // try to force the check, in case there is no connection, we may need that
}
}
2011-03-28 10:55:09 +02:00
2010-09-06 15:31:00 +02:00
// does the folder exist???
2013-07-26 15:12:32 +02:00
//error_log(__METHOD__."->Connected?".$this->icServer->_connected.", ".$_folder.", ".($forceCheck?' forceCheck activated':'dont check on server'));
if (( ! ( $this -> icServer -> _connected == 1 )) && $forceCheck || empty ( $folderInfo ) || ! isset ( $folderInfo [ $this -> profileID ]) || ! isset ( $folderInfo [ $this -> profileID ][ $_folder ])) {
//error_log(__METHOD__."->NotConnected and forceCheck with profile:".$this->profileID);
2010-09-06 15:31:00 +02:00
//return false;
//try to connect
2013-07-26 15:12:32 +02:00
if ( ! $this -> icServer -> _connected ) $this -> openConnection ( $this -> profileID , false );
}
if (( $this -> icServer instanceof defaultimap ))
{
$folderInfo [ $this -> profileID ][ $_folder ] = $this -> icServer -> mailboxExist ( $_folder ); //LIST Command, may return OK, but no attributes
if ( $folderInfo [ $this -> profileID ][ $_folder ] == false )
{
// some servers dont serve the LIST command in certain cases; this is a ServerBUG and
// we try to work around it here.
if (( isset ( $this -> mailPreferences -> preferences [ 'trustServersUnseenInfo' ]) &&
$this -> mailPreferences -> preferences [ 'trustServersUnseenInfo' ] == false ) ||
( isset ( $this -> mailPreferences -> preferences [ 'trustServersUnseenInfo' ]) &&
$this -> mailPreferences -> preferences [ 'trustServersUnseenInfo' ] == 2 )
)
{
$nameSpace = $this -> _getNameSpaces ();
if ( isset ( $nameSpace [ 'personal' ])) unset ( $nameSpace [ 'personal' ]);
$prefix = $this -> getFolderPrefixFromNamespace ( $nameSpace , $_folder );
if ( $prefix != '' && stripos ( $_folder , $prefix ) !== false )
{
if ( ! PEAR :: isError ( $r = $this -> _getStatus ( $_folder )) && is_array ( $r )) $folderInfo [ $this -> profileID ][ $_folder ] = true ;
}
}
}
2010-09-06 15:31:00 +02:00
}
2013-07-26 15:12:32 +02:00
//error_log(__METHOD__.__LINE__.' Folder Exists:'.$folderInfo[$this->profileID][$_folder].function_backtrace());
2011-03-28 10:55:09 +02:00
2013-07-26 15:12:32 +02:00
if ( ! empty ( $folderInfo ) && isset ( $folderInfo [ $this -> profileID ][ $_folder ]) &&
( $folderInfo [ $this -> profileID ][ $_folder ] instanceof PEAR_Error ) || $folderInfo [ $this -> profileID ][ $_folder ] !== true )
2011-03-28 10:55:09 +02:00
{
2013-07-26 15:12:32 +02:00
$folderInfo [ $this -> profileID ][ $_folder ] = false ; // set to false, whatever it was (to have a valid returnvalue for the static return)
2010-09-06 15:31:00 +02:00
}
2013-07-26 15:12:32 +02:00
egw_cache :: setCache ( egw_cache :: INSTANCE , 'email' , 'icServerFolderExistsInfo' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $folderInfo , $expiration = 60 * 5 );
return ( ! empty ( $folderInfo ) && isset ( $folderInfo [ $this -> profileID ][ $_folder ]) ? $folderInfo [ $this -> profileID ][ $_folder ] : false );
2010-09-06 15:31:00 +02:00
}
function moveMessages ( $_foldername , $_messageUID , $deleteAfterMove = true )
{
$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 ( $deleteAfterMove === true )
{
2012-04-17 11:12:01 +02:00
if ( PEAR :: isError ( $this -> icServer -> deleteMessages ( $_messageUID , true )))
2010-09-06 15:31:00 +02:00
{
return false ;
}
2012-04-17 11:12:01 +02:00
if ( $deleteOptions != " mark_as_deleted " )
2010-09-06 15:31:00 +02:00
{
// delete the messages finaly
$this -> icServer -> expunge ();
}
}
return true ;
}
function openConnection ( $_icServerID = 0 , $_adminConnection = false )
{
2012-04-17 11:12:01 +02:00
if ( ! is_object ( $this -> mailPreferences ))
2010-09-06 15:31:00 +02:00
{
error_log ( __METHOD__ . " No Object for MailPreferences found. " . function_backtrace ());
$this -> errorMessage .= lang ( 'No valid data to create MailProfile!!' );
return false ;
}
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 .= " <br> " . lang ( " Configure a valid IMAP Server in emailadmin for the profile you are using. " );
} else {
$errormessage .= " <br> " . 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 <br>");
#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));
2013-07-26 15:12:32 +02:00
//make sure we are working with the correct hierarchyDelimiter on the current connection, calling getHierarchyDelimiter with false to reset the cache
$hD = $this -> getHierarchyDelimiter ( false );
self :: $specialUseFolders = $this -> getSpecialUseFolders ();
2010-09-06 15:31:00 +02:00
return $tretval ;
}
2013-07-26 15:12:32 +02:00
/**
* getSpecialUseFolders
* @ ToDo : could as well be static , when icServer is passed
* @ return mixed null / array
*/
function getSpecialUseFolders ()
{
//error_log(__METHOD__.__LINE__.':'.$this->icServer->ImapServerId.' Connected:'.$this->icServer->_connected);
static $_specialUseFolders ;
if ( is_null ( $_specialUseFolders ) || empty ( $_specialUseFolders )) $_specialUseFolders = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'specialUseFolders' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $callback = null , $callback_params = array (), $expiration = 60 * 60 * 24 * 5 );
if ( isset ( $_specialUseFolders [ $this -> icServer -> ImapServerId ]) &&! empty ( $_specialUseFolders [ $this -> icServer -> ImapServerId ]))
{
if (( $this -> icServer instanceof defaultimap ))
{
//error_log(__METHOD__.__LINE__.array2string($specialUseFolders[$this->icServer->ImapServerId]));
// array('Drafts', 'Templates', 'Sent', 'Trash', 'Junk', 'Outbox');
if ( empty ( $this -> icServer -> trashfolder ) && ( $f = array_search ( 'Trash' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> trashfolder = $f ;
if ( empty ( $this -> icServer -> draftfolder ) && ( $f = array_search ( 'Drafts' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> draftfolder = $f ;
if ( empty ( $this -> icServer -> sentfolder ) && ( $f = array_search ( 'Sent' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> sentfolder = $f ;
if ( empty ( $this -> icServer -> templatefolder ) && ( $f = array_search ( 'Templates' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> templatefolder = $f ;
}
//error_log(__METHOD__.__LINE__.array2string($_specialUseFolders[$this->icServer->ImapServerId]));
self :: $specialUseFolders = $_specialUseFolders [ $this -> icServer -> ImapServerId ]; // make sure this one is set on function call
return $_specialUseFolders [ $this -> icServer -> ImapServerId ];
}
if (( $this -> icServer instanceof defaultimap ) && $this -> icServer -> _connected )
{
//error_log(__METHOD__.__LINE__);
if (( $this -> hasCapability ( 'SPECIAL-USE' )))
{
//error_log(__METHOD__.__LINE__);
$ret = $this -> icServer -> getSpecialUseFolders ();
if ( PEAR :: isError ( $ret ))
{
$_specialUseFolders [ $this -> icServer -> ImapServerId ] = array ();
}
else
{
foreach ( $ret as $k => $f )
{
if ( isset ( $f [ 'ATTRIBUTES' ]) && ! empty ( $f [ 'ATTRIBUTES' ]) &&
! in_array ( '\\NonExistent' , $f [ 'ATTRIBUTES' ]))
{
foreach ( self :: $autoFolders as $i => $n ) // array('Drafts', 'Templates', 'Sent', 'Trash', 'Junk', 'Outbox');
{
if ( in_array ( '\\' . $n , $f [ 'ATTRIBUTES' ])) $_specialUseFolders [ $this -> icServer -> ImapServerId ][ $f [ 'MAILBOX' ]] = $n ;
}
}
}
}
egw_cache :: setCache ( egw_cache :: INSTANCE , 'email' , 'specialUseFolders' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $_specialUseFolders , $expiration = 60 * 60 * 24 * 5 );
}
//error_log(__METHOD__.__LINE__.array2string($_specialUseFolders[$this->icServer->ImapServerId]));
if ( empty ( $this -> icServer -> trashfolder ) && ( $f = array_search ( 'Trash' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> trashfolder = $f ;
if ( empty ( $this -> icServer -> draftfolder ) && ( $f = array_search ( 'Drafts' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> draftfolder = $f ;
if ( empty ( $this -> icServer -> sentfolder ) && ( $f = array_search ( 'Sent' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> sentfolder = $f ;
if ( empty ( $this -> icServer -> templatefolder ) && ( $f = array_search ( 'Templates' ,( array ) $_specialUseFolders [ $this -> icServer -> ImapServerId ]))) $this -> icServer -> templatefolder = $f ;
}
self :: $specialUseFolders = $_specialUseFolders [ $this -> icServer -> ImapServerId ]; // make sure this one is set on function call
//error_log(__METHOD__.__LINE__.array2string($_specialUseFolders[$this->icServer->ImapServerId]));
return $_specialUseFolders [ $this -> icServer -> ImapServerId ];
}
2010-09-06 15:31:00 +02:00
/**
* 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-<br>");
#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 )
{
if ( is_object ( $this -> mailPreferences )) $icServer = $this -> mailPreferences -> getIncomingServer ( 0 );
2011-09-12 17:31:35 +02:00
if (( $icServer instanceof defaultimap )) {
2010-09-06 15:31:00 +02:00
$icServer -> updateAccount ( $_hookValues );
}
if ( is_object ( $this -> mailPreferences )) $ogServer = $this -> mailPreferences -> getOutgoingServer ( 0 );
2011-09-12 17:31:35 +02:00
if (( $ogServer instanceof defaultsmtp )) {
2010-09-06 15:31:00 +02:00
$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 ;
}
2010-09-07 11:14:14 +02:00
static function wordwrap ( $str , $cols , $cut , $dontbreaklinesstartingwith = false )
2010-09-06 15:31:00 +02:00
{
$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 );
2010-09-07 11:14:14 +02:00
if ( strlen ( $line ) > $allowedLength &&
( $dontbreaklinesstartingwith == false ||
( $dontbreaklinesstartingwith &&
strlen ( $dontbreaklinesstartingwith ) >= 1 &&
substr ( $line , 0 , strlen ( $dontbreaklinesstartingwith )) != $dontbreaklinesstartingwith
)
)
2013-08-20 13:22:18 +02:00
)
{
2010-09-06 15:31:00 +02:00
$s = explode ( " " , $line );
$line = " " ;
$linecnt = 0 ;
foreach ( $s as $k => $v ) {
$cnt = strlen ( $v );
// only break long words within the wordboundaries,
2013-08-20 13:22:18 +02:00
// but it may destroy links, so we check for href and dont do it if we find one
// we check for any html within the word, because we do not want to break html by accident
if ( $cnt > $allowedLength && stripos ( $v , 'href=' ) === false && stripos ( $v , 'onclick=' ) === false && $cnt == strlen ( html_entity_decode ( $v )))
2010-11-22 13:56:49 +01:00
{
2010-09-06 15:31:00 +02:00
$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
*
2012-10-18 12:52:53 +02:00
* @ param mixed _sort the integer sort order / or a valid and handeled SORTSTRING ( right now : UID / ARRIVAL / INTERNALDATE ( -> ARRIVAL ))
* @ param bool _reverse wether to add REVERSE to the Sort String or not
2010-09-06 15:31:00 +02:00
* @ returns the ascii sort string
*/
2012-10-18 12:52:53 +02:00
function _getSortString ( $_sort , $_reverse = false )
2010-09-06 15:31:00 +02:00
{
2012-10-18 12:52:53 +02:00
$_reverse = false ;
if ( is_numeric ( $_sort ))
{
switch ( $_sort ) {
case 2 :
$retValue = 'FROM' ;
break ;
case 4 :
$retValue = 'TO' ;
break ;
case 3 :
$retValue = 'SUBJECT' ;
break ;
case 6 :
$retValue = 'SIZE' ;
break ;
case 0 :
default :
$retValue = 'DATE' ;
//$retValue = 'ARRIVAL';
break ;
}
2010-09-06 15:31:00 +02:00
}
2012-10-18 12:52:53 +02:00
else
{
switch ( $_sort ) {
case 'UID' : // should be equivalent to INTERNALDATE, which is ARRIVAL, which should be highest (latest) uid should be newest date
case 'ARRIVAL' :
case 'INTERNALDATE' :
$retValue = 'ARRIVAL' ;
break ;
default :
$retValue = 'DATE' ;
//$retValue = 'ARRIVAL';
break ;
}
}
//error_log(__METHOD__.__LINE__.' '.($_reverse?'REVERSE ':'').$_sort.'->'.$retValue);
return ( $_reverse ? 'REVERSE ' : '' ) . $retValue ;
2010-09-06 15:31:00 +02:00
}
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 ;
2010-09-15 12:51:44 +02:00
error_log ( __METHOD__ . __LINE__ . ' using identity for send from:' . $send -> From . ' to match header information:' . $headers [ 'TO' ]);
2010-09-06 15:31:00 +02:00
break ;
}
if ( $identity -> default ) {
$send -> From = $identity -> emailAddress ;
$send -> FromName = $identity -> realName ;
}
}
if ( isset ( $headers [ 'DISPOSITION-NOTIFICATION-TO' ])) {
2010-09-15 12:51:44 +02:00
$toAddr = $headers [ 'DISPOSITION-NOTIFICATION-TO' ];
2010-09-06 15:31:00 +02:00
} else if ( isset ( $headers [ 'RETURN-RECEIPT-TO' ]) ) {
2010-09-15 12:51:44 +02:00
$toAddr = $headers [ 'RETURN-RECEIPT-TO' ];
2010-09-06 15:31:00 +02:00
} else if ( isset ( $headers [ 'X-CONFIRM-READING-TO' ]) ) {
2010-09-15 12:51:44 +02:00
$toAddr = $headers [ 'X-CONFIRM-READING-TO' ];
2010-09-06 15:31:00 +02:00
} else return false ;
2010-09-15 12:51:44 +02:00
$singleAddress = imap_rfc822_parse_adrlist ( $toAddr , '' );
if ( self :: $debug ) error_log ( __METHOD__ . __LINE__ . ' To Address:' . $singleAddress [ 0 ] -> mailbox . " @ " . $singleAddress [ 0 ] -> host . " , " . $singleAddress [ 0 ] -> personal );
2012-04-17 11:12:01 +02:00
$send -> AddAddress ( $singleAddress [ 0 ] -> mailbox . " @ " . $singleAddress [ 0 ] -> host , $singleAddress [ 0 ] -> personal );
2010-09-06 15:31:00 +02:00
$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 " .
" \t boundary= \" " . $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 8 bit 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 8 bit 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 );
}
2010-11-08 10:30:58 +01:00
/**
2012-04-17 11:12:01 +02:00
* htmlspecialchars
2010-11-08 10:30:58 +01:00
* helperfunction to cope with wrong encoding in strings
* @ param string $_string input to be converted
* @ param mixed $charset false or string -> Target charset , if false bofelamimail displayCharset will be used
2012-04-17 11:12:01 +02:00
* @ return string
2010-11-08 10:30:58 +01:00
*/
static function htmlspecialchars ( $_string , $_charset = false )
{
//setting the charset (if not given)
if ( $_charset === false ) $_charset = bofelamimail :: $displayCharset ;
$_stringORG = $_string ;
$_string = @ htmlspecialchars ( $_string , ENT_QUOTES , $_charset , false );
if ( empty ( $_string ) && ! empty ( $_stringORG )) $_string = @ htmlspecialchars ( $GLOBALS [ 'egw' ] -> translation -> convert ( $_stringORG , bofelamimail :: detect_encoding ( $_stringORG ), $_charset ), ENT_QUOTES | ENT_IGNORE , $_charset , false );
return $_string ;
}
/**
* htmlentities
* helperfunction to cope with wrong encoding in strings
* @ param string $_string input to be converted
* @ param mixed $charset false or string -> Target charset , if false bofelamimail displayCharset will be used
2012-04-17 11:12:01 +02:00
* @ return string
2010-11-08 10:30:58 +01:00
*/
static function htmlentities ( $_string , $_charset = false )
{
//setting the charset (if not given)
if ( $_charset === false ) $_charset = bofelamimail :: $displayCharset ;
$_stringORG = $_string ;
$_string = @ htmlentities ( $_string , ENT_QUOTES , $_charset , false );
if ( empty ( $_string ) && ! empty ( $_stringORG )) $_string = @ htmlentities ( $GLOBALS [ 'egw' ] -> translation -> convert ( $_stringORG , bofelamimail :: detect_encoding ( $_stringORG ), $_charset ), ENT_QUOTES | ENT_IGNORE , $_charset , false );
return $_string ;
}
/**
* detect_encoding - try to detect the encoding
* only to be used if the string in question has no structure that determines his encoding
* @ param string - to be evaluated
* @ returns mixed string / boolean ( encoding or false
*/
2012-04-17 11:12:01 +02:00
static function detect_encoding ( $string ) {
2010-11-08 10:30:58 +01:00
static $list = array ( 'utf-8' , 'iso-8859-1' , 'windows-1251' ); // list may be extended
if ( function_exists ( 'iconv' ))
2012-04-17 11:12:01 +02:00
{
2010-11-08 10:30:58 +01:00
foreach ( $list as $item ) {
$sample = iconv ( $item , $item , $string );
if ( md5 ( $sample ) == md5 ( $string ))
return $item ;
}
}
return false ; // we may choose to return iso-8859-1 as default at some point
}
2010-09-06 15:31:00 +02:00
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 );
}
/**
* Helper function to handle wrong or unrecognized timezones
* returns the date as it is parseable by strtotime , or current timestamp if everything failes
2010-09-07 11:14:14 +02:00
* @ param string date to be parsed / formatted
* @ param string format string , if none is passed , use the users common dateformat supplemented by the time hour : minute : second
* @ return string returns the date as it is parseable by strtotime , or current timestamp if everything failes
2010-09-06 15:31:00 +02:00
*/
2010-11-17 10:53:16 +01:00
static function _strtotime ( $date = '' , $format = NULL , $convert2usertime = false )
2010-09-06 15:31:00 +02:00
{
2010-11-17 10:53:16 +01:00
if ( $format == NULL ) $format = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ] . ' ' . ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ] == 12 ? 'h:i:s a' : 'H:i:s' );
$date2return = ( $convert2usertime ? egw_time :: server2user ( $date , $format ) : egw_time :: to ( $date , $format ));
2010-09-07 11:14:14 +02:00
if ( $date2return == null )
2010-09-06 15:31:00 +02:00
{
$dtarr = explode ( ' ' , $date );
2010-09-07 11:14:14 +02:00
$test = null ;
2012-04-17 11:12:01 +02:00
while ( $test === null && count ( $dtarr ) >= 1 )
2010-09-06 15:31:00 +02:00
{
array_pop ( $dtarr );
2010-11-17 10:53:16 +01:00
$test = ( $convert2usertime ? egw_time :: server2user ( implode ( ' ' , $dtarr ), $format ) : egw_time :: to ( implode ( ' ' , $dtarr ), $format ));
2012-04-17 11:12:01 +02:00
if ( $test ) $date2return = $test ;
2010-09-06 15:31:00 +02:00
}
2010-09-07 11:14:14 +02:00
if ( $test === null ) $date2return = egw_time :: to ( 'now' , $format );
2010-09-06 15:31:00 +02:00
}
2010-09-07 11:14:14 +02:00
return $date2return ;
2010-09-06 15:31:00 +02:00
}
2010-11-08 10:30:58 +01:00
/**
* checkFileBasics
* check if formdata meets basic restrictions ( in tmp dir , or vfs , mimetype , etc . )
*
* @ param array $_formData passed by reference Array with information of name , type , file and size , mimetype may be adapted
* @ param string $IDtoAddToFileName id to enrich the returned tmpfilename
* @ param string $reqMimeType / ( default message / rfc822 , if set to false , mimetype check will not be performed
* @ return mixed $fullPathtoFile or exception
*/
static function checkFileBasics ( & $_formData , $IDtoAddToFileName = '' , $reqMimeType = 'message/rfc822' )
{
//error_log(__METHOD__.__FILE__.array2string($_formData).' Id:'.$IDtoAddToFileName.' ReqMimeType:'.$reqMimeType);
$importfailed = $tmpFileName = false ;
2012-04-17 11:12:01 +02:00
if ( $_formData [ 'size' ] != 0 && ( is_uploaded_file ( $_formData [ 'file' ]) ||
2010-11-08 10:30:58 +01:00
realpath ( dirname ( $_formData [ 'file' ])) == realpath ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ]) ||
parse_url ( $_formData [ 'file' ], PHP_URL_SCHEME ) == 'vfs' ))
{
// ensure existance of eGW temp dir
2012-04-17 11:12:01 +02:00
// note: this is different from apache temp dir,
2010-11-08 10:30:58 +01:00
// and different from any other temp file location set in php.ini
if ( ! file_exists ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ]))
{
@ mkdir ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ], 0700 );
}
2012-04-17 11:12:01 +02:00
2010-11-08 10:30:58 +01:00
// if we were NOT able to create this temp directory, then make an ERROR report
if ( ! file_exists ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ]))
{
$alert_msg .= 'Error:' . '<br>'
. 'Server is unable to access phpgw tmp directory' . '<br>'
. $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] . '<br>'
. 'Please check your configuration' . '<br>'
. '<br>' ;
}
2012-04-17 11:12:01 +02:00
2010-11-08 10:30:58 +01:00
// sometimes PHP is very clue-less about MIME types, and gives NO file_type
// rfc default for unknown MIME type is:
2012-04-17 11:12:01 +02:00
if ( $reqMimeType == 'message/rfc822' )
2010-11-08 10:30:58 +01:00
{
$mime_type_default = 'message/rfc' ;
}
else
{
$mime_type_default = $reqMimeType ;
}
2011-10-26 14:15:06 +02:00
// check the mimetype by extension. as browsers seem to report crap
// maybe its application/octet-stream -> this may mean that we could not determine the type
// so we check for the suffix too
$buff = explode ( '.' , $_formData [ 'name' ]);
$suffix = '' ;
if ( is_array ( $buff )) $suffix = array_pop ( $buff ); // take the last extension to check with ext2mime
if ( ! empty ( $suffix )) $sfxMimeType = mime_magic :: ext2mime ( $suffix );
2012-04-17 11:12:01 +02:00
if ( ! empty ( $suffix ) && ! empty ( $sfxMimeType ) &&
2011-10-26 14:15:06 +02:00
( strlen ( trim ( $_formData [ 'type' ])) == 0 || ( strtolower ( trim ( $_formData [ 'type' ])) != $sfxMimeType )))
{
error_log ( __METHOD__ . __LINE__ . ' Data:' . array2string ( $_formData ));
error_log ( __METHOD__ . __LINE__ . ' Form reported Mimetype:' . $_formData [ 'type' ] . ' but seems to be:' . $sfxMimeType );
$_formData [ 'type' ] = $sfxMimeType ;
}
2010-11-08 10:30:58 +01:00
if ( trim ( $_formData [ 'type' ]) == '' )
{
$_formData [ 'type' ] = 'application/octet-stream' ;
}
// if reqMimeType is set to false do not test for that
if ( $reqMimeType )
{
// so if PHP did not pass any file_type info, then substitute the rfc default value
if ( substr ( strtolower ( trim ( $_formData [ 'type' ])), 0 , strlen ( $mime_type_default )) != $mime_type_default )
{
2011-10-26 14:15:06 +02:00
if ( ! ( strtolower ( trim ( $_formData [ 'type' ])) == " application/octet-stream " && $sfxMimeType == $reqMimeType ))
2010-11-08 10:30:58 +01:00
{
//error_log("Message rejected, no message/rfc. Is:".$_formData['type']);
$importfailed = true ;
$alert_msg .= lang ( " File rejected, no %2. Is:%1 " , $_formData [ 'type' ], $reqMimeType );
}
2011-10-26 14:15:06 +02:00
if (( strtolower ( trim ( $_formData [ 'type' ])) != $reqMimeType && $sfxMimeType == $reqMimeType ))
2010-11-08 10:30:58 +01:00
{
$_formData [ 'type' ] = mime_magic :: ext2mime ( $suffix );
}
}
}
2010-12-01 15:16:59 +01:00
// as FreeBSD seems to have problems with the generated temp names we append some more random stuff
$randomString = chr ( rand ( 65 , 90 )) . chr ( rand ( 48 , 57 )) . chr ( rand ( 65 , 90 )) . chr ( rand ( 48 , 57 )) . chr ( rand ( 65 , 90 ));
2010-11-08 10:30:58 +01:00
$tmpFileName = $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] .
SEP .
$GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ] .
2010-12-01 15:16:59 +01:00
trim ( $IDtoAddToFileName ) . basename ( $_formData [ 'file' ]) . '_' . $randomString ;
2012-04-17 11:12:01 +02:00
2010-11-08 10:30:58 +01:00
if ( parse_url ( $_formData [ 'file' ], PHP_URL_SCHEME ) == 'vfs' )
{
$tmpFileName = $_formData [ 'file' ]; // no need to store it somewhere
}
elseif ( is_uploaded_file ( $_formData [ 'file' ]))
{
move_uploaded_file ( $_formData [ 'file' ], $tmpFileName ); // requirement for safe_mode!
}
else
{
rename ( $_formData [ 'file' ], $tmpFileName );
}
} else {
//error_log("Import of message ".$_formData['file']." failes to meet basic restrictions");
$importfailed = true ;
$alert_msg .= lang ( " Processing of file %1 failed. Failed to meet basic restrictions. " , $_formData [ 'name' ]);
}
if ( $importfailed == true )
{
throw new egw_exception_wrong_userinput ( $alert_msg );
}
else
{
if ( parse_url ( $tmpFileName , PHP_URL_SCHEME ) == 'vfs' )
{
egw_vfs :: load_wrapper ( 'vfs' );
}
return $tmpFileName ;
2012-04-17 11:12:01 +02:00
}
2010-11-08 10:30:58 +01:00
}
/**
* getRandomString - function to be used to fetch a random string and md5 encode that one
* @ param none
* @ return string - a random number which is md5 encoded
*/
static function getRandomString () {
mt_srand (( float ) microtime () * 1000000 );
return md5 ( mt_rand ( 100000 , 999999 ));
}
/**
* functions to allow access to mails through other apps to fetch content
* used in infolog , tracker
*/
/**
* get_mailcontent - fetches the actual mailcontent , and returns it as well defined array
* @ param bofelamimail the bofelamimailobject to be used
* @ param uid the uid of the email to be processed
* @ param partid the partid of the email
* @ param mailbox the mailbox , that holds the message
* @ returns array with 'mailaddress' => $mailaddress ,
* 'subject' => $subject ,
* 'message' => $message ,
* 'attachments' => $attachments ,
* 'headers' => $headers ,
*/
static function get_mailcontent ( & $bofelamimail , $uid , $partid = '' , $mailbox = '' )
{
//echo __METHOD__." called for $uid,$partid <br>";
$headers = $bofelamimail -> getMessageHeader ( $uid , $partid , true );
// dont force retrieval of the textpart, let felamimail preferences decide
$bodyParts = $bofelamimail -> getMessageBody ( $uid , '' , $partid );
$attachments = $bofelamimail -> getMessageAttachments ( $uid , $partid );
if ( $bofelamimail -> isSentFolder ( $mailbox )) $mailaddress = $headers [ 'TO' ];
elseif ( isset ( $headers [ 'FROM' ])) $mailaddress = $headers [ 'FROM' ];
elseif ( isset ( $headers [ 'SENDER' ])) $mailaddress = $headers [ 'SENDER' ];
if ( isset ( $headers [ 'CC' ])) $mailaddress .= ',' . $headers [ 'CC' ];
//_debug_array($headers);
$subject = $headers [ 'SUBJECT' ];
$message = self :: getdisplayableBody ( $bofelamimail , $bodyParts );
$headdata = self :: createHeaderInfoSection ( $headers );
$message = $headdata . $message ;
//echo __METHOD__.'<br>';
//_debug_array($attachments);
if ( is_array ( $attachments ))
{
foreach ( $attachments as $num => $attachment )
{
if ( $attachment [ 'mimeType' ] == 'MESSAGE/RFC822' )
{
//_debug_array($bofelamimail->getMessageHeader($uid, $attachment['partID']));
//_debug_array($bofelamimail->getMessageBody($uid,'', $attachment['partID']));
//_debug_array($bofelamimail->getMessageAttachments($uid, $attachment['partID']));
$mailcontent = self :: get_mailcontent ( $bofelamimail , $uid , $attachment [ 'partID' ]);
$headdata = '' ;
if ( $mailcontent [ 'headers' ])
{
$headdata = self :: createHeaderInfoSection ( $mailcontent [ 'headers' ]);
}
if ( $mailcontent [ 'message' ])
{
$tempname = tempnam ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ], $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] . " _ " );
$attachedMessages [] = array (
'type' => 'TEXT/PLAIN' ,
'name' => $mailcontent [ 'subject' ] . '.txt' ,
'tmp_name' => $tempname ,
);
$tmpfile = fopen ( $tempname , 'w' );
fwrite ( $tmpfile , $headdata . $mailcontent [ 'message' ]);
fclose ( $tmpfile );
}
foreach ( $mailcontent [ 'attachments' ] as $tmpattach => $tmpval )
{
$attachedMessages [] = $tmpval ;
}
unset ( $attachments [ $num ]);
}
else
{
$attachments [ $num ] = array_merge ( $attachments [ $num ], $bofelamimail -> getAttachment ( $uid , $attachment [ 'partID' ]));
if ( isset ( $attachments [ $num ][ 'charset' ])) {
if ( $attachments [ $num ][ 'charset' ] === false ) $attachments [ $num ][ 'charset' ] = self :: detect_encoding ( $attachments [ $num ][ 'attachment' ]);
$GLOBALS [ 'egw' ] -> translation -> convert ( $attachments [ $num ][ 'attachment' ], $attachments [ $num ][ 'charset' ]);
}
$attachments [ $num ][ 'type' ] = $attachments [ $num ][ 'mimeType' ];
$attachments [ $num ][ 'tmp_name' ] = tempnam ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ], $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] . " _ " );
$tmpfile = fopen ( $attachments [ $num ][ 'tmp_name' ], 'w' );
fwrite ( $tmpfile , $attachments [ $num ][ 'attachment' ]);
fclose ( $tmpfile );
unset ( $attachments [ $num ][ 'attachment' ]);
}
}
if ( is_array ( $attachedMessages )) $attachments = array_merge ( $attachments , $attachedMessages );
}
return array (
'mailaddress' => $mailaddress ,
'subject' => $subject ,
'message' => $message ,
'attachments' => $attachments ,
'headers' => $headers ,
);
}
/**
* createHeaderInfoSection - creates a textual headersection from headerobject
* @ params header headerarray may contain SUBJECT , FROM , SENDER , TO , CC , BCC , DATE , PRIORITY , IMPORTANCE
* @ returns string a preformatted string with the information of the header worked into it
*/
static function createHeaderInfoSection ( $header , $headline = '' )
{
$headdata = null ;
if ( $header [ 'SUBJECT' ]) $headdata = lang ( 'subject' ) . ': ' . $header [ 'SUBJECT' ] . " \n " ;
if ( $header [ 'FROM' ]) $headdata .= lang ( 'from' ) . ': ' . $header [ 'FROM' ] . " \n " ;
if ( $header [ 'SENDER' ]) $headdata .= lang ( 'sender' ) . ': ' . $header [ 'SENDER' ] . " \n " ;
if ( $header [ 'TO' ]) $headdata .= lang ( 'to' ) . ': ' . $header [ 'TO' ] . " \n " ;
if ( $header [ 'CC' ]) $headdata .= lang ( 'cc' ) . ': ' . $header [ 'CC' ] . " \n " ;
if ( $header [ 'BCC' ]) $headdata .= lang ( 'bcc' ) . ': ' . $header [ 'BCC' ] . " \n " ;
if ( $header [ 'DATE' ]) $headdata .= lang ( 'date' ) . ': ' . $header [ 'DATE' ] . " \n " ;
if ( $header [ 'PRIORITY' ] && $header [ 'PRIORITY' ] != 'normal' ) $headdata .= lang ( 'priority' ) . ': ' . $header [ 'PRIORITY' ] . " \n " ;
if ( $header [ 'IMPORTANCE' ] && $header [ 'IMPORTANCE' ] != 'normal' ) $headdata .= lang ( 'importance' ) . ': ' . $header [ 'IMPORTANCE' ] . " \n " ;
//if ($mailcontent['headers']['ORGANIZATION']) $headdata .= lang('organization').': '.$mailcontent['headers']['ORGANIZATION']."\
2012-04-17 11:12:01 +02:00
if ( ! empty ( $headdata ))
2010-11-08 10:30:58 +01:00
{
if ( ! empty ( $headline )) $headdata = " ---------------------------- $headline ---------------------------- \n " . $headdata ;
if ( empty ( $headline )) $headdata = " -------------------------------------------------------- \n " . $headdata ;
$headdata .= " -------------------------------------------------------- \n " ;
}
else
{
$headdata = " -------------------------------------------------------- \n " ;
}
return $headdata ;
}
/**
* getdisplayableBody - creates the bodypart of the email as textual representation
* @ param bofelamimail the bofelamimailobject to be used
* @ params bodyPorts array with the bodyparts
* @ returns string a preformatted string with the mails converted to text
*/
2012-03-13 09:59:29 +01:00
static function & getdisplayableBody ( & $bofelamimail , $bodyParts , $preserveHTML = false )
2010-11-08 10:30:58 +01:00
{
for ( $i = 0 ; $i < count ( $bodyParts ); $i ++ )
{
if ( ! isset ( $bodyParts [ $i ][ 'body' ])) {
$bodyParts [ $i ][ 'body' ] = self :: getdisplayableBody ( $bofelamimail , $bodyParts [ $i ]);
$message .= $bodyParts [ $i ][ 'body' ];
continue ;
}
if ( $bodyParts [ $i ][ 'charSet' ] === false ) $bodyParts [ $i ][ 'charSet' ] = self :: detect_encoding ( $bodyParts [ $i ][ 'body' ]);
// add line breaks to $bodyParts
$newBody = $GLOBALS [ 'egw' ] -> translation -> convert ( $bodyParts [ $i ][ 'body' ], $bodyParts [ $i ][ 'charSet' ]);
if ( $bodyParts [ $i ][ 'mimeType' ] == 'text/html' ) {
2012-03-13 09:59:29 +01:00
// as translation::convert reduces \r\n to \n and purifier eats \n -> peplace it with a single space
$newBody = str_replace ( " \n " , " " , $newBody );
2010-11-08 10:30:58 +01:00
// convert HTML to text, as we dont want HTML in infologs
2012-03-13 09:59:29 +01:00
if ( extension_loaded ( 'tidy' ))
{
$tidy = new tidy ();
$cleaned = $tidy -> repairString ( $newBody , self :: $tidy_config , 'utf8' );
// Found errors. Strip it all so there's some output
if ( $tidy -> getStatus () == 2 )
{
error_log ( __METHOD__ . __LINE__ . ' ->' . $tidy -> errorBuffer );
}
else
{
$newBody = $cleaned ;
}
}
else
{
$newBody = html :: purify ( $newBody );
}
//error_log(__METHOD__.__LINE__.' after purify:'.$newBody);
if ( $preserveHTML == false ) $newBody = $bofelamimail -> convertHTMLToText ( $newBody , true );
$bofelamimail -> getCleanHTML ( $newBody , false , $preserveHTML ); // new Body passed by reference
//error_log(__METHOD__.__LINE__.' after getClean:'.$newBody);
2010-11-08 10:30:58 +01:00
$message .= $newBody ;
continue ;
}
$newBody = strip_tags ( $newBody );
$newBody = explode ( " \n " , $newBody );
// create it new, with good line breaks
reset ( $newBody );
while ( list ( $key , $value ) = @ each ( $newBody ))
{
if ( trim ( $value ) != '' ) {
#if ($value != "\r") $value .= "\n";
} else {
// if you want to strip all empty lines uncomment the following
#continue;
}
$message .= $bofelamimail -> wordwrap ( $value , 75 , " \n " );
}
}
return $message ;
}
2010-09-06 15:31:00 +02:00
}