Fix constant names since _Base doesn't extend H_I_C now.
*
* Copyright 2008-2009 The Horde Project (http://www.horde.org/)
*
- * getBaseSubject() code adapted from imap-base-subject.c (Dovecot 1.2)
- * Original code released under the LGPL v2.1
- * Copyright (c) 2002-2008 Timo Sirainen <tss@iki.fi>
- *
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
);
/**
+ * The Horde_Imap_Client_Utils object
+ *
+ * @var Horde_Imap_Client_Utils
+ */
+ protected $_utils = null;
+
+ /**
* The Horde_Imap_Client_Cache object.
*
- * @var Horde_Cache
+ * @var Horde_Imap_Client_Cache
*/
protected $_cacheOb = null;
protected $_debug = null;
/**
- * Create an IMAP message sequence string from a list of indices.
- * Format: range_start:range_end,uid,uid2,range2_start:range2_end,...
- *
- * @param array $in An array of indices.
- * @param array $options Additional options:
- * <pre>
- * 'nosort' - (boolean) Do not numerically sort the IDs before creating
- * the range?
- * DEFAULT: IDs are sorted
- * </pre>
- *
- * @return string The IMAP message sequence string.
- */
- static public function toSequenceString($ids, $options = array())
- {
- if (empty($ids)) {
- return '';
- }
-
- // Make sure IDs are unique
- $ids = array_keys(array_flip($ids));
-
- if (empty($options['nosort'])) {
- sort($ids, SORT_NUMERIC);
- }
-
- $first = $last = array_shift($ids);
- $out = array();
-
- foreach ($ids as $val) {
- if ($last + 1 == $val) {
- $last = $val;
- } else {
- $out[] = $first . ($last == $first ? '' : (':' . $last));
- $first = $last = $val;
- }
- }
- $out[] = $first . ($last == $first ? '' : (':' . $last));
-
- return implode(',', $out);
- }
-
- /**
- * Parse an IMAP message sequence string into a list of indices.
- * Format: range_start:range_end,uid,uid2,range2_start:range2_end,...
- *
- * @param string $str The IMAP message sequence string.
- *
- * @return array An array of indices.
- */
- static public function fromSequenceString($str)
- {
- $ids = array();
- $str = trim($str);
-
- $idarray = explode(',', $str);
- if (empty($idarray)) {
- $idarray = array($str);
- }
-
- foreach ($idarray as $val) {
- $range = array_map('intval', explode(':', $val));
- if (count($range) == 1) {
- $ids[] = $val;
- } else {
- list($low, $high) = ($range[0] < $range[1]) ? $range : array_reverse($range);
- $ids = array_merge($ids, range($low, $high));
- }
- }
-
- return $ids;
- }
-
- /**
- * Remove "bare newlines" from a string.
- *
- * @param string $str The original string.
- *
- * @return string The string with all bare newlines removed.
- */
- static public function removeBareNewlines($str)
- {
- return str_replace(array("\r\n", "\n"), array("\n", "\r\n"), $str);
- }
-
- /**
- * Escape IMAP output via a quoted string (see RFC 3501 [4.3]).
- *
- * @param string $str The unescaped string.
- *
- * @return string The escaped string.
- */
- static public function escape($str)
- {
- return '"' . addcslashes($str, '"\\') . '"';
- }
-
- /**
- * Return the "base subject" defined in RFC 5256 [2.1].
- *
- * @param string $str The original subject string.
- * @param array $options Additional options:
- * <pre>
- * 'keepblob' - (boolean) Don't remove any "blob" information (i.e. text
- * leading text between square brackets) from string.
- * </pre>
- *
- * @return string The cleaned up subject string.
- */
- static public function getBaseSubject($str, $options = array())
- {
- // Rule 1a: MIME decode to UTF-8 (if possible).
- $str = Horde_Mime::decode($str, 'UTF-8');
-
- // Rule 1b: Remove superfluous whitespace.
- $str = preg_replace("/\s{2,}/", '', $str);
-
- if (!$str) {
- return '';
- }
-
- do {
- /* (2) Remove all trailing text of the subject that matches the
- * the subj-trailer ABNF, repeat until no more matches are
- * possible. */
- $str = preg_replace("/(?:\s*\(fwd\)\s*)+$/i", '', $str);
-
- do {
- /* (3) Remove all prefix text of the subject that matches the
- * subj-leader ABNF. */
- $found = self::_removeSubjLeader($str, !empty($options['keepblob']));
-
- /* (4) If there is prefix text of the subject that matches
- * the subj-blob ABNF, and removing that prefix leaves a
- * non-empty subj-base, then remove the prefix text. */
- $found = (empty($options['keepblob']) && self::_removeBlobWhenNonempty($str)) || $found;
-
- /* (5) Repeat (3) and (4) until no matches remain. */
- } while ($found);
-
- /* (6) If the resulting text begins with the subj-fwd-hdr ABNF and
- * ends with the subj-fwd-trl ABNF, remove the subj-fwd-hdr and
- * subj-fwd-trl and repeat from step (2). */
- } while (self::_removeSubjFwdHdr($str));
-
- return $str;
- }
-
- /**
- * Parse an IMAP URL (RFC 5092).
- *
- * @param string $url A IMAP URL string.
- *
- * @return mixed False if the URL is invalid. If valid, a URL with the
- * following fields:
- * <pre>
- * 'auth' - (string) The authentication method to use.
- * 'port' - (integer) The remote port
- * 'hostspec' - (string) The remote server
- * 'username' - (string) The username to use on the remote server.
- * </pre>
- */
- static public function parseImapUrl($url)
- {
- $url = trim($url);
- if (stripos($url, 'imap://') !== 0) {
- return false;
- }
- $url = substr($url, 7);
-
- /* At present, only support imap://<iserver>[/] style URLs. */
- if (($pos = strpos($url, '/')) !== false) {
- $url = substr($url, 0, $pos);
- }
-
- $ret_array = array();
-
- /* Check for username/auth information. */
- if (($pos = strpos($url, '@')) !== false) {
- if ((($apos = stripos($url, ';AUTH=')) !== false) &&
- ($apos < $pos)) {
- $auth = substr($url, $apos + 6, $pos - $apos - 6);
- if ($auth != '*') {
- $ret_array['auth'] = $auth;
- }
- if ($apos) {
- $ret_array['username'] = substr($url, 0, $apos);
- }
- }
- $url = substr($url, $pos + 1);
- }
-
- /* Check for port information. */
- if (($pos = strpos($url, ':')) !== false) {
- $ret_array['port'] = substr($url, $pos + 1);
- $url = substr($url, 0, $pos);
- }
-
- $ret_array['hostspec'] = $url;
-
- return $ret_array;
- }
-
- /**
- * Remove all prefix text of the subject that matches the subj-leader
- * ABNF.
- *
- * @param string &$str The subject string.
- * @param boolean $keepblob Remove blob information?
- *
- * @return boolean True if string was altered.
- */
- static protected function _removeSubjLeader(&$str, $keepblob = false)
- {
- $ret = false;
-
- if (!$str) {
- return $ret;
- }
-
- if ($str[0] == ' ') {
- $str = substr($str, 1);
- $ret = true;
- }
-
- $i = 0;
-
- if (!$keepblob) {
- while ($str[$i] == '[') {
- if (($i = self::_removeBlob($str, $i)) === false) {
- return $ret;
- }
- }
- }
-
- $cmp_str = substr($str, $i);
- if (stripos($cmp_str, 're') === 0) {
- $i += 2;
- } elseif (stripos($cmp_str, 'fwd') === 0) {
- $i += 3;
- } elseif (stripos($cmp_str, 'fw') === 0) {
- $i += 2;
- } else {
- return $ret;
- }
-
- if ($str[$i] == ' ') {
- ++$i;
- }
-
- if (!$keepblob) {
- while ($str[$i] == '[') {
- if (($i = self::_removeBlob($str, $i)) === false) {
- return $ret;
- }
- }
- }
-
- if ($str[$i] != ':') {
- return $ret;
- }
-
- $str = substr($str, ++$i);
-
- return true;
- }
-
- /**
- * Remove "[...]" text.
- *
- * @param string &$str The subject string.
- *
- * @return boolean True if string was altered.
- */
- static protected function _removeBlob($str, $i)
- {
- if ($str[$i] != '[') {
- return false;
- }
-
- ++$i;
-
- for ($cnt = strlen($str); $i < $cnt; ++$i) {
- if ($str[$i] == ']') {
- break;
- }
-
- if ($str[$i] == '[') {
- return false;
- }
- }
-
- if ($i == ($cnt - 1)) {
- return false;
- }
-
- ++$i;
-
- if ($str[$i] == ' ') {
- ++$i;
- }
-
- return $i;
- }
-
- /**
- * Remove "[...]" text if it doesn't result in the subject becoming
- * empty.
- *
- * @param string &$str The subject string.
- *
- * @return boolean True if string was altered.
- */
- static protected function _removeBlobWhenNonempty(&$str)
- {
- if ($str &&
- ($str[0] == '[') &&
- (($i = self::_removeBlob($str, 0)) !== false) &&
- ($i != strlen($str))) {
- $str = substr($str, $i);
- return true;
- }
-
- return false;
- }
-
- /**
- * Remove a "[fwd: ... ]" string.
- *
- * @param string &$str The subject string.
- *
- * @return boolean True if string was altered.
- */
- static protected function _removeSubjFwdHdr(&$str)
- {
- if ((stripos($str, '[fwd:') !== 0) || (substr($str, -1) != ']')) {
- return false;
- }
-
- $str = substr($str, 5, -1);
- return true;
- }
-
- /**
* Constructs a new Horde_Imap_Client object.
* Throws a Horde_Imap_Client_Exception on error.
*
$params['cache'] = array('fields' => array());
} elseif (empty($params['cache']['fields'])) {
$params['cache']['fields'] = array(
- self::FETCH_STRUCTURE => 1,
- self::FETCH_ENVELOPE => 1,
- self::FETCH_FLAGS => 1,
- self::FETCH_DATE => 1,
- self::FETCH_SIZE => 1
+ Horde_Imap_Client::FETCH_STRUCTURE => 1,
+ Horde_Imap_Client::FETCH_ENVELOPE => 1,
+ Horde_Imap_Client::FETCH_FLAGS => 1,
+ Horde_Imap_Client::FETCH_DATE => 1,
+ Horde_Imap_Client::FETCH_SIZE => 1
);
} else {
$params['cache']['fields'] = array_flip($params['cache']['fields']);
$this->_params = $params;
+ $this->_utils = new Horde_Imap_Client_Utils();
+
// This will initialize debugging, if needed.
$this->__wakeup();
}
continue;
}
- $mbox = $this->listMailboxes($val, self::MBOX_ALL, array('delimiter' => true));
+ $mbox = $this->listMailboxes($val, Horde_Imap_Client::MBOX_ALL, array('delimiter' => true));
$first = reset($mbox);
if ($first && ($first['mailbox'] == $val)) {
/* This accurately determines the namespace information of the
* base namespace if the NAMESPACE command is not supported.
* See: RFC 3501 [6.3.8] */
- $mbox = $this->listMailboxes('', self::MBOX_ALL, array('delimiter' => true));
+ $mbox = $this->listMailboxes('', Horde_Imap_Client::MBOX_ALL, array('delimiter' => true));
$first = reset($mbox);
$ns[''] = array(
'name' => '',
}
/* Check for ability to cache flags here. */
- if (isset($this->_params['cache']['fields'][self::FETCH_FLAGS]) &&
+ if (isset($this->_params['cache']['fields'][Horde_Imap_Client::FETCH_FLAGS]) &&
!isset($this->_init['enabled']['CONDSTORE'])) {
- unset($this->_params['cache']['fields'][self::FETCH_FLAGS]);
+ unset($this->_params['cache']['fields'][Horde_Imap_Client::FETCH_FLAGS]);
}
}
* Horde_Imap_Client::OPEN_READWRITE, or
* Horde_Imap_Client::OPEN_AUTO.
*/
- public function openMailbox($mailbox, $mode = self::OPEN_AUTO)
+ public function openMailbox($mailbox, $mode = Horde_Imap_Client::OPEN_AUTO)
{
$change = false;
$mailbox = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($mailbox);
- if ($mode == self::OPEN_AUTO) {
+ if ($mode == Horde_Imap_Client::OPEN_AUTO) {
if (is_null($this->_selected) || ($this->_selected != $mailbox)) {
- $mode = self::OPEN_READONLY;
+ $mode = Horde_Imap_Client::OPEN_READONLY;
$change = true;
}
} elseif (is_null($this->_selected) ||
$new = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($new);
/* Check if old mailbox was subscribed to. */
- $subscribed = $this->listMailboxes($old, self::MBOX_SUBSCRIBED, array('flat' => true));
+ $subscribed = $this->listMailboxes($old, Horde_Imap_Client::MBOX_SUBSCRIBED, array('flat' => true));
$this->_renameMailbox($old, $new);
* if 'attributes' option is true), and 'delimiter' (only
* if 'delimiter' option is true).
*/
- public function listMailboxes($pattern, $mode = self::MBOX_ALL,
+ public function listMailboxes($pattern, $mode = Horde_Imap_Client::MBOX_ALL,
$options = array())
{
$ret = $this->_listMailboxes(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($pattern), $mode, $options);
*
* @return array An array with the requested keys (see above).
*/
- public function status($mailbox, $flags = self::STATUS_ALL)
+ public function status($mailbox, $flags = Horde_Imap_Client::STATUS_ALL)
{
- if ($flags & self::STATUS_ALL) {
- $flags |= self::STATUS_MESSAGES | self::STATUS_RECENT | self::STATUS_UNSEEN | self::STATUS_UIDNEXT | self::STATUS_UIDVALIDITY;
+ if ($flags & Horde_Imap_Client::STATUS_ALL) {
+ $flags |= Horde_Imap_Client::STATUS_MESSAGES | Horde_Imap_Client::STATUS_RECENT | Horde_Imap_Client::STATUS_UNSEEN | Horde_Imap_Client::STATUS_UIDNEXT | Horde_Imap_Client::STATUS_UIDVALIDITY;
}
/* STATUS_PERMFLAGS requires a read/write mailbox. */
- if ($flags & self::STATUS_PERMFLAGS) {
- $this->openMailbox($mailbox, self::OPEN_READWRITE);
+ if ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) {
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE);
}
return $this->_status(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($mailbox), $flags);
* @param string $flags A bitmask of information requested from the
* server.
*
- * @return array See Horde_Imap_Client_Base::status().
+ * @return array See self::status().
*/
abstract protected function _status($mailbox, $flags);
*/
public function expunge($mailbox, $options = array())
{
- $this->openMailbox($mailbox, self::OPEN_READWRITE);
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE);
$this->_expunge($options);
}
*/
public function search($mailbox, $query = null, $options = array())
{
- $this->openMailbox($mailbox, self::OPEN_AUTO);
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
if (empty($options['results'])) {
$options['results'] = array(
- self::SORT_RESULTS_MATCH,
- self::SORT_RESULTS_COUNT
+ Horde_Imap_Client::SORT_RESULTS_MATCH,
+ Horde_Imap_Client::SORT_RESULTS_COUNT
);
}
* optimize with unseen queries because we may cause an infinite loop
* between here and the status() call. */
if ((count($options['results']) == 1) &&
- (reset($options['results']) == self::SORT_RESULTS_COUNT)) {
+ (reset($options['results']) == Horde_Imap_Client::SORT_RESULTS_COUNT)) {
switch ($options['_query']['query']) {
case 'ALL':
- $ret = $this->status($this->_selected, self::STATUS_MESSAGES);
+ $ret = $this->status($this->_selected, Horde_Imap_Client::STATUS_MESSAGES);
return array('count' => $ret['messages']);
case 'RECENT':
- $ret = $this->status($this->_selected, self::STATUS_RECENT);
+ $ret = $this->status($this->_selected, Horde_Imap_Client::STATUS_RECENT);
return array('count' => $ret['recent']);
}
}
*/
public function thread($mailbox, $options = array())
{
- $this->openMailbox($mailbox, self::OPEN_AUTO);
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
$ret = $this->_thread($options);
return new Horde_Imap_Client_Thread($ret, empty($options['sequence']) ? 'uid' : 'sequence');
/* If using cache, we store by UID so we need to return UIDs. */
if ($seq && !empty($cf)) {
- $criteria[self::FETCH_UID] = true;
+ $criteria[Horde_Imap_Client::FETCH_UID] = true;
}
- $this->openMailbox($mailbox, self::OPEN_AUTO);
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
/* We need the UIDVALIDITY for the current mailbox. */
- $status_res = $this->status($this->_selected, self::STATUS_HIGHESTMODSEQ | self::STATUS_UIDVALIDITY);
+ $status_res = $this->status($this->_selected, Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_UIDVALIDITY);
/* Determine if caching is available and if anything in $criteria is
* cacheable. Do some sanity checking on criteria also. */
$cache_field = null;
switch ($k) {
- case self::FETCH_STRUCTURE:
+ case Horde_Imap_Client::FETCH_STRUCTURE:
/* Don't cache if 'noext' is present. It will probably be a
* rare event anyway. */
if (empty($v['noext']) && isset($cf[$k])) {
}
break;
- case self::FETCH_BODYPARTSIZE:
+ case Horde_Imap_Client::FETCH_BODYPARTSIZE:
if (!$this->queryCapability('BINARY')) {
unset($criteria[$k]);
}
break;
- case self::FETCH_ENVELOPE:
+ case Horde_Imap_Client::FETCH_ENVELOPE:
if (isset($cf[$k])) {
$cache_field = 'HICenv';
$fetch_field = 'envelope';
}
break;
- case self::FETCH_FLAGS:
+ case Horde_Imap_Client::FETCH_FLAGS:
if (isset($cf[$k])) {
/* QRESYNC would have already done syncing on mailbox
* open, so no need to do again. */
($metadata['HICmodseq'] != $status_res['highestmodseq'])) {
$uids = $this->_cacheOb->get($this->_selected, array(), array(), $status_res['uidvalidity']);
if (!empty($uids)) {
- $this->_fetch(array(self::FETCH_FLAGS => true), array('changedsince' => $metadata['HICmodseq'], 'ids' => $uids));
+ $this->_fetch(array(Horde_Imap_Client::FETCH_FLAGS => true), array('changedsince' => $metadata['HICmodseq'], 'ids' => $uids));
}
$this->_cacheOb->setMetaData($mailbox, array('HICmodseq' => $status_res['highestmodseq']));
}
}
break;
- case self::FETCH_DATE:
+ case Horde_Imap_Client::FETCH_DATE:
if (isset($cf[$k])) {
$cache_field = 'HICdate';
$fetch_field = 'date';
}
break;
- case self::FETCH_SIZE:
+ case Horde_Imap_Client::FETCH_SIZE:
if (isset($cf[$k])) {
$cache_field = 'HICsize';
$fetch_field = 'size';
}
break;
- case self::FETCH_MODSEQ:
+ case Horde_Imap_Client::FETCH_MODSEQ:
if (!isset($this->_init['enabled']['CONDSTORE'])) {
unset($criteria[$k]);
}
}
if (!$seq) {
- unset($crit[self::FETCH_UID]);
+ unset($crit[Horde_Imap_Client::FETCH_UID]);
}
if (!empty($crit)) {
*/
public function store($mailbox, $options = array())
{
- $this->openMailbox($mailbox, self::OPEN_READWRITE);
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE);
if (!empty($options['unchangedsince']) &&
!isset($this->_init['enabled']['CONDSTORE'])) {
*
* @param array $options Additional options.
*
- * @return array See Horde_Imap_Client::store().
+ * @return array See self::store().
*/
abstract protected function _store($options);
*/
public function copy($source, $dest, $options = array())
{
- $this->openMailbox($source, empty($options['move']) ? self::OPEN_AUTO : self::OPEN_READWRITE);
+ $this->openMailbox($source, empty($options['move']) ? Horde_Imap_Client::OPEN_AUTO : Horde_Imap_Client::OPEN_READWRITE);
return $this->_copy(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($dest), $options);
}
{
$search = new Horde_Imap_Client_Search_Query();
$search->sequence($ids, $seq);
- $res = $this->search($this->_selected, $search, array('sort' => array(self::SORT_ARRIVAL)));
+ $res = $this->search($this->_selected, $search, array('sort' => array(Horde_Imap_Client::SORT_ARRIVAL)));
$ret = array('uids' => $res['sort']);
if ($seq) {
if (empty($ids)) {
$mailbox = empty($options['mailbox']) ? $this->_selected : $options['mailbox'];
if (empty($options['uidvalid'])) {
- $status_res = $this->status($mailbox, self::STATUS_HIGHESTMODSEQ | self::STATUS_UIDVALIDITY);
+ $status_res = $this->status($mailbox, Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_UIDVALIDITY);
$uidvalid = $status_res['uidvalidity'];
if (isset($status_res['highestmodseq'])) {
$highestmodseq[] = $status_res['highestmodseq'];
while (list($label, $val) = each($v)) {
switch ($label) {
case 'structure':
- if (isset($cf[self::FETCH_STRUCTURE])) {
+ if (isset($cf[Horde_Imap_Client::FETCH_STRUCTURE])) {
$tmp[is_array($val) ? 'HICstructa' : 'HICstructm'] = $val;
}
break;
case 'envelope':
- if (isset($cf[self::FETCH_ENVELOPE])) {
+ if (isset($cf[Horde_Imap_Client::FETCH_ENVELOPE])) {
$tmp['HICenv'] = $val;
}
break;
case 'flags':
- if (isset($cf[self::FETCH_FLAGS])) {
+ if (isset($cf[Horde_Imap_Client::FETCH_FLAGS])) {
/* A FLAGS FETCH can only occur if we are in the
* mailbox. So either HIGHESTMODSEQ has already been
* updated or the flag FETCHs will provide the new
break;
case 'date':
- if (isset($cf[self::FETCH_DATE])) {
+ if (isset($cf[Horde_Imap_Client::FETCH_DATE])) {
$tmp['HICdate'] = $val;
}
break;
case 'size':
- if (isset($cf[self::FETCH_SIZE])) {
+ if (isset($cf[Horde_Imap_Client::FETCH_SIZE])) {
$tmp['HICsize'] = $val;
}
break;
protected function _openMailbox($mailbox, $mode)
{
$this->login();
- $flag = ($mode == self::OPEN_READONLY) ? OP_READONLY : 0;
+ $flag = ($mode == Horde_Imap_Client::OPEN_READONLY) ? OP_READONLY : 0;
$old_error = error_reporting(0);
if (version_compare(PHP_VERSION, '5.2.1') != -1) {
$this->login();
switch ($mode) {
- case self::MBOX_ALL:
+ case Horde_Imap_Client::MBOX_ALL:
if (!empty($options['flat'])) {
$mboxes = $this->_getMailboxList($pattern, $mode);
return (empty($options['utf8'])) ? $mboxes : array_map(array('Horde_Imap_Client_Utf7imap', 'Utf7ImapToUtf8'), $mboxes);
$check = false;
break;
- case self::MBOX_SUBSCRIBED:
- case self::MBOX_UNSUBSCRIBED:
- $sub = $this->_getMailboxList($pattern, self::MBOX_SUBSCRIBED);
+ case Horde_Imap_Client::MBOX_SUBSCRIBED:
+ case Horde_Imap_Client::MBOX_UNSUBSCRIBED:
+ $sub = $this->_getMailboxList($pattern, Horde_Imap_Client::MBOX_SUBSCRIBED);
if (!empty($options['flat'])) {
if (!empty($options['utf8'])) {
$sub = array_map(array('Horde_Imap_Client_Utf7imap', 'Utf7ImapToUtf8'), $sub);
}
- if ($mode == self::MBOX_SUBSCRIBED) {
+ if ($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) {
return $sub;
}
- $mboxes = $this->_getMailboxList($pattern, self::MBOX_ALL);
+ $mboxes = $this->_getMailboxList($pattern, Horde_Imap_Client::MBOX_ALL);
if (!empty($options['utf8'])) {
$sub = array_map(array('Horde_Imap_Client_Utf7imap', 'Utf7ImapToUtf8'), $sub);
}
$mbox = substr($val->name, strpos($val->name, '}') + 1);
if ($check &&
- ((($mode == self::MBOX_UNSUBSCRIBED) &&
+ ((($mode == Horde_Imap_Client::MBOX_UNSUBSCRIBED) &&
isset($sub[$mbox])) ||
- (($mode == self::MBOX_SUBSCRIBED) &&
+ (($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) &&
!isset($sub[$mbox])))) {
continue;
}
$mboxes = array();
$old_error = error_reporting(0);
- if ($mode != self::MBOX_ALL) {
+ if ($mode != Horde_Imap_Client::MBOX_ALL) {
$res = imap_list($this->_stream, $this->_connString(), $pattern);
} else {
$res = imap_lsub($this->_stream, $this->_connString(), $pattern);
/* If FLAGS/PERMFLAGS/HIGHESTMODSEQ/UIDNOTSTICKY are needed, we must
* use the Socket driver. */
- if (($flags & self::STATUS_FLAGS) ||
- ($flags & self::STATUS_PERMFLAGS) ||
- ($flags & self::STATUS_HIGHESTMODSEQ) ||
- ($flags & self::STATUS_UIDNOTSTICKY)) {
+ if (($flags & Horde_Imap_Client::STATUS_FLAGS) ||
+ ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) ||
+ ($flags & Horde_Imap_Client::STATUS_HIGHESTMODSEQ) ||
+ ($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY)) {
return $this->_getSocket()->status($mailbox, $flags);
}
$items = array(
- self::STATUS_MESSAGES => SA_MESSAGES,
- self::STATUS_RECENT => SA_RECENT,
- self::STATUS_UIDNEXT => SA_UIDNEXT,
- self::STATUS_UIDVALIDITY => SA_UIDVALIDITY,
- self::STATUS_UNSEEN => SA_UNSEEN
+ Horde_Imap_Client::STATUS_MESSAGES => SA_MESSAGES,
+ Horde_Imap_Client::STATUS_RECENT => SA_RECENT,
+ Horde_Imap_Client::STATUS_UIDNEXT => SA_UIDNEXT,
+ Horde_Imap_Client::STATUS_UIDVALIDITY => SA_UIDVALIDITY,
+ Horde_Imap_Client::STATUS_UNSEEN => SA_UNSEEN
);
$c_flag = 0;
}
}
- if ($flags & self::STATUS_FIRSTUNSEEN) {
+ if ($flags & Horde_Imap_Client::STATUS_FIRSTUNSEEN) {
$search_query = new Horde_Imap_Client_Search_Query();
$search_query->flag('\\unseen', false);
- $search = $this->search($mailbox, $search_query, array('results' => array(self::SORT_RESULTS_MIN), 'sequence' => true));
+ $search = $this->search($mailbox, $search_query, array('results' => array(Horde_Imap_Client::SORT_RESULTS_MIN), 'sequence' => true));
if (is_null($res)) {
return array('firstunseen' => $search['min']);
while (list(,$val) = each($data)) {
$old_error = error_reporting(0);
$text = is_resource($val['data']) ? stream_get_contents($val['data']) : $val['data'];
- $res = imap_append($this->_stream, $this->_connString($mailbox), $this->removeBareNewlines($text), empty($val['flags']) ? null : implode(' ', $val['flags']));
+ $res = imap_append($this->_stream, $this->_connString($mailbox), $this->_utils->removeBareNewlines($text), empty($val['flags']) ? null : implode(' ', $val['flags']));
error_reporting($old_error);
if ($res === false) {
if (!empty($options['expunge'])) {
$this->expunge($this->_selected);
}
- $this->openMailbox($this->_selected, self::OPEN_READONLY);
+ $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READONLY);
}
/**
if ($options['_query']['imap4'] ||
(!empty($options['sort']) &&
((count($options['sort']) > 1) ||
- in_array(self::SORT_REVERSE, $options['sort'])))) {
+ in_array(Horde_Imap_Client::SORT_REVERSE, $options['sort'])))) {
return $this->_getSocket()->search($this->_selected, $query, $options);
}
$res = imap_search($this->_stream, $options['_query']['query'], empty($options['sequence']) ? SE_UID : 0, $options['_query']['charset']);
} else {
$sort_criteria = array(
- self::SORT_ARRIVAL => SORTARRIVAL,
- self::SORT_CC => SORTCC,
- self::SORT_DATE => SORTDATE,
- self::SORT_FROM => SORTFROM,
- self::SORT_SIZE => SORTSIZE,
- self::SORT_SUBJECT => SORTSUBJECT,
- self::SORT_TO => SORTTO
+ Horde_Imap_Client::SORT_ARRIVAL => SORTARRIVAL,
+ Horde_Imap_Client::SORT_CC => SORTCC,
+ Horde_Imap_Client::SORT_DATE => SORTDATE,
+ Horde_Imap_Client::SORT_FROM => SORTFROM,
+ Horde_Imap_Client::SORT_SIZE => SORTSIZE,
+ Horde_Imap_Client::SORT_SUBJECT => SORTSUBJECT,
+ Horde_Imap_Client::SORT_TO => SORTTO
);
$res = imap_sort($this->_stream, $sort_criteria[reset($options['sort'])], 0, empty($options['sequence']) ? SE_UID : 0, $options['_query']['query'], $options['_query']['charset']);
$ret = array();
foreach ($options['results'] as $val) {
switch ($val) {
- case self::SORT_RESULTS_COUNT:
+ case Horde_Imap_Client::SORT_RESULTS_COUNT:
$ret['count'] = count($res);
break;
- case self::SORT_RESULTS_MATCH:
+ case Horde_Imap_Client::SORT_RESULTS_MATCH:
$ret[empty($options['sort']) ? 'match' : 'sort'] = $res;
break;
- case self::SORT_RESULTS_MAX:
+ case Horde_Imap_Client::SORT_RESULTS_MAX:
$ret['max'] = empty($res) ? null : max($res);
break;
- case self::SORT_RESULTS_MIN:
+ case Horde_Imap_Client::SORT_RESULTS_MIN:
$ret['min'] = empty($res) ? null : min($res);
break;
}
* and does not support defining search criteria. */
if (!empty($options['search']) ||
(!empty($options['criteria']) &&
- $options['criteria'] != self::THREAD_REFERENCES)) {
+ $options['criteria'] != Horde_Imap_Client::THREAD_REFERENCES)) {
return $this->_getSocket()->thread($this->_selected, $options);
}
// These options are not supported by this driver.
if (!empty($options['changedsince']) ||
- (reset($options['ids']) == self::USE_SEARCHRES)) {
+ (reset($options['ids']) == Horde_Imap_Client::USE_SEARCHRES)) {
return $this->_getSocket()->fetch($this->_selected, $criteria, $options);
}
$seq = '1:*';
$options['ids'] = range(1, imap_num_msg($this->_stream));
} else {
- $seq = $this->toSequenceString($options['ids']);
+ $seq = $this->_utils->toSequenceString($options['ids']);
}
$ret = array_combine($options['ids'], array_fill(0, count($options['ids']), array()));
}
switch ($type) {
- case self::FETCH_STRUCTURE:
+ case Horde_Imap_Client::FETCH_STRUCTURE:
// 'noext' has no effect in this driver
foreach ($options['ids'] as $id) {
$structure = imap_fetchstructure($this->_stream, $id, empty($options['sequence']) ? FT_UID : 0);
}
break;
- case self::FETCH_FULLMSG:
+ case Horde_Imap_Client::FETCH_FULLMSG:
foreach ($options['ids'] as $id) {
$tmp = imap_fetchheader($this->_stream, $id, (empty($options['sequence']) ? FT_UID : 0) | FT_PREFETCHTEXT) .
imap_body($this->_stream, $id, (empty($options['sequence']) ? FT_UID : 0) | (empty($c_val['peek']) ? 0 : FT_PEEK));
}
break;
- case self::FETCH_HEADERTEXT:
- case self::FETCH_BODYPART:
+ case Horde_Imap_Client::FETCH_HEADERTEXT:
+ case Horde_Imap_Client::FETCH_BODYPART:
foreach ($c_val as $val) {
- if ($type == self::FETCH_HEADERTEXT) {
+ if ($type == Horde_Imap_Client::FETCH_HEADERTEXT) {
$label = 'headertext';
/* imap_fetchbody() can return header parts for a
* given MIME part by appending '.0' (or 0 for the
}
break;
- case self::FETCH_BODYTEXT:
+ case Horde_Imap_Client::FETCH_BODYTEXT:
foreach ($c_val as $val) {
// This is the base body. This is easily obtained via
// imap_body().
}
break;
- case self::FETCH_MIMEHEADER:
- case self::FETCH_HEADERS:
- case self::FETCH_MODSEQ:
+ case Horde_Imap_Client::FETCH_MIMEHEADER:
+ case Horde_Imap_Client::FETCH_HEADERS:
+ case Horde_Imap_Client::FETCH_MODSEQ:
// Can't do it. Nope. Nada. Without heavy duty parsing of the
// full imap_body() object, it is impossible to retrieve the
// MIME headers for each individual part. Ship it off to
// This goes for header field searches also.
// MODSEQ isn't available in c-client either.
switch ($type) {
- case self::FETCH_MIMEHEADER:
+ case Horde_Imap_Client::FETCH_MIMEHEADER:
$label = 'mimeheader';
break;
- case self::FETCH_HEADERS:
+ case Horde_Imap_Client::FETCH_HEADERS:
$label = 'headers';
break;
- case self::FETCH_MODSEQ:
+ case Horde_Imap_Client::FETCH_MODSEQ:
$label = 'modseq';
break;
}
}
break;
- case self::FETCH_ENVELOPE:
+ case Horde_Imap_Client::FETCH_ENVELOPE:
if (is_null($hdrinfo)) {
$hdrinfo = array();
foreach ($options['ids'] as $id) {
}
break;
- case self::FETCH_FLAGS:
+ case Horde_Imap_Client::FETCH_FLAGS:
if (is_null($overview)) {
$overview = imap_fetch_overview($this->_stream, $seq, empty($options['sequence']) ? FT_UID : 0);
if (!$overview) {
}
break;
- case self::FETCH_DATE:
+ case Horde_Imap_Client::FETCH_DATE:
if (is_null($hdrinfo)) {
$hdrinfo = array();
foreach ($options['ids'] as $id) {
}
break;
- case self::FETCH_SIZE:
+ case Horde_Imap_Client::FETCH_SIZE:
if (!is_null($hdrinfo)) {
foreach ($options['ids'] as $id) {
$ret[$id]['size'] = $hdrinfo[$id]->Size;
}
break;
- case self::FETCH_UID:
+ case Horde_Imap_Client::FETCH_UID:
if (empty($options['sequence'])) {
foreach ($options['ids'] as $id) {
$ret[$id]['uid'] = $id;
}
break;
- case self::FETCH_SEQ:
+ case Horde_Imap_Client::FETCH_SEQ:
if (!empty($options['sequence'])) {
foreach ($options['ids'] as $id) {
$ret[$id]['seq'] = $id;
// options, nor does it support using stored searches.
if (!empty($options['unchangedsince']) ||
!empty($options['replace']) ||
- (reset($options['ids']) == self::USE_SEARCHRES)) {
+ (reset($options['ids']) == Horde_Imap_Client::USE_SEARCHRES)) {
// Requires Socket driver.
return $this->_getSocket()->store($this->_selected, $options);
}
$seq = empty($options['ids'])
? '1:*'
- : $this->toSequenceString($options['ids']);
+ : $this->_utils->toSequenceString($options['ids']);
$old_error = error_reporting(0);
$opts |= CP_MOVE;
}
- if (reset($options['ids']) == self::USE_SEARCHRES) {
+ if (reset($options['ids']) == Horde_Imap_Client::USE_SEARCHRES) {
// Requires Socket driver.
return $this->_getSocket()->copy($this->_selected, $options);
}
$seq = empty($options['ids'])
? '1:*'
- : $this->toSequenceString($options['ids']);
+ : $this->_utils->toSequenceString($options['ids']);
$old_error = error_reporting(0);
$res = imap_mail_copy($this->_stream, $seq, $this->_connString($dest), $opts);
if ($search_query['imap4'] ||
(!empty($options['sort']) &&
((count($options['sort']) > 1) ||
- in_array(self::SORT_REVERSE, $options['sort'])))) {
+ in_array(Horde_Imap_Client::SORT_REVERSE, $options['sort'])))) {
throw new Horde_Imap_Client_Exception('Unsupported search criteria on POP3 server.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
}
* and does not support defining search criteria. */
if (!empty($options['search']) ||
(!empty($options['criteria']) &&
- $options['criteria'] != self::THREAD_REFERENCES)) {
+ $options['criteria'] != Horde_Imap_Client::THREAD_REFERENCES)) {
throw new Horde_Imap_Client_Exception('Unsupported threading criteria on POP3 server.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
}
protected function _fetch($criteria, $options)
{
// No support for FETCH_MIMEHEADER or FETCH_HEADERS
- $nosupport = array(self::FETCH_MIMEHEADER, self::FETCH_HEADERS);
+ $nosupport = array(Horde_Imap_Client::FETCH_MIMEHEADER, Horde_Imap_Client::FETCH_HEADERS);
reset($criteria);
while (list($val,) = each($criteria)) {
protected $_exts = array();
/**
+ * The Horde_Imap_Client_Utils object
+ *
+ * @var Horde_Imap_Client_Utils
+ */
+ protected $_utils = null;
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ $this->_utils = new Horde_Imap_Client_Utils();
+ }
+
+ /**
* Sets the charset of the search text.
*
* @param string $charset The charset to use for the search.
$tmp .= 'HEADER ';
$imap4 = true;
}
- $cmds[] = $tmp . $val['header'] . ' ' . Horde_Imap_Client::escape($val['text']);
+ $cmds[] = $tmp . $val['header'] . ' ' . $this->_utils->escape($val['text']);
}
}
// NOT searches were not in IMAP2
$imap4 = true;
}
- $cmds[] = $tmp . $val['type'] . ' ' . Horde_Imap_Client::escape($val['text']);
+ $cmds[] = $tmp . $val['type'] . ' ' . $this->_utils->escape($val['text']);
}
}
'MODSEQ ' .
(is_null($ptr['modseq']['name'])
? ''
- : Horde_Imap_Client::escape($ptr['modseq']['name']) . ' ' . $ptr['modseq']['type'] . ' ') .
+ : $this->_utils->escape($ptr['modseq']['name']) . ' ' . $ptr['modseq']['type'] . ' ') .
$ptr['modseq']['value'];
}
if (empty($ids)) {
$ids = '1:*';
} else {
- $ids = Horde_Imap_Client::toSequenceString($ids);
+ $ids = $this->_utils->toSequenceString($ids);
}
$this->_search['sequence'] = array(
'ids' => $ids,
break;
case 'LOGIN':
- $this->_sendLine('LOGIN ' . $this->escape($this->_params['username']) . ' ' . $this->escape($this->_params['password']), array('debug' => '[LOGIN Command]'));
+ $this->_sendLine('LOGIN ' . $this->_utils->escape($this->_params['username']) . ' ' . $this->_utils->escape($this->_params['password']), array('debug' => '[LOGIN Command]'));
break;
case 'PLAIN':
} else {
$cmd = '(';
foreach ($info as $key => $val) {
- $cmd .= $this->escape(strtolower($key)) . ' ' . $this->escape($val);
+ $cmd .= $this->_utils->escape(strtolower($key)) . ' ' . $this->_utils->escape($val);
}
$cmd .= ')';
}
{
$cmd = array();
foreach ($langs as $val) {
- $cmd[] = $this->escape($val);
+ $cmd[] = $this->_utils->escape($val);
}
try {
$this->_temp['qresyncmbox'] = $mailbox;
}
- $cmd = (($mode == self::OPEN_READONLY) ? 'EXAMINE' : 'SELECT') . ' ' . $this->escape($mailbox);
+ $cmd = (($mode == Horde_Imap_Client::OPEN_READONLY) ? 'EXAMINE' : 'SELECT') . ' ' . $this->_utils->escape($mailbox);
/* If QRESYNC is available, synchronize the mailbox. */
if ($qresync) {
* response handlers.
* TODO: Use 4th parameter (useful if we keep a sequence
* number->UID lookup in the future). */
- $cmd .= ' (QRESYNC (' . $metadata['uidvalid'] . ' ' . $metadata['HICmodseq'] . ' ' . $this->toSequenceString($uids) . '))';
+ $cmd .= ' (QRESYNC (' . $metadata['uidvalid'] . ' ' . $metadata['HICmodseq'] . ' ' . $this->_utils->toSequenceString($uids) . '))';
}
}
} elseif (!isset($this->_init['enabled']['CONDSTORE']) &&
$this->login();
// CREATE returns no untagged information (RFC 3501 [6.3.3])
- $this->_sendLine('CREATE ' . $this->escape($mailbox));
+ $this->_sendLine('CREATE ' . $this->_utils->escape($mailbox));
}
/**
try {
// DELETE returns no untagged information (RFC 3501 [6.3.4])
- $this->_sendLine('DELETE ' . $this->escape($mailbox));
+ $this->_sendLine('DELETE ' . $this->_utils->escape($mailbox));
} catch (Horde_Imap_Client_Exception $e) {
// Some IMAP servers won't allow a mailbox delete unless all
// messages in that mailbox are deleted.
$this->login();
// RENAME returns no untagged information (RFC 3501 [6.3.5])
- $this->_sendLine('RENAME ' . $this->escape($old) . ' ' . $this->escape($new));
+ $this->_sendLine('RENAME ' . $this->_utils->escape($old) . ' ' . $this->_utils->escape($new));
}
/**
// SUBSCRIBE/UNSUBSCRIBE returns no untagged information (RFC 3501
// [6.3.6 & 6.3.7])
- $this->_sendLine(($subscribe ? '' : 'UN') . 'SUBSCRIBE ' . $this->escape($mailbox));
+ $this->_sendLine(($subscribe ? '' : 'UN') . 'SUBSCRIBE ' . $this->_utils->escape($mailbox));
}
/**
// Get the list of subscribed/unsubscribed mailboxes. Since LSUB is
// not guaranteed to have correct attributes, we must use LIST to
// ensure we receive the correct information.
- if ($mode != self::MBOX_ALL) {
- $subscribed = $this->_getMailboxList($pattern, self::MBOX_SUBSCRIBED, array('flat' => true));
+ if ($mode != Horde_Imap_Client::MBOX_ALL) {
+ $subscribed = $this->_getMailboxList($pattern, Horde_Imap_Client::MBOX_SUBSCRIBED, array('flat' => true));
// If mode is subscribed, and 'flat' option is true, we can
// return now.
- if (($mode == self::MBOX_SUBSCRIBED) && !empty($options['flat'])) {
+ if (($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) && !empty($options['flat'])) {
return $subscribed;
}
} else {
protected function _getMailboxList($pattern, $mode, $options,
$subscribed = null)
{
- $check = (($mode != self::MBOX_ALL) && !is_null($subscribed));
+ $check = (($mode != Horde_Imap_Client::MBOX_ALL) && !is_null($subscribed));
// Setup cache entry for use in _parseList()
$t = &$this->_temp;
);
$t['listresponse'] = array();
- $this->_sendLine((($mode == self::MBOX_SUBSCRIBED) ? 'LSUB' : 'LIST') . ' "" ' . $this->escape($pattern));
+ $this->_sendLine((($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) ? 'LSUB' : 'LIST') . ' "" ' . $this->_utils->escape($pattern));
return (empty($options['flat'])) ? $t['listresponse'] : array_values($t['listresponse']);
}
$search = null;
$items = array(
- self::STATUS_MESSAGES => 'messages',
- self::STATUS_RECENT => 'recent',
- self::STATUS_UIDNEXT => 'uidnext',
- self::STATUS_UIDVALIDITY => 'uidvalidity',
- self::STATUS_UNSEEN => 'unseen',
- self::STATUS_FIRSTUNSEEN => 'firstunseen',
- self::STATUS_FLAGS => 'flags',
- self::STATUS_PERMFLAGS => 'permflags',
- self::STATUS_UIDNOTSTICKY => 'uidnotsticky',
+ Horde_Imap_Client::STATUS_MESSAGES => 'messages',
+ Horde_Imap_Client::STATUS_RECENT => 'recent',
+ Horde_Imap_Client::STATUS_UIDNEXT => 'uidnext',
+ Horde_Imap_Client::STATUS_UIDVALIDITY => 'uidvalidity',
+ Horde_Imap_Client::STATUS_UNSEEN => 'unseen',
+ Horde_Imap_Client::STATUS_FIRSTUNSEEN => 'firstunseen',
+ Horde_Imap_Client::STATUS_FLAGS => 'flags',
+ Horde_Imap_Client::STATUS_PERMFLAGS => 'permflags',
+ Horde_Imap_Client::STATUS_UIDNOTSTICKY => 'uidnotsticky',
);
/* Don't include 'highestmodseq' return if server does not support it.
* OK to use queryCapability('CONDSTORE') here because we may not have
* yet sent an enabling command. */
if ($this->queryCapability('CONDSTORE')) {
- $items[self::STATUS_HIGHESTMODSEQ] = 'highestmodseq';
+ $items[Horde_Imap_Client::STATUS_HIGHESTMODSEQ] = 'highestmodseq';
}
/* If FLAGS/PERMFLAGS/UIDNOTSTICKY/FIRSTUNSEEN are needed, we must do
* a SELECT/EXAMINE to get this information (data will be caught in
* the code below). */
- if (($flags & self::STATUS_FIRSTUNSEEN) ||
- ($flags & self::STATUS_FLAGS) ||
- ($flags & self::STATUS_PERMFLAGS) ||
- ($flags & self::STATUS_UIDNOTSTICKY)) {
+ if (($flags & Horde_Imap_Client::STATUS_FIRSTUNSEEN) ||
+ ($flags & Horde_Imap_Client::STATUS_FLAGS) ||
+ ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) ||
+ ($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY)) {
$this->openMailbox($mailbox);
} else {
$this->login();
if (isset($this->_temp['mailbox'][$val])) {
$data[$val] = $this->_temp['mailbox'][$val];
} else {
- if ($key == self::STATUS_UIDNOTSTICKY) {
+ if ($key == Horde_Imap_Client::STATUS_UIDNOTSTICKY) {
/* In the absence of uidnotsticky information, or
* if UIDPLUS is not supported, we assume the UIDs
* are sticky. */
$data[$val] = false;
- } elseif (in_array($key, array(self::STATUS_FIRSTUNSEEN, self::STATUS_UNSEEN))) {
+ } elseif (in_array($key, array(Horde_Imap_Client::STATUS_FIRSTUNSEEN, Horde_Imap_Client::STATUS_UNSEEN))) {
/* If we already know there are no messages in the
* current mailbox, we know there is no
* firstunseen and unseen info also. */
if (empty($this->_temp['mailbox']['messages'])) {
- $data[$val] = ($key == self::STATUS_FIRSTUNSEEN) ? null : 0;
+ $data[$val] = ($key == Horde_Imap_Client::STATUS_FIRSTUNSEEN) ? null : 0;
} else {
/* RFC 3501 [6.3.1] - FIRSTUNSEEN information
* is not mandatory. If missing EXAMINE/SELECT
if (is_null($search)) {
$search_query = new Horde_Imap_Client_Search_Query();
$search_query->flag('\\seen', false);
- $search = $this->search($mailbox, $search_query, array('results' => array(($key == self::STATUS_FIRSTUNSEEN) ? self::SORT_RESULTS_MIN : self::SORT_RESULTS_COUNT), 'sequence' => true));
+ $search = $this->search($mailbox, $search_query, array('results' => array(($key == Horde_Imap_Client::STATUS_FIRSTUNSEEN) ? Horde_Imap_Client::SORT_RESULTS_MIN : Horde_Imap_Client::SORT_RESULTS_COUNT), 'sequence' => true));
}
- $data[$val] = $search[($key == self::STATUS_FIRSTUNSEEN) ? 'min' : 'count'];
+ $data[$val] = $search[($key == Horde_Imap_Client::STATUS_FIRSTUNSEEN) ? 'min' : 'count'];
}
}
}
}
$this->_temp['status'] = array();
- $this->_sendLine('STATUS ' . $this->escape($mailbox) . ' (' . implode(' ', array_map('strtoupper', $query)) . ')');
+ $this->_sendLine('STATUS ' . $this->_utils->escape($mailbox) . ' (' . implode(' ', array_map('strtoupper', $query)) . ')');
return $this->_temp['status'];
}
reset($data);
while (list(,$m_data) = each($data)) {
if (!$i++ || !$multiappend) {
- $cmd = 'APPEND ' . $this->escape($mailbox);
+ $cmd = 'APPEND ' . $this->_utils->escape($mailbox);
} else {
$cmd = '';
$notag = true;
}
if (!empty($m_data['internaldate'])) {
- $cmd .= ' ' . $this->escape($m_data['internaldate']->format('j-M-Y H:i:s O'));
+ $cmd .= ' ' . $this->_utils->escape($m_data['internaldate']->format('j-M-Y H:i:s O'));
}
/* @todo There is no way I am aware of to determine the length of
* for now, simply grab the contents of the stream and do a
* strlen() call to determine the literal size to send to the
* IMAP server. */
- $text = $this->removeBareNewlines(is_resource($m_data['data']) ? stream_get_contents($m_data['data']) : $m_data['data']);
+ $text = $this->_utils->removeBareNewlines(is_resource($m_data['data']) ? stream_get_contents($m_data['data']) : $m_data['data']);
$datalength = strlen($text);
/* RFC 3516/4466 says we should be able to append binary data
$uid_string = '1:*';
} elseif ($uidplus) {
/* UID EXPUNGE command needs UIDs. */
- if (reset($options['ids']) === self::USE_SEARCHRES) {
+ if (reset($options['ids']) === Horde_Imap_Client::USE_SEARCHRES) {
$uid_string = '$';
} elseif ($seq) {
- $results = array(self::SORT_RESULTS_MATCH);
+ $results = array(Horde_Imap_Client::SORT_RESULTS_MATCH);
if ($this->queryCapability('SEARCHRES')) {
- $results[] = self::SORT_RESULTS_SAVE;
+ $results[] = Horde_Imap_Client::SORT_RESULTS_SAVE;
}
$s_res = $this->search($mailbox, null, array('results' => $results));
- $uid_string = (in_array(self::SORT_RESULTS_SAVE, $results) && !empty($s_res['save']))
+ $uid_string = (in_array(Horde_Imap_Client::SORT_RESULTS_SAVE, $results) && !empty($s_res['save']))
? '$'
- : $this->toSequenceString($s_res['match']);
+ : $this->_utils->toSequenceString($s_res['match']);
} else {
- $uid_string = $this->toSequenceString($options['ids']);
+ $uid_string = $this->_utils->toSequenceString($options['ids']);
}
} else {
/* Without UIDPLUS, need to temporarily unflag all messages marked
* searches to accomplish this goal. */
$search_query = new Horde_Imap_Client_Search_Query();
$search_query->flag('\\deleted', true);
- if (reset($options['ids']) === self::USE_SEARCHRES) {
+ if (reset($options['ids']) === Horde_Imap_Client::USE_SEARCHRES) {
$search_query->previousSearch(true);
} else {
$search_query->sequence($options['ids'], $seq, true);
* we will get VANISHED responses, so we need to do this. */
if ($use_cache && is_null($s_res)) {
/* Keys in $s_res['sort'] start at 0, not 1. */
- $s_res = $this->search($mailbox, null, array('sort' => array(self::SORT_ARRIVAL)));
+ $s_res = $this->search($mailbox, null, array('sort' => array(Horde_Imap_Client::SORT_ARRIVAL)));
}
$tmp = &$this->_temp;
* the tagged response. */
if (is_array($data[0])) {
if (strtoupper(reset($data[0])) == 'EARLIER') {
- $this->_cacheOb->deleteMsgs($this->_temp['mailbox']['name'], $this->fromSequenceString($data[1]));
+ $this->_cacheOb->deleteMsgs($this->_temp['mailbox']['name'], $this->_utils->fromSequenceString($data[1]));
}
} else {
/* The second form is just VANISHED. This is returned from an
* EXPUNGE command and will be processed in _expunge() (since
* we need to adjust message counts in the current mailbox). */
- $this->_temp['vanished'] = $this->fromSequenceString($data[0]);
+ $this->_temp['vanished'] = $this->_utils->fromSequenceString($data[0]);
}
}
}
$sort_criteria = array(
- self::SORT_ARRIVAL => 'ARRIVAL',
- self::SORT_CC => 'CC',
- self::SORT_DATE => 'DATE',
- self::SORT_FROM => 'FROM',
- self::SORT_REVERSE => 'REVERSE',
- self::SORT_SIZE => 'SIZE',
- self::SORT_SUBJECT => 'SUBJECT',
- self::SORT_TO => 'TO'
+ Horde_Imap_Client::SORT_ARRIVAL => 'ARRIVAL',
+ Horde_Imap_Client::SORT_CC => 'CC',
+ Horde_Imap_Client::SORT_DATE => 'DATE',
+ Horde_Imap_Client::SORT_FROM => 'FROM',
+ Horde_Imap_Client::SORT_REVERSE => 'REVERSE',
+ Horde_Imap_Client::SORT_SIZE => 'SIZE',
+ Horde_Imap_Client::SORT_SUBJECT => 'SUBJECT',
+ Horde_Imap_Client::SORT_TO => 'TO'
);
$results_criteria = array(
- self::SORT_RESULTS_COUNT => 'COUNT',
- self::SORT_RESULTS_MATCH => 'ALL',
- self::SORT_RESULTS_MAX => 'MAX',
- self::SORT_RESULTS_MIN => 'MIN',
- self::SORT_RESULTS_SAVE => 'SAVE'
+ Horde_Imap_Client::SORT_RESULTS_COUNT => 'COUNT',
+ Horde_Imap_Client::SORT_RESULTS_MATCH => 'ALL',
+ Horde_Imap_Client::SORT_RESULTS_MAX => 'MAX',
+ Horde_Imap_Client::SORT_RESULTS_MIN => 'MIN',
+ Horde_Imap_Client::SORT_RESULTS_SAVE => 'SAVE'
);
// Check if the server supports server-side sorting (RFC 5256).
/* Make sure sort options are correct. If not, default to ARRIVAL
* sort. */
if (count(array_intersect($options['sort'], array_keys($sort_criteria))) === 0) {
- $options['sort'] = array(self::SORT_ARRIVAL);
+ $options['sort'] = array(Horde_Imap_Client::SORT_ARRIVAL);
}
}
$results = array();
foreach ($options['results'] as $val) {
if (isset($results_criteria[$val]) &&
- ($val != self::SORT_RESULTS_SAVE)) {
+ ($val != Horde_Imap_Client::SORT_RESULTS_SAVE)) {
$results[] = $results_criteria[$val];
}
}
$ret = array();
foreach ($options['results'] as $val) {
switch ($val) {
- case self::SORT_RESULTS_COUNT:
+ case Horde_Imap_Client::SORT_RESULTS_COUNT:
$ret['count'] = $esearch ? $er['count'] : count($sr);
break;
- case self::SORT_RESULTS_MATCH:
+ case Horde_Imap_Client::SORT_RESULTS_MATCH:
$ret[$return_sort ? 'sort' : 'match'] = $sr;
break;
- case self::SORT_RESULTS_MAX:
+ case Horde_Imap_Client::SORT_RESULTS_MAX:
$ret['max'] = $esearch ? (isset($er['max']) ? $er['max'] : null) : (empty($sr) ? null : max($sr));
break;
- case self::SORT_RESULTS_MIN:
+ case Horde_Imap_Client::SORT_RESULTS_MIN:
$ret['min'] = $esearch ? (isset($er['min']) ? $er['min'] : null) : (empty($sr) ? null : min($sr));
break;
- case self::SORT_RESULTS_SAVE:
+ case Horde_Imap_Client::SORT_RESULTS_SAVE:
$ret['save'] = $esearch ? empty($this->_temp['searchnotsaved']) : false;
}
}
$tag = strtoupper($data[$i]);
switch ($tag) {
case 'ALL':
- $this->_temp['searchresp'] = $this->fromSequenceString($val);
+ $this->_temp['searchresp'] = $this->_utils->fromSequenceString($val);
break;
case 'COUNT':
$criteria = array();
foreach ($opts['sort'] as $val) {
switch ($val) {
- case self::SORT_DATE:
- $criteria[self::FETCH_DATE] = true;
+ case Horde_Imap_Client::SORT_DATE:
+ $criteria[Horde_Imap_Client::FETCH_DATE] = true;
// Fall through
- case self::SORT_CC:
- case self::SORT_FROM:
- case self::SORT_SUBJECT:
- case self::SORT_TO:
- $criteria[self::FETCH_ENVELOPE] = true;
+ case Horde_Imap_Client::SORT_CC:
+ case Horde_Imap_Client::SORT_FROM:
+ case Horde_Imap_Client::SORT_SUBJECT:
+ case Horde_Imap_Client::SORT_TO:
+ $criteria[Horde_Imap_Client::FETCH_ENVELOPE] = true;
break;
- case self::SORT_SIZE:
- $criteria[self::FETCH_SIZE] = true;
+ case Horde_Imap_Client::SORT_SIZE:
+ $criteria[Horde_Imap_Client::FETCH_SIZE] = true;
break;
}
}
$reverse = false;
foreach ($opts['sort'] as $val) {
- if ($val == self::SORT_REVERSE) {
+ if ($val == Horde_Imap_Client::SORT_REVERSE) {
$reverse = true;
continue;
}
}
switch ($val) {
- case self::SORT_ARRIVAL:
+ case Horde_Imap_Client::SORT_ARRIVAL:
/* There is no requirement that IDs be returned in
* sequence order (see RFC 4549 [4.3.1]). So we must sort
* ourselves. */
sort($sorted, SORT_NUMERIC);
break;
- case self::SORT_SIZE:
+ case Horde_Imap_Client::SORT_SIZE:
foreach ($slice as $num) {
$sorted[$num] = $fetch_res[$num]['size'];
}
asort($sorted, SORT_NUMERIC);
break;
- case self::SORT_CC:
- case self::SORT_FROM:
- case self::SORT_TO:
- if ($val == self::SORT_CC) {
+ case Horde_Imap_Client::SORT_CC:
+ case Horde_Imap_Client::SORT_FROM:
+ case Horde_Imap_Client::SORT_TO:
+ if ($val == Horde_Imap_Client::SORT_CC) {
$field = 'cc';
- } elseif ($val = self::SORT_FROM) {
+ } elseif ($val = Horde_Imap_Client::SORT_FROM) {
$field = 'from';
} else {
$field = 'to';
asort($sorted, SORT_LOCALE_STRING);
break;
- case self::SORT_DATE:
+ case Horde_Imap_Client::SORT_DATE:
// Date sorting rules in RFC 5256 [2.2]
$sorted = $this->_getSentDates($fetch_res, $slice);
asort($sorted, SORT_NUMERIC);
break;
- case self::SORT_SUBJECT:
+ case Horde_Imap_Client::SORT_SUBJECT:
// Subject sorting rules in RFC 5256 [2.1]
foreach ($slice as $num) {
$sorted[$num] = empty($fetch_res[$num]['envelope']['subject'])
? ''
- : $this->getBaseSubject($fetch_res[$num]['envelope']['subject']);
+ : $this->_utils->getBaseSubject($fetch_res[$num]['envelope']['subject']);
}
asort($sorted, SORT_LOCALE_STRING);
break;
$cmd = array();
foreach (explode(' ', $comparator) as $val) {
- $cmd[] = $this->escape($val);
+ $cmd[] = $this->_utils->escape($val);
}
$this->_sendLine('COMPARATOR ' . implode(' ', $cmd));
protected function _thread($options)
{
$thread_criteria = array(
- self::THREAD_ORDEREDSUBJECT => 'ORDEREDSUBJECT',
- self::THREAD_REFERENCES => 'REFERENCES'
+ Horde_Imap_Client::THREAD_ORDEREDSUBJECT => 'ORDEREDSUBJECT',
+ Horde_Imap_Client::THREAD_REFERENCES => 'REFERENCES'
);
$tsort = (isset($options['criteria']))
}
/* Do client-side ORDEREDSUBJECT threading. */
- $fetch_res = $this->fetch($this->_selected, array(self::FETCH_ENVELOPE => true, self::FETCH_DATE => true), array('ids' => $ids, 'sequence' => !empty($options['sequence'])));
+ $fetch_res = $this->fetch($this->_selected, array(Horde_Imap_Client::FETCH_ENVELOPE => true, Horde_Imap_Client::FETCH_DATE => true), array('ids' => $ids, 'sequence' => !empty($options['sequence'])));
return $this->_clientThreadOrderedsubject($fetch_res);
} else {
throw new Horde_Imap_Client_Exception('Server does not support REFERENCES thread sort.', Horde_Imap_Client_Exception::NOSUPPORTIMAPEXT);
while(list($k, $v) = each($data)) {
$subject = empty($v['envelope']['subject'])
? ''
- : $this->getBaseSubject($v['envelope']['subject']);
+ : $this->_utils->getBaseSubject($v['envelope']['subject']);
if (!isset($sorted[$subject])) {
$sorted[$subject] = array();
}
}
switch ($type) {
- case self::FETCH_STRUCTURE:
+ case Horde_Imap_Client::FETCH_STRUCTURE:
$fp['parsestructure'] = !empty($c_val['parse']);
$fetch[] = !empty($c_val['noext']) ? 'BODY' : 'BODYSTRUCTURE';
break;
- case self::FETCH_FULLMSG:
+ case Horde_Imap_Client::FETCH_FULLMSG:
if (empty($c_val['peek'])) {
- $this->openMailbox($this->_selected, self::OPEN_READWRITE);
+ $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE);
}
$fetch[] = 'BODY' .
(!empty($c_val['peek']) ? '.PEEK' : '') .
(isset($c_val['start']) && !empty($c_val['length']) ? ('<' . $c_val['start'] . '.' . $c_val['length'] . '>') : '');
break;
- case self::FETCH_HEADERTEXT:
- case self::FETCH_BODYTEXT:
- case self::FETCH_MIMEHEADER:
- case self::FETCH_BODYPART:
- case self::FETCH_HEADERS:
+ case Horde_Imap_Client::FETCH_HEADERTEXT:
+ case Horde_Imap_Client::FETCH_BODYTEXT:
+ case Horde_Imap_Client::FETCH_MIMEHEADER:
+ case Horde_Imap_Client::FETCH_BODYPART:
+ case Horde_Imap_Client::FETCH_HEADERS:
foreach ($c_val as $val) {
$main_cmd = 'BODY';
}
switch ($type) {
- case self::FETCH_HEADERTEXT:
+ case Horde_Imap_Client::FETCH_HEADERTEXT:
$fp['parseheadertext'] = !empty($val['parse']);
$cmd .= 'HEADER';
break;
- case self::FETCH_BODYTEXT:
+ case Horde_Imap_Client::FETCH_BODYTEXT:
$cmd .= 'TEXT';
break;
- case self::FETCH_MIMEHEADER:
+ case Horde_Imap_Client::FETCH_MIMEHEADER:
if (empty($val['id'])) {
throw new Horde_Imap_Client_Exception('Need a MIME ID when retrieving a MIME header.');
}
$cmd .= 'MIME';
break;
- case self::FETCH_BODYPART:
+ case Horde_Imap_Client::FETCH_BODYPART:
if (empty($val['id'])) {
throw new Horde_Imap_Client_Exception('Need a MIME ID when retrieving a MIME body part.');
}
}
break;
- case self::FETCH_HEADERS:
+ case Horde_Imap_Client::FETCH_HEADERS:
if (empty($val['label'])) {
throw new Horde_Imap_Client_Exception('Need a unique label when doing a headers field search.');
}
}
if (empty($val['peek'])) {
- $this->openMailbox($this->_selected, self::OPEN_READWRITE);
+ $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE);
}
$fetch[] = $main_cmd .
}
break;
- case self::FETCH_BODYPARTSIZE:
+ case Horde_Imap_Client::FETCH_BODYPARTSIZE:
foreach ($c_val as $val) {
if (empty($val['id'])) {
throw new Horde_Imap_Client_Exception('Need a MIME ID when retrieving unencoded MIME body part size.');
}
break;
- case self::FETCH_ENVELOPE:
+ case Horde_Imap_Client::FETCH_ENVELOPE:
$fetch[] = 'ENVELOPE';
break;
- case self::FETCH_FLAGS:
+ case Horde_Imap_Client::FETCH_FLAGS:
$fetch[] = 'FLAGS';
break;
- case self::FETCH_DATE:
+ case Horde_Imap_Client::FETCH_DATE:
$fetch[] = 'INTERNALDATE';
break;
- case self::FETCH_SIZE:
+ case Horde_Imap_Client::FETCH_SIZE:
$fetch[] = 'RFC822.SIZE';
break;
- case self::FETCH_UID:
+ case Horde_Imap_Client::FETCH_UID:
$fetch[] = 'UID';
break;
- case self::FETCH_SEQ:
+ case Horde_Imap_Client::FETCH_SEQ:
// Nothing we need to add to fetch criteria.
break;
- case self::FETCH_MODSEQ:
+ case Horde_Imap_Client::FETCH_MODSEQ:
/* RFC 4551 [3.1] - trying to do a FETCH of MODSEQ on a
* mailbox that doesn't support it will return BAD. Catch that
* here and throw an exception. */
$seq = empty($options['ids'])
? '1:*'
- : ((reset($options['ids']) === self::USE_SEARCHRES)
+ : ((reset($options['ids']) === Horde_Imap_Client::USE_SEARCHRES)
? '$'
- : $this->toSequenceString($options['ids']));
+ : $this->_utils->toSequenceString($options['ids']));
$use_seq = !empty($options['sequence']);
$cmd = ($use_seq ? '' : 'UID ') . 'FETCH ' . $seq . ' (' . implode(' ', $fetch) . ')';
{
$seq = empty($options['ids'])
? '1:*'
- : ((reset($options['ids']) === self::USE_SEARCHRES)
+ : ((reset($options['ids']) === Horde_Imap_Client::USE_SEARCHRES)
? '$'
- : $this->toSequenceString($options['ids']));
+ : $this->_utils->toSequenceString($options['ids']));
$cmd_prefix = (empty($options['sequence']) ? 'UID ' : '') .
'STORE ' . $seq . ' ';
$seq = empty($options['ids'])
? '1:*'
- : ((reset($options['ids']) === self::USE_SEARCHRES)
+ : ((reset($options['ids']) === Horde_Imap_Client::USE_SEARCHRES)
? '$'
- : $this->toSequenceString($options['ids']));
+ : $this->_utils->toSequenceString($options['ids']));
// COPY returns no untagged information (RFC 3501 [6.4.7])
try {
- $this->_sendLine((empty($options['sequence']) ? 'UID ' : '') . 'COPY ' . $seq . ' ' . $this->escape($dest));
+ $this->_sendLine((empty($options['sequence']) ? 'UID ' : '') . 'COPY ' . $seq . ' ' . $this->_utils->escape($dest));
} catch (Horde_Imap_Client_Exception $e) {
if (!empty($options['create']) && $this->_temp['trycreate']) {
$this->createMailbox($dest);
$limits[] = 'STORAGE ' . $options['storage'];
}
- $this->_sendLine('SETQUOTA ' . $this->escape($root) . ' (' . implode(' ', $limits) . ')');
+ $this->_sendLine('SETQUOTA ' . $this->_utils->escape($root) . ' (' . implode(' ', $limits) . ')');
}
/**
$this->login();
$this->_temp['quotaresp'] = array();
- $this->_sendLine('GETQUOTA ' . $this->escape($root));
+ $this->_sendLine('GETQUOTA ' . $this->_utils->escape($root));
return reset($this->_temp['quotaresp']);
}
$this->login();
$this->_temp['quotaresp'] = array();
- $this->_sendLine('GETQUOTAROOT ' . $this->escape($mailbox));
+ $this->_sendLine('GETQUOTAROOT ' . $this->_utils->escape($mailbox));
return $this->_temp['quotaresp'];
}
// SETACL/DELETEACL returns no untagged information (RFC 4314 [3.1 &
// 3.2]).
if (empty($options['rights']) && !empty($options['remove'])) {
- $this->_sendLine('DELETEACL ' . $this->escape($mailbox) . ' ' . $identifier);
+ $this->_sendLine('DELETEACL ' . $this->_utils->escape($mailbox) . ' ' . $identifier);
} else {
- $this->_sendLine('SETACL ' . $this->escape($mailbox) . ' ' . $identifier . ' ' . $options['rights']);
+ $this->_sendLine('SETACL ' . $this->_utils->escape($mailbox) . ' ' . $identifier . ' ' . $options['rights']);
}
}
$this->login();
$this->_temp['getacl'] = array();
- $this->_sendLine('GETACL ' . $this->escape($mailbox));
+ $this->_sendLine('GETACL ' . $this->_utils->escape($mailbox));
return $this->_temp['getacl'];
}
$this->login();
$this->_temp['listaclrights'] = array();
- $this->_sendLine('LISTRIGHTS ' . $this->escape($mailbox) . ' ' . $identifier);
+ $this->_sendLine('LISTRIGHTS ' . $this->_utils->escape($mailbox) . ' ' . $identifier);
return $this->_temp['listaclrights'];
}
$this->login();
$this->_temp['myrights'] = array();
- $this->_sendLine('MYRIGHTS ' . $this->escape($mailbox));
+ $this->_sendLine('MYRIGHTS ' . $this->_utils->escape($mailbox));
return $this->_temp['myrights'];
}
case 'REFERRAL':
// Defined by RFC 2221
- $this->_temp['referral'] = $this->parseImapUrl($data);
+ $this->_temp['referral'] = $this->_utils->parseImapUrl($data);
break;
case 'UNKNOWN-CTE':
$this->_updateCache(array(), array('mailbox' => $this->_temp['uidplusmbox'], 'uidvalid' => $parts[0]));
if ($code == 'APPENDUID') {
- $this->_temp['appenduid'] = array_merge($this->_temp['appenduid'], $this->fromSequenceString($parts[1]));
+ $this->_temp['appenduid'] = array_merge($this->_temp['appenduid'], $this->_utils->fromSequenceString($parts[1]));
} else {
- $this->_temp['copyuid'] = array_combine($this->fromSequenceString($parts[1]), $this->fromSequenceString($parts[2]));
+ $this->_temp['copyuid'] = array_combine($this->_utils->fromSequenceString($parts[1]), $this->_utils->fromSequenceString($parts[2]));
}
break;
case 'MODIFIED':
// Defined by RFC 4551 [3.2]
- $this->_temp['modified'] = $this->fromSequenceString($data);
+ $this->_temp['modified'] = $this->_utils->fromSequenceString($data);
break;
case 'CLOSED':
--- /dev/null
+<?php
+/**
+ * Horde_Imap_Client_Utils provides utility functions for the Horde IMAP client.
+ *
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * getBaseSubject() code adapted from imap-base-subject.c (Dovecot 1.2)
+ * Original code released under the LGPL v2.1
+ * Copyright (c) 2002-2008 Timo Sirainen <tss@iki.fi>
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@curecanti.org>
+ * @category Horde
+ * @package Horde_Imap_Client
+ */
+class Horde_Imap_Client_Utils
+{
+ /**
+ * Create an IMAP message sequence string from a list of indices.
+ * Format: range_start:range_end,uid,uid2,range2_start:range2_end,...
+ *
+ * @param array $in An array of indices.
+ * @param array $options Additional options:
+ * <pre>
+ * 'nosort' - (boolean) Do not numerically sort the IDs before creating
+ * the range?
+ * DEFAULT: IDs are sorted
+ * </pre>
+ *
+ * @return string The IMAP message sequence string.
+ */
+ public function toSequenceString($ids, $options = array())
+ {
+ if (empty($ids)) {
+ return '';
+ }
+
+ // Make sure IDs are unique
+ $ids = array_keys(array_flip($ids));
+
+ if (empty($options['nosort'])) {
+ sort($ids, SORT_NUMERIC);
+ }
+
+ $first = $last = array_shift($ids);
+ $out = array();
+
+ foreach ($ids as $val) {
+ if ($last + 1 == $val) {
+ $last = $val;
+ } else {
+ $out[] = $first . ($last == $first ? '' : (':' . $last));
+ $first = $last = $val;
+ }
+ }
+ $out[] = $first . ($last == $first ? '' : (':' . $last));
+
+ return implode(',', $out);
+ }
+
+ /**
+ * Parse an IMAP message sequence string into a list of indices.
+ * Format: range_start:range_end,uid,uid2,range2_start:range2_end,...
+ *
+ * @param string $str The IMAP message sequence string.
+ *
+ * @return array An array of indices.
+ */
+ public function fromSequenceString($str)
+ {
+ $ids = array();
+ $str = trim($str);
+
+ $idarray = explode(',', $str);
+ if (empty($idarray)) {
+ $idarray = array($str);
+ }
+
+ foreach ($idarray as $val) {
+ $range = array_map('intval', explode(':', $val));
+ if (count($range) == 1) {
+ $ids[] = $val;
+ } else {
+ list($low, $high) = ($range[0] < $range[1]) ? $range : array_reverse($range);
+ $ids = array_merge($ids, range($low, $high));
+ }
+ }
+
+ return $ids;
+ }
+
+ /**
+ * Remove "bare newlines" from a string.
+ *
+ * @param string $str The original string.
+ *
+ * @return string The string with all bare newlines removed.
+ */
+ public function removeBareNewlines($str)
+ {
+ return str_replace(array("\r\n", "\n"), array("\n", "\r\n"), $str);
+ }
+
+ /**
+ * Escape IMAP output via a quoted string (see RFC 3501 [4.3]).
+ *
+ * @param string $str The unescaped string.
+ *
+ * @return string The escaped string.
+ */
+ public function escape($str)
+ {
+ return '"' . addcslashes($str, '"\\') . '"';
+ }
+
+ /**
+ * Return the "base subject" defined in RFC 5256 [2.1].
+ *
+ * @param string $str The original subject string.
+ * @param array $options Additional options:
+ * <pre>
+ * 'keepblob' - (boolean) Don't remove any "blob" information (i.e. text
+ * leading text between square brackets) from string.
+ * </pre>
+ *
+ * @return string The cleaned up subject string.
+ */
+ public function getBaseSubject($str, $options = array())
+ {
+ // Rule 1a: MIME decode to UTF-8 (if possible).
+ $str = Horde_Mime::decode($str, 'UTF-8');
+
+ // Rule 1b: Remove superfluous whitespace.
+ $str = preg_replace("/\s{2,}/", '', $str);
+
+ if (!$str) {
+ return '';
+ }
+
+ do {
+ /* (2) Remove all trailing text of the subject that matches the
+ * the subj-trailer ABNF, repeat until no more matches are
+ * possible. */
+ $str = preg_replace("/(?:\s*\(fwd\)\s*)+$/i", '', $str);
+
+ do {
+ /* (3) Remove all prefix text of the subject that matches the
+ * subj-leader ABNF. */
+ $found = $this->_removeSubjLeader($str, !empty($options['keepblob']));
+
+ /* (4) If there is prefix text of the subject that matches
+ * the subj-blob ABNF, and removing that prefix leaves a
+ * non-empty subj-base, then remove the prefix text. */
+ $found = (empty($options['keepblob']) && $this->_removeBlobWhenNonempty($str)) || $found;
+
+ /* (5) Repeat (3) and (4) until no matches remain. */
+ } while ($found);
+
+ /* (6) If the resulting text begins with the subj-fwd-hdr ABNF and
+ * ends with the subj-fwd-trl ABNF, remove the subj-fwd-hdr and
+ * subj-fwd-trl and repeat from step (2). */
+ } while ($this->_removeSubjFwdHdr($str));
+
+ return $str;
+ }
+
+ /**
+ * Parse an IMAP URL (RFC 5092).
+ *
+ * @param string $url A IMAP URL string.
+ *
+ * @return mixed False if the URL is invalid. If valid, a URL with the
+ * following fields:
+ * <pre>
+ * 'auth' - (string) The authentication method to use.
+ * 'port' - (integer) The remote port
+ * 'hostspec' - (string) The remote server
+ * 'username' - (string) The username to use on the remote server.
+ * </pre>
+ */
+ public function parseImapUrl($url)
+ {
+ $url = trim($url);
+ if (stripos($url, 'imap://') !== 0) {
+ return false;
+ }
+ $url = substr($url, 7);
+
+ /* At present, only support imap://<iserver>[/] style URLs. */
+ if (($pos = strpos($url, '/')) !== false) {
+ $url = substr($url, 0, $pos);
+ }
+
+ $ret_array = array();
+
+ /* Check for username/auth information. */
+ if (($pos = strpos($url, '@')) !== false) {
+ if ((($apos = stripos($url, ';AUTH=')) !== false) &&
+ ($apos < $pos)) {
+ $auth = substr($url, $apos + 6, $pos - $apos - 6);
+ if ($auth != '*') {
+ $ret_array['auth'] = $auth;
+ }
+ if ($apos) {
+ $ret_array['username'] = substr($url, 0, $apos);
+ }
+ }
+ $url = substr($url, $pos + 1);
+ }
+
+ /* Check for port information. */
+ if (($pos = strpos($url, ':')) !== false) {
+ $ret_array['port'] = substr($url, $pos + 1);
+ $url = substr($url, 0, $pos);
+ }
+
+ $ret_array['hostspec'] = $url;
+
+ return $ret_array;
+ }
+
+ /**
+ * Remove all prefix text of the subject that matches the subj-leader
+ * ABNF.
+ *
+ * @param string &$str The subject string.
+ * @param boolean $keepblob Remove blob information?
+ *
+ * @return boolean True if string was altered.
+ */
+ protected function _removeSubjLeader(&$str, $keepblob = false)
+ {
+ $ret = false;
+
+ if (!$str) {
+ return $ret;
+ }
+
+ if ($str[0] == ' ') {
+ $str = substr($str, 1);
+ $ret = true;
+ }
+
+ $i = 0;
+
+ if (!$keepblob) {
+ while ($str[$i] == '[') {
+ if (($i = $this->_removeBlob($str, $i)) === false) {
+ return $ret;
+ }
+ }
+ }
+
+ $cmp_str = substr($str, $i);
+ if (stripos($cmp_str, 're') === 0) {
+ $i += 2;
+ } elseif (stripos($cmp_str, 'fwd') === 0) {
+ $i += 3;
+ } elseif (stripos($cmp_str, 'fw') === 0) {
+ $i += 2;
+ } else {
+ return $ret;
+ }
+
+ if ($str[$i] == ' ') {
+ ++$i;
+ }
+
+ if (!$keepblob) {
+ while ($str[$i] == '[') {
+ if (($i = $this->_removeBlob($str, $i)) === false) {
+ return $ret;
+ }
+ }
+ }
+
+ if ($str[$i] != ':') {
+ return $ret;
+ }
+
+ $str = substr($str, ++$i);
+
+ return true;
+ }
+
+ /**
+ * Remove "[...]" text.
+ *
+ * @param string &$str The subject string.
+ *
+ * @return boolean True if string was altered.
+ */
+ protected function _removeBlob($str, $i)
+ {
+ if ($str[$i] != '[') {
+ return false;
+ }
+
+ ++$i;
+
+ for ($cnt = strlen($str); $i < $cnt; ++$i) {
+ if ($str[$i] == ']') {
+ break;
+ }
+
+ if ($str[$i] == '[') {
+ return false;
+ }
+ }
+
+ if ($i == ($cnt - 1)) {
+ return false;
+ }
+
+ ++$i;
+
+ if ($str[$i] == ' ') {
+ ++$i;
+ }
+
+ return $i;
+ }
+
+ /**
+ * Remove "[...]" text if it doesn't result in the subject becoming
+ * empty.
+ *
+ * @param string &$str The subject string.
+ *
+ * @return boolean True if string was altered.
+ */
+ protected function _removeBlobWhenNonempty(&$str)
+ {
+ if ($str &&
+ ($str[0] == '[') &&
+ (($i = $this->_removeBlob($str, 0)) !== false) &&
+ ($i != strlen($str))) {
+ $str = substr($str, $i);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove a "[fwd: ... ]" string.
+ *
+ * @param string &$str The subject string.
+ *
+ * @return boolean True if string was altered.
+ */
+ protected function _removeSubjFwdHdr(&$str)
+ {
+ if ((stripos($str, '[fwd:') !== 0) || (substr($str, -1) != ']')) {
+ return false;
+ }
+
+ $str = substr($str, 5, -1);
+ return true;
+ }
+
+}
<file name="Sort.php" role="php" />
<file name="Thread.php" role="php" />
<file name="Utf7imap.php" role="php" />
+ <file name="Utils.php" role="php" />
</dir> <!-- /lib/Horde/Imap/Client -->
<file name="Client.php" role="php" />
</dir> <!-- /lib/Horde/Imap -->
<install name="lib/Horde/Imap/Client/Sort.php" as="Horde/Imap/Client/Sort.php" />
<install name="lib/Horde/Imap/Client/Thread.php" as="Horde/Imap/Client/Thread.php" />
<install name="lib/Horde/Imap/Client/Utf7imap.php" as="Horde/Imap/Client/Utf7imap.php" />
+ <install name="lib/Horde/Imap/Client/Utils.php" as="Horde/Imap/Client/Utils.php" />
<install name="lib/Horde/Imap/Client.php" as="Horde/Imap/Client.php" />
</filelist>
</phprelease>
}
if (!empty($argv[3])) {
- $params = array_merge($params, Horde_Imap_Client::parseImapUrl($argv[3]));
+ $params = array_merge($params, $imap_utils->parseImapUrl($argv[3]));
}
function exception_handler($exception) {
// Add an ID field to send to server (ID extension)
$params['id'] = array('name' => 'Horde_Imap_Client test program');
+$imap_utils = new Horde_Imap_Client_Utils();
$imap_client = Horde_Imap_Client::getInstance($driver, $params);
if ($driver == 'Cclient_Pop3') {
$test_mbox = $test_mbox_utf8 = 'INBOX';
print "\nSort 1st 5 messages in " . $test_mbox . " by thread - references algorithm (UIDs).\n";
try {
$ten_query = new Horde_Imap_Client_Search_Query();
- $ten_query->sequence(Horde_Imap_Client::fromSequenceString('1:5'), true);
+ $ten_query->sequence($imap_utils->fromSequenceString('1:5'), true);
print_r($imap_client->thread($test_mbox, array('search' => $ten_query, 'criteria' => Horde_Imap_Client::THREAD_REFERENCES)));
print "Thread search: OK\n";
} catch (Horde_Imap_Client_Exception $e) {
print "\nBase subject parsing:\n";
foreach ($subject_lines as $val) {
print " ORIGINAL: \"" . $val . "\"\n";
- print " BASE: \"" . Horde_Imap_Client::getBaseSubject($val) . "\"\n\n";
+ print " BASE: \"" . $imap_utils->getBaseSubject($val) . "\"\n\n";
}
$imap_urls = array(
foreach ($imap_urls as $val) {
print "URL: " . $val . "\n";
print "PARSED:\n";
- print_r(Horde_Imap_Client::parseImapUrl($val));
+ print_r($imap_utils->parseImapUrl($val));
print "\n";
}