From 1c6c67afbf3529bda3e2b32f2a991d32ec34ad28 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 2 Jun 2009 22:05:02 -0600 Subject: [PATCH] Initial work on rewriting IMAP support in ingo. This is 100% guaranteed not to work yet (I don't have setup to test at the moment), although it is a start. The 'mock' driver is guaranteed never to work since I have no idea what the hell it does and there is absolutely zero documentation on it. Unless someone comes forward to fix it, it will get the ax here very soon. --- imp/lib/Filter.php | 1 - imp/lib/api.php | 185 +++++++++++++++++++++++++++++++- imp/lib/prefs.php | 2 +- ingo/filters.php | 4 +- ingo/lib/Script/imap.php | 243 ++++++++++++++++++++---------------------- ingo/lib/Script/imap/live.php | 82 ++++++-------- ingo/lib/Script/imap/mock.php | 86 +++++++++------ 7 files changed, 389 insertions(+), 214 deletions(-) diff --git a/imp/lib/Filter.php b/imp/lib/Filter.php index 26556248b..155c17b63 100644 --- a/imp/lib/Filter.php +++ b/imp/lib/Filter.php @@ -39,7 +39,6 @@ class IMP_Filter : array($mbox); foreach ($mbox_list as $val) { - // @todo ingo needs to be rewritten to use non-stream access $GLOBALS['registry']->call('mail/applyFilters', array(array('mailbox' => $val))); } } diff --git a/imp/lib/api.php b/imp/lib/api.php index 3e8cc5bb3..f50fc86ca 100644 --- a/imp/lib/api.php +++ b/imp/lib/api.php @@ -46,6 +46,41 @@ $_services['createFolder'] = array( 'type' => 'string' ); +$_services['deleteMessages'] = array( + 'args' => array('mailbox' => 'string', 'indices' => '{urn:horde}integerArray'), + 'type' => 'integer' +); + +$_services['copyMessages'] = array( + 'args' => array('mailbox' => 'string', 'indices' => '{urn:horde}integerArray', 'target' => 'string'), + 'type' => 'boolean' +); + +$_services['moveMessages'] = array( + 'args' => array('mailbox' => 'string', 'indices' => '{urn:horde}integerArray', 'target' => 'string'), + 'type' => 'boolean' +); + +$_services['flagMessages'] = array( + 'args' => array('mailbox' => 'string', 'indices' => '{urn:horde}integerArray', 'flags' => '{urn:horde}stringArray', 'set' => 'boolean'), + 'type' => 'boolean' +); + +$_services['msgEnvelope'] = array( + 'args' => array('mailbox' => 'string', 'indices' => '{urn:horde}integerArray'), + 'type' => '{urn:horde}hashHash' +); + +$_services['searchMailbox'] = array( + 'args' => array('mailbox' => 'string', 'query' => 'object'), + 'type' => '{urn:horde}integerArray' +); + +$_services['mailboxCacheId'] = array( + 'args' => array('mailbox' => 'string'), + 'type' => 'string' +); + $_services['server'] = array( 'args' => array(), 'type' => 'string' @@ -250,6 +285,149 @@ function _imp_createFolder($folder) } /** + * Deletes messages from a mailbox. + * + * @param string $mailbox The name of the mailbox (UTF7-IMAP). + * @param array $indices The list of UIDs to delete. + * + * @return integer|boolean The number of messages deleted if successful, + * false if not. + */ +function _imp_deleteMessages($mailbox, $indices) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + if (IMP::checkAuthentication(true)) { + $imp_message = &IMP_Message::singleton(); + return $imp_message->delete(array($mailbox => $indices), array('nuke' => true)); + } + + return false; +} + +/** + * Copies messages to a mailbox. + * + * @param string $mailbox The name of the source mailbox (UTF7-IMAP). + * @param array $indices The list of UIDs to copy. + * @param string $target The name of the target mailbox (UTF7-IMAP). + * + * @return boolean True if successful, false if not. + */ +function _imp_copyMessages($mailbox, $indices, $target) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + if (IMP::checkAuthentication(true)) { + $imp_message = &IMP_Message::singleton(); + return $imp_message->copy($target, 'copy', array($mailbox => $indices), true); + } + + return false; +} + +/** + * Moves messages to a mailbox. + * + * @param string $mailbox The name of the source mailbox (UTF7-IMAP). + * @param array $indices The list of UIDs to move. + * @param string $target The name of the target mailbox (UTF7-IMAP). + * + * @return boolean True if successful, false if not. + */ +function _imp_moveMessages($mailbox, $indices, $target) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + if (IMP::checkAuthentication(true)) { + $imp_message = &IMP_Message::singleton(); + return $imp_message->copy($target, 'move', array($mailbox => $indices), true); + } + + return false; +} + +/** + * Flag messages. + * + * @param string $mailbox The name of the source mailbox (UTF7-IMAP). + * @param array $indices The list of UIDs to flag. + * @param array $flags The flags to set. + * @param boolean $set True to set flags, false to clear flags. + * + * @return boolean True if successful, false if not. + */ +function _imp_flagMessages($mailbox, $indices, $flags, $set) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + if (IMP::checkAuthentication(true)) { + $imp_message = &IMP_Message::singleton(); + return $imp_message->flag($flags, 'move', array($mailbox => $indices), $set); + } + + return false; +} + +/** + * Return envelope information for the given list of indices. + * + * @param string $mailbox The name of the mailbox (UTF7-IMAP). + * @param array $indices The list of UIDs. + * + * @return array|boolean TODO if successful, false if not. + */ +function _imp_msgEnvelope($mailbox, $indices) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + return IMP::checkAuthentication(true) + ? $GLOBALS['imp_imap']->ob->fetch($mailbox, array(Horde_Imap_Client::FETCH_ENVELOPE => true), array('ids' => $indices)) + : false; +} + +/** + * Perform a search query on the remote IMAP server. + * + * @param string $mailbox The name of the source mailbox + * (UTF7-IMAP). + * @param Horde_Imap_Client_Search_Query $query The query object. + * + * @return array|boolean The search results (UID list) or false. + */ +function _imp_searchMailbox($mailbox, $query) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + return IMP::checkAuthentication(true) + ? $GLOBALS['imp_search']->runSearchQuery($mailbox, $query) + : false; +} + +/** + * Returns the cache ID value for a mailbox + * + * @param string $mailbox The name of the source mailbox (UTF7-IMAP). + * + * @return string|boolean The cache ID value, or false if not authenticated. + */ +function _imp_mailboxCacheId($mailbox) +{ + $GLOBALS['authentication'] = 'none'; + require_once dirname(__FILE__) . '/base.php'; + + return IMP::checkAuthentication(true) + ? $GLOBALS['imp_imap']->ob->getCacheId($mailbox); + : null; +} + +/** * Returns the currently logged on IMAP server. * * @return string The server hostname. Returns null if the user has not @@ -260,7 +438,9 @@ function _imp_server() $GLOBALS['authentication'] = 'none'; require_once dirname(__FILE__) . '/base.php'; - return (IMP::checkAuthentication(true)) ? $_SESSION['imp']['server'] : null; + return IMP::checkAuthentication(true) + ? $_SESSION['imp']['server'] + : null; } /** @@ -299,8 +479,7 @@ function _imp_changeLanguage() $imp_folder->clearFlistCache(); $imaptree = &IMP_Imap_Tree::singleton(); $imaptree->init(); - $imp_search = new IMP_Search(); - $imp_search->sessionSetup(true); + $GLOBALS['imp_search']->sessionSetup(true); } } diff --git a/imp/lib/prefs.php b/imp/lib/prefs.php index 794a7b8dc..b560aa0ff 100644 --- a/imp/lib/prefs.php +++ b/imp/lib/prefs.php @@ -262,7 +262,7 @@ foreach (($maint->exportIntervalPrefs()) as $val) { } /* Make sure we have an active IMAP stream. */ -if (!$GLOBALS['registry']->call('mail/getStream')) { +if (!$GLOBALS['registry']->call('mail/server')) { header('Location: ' . Util::addParameter(Horde::applicationUrl('redirect.php'), 'url', Horde::selfUrl(true))); exit; } diff --git a/ingo/filters.php b/ingo/filters.php index ef8cc6559..2d39f025c 100644 --- a/ingo/filters.php +++ b/ingo/filters.php @@ -123,9 +123,7 @@ case 'apply_filters': header('Location: ' . Horde::applicationUrl('filters.php', true)); exit; } - if ($ingo_script->canApply()) { - $ingo_script->apply(); - } + $ingo_script->apply(); break; } diff --git a/ingo/lib/Script/imap.php b/ingo/lib/Script/imap.php index ad57e37e3..a64ddf154 100644 --- a/ingo/lib/Script/imap.php +++ b/ingo/lib/Script/imap.php @@ -13,14 +13,14 @@ * @author Michael Slusarz * @package Ingo */ -class Ingo_Script_imap extends Ingo_Script { - +class Ingo_Script_imap extends Ingo_Script +{ /** * The list of actions allowed (implemented) for this driver. * * @var array */ - var $_actions = array( + protected $_actions = array( Ingo_Storage::ACTION_KEEP, Ingo_Storage::ACTION_MOVE, Ingo_Storage::ACTION_DISCARD, @@ -32,7 +32,7 @@ class Ingo_Script_imap extends Ingo_Script { * * @var array */ - var $_categories = array( + protected $_categories = array( Ingo_Storage::ACTION_BLACKLIST, Ingo_Storage::ACTION_WHITELIST ); @@ -42,7 +42,7 @@ class Ingo_Script_imap extends Ingo_Script { * * @var array */ - var $_tests = array( + protected $_tests = array( 'contains', 'not contain' ); @@ -51,7 +51,7 @@ class Ingo_Script_imap extends Ingo_Script { * * @var array */ - var $_types = array( + protected $_types = array( Ingo_Storage::TYPE_HEADER, Ingo_Storage::TYPE_SIZE, Ingo_Storage::TYPE_BODY @@ -62,14 +62,14 @@ class Ingo_Script_imap extends Ingo_Script { * * @var boolean */ - var $_supportIMAPFlags = true; + protected $_supportIMAPFlags = true; /** * Does the driver support the stop-script option? * * @var boolean */ - var $_supportStopScript = true; + protected $_supportStopScript = true; /** * This driver can perform on demand filtering (in fact, that is all @@ -77,30 +77,27 @@ class Ingo_Script_imap extends Ingo_Script { * * @var boolean */ - var $_ondemand = true; + protected $_ondemand = true; /** * The API to use for IMAP functions. * * @var Ingo_Script_imap_api */ - var $_api; + protected $_api; /** * Perform the filtering specified in the rules. * * @param array $params The parameter array. It MUST contain: *
-     * 'imap'     --  An open IMAP stream.
-     * 'mailbox'  --  The name of the mailbox to filter.
+     * 'mailbox' - The name of the mailbox to filter.
      * 
* * @return boolean True if filtering performed, false if not. */ - function perform($params) + public function perform($params) { - global $ingo_storage, $notification, $prefs; - if (empty($params['api'])) { $this->_api = Ingo_Script_imap_api::factory('live', $params); } else { @@ -120,13 +117,13 @@ class Ingo_Script_imap extends Ingo_Script { } /* Grab the rules list. */ - $filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS); + $filters = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS); /* Should we filter only [un]seen messages? */ - $seen_flag = $prefs->getValue('filter_seen'); + $seen_flag = $GLOBALS['prefs']->getValue('filter_seen'); /* Should we use detailed notification messages? */ - $detailmsg = $prefs->getValue('show_filter_msg'); + $detailmsg = $GLOBALS['prefs']->getValue('show_filter_msg'); /* Parse through the rules, one-by-one. */ foreach ($filters->getFilterlist() as $rule) { @@ -145,11 +142,11 @@ class Ingo_Script_imap extends Ingo_Script { $bl_folder = null; if ($rule['action'] == Ingo_Storage::ACTION_BLACKLIST) { - $blacklist = &$ingo_storage->retrieve(Ingo_Storage::ACTION_BLACKLIST); + $blacklist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST); $addr = $blacklist->getBlacklist(); $bl_folder = $blacklist->getBlacklistFolder(); } else { - $whitelist = &$ingo_storage->retrieve(Ingo_Storage::ACTION_WHITELIST); + $whitelist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST); $addr = $whitelist->getWhitelist(); } @@ -158,27 +155,26 @@ class Ingo_Script_imap extends Ingo_Script { continue; } - $query = new Ingo_IMAP_Search_Query(); + $query = new Horde_Imap_Client_Search_Query(); foreach ($addr as $val) { - $ob = new Ingo_IMAP_Search_Query(); - $ob->deleted(false); + $ob = new Horde_Imap_Client_Search_Query(); + $ob->flag('\\deleted', false); if ($seen_flag == Ingo_Script::FILTER_UNSEEN) { - $ob->seen(false); + $ob->flag('\\seen', false); } elseif ($seen_flag == Ingo_Script::FILTER_SEEN) { - $ob->seen(true); + $ob->flag('\\seen', true); } - $ob->header('from', $val); + $ob->headerText('from', $val); $search_array[] = $ob; } - $query->imapOr($search_array); + $query->orSearch($search_array); $indices = $this->_api->search($query); /* Remove any indices that got in there by way of partial * address match. */ - $sequence = implode(',', $indices); - $msgs = $this->_api->fetchMessageOverviews($sequence); - foreach ($msgs as $msg) { - $from_addr = MIME::bareAddress($msg->from); + $msgs = $this->_api->fetchEnvelope($indices); + foreach ($msgs as $k => $v) { + $from_addr = Horde_Mime_Address::bareAddress($v['envelope']['from']); $found = false; foreach ($addr as $val) { if (strtolower($from_addr) == strtolower($val)) { @@ -186,21 +182,19 @@ class Ingo_Script_imap extends Ingo_Script { } } if (!$found) { - $indices = array_diff($indices, array($msg->uid)); + $indices = array_diff($indices, $k); } } if ($rule['action'] == Ingo_Storage::ACTION_BLACKLIST) { $indices = array_diff($indices, $ignore_ids); if (!empty($indices)) { - $sequence = implode(',', $indices); if (!empty($bl_folder)) { - $this->_api->moveMessages($sequence, $bl_folder); + $this->_api->moveMessages($indices, $bl_folder); } else { - $this->_api->deleteMessages($sequence); + $this->_api->deleteMessages($indices); } - $this->_api->expunge($indices); - $notification->push(sprintf(_("Filter activity: %s message(s) that matched the blacklist were deleted."), count($indices)), 'horde.message'); + $GLOBALS['notification']->push(sprintf(_("Filter activity: %s message(s) that matched the blacklist were deleted."), count($indices)), 'horde.message'); } } else { $ignore_ids = $indices; @@ -210,44 +204,31 @@ class Ingo_Script_imap extends Ingo_Script { case Ingo_Storage::ACTION_KEEP: case Ingo_Storage::ACTION_MOVE: case Ingo_Storage::ACTION_DISCARD: - $query = new Ingo_IMAP_Search_Query(); + $query = new Horde_Imap_Client_Search_Query(); foreach ($rule['conditions'] as $val) { - $ob = new Ingo_IMAP_Search_Query(); - $ob->deleted(false); + $ob = new Horde_Imap_Client_Search_Query(); + $ob->flag('\\deleted', false); if ($seen_flag == Ingo_Script::FILTER_UNSEEN) { - $ob->seen(false); + $ob->flag('\\seen', false); } elseif ($seen_flag == Ingo_Script::FILTER_SEEN) { - $ob->seen(true); + $ob->flag('\\seen', true); } if (!empty($val['type']) && ($val['type'] == Ingo_Storage::TYPE_SIZE)) { - if ($val['match'] == 'greater than') { - $operator = '>'; - } elseif ($val['match'] == 'less than') { - $operator = '<'; - } - $ob->size($val['value'], $operator); + $ob->size($val['value'], ($val['match'] == 'greater than')); } elseif (!empty($val['type']) && ($val['type'] == Ingo_Storage::TYPE_BODY)) { - if ($val['match'] == 'contains') { - $ob->body($val['value'], false); - } elseif ($val['match'] == 'not contain') { - $ob->body($val['value'], true); - } + $ob->text($val['value'], true, ($val['match'] == 'not contain')); } else { - if ($val['match'] == 'contains') { - $ob->header($val['field'], $val['value'], false); - } elseif ($val['match'] == 'not contain') { - $ob->header($val['field'], $val['value'], true); - } + $ob->headerText($val['field'], $val['value'], ($val['match'] == 'not contain')); } $search_array[] = $ob; } if ($rule['combine'] == Ingo_Storage::COMBINE_ALL) { - $query->imapAnd($search_array); + $query->andSearch($search_array); } else { - $query->imapOr($search_array); + $query->orSearch($search_array); } $indices = $this->_api->search($query); @@ -260,26 +241,23 @@ class Ingo_Script_imap extends Ingo_Script { $ignore_ids = array_unique($indices + $ignore_ids); } - $sequence = implode(',', $indices); - /* Set the flags. */ if (!empty($rule['flags']) && ($rule['action'] != Ingo_Storage::ACTION_DISCARD)) { $flags = array(); if ($rule['flags'] & Ingo_Storage::FLAG_ANSWERED) { - $flags[] = '\\Answered'; + $flags[] = '\\answered'; } if ($rule['flags'] & Ingo_Storage::FLAG_DELETED) { - $flags[] = '\\Deleted'; + $flags[] = '\\deleted'; } if ($rule['flags'] & Ingo_Storage::FLAG_FLAGGED) { - $flags[] = '\\Flagged'; + $flags[] = '\\flagged'; } if ($rule['flags'] & Ingo_Storage::FLAG_SEEN) { - $flags[] = '\\Seen'; + $flags[] = '\\seen'; } - $this->_api->setMessageFlags($sequence, - implode(' ', $flags)); + $this->_api->setMessageFlags($indices, implode(' ', $flags)); } if ($rule['action'] == Ingo_Storage::ACTION_KEEP) { @@ -288,69 +266,66 @@ class Ingo_Script_imap extends Ingo_Script { } elseif ($rule['action'] == Ingo_Storage::ACTION_MOVE) { /* We need to grab the overview first. */ if ($detailmsg) { - $overview = $this->_api->fetchMessageOverviews($sequence); + $overview = $this->_api->fetchEnvelope($indices); } /* Move the messages to the requested mailbox. */ - $this->_api->moveMessages($sequence, - $rule['action-value']); - $this->_api->expunge($indices); + $this->_api->moveMessages($indices, $rule['action-value']); /* Display notification message(s). */ if ($detailmsg) { foreach ($overview as $msg) { - $notification->push( + $GLOBALS['notification']->push( sprintf(_("Filter activity: The message \"%s\" from \"%s\" has been moved to the folder \"%s\"."), - isset($msg->subject) ? MIME::decode($msg->subject, NLS::getCharset()) : _("[No Subject]"), - isset($msg->from) ? MIME::decode($msg->from, NLS::getCharset()) : _("[No Sender]"), + !empty($msg['envelope']['subject']) ? Horde_Mime::decode($msg['envelope']['subject'], NLS::getCharset()) : _("[No Subject]"), + !empty($msg['envelope']['from']) ? Horde_Mime::decode($msg['envelope']['from'], NLS::getCharset()) : _("[No Sender]"), String::convertCharset($rule['action-value'], 'UTF7-IMAP', NLS::getCharset())), 'horde.message'); } } else { - $notification->push(sprintf(_("Filter activity: %s message(s) have been moved to the folder \"%s\"."), + $GLOBALS['notification']->push(sprintf(_("Filter activity: %s message(s) have been moved to the folder \"%s\"."), count($indices), String::convertCharset($rule['action-value'], 'UTF7-IMAP', NLS::getCharset())), 'horde.message'); } } elseif ($rule['action'] == Ingo_Storage::ACTION_DISCARD) { /* We need to grab the overview first. */ if ($detailmsg) { - $overview = $this->_api->fetchMessageOverviews($sequence); + $overview = $this->_api->fetchEnvelope($indices); } /* Delete the messages now. */ - $this->_api->deleteMessages($sequence); - $this->_api->expunge($indices); + $this->_api->deleteMessages($indices); /* Display notification message(s). */ if ($detailmsg) { foreach ($overview as $msg) { - $notification->push( + $GLOBALS['notification']->push( sprintf(_("Filter activity: The message \"%s\" from \"%s\" has been deleted."), - isset($msg->subject) ? MIME::decode($msg->subject, NLS::getCharset()) : _("[No Subject]"), - isset($msg->from) ? MIME::decode($msg->from, NLS::getCharset()) : _("[No Sender]")), + !empty($msg['envelope']['subject']) ? Horde_Mime::decode($msg['envelope']['subject'], NLS::getCharset()) : _("[No Subject]"), + !empty($msg['envelope']['from']) ? Horde_Mime::decode($msg['envelope']['from'], NLS::getCharset()) : _("[No Sender]")), 'horde.message'); } } else { - $notification->push(sprintf(_("Filter activity: %s message(s) have been deleted."), count($indices)), 'horde.message'); + $GLOBALS['notification']->push(sprintf(_("Filter activity: %s message(s) have been deleted."), count($indices)), 'horde.message'); } } elseif ($rule['action'] == Ingo_Storage::ACTION_MOVEKEEP) { /* Copy the messages to the requested mailbox. */ - $this->_api->copyMessages($sequence, + $this->_api->copyMessages($indices, $rule['action-value']); /* Display notification message(s). */ if ($detailmsg) { - $overview = $this->_api->fetchMessageOverviews($sequence); + $overview = $this->_api->fetchEnvelope($indices); foreach ($overview as $msg) { - $notification->push( + $GLOBALS['notification']->push( sprintf(_("Filter activity: The message \"%s\" from \"%s\" has been copied to the folder \"%s\"."), - isset($msg->subject) ? MIME::decode($msg->subject, NLS::getCharset()) : _("[No Subject]"), - isset($msg->from) ? MIME::decode($msg->from, NLS::getCharset()) : _("[No Sender]"), + !empty($msg['envelope']['subject']) ? Horde_Mime::decode($msg['envelope']['subject'], NLS::getCharset()) : _("[No Subject]"), + !empty($msg['envelope']['from']) ? Horde_Mime::decode($msg['envelope']['from'], NLS::getCharset()) : _("[No Sender]"), String::convertCharset($rule['action-value'], 'UTF7-IMAP', NLS::getCharset())), 'horde.message'); } } else { - $notification->push(sprintf(_("Filter activity: %s message(s) have been copied to the folder \"%s\"."), count($indices), String::convertCharset($rule['action-value'], 'UTF7-IMAP', NLS::getCharset())), 'horde.message'); + $GLOBALS['notification']->push(sprintf(_("Filter activity: %s message(s) have been copied to the folder \"%s\"."), count($indices), String::convertCharset($rule['action-value'], 'UTF7-IMAP', NLS::getCharset())), 'horde.message'); } } } @@ -360,20 +335,19 @@ class Ingo_Script_imap extends Ingo_Script { /* Set cache flag. */ $this->_api->storeCache($_SESSION['ingo']['change']); + return true; } /** * Is the apply() function available? - * The 'mail/getStream' API function must be available. * * @return boolean True if apply() is available, false if not. */ - function canApply() + public function canApply() { - global $registry; - - return ($this->performAvailable() && $registry->hasMethod('mail/getStream')); + return $this->performAvailable() && + $GLOBALS['registry']->hasMethod('mail/server'); } /** @@ -381,16 +355,10 @@ class Ingo_Script_imap extends Ingo_Script { * * @return boolean See perform(). */ - function apply() + public function apply() { - global $registry; - if ($this->canApply()) { - $res = $registry->call('mail/getStream', array('INBOX')); - if ($res !== false) { - $ob = @imap_check($res); - return $this->perform(array('imap' => $res, 'mailbox' => $ob->Mailbox)); - } + return $this->perform(array('mailbox' => 'INBOX')); } return false; @@ -398,66 +366,91 @@ class Ingo_Script_imap extends Ingo_Script { } -class Ingo_Script_imap_api { - - var $_params; - - function Ingo_Script_imap_api($params = array()) - { - $this->_params = $params; - } +class Ingo_Script_imap_api +{ + /** + * TODO + */ + protected $_params; - function factory($type, $params) + /** + * TODO + */ + static public function factory($type, $params) { $class = 'Ingo_Script_imap_' . $type; - if (!class_exists($class)) { - require dirname(__FILE__) . '/imap/' . $type . '.php'; - } return new $class($params); } - function deleteMessages($sequence) + /** + * TODO + */ + public function __construct($params = array()) { - return PEAR::raiseError('Not implemented.'); + $this->_params = $params; } - function expunge($indices) + /** + * TODO + */ + public function deleteMessages($indices) { return PEAR::raiseError('Not implemented.'); } - function moveMessages($sequence, $folder) + /** + * TODO + */ + public function moveMessages($indices, $folder) { return PEAR::raiseError('Not implemented.'); } - function copyMessages($sequence, $folder) + /** + * TODO + */ + public function copyMessages($indices, $folder) { return PEAR::raiseError('Not implemented.'); } - function setMessageFlags($sequence, $flags) + /** + * TODO + */ + public function setMessageFlags($indices, $flags) { return PEAR::raiseError('Not implemented.'); } - function fetchMessageOverviews($sequence) + /** + * TODO + */ + public function fetchEnvelope($indices) { return PEAR::raiseError('Not implemented.'); } - function search($query) + /** + * TODO + */ + public function search($query) { return PEAR::raiseError('Not implemented.'); } - function getCache() + /** + * TODO + */ + public function getCache() { return false; } - function storeCache($timestamp) + /** + * TODO + */ + public function storeCache($timestamp) { } - +} diff --git a/ingo/lib/Script/imap/live.php b/ingo/lib/Script/imap/live.php index 1c9059489..a2ad225ad 100644 --- a/ingo/lib/Script/imap/live.php +++ b/ingo/lib/Script/imap/live.php @@ -8,88 +8,75 @@ * did not receive this file, see http://www.horde.org/licenses/asl.php. * * @author Jason M. Felice + * @author Michael Slusarz * @package Ingo */ -class Ingo_Script_imap_live extends Ingo_Script_imap_api { - - /** - */ - function deleteMessages($sequence) - { - @imap_delete($this->_params['imap'], $sequence, FT_UID); - } - +class Ingo_Script_imap_live extends Ingo_Script_imap_api +{ /** */ - function expunge($indices) + public function deleteMessages($indices) { - if (!count($indices)) { - return; - } - - $ids = @imap_search($this->_params['imap'], 'DELETED', SE_UID); - $unflag = false; - if (!empty($ids)) { - $unflag = array_diff($ids, $indices); - if (!empty($unflag)) { - $unflag = implode(',', $unflag); - @imap_clearflag_full($this->_params['imap'], $unflag, '\\DELETED', ST_UID); - } - } - - @imap_expunge($this->_params['imap']); - if ($unflag) { - @imap_setflag_full($this->_params['imap'], $unflag, '\\DELETED', ST_UID); - } + return $GLOBALS['registry']->hasMethod('mail/deleteMessages') + ? $GLOBALS['registry']->call('mail/deleteMessages', array($this->_params['mailbox'], $indices)) + : false; } /** */ - function moveMessages($sequence, $folder) + public function moveMessages($indices, $folder) { - @imap_mail_move($this->_params['imap'], $sequence, $folder, CP_UID); + return $GLOBALS['registry']->hasMethod('mail/moveMessages') + ? $GLOBALS['registry']->call('mail/moveMessages', array($this->_params['mailbox'], $indices, $folder)) + : false; } /** */ - function copyMessages($sequence, $folder) + public function copyMessages($indices, $folder) { - @imap_mail_copy($this->_params['imap'], $sequence, $folder, CP_UID); + return $GLOBALS['registry']->hasMethod('mail/copyMessages') + ? $GLOBALS['registry']->call('mail/copyMessages', array($this->_params['mailbox'], $indices, $folder)) + : false; } /** */ - function setMessageFlags($sequence, $flags) + public function setMessageFlags($indices, $flags) { - @imap_setflag_full($this->_params['imap'], $sequence, $flags, ST_UID); + return $GLOBALS['registry']->hasMethod('mail/flagMessages') + ? $GLOBALS['registry']->call('mail/flagMessages', array($this->_params['mailbox'], $indices, $flags, true)) + : false; } /** */ - function fetchMessageOverviews($sequence) + public function fetchEnvelope($indices) { - return @imap_fetch_overview($this->_params['imap'], $sequence, FT_UID); + return $GLOBALS['registry']->hasMethod('mail/msgEnvelope') + ? $GLOBALS['registry']->call('mail/msgEnvelope', array($this->_params['mailbox'], $indices)) + : false; } /** */ - function search($query) + public function search($query) { - $search = &Ingo_IMAP_Search::singleton($this->_params); - return $search->searchMailbox($query, $this->_params['imap'], - $this->_params['mailbox']); + return $GLOBALS['registry']->hasMethod('mail/searchMailbox') + ? $GLOBALS['registry']->call('mail/searchMailbox', array($this->_params['mailbox'], $query)) + : false; } /** */ - function getCache() + public function getCache() { if (empty($_SESSION['ingo']['imapcache'][$this->_params['mailbox']])) { return false; } $ptr = &$_SESSION['ingo']['imapcache'][$this->_params['mailbox']]; - if ($this->_getCacheID() != $ptr['id']) { + if ($this->_cacheId() != $ptr['id']) { $ptr = array(); return false; } @@ -99,24 +86,25 @@ class Ingo_Script_imap_live extends Ingo_Script_imap_api { /** */ - function storeCache($timestamp) + public function storeCache($timestamp) { if (!isset($_SESSION['ingo']['imapcache'])) { $_SESSION['ingo']['imapcache'] = array(); } $_SESSION['ingo']['imapcache'][$this->_params['mailbox']] = array( - 'id' => $this->_getCacheID(), + 'id' => $this->_cacheId(), 'ts' => $timestamp ); } /** */ - function _getCacheID() + protected function _cacheId() { - $ob = @imap_status($this->_params['imap'], $this->_params['mailbox'], SA_ALL); - return $ob ? implode('|', array($ob->messages, $ob->uidnext, $ob->uidvalidity)) : null; + return $GLOBALS['registry']->hasMethod('mail/mailboxCacheId') + ? $GLOBALS['registry']->call('mail/mailboxCacheId', array($this->_params['mailbox'])) + : time(); } } diff --git a/ingo/lib/Script/imap/mock.php b/ingo/lib/Script/imap/mock.php index 797cc2a93..849b7f34b 100644 --- a/ingo/lib/Script/imap/mock.php +++ b/ingo/lib/Script/imap/mock.php @@ -1,12 +1,23 @@ _fixtures = array(); @@ -36,7 +47,10 @@ class Ingo_Script_imap_mock extends Ingo_Script_imap_api { } } - function hasMessage($fixture, $folder = 'INBOX') + /** + * TODO + */ + public function hasMessage($fixture, $folder = 'INBOX') { if (empty($this->_folders[$folder])) { return false; @@ -49,7 +63,10 @@ class Ingo_Script_imap_mock extends Ingo_Script_imap_api { return false; } - function search(&$query) + /** + * TODO + */ + public function search(&$query) { $result = array(); foreach ($this->_folders['INBOX'] as $message) { @@ -63,54 +80,55 @@ class Ingo_Script_imap_mock extends Ingo_Script_imap_api { return $result; } - function deleteMessages($sequence) + /** + * TODO + */ + public function deleteMessages($indices) { - $uids = explode(',', $sequence); foreach (array_keys($this->_folders['INBOX']) as $i) { - if (in_array($this->_folders['INBOX'][$i]['uid'], $uids)) { - $this->_folders['INBOX'][$i]['deleted'] = true; + if (in_array($this->_folders['INBOX'][$i]['uid'], $indices)) { + unset($this->_folders['INBOX'][$i]); } } - } - function moveMessages($sequence, $folder) - { - $uids = explode(',', $sequence); - foreach (array_keys($this->_folders['INBOX']) as $i) { - if (in_array($this->_folders['INBOX'][$i]['uid'], $uids)) { - $this->_folders[$folder][] = $this->_folders['INBOX'][$i]; - } - } - return $this->deleteMessages($sequence); + // Force renumbering + $this->_folders['INBOX'] = array_merge($this->_folders['INBOX'], array()); } - function expunge($indices) + /** + * TODO + */ + public function moveMessages($indices, $folder) { foreach (array_keys($this->_folders['INBOX']) as $i) { if (in_array($this->_folders['INBOX'][$i]['uid'], $indices)) { - unset($this->_folders['INBOX'][$i]); + $this->_folders[$folder][] = $this->_folders['INBOX'][$i]; } } - - // Force renumbering - $this->_folders['INBOX'] = array_merge($this->_folders['INBOX'], - array()); + return $this->deleteMessages($indices); } - function fetchMessageOverviews($sequence) + /** + * TODO + */ + public function fetchEnvelope($indices) { $result = array(); - foreach (explode(',',$sequence) as $uid) { + + foreach ($indices as $uid) { foreach (array_keys($this->_folders['INBOX']) as $i) { if ($this->_folders['INBOX'][$i]['uid'] == $uid) { $fixture = $this->_fixtures[$this->_folders['INBOX'][$i]['fixture']]; - $ob = new stdClass(); - $ob->from = $fixture->headers['from']; - $ob->uid = $uid; - $result[] = $ob; + $result[] = array( + 'envelope' => array( + 'from' => $fixture->headers['from'], + 'uid' => $uid + ) + ); } } } + return $result; } -- 2.11.0