MDL-80207 core: Remove Horde library

This commit is contained in:
Huong Nguyen 2024-01-19 09:32:26 +07:00
parent a63d39b0ad
commit 6bddb8626f
No known key found for this signature in database
GPG Key ID: 40D88AB693A3E72A
429 changed files with 2 additions and 57824 deletions

View File

@ -88,7 +88,6 @@ class core_component {
protected static $filestomap = ['lib.php', 'settings.php'];
/** @var array associative array of PSR-0 namespaces and corresponding paths. */
protected static $psr0namespaces = [
'Horde' => 'lib/horde/framework/Horde',
'Mustache' => 'lib/mustache/src/Mustache',
'CFPropertyList' => 'lib/plist/classes/CFPropertyList',
];

View File

@ -1,147 +0,0 @@
<?php
/**
* The Horde_Array:: class provides various methods for array manipulation.
*
* Copyright 2003-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Michael Slusarz <slusarz@horde.org>
* @author Marko Djukic <marko@oblo.com>
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Util
*/
class Horde_Array
{
/**
* Sorts an array on a specified key. If the key does not exist,
* defaults to the first key of the array.
*
* @param array &$array The array to be sorted, passed by reference.
* @param string $key The key by which to sort. If not specified then
* the first key is used.
* @param integer $dir Sort direction:
* 0 = ascending (default)
* 1 = descending
* @param boolean $assoc Keep key value association?
*/
public static function arraySort(array &$array, $key = null, $dir = 0,
$assoc = true)
{
/* Return if the array is empty. */
if (empty($array)) {
return;
}
/* If no key to sort by is specified, use the first key of the
* first element. */
if (is_null($key)) {
$keys = array_keys(reset($array));
$key = array_shift($keys);
}
/* Call the appropriate sort function. */
$helper = new Horde_Array_Sort_Helper();
$helper->key = $key;
$function = $dir ? 'reverseCompare' : 'compare';
if ($assoc) {
uasort($array, array($helper, $function));
} else {
usort($array, array($helper, $function));
}
}
/**
* Given an HTML type array field "example[key1][key2][key3]" breaks up
* the keys so that they could be used to reference a regular PHP array.
*
* @param string $field The field name to be examined.
* @param string &$base Will be set to the base element.
* @param array &$keys Will be set to the list of keys.
*
* @return boolean True on sucess, false on error.
*/
public static function getArrayParts($field, &$base, &$keys)
{
if (!preg_match('|([^\[]*)((\[[^\[\]]*\])+)|', $field, $matches)) {
return false;
}
$base = $matches[1];
$keys = explode('][', $matches[2]);
$keys[0] = substr($keys[0], 1);
$keys[count($keys) - 1] = substr($keys[count($keys) - 1], 0, strlen($keys[count($keys) - 1]) - 1);
return true;
}
/**
* Using an array of keys iterate through the array following the
* keys to find the final key value. If a value is passed then set
* that value.
*
* @param array &$array The array to be used.
* @param array &$keys The key path to follow as an array.
* @param array $value If set the target element will have this value set
* to it.
*
* @return mixed The final value of the key path.
*/
public static function getElement(&$array, array &$keys, $value = null)
{
if (count($keys)) {
$key = array_shift($keys);
return isset($array[$key])
? self::getElement($array[$key], $keys, $value)
: false;
}
if (!is_null($value)) {
$array = $value;
}
return $array;
}
/**
* Returns a rectangle of a two-dimensional array.
*
* @param array $array The array to extract the rectangle from.
* @param integer $row The start row of the rectangle.
* @param integer $col The start column of the rectangle.
* @param integer $height The height of the rectangle.
* @param integer $width The width of the rectangle.
*
* @return array The extracted rectangle.
*/
public static function getRectangle(array $array, $row, $col, $height,
$width)
{
$rec = array();
for ($y = $row; $y < $row + $height; $y++) {
$rec[] = array_slice($array[$y], $col, $width);
}
return $rec;
}
/**
* Given an array, returns an associative array with each element key
* derived from its value.
* For example:
* array(0 => 'foo', 1 => 'bar')
* would become:
* array('foo' => 'foo', 'bar' => 'bar')
*
* @param array $array An array of values.
*
* @return array An array with keys the same as values.
*/
public static function valuesToKeys(array $array)
{
return $array
? array_combine($array, $array)
: array();
}
}

View File

@ -1,77 +0,0 @@
<?php
/**
* Helper class for sorting arrays on arbitrary criteria for usort/uasort.
*
* Copyright 2003-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Marko Djukic <marko@oblo.com>
* @author Jan Schneider <jan@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Util
*/
class Horde_Array_Sort_Helper
{
/**
* The array key to sort by.
*
* @var string
*/
public $key;
/**
* Compare two associative arrays by the array key defined in self::$key.
*
* @param array $a
* @param array $b
*/
public function compare($a, $b)
{
return strcoll(Horde_String::lower($a[$this->key], true, 'UTF-8'), Horde_String::lower($b[$this->key], true, 'UTF-8'));
}
/**
* Compare, in reverse order, two associative arrays by the array key
* defined in self::$key.
*
* @param scalar $a TODO
* @param scalar $b TODO
*
* @return TODO
*/
public function reverseCompare($a, $b)
{
return strcoll(Horde_String::lower($b[$this->key], true, 'UTF-8'), Horde_String::lower($a[$this->key], true, 'UTF-8'));
}
/**
* Compare array keys case insensitively for uksort.
*
* @param scalar $a TODO
* @param scalar $b TODO
*
* @return TODO
*/
public function compareKeys($a, $b)
{
return strcoll(Horde_String::lower($a, true, 'UTF-8'), Horde_String::lower($b, true, 'UTF-8'));
}
/**
* Compare, in reverse order, array keys case insensitively for uksort.
*
* @param scalar $a TODO
* @param scalar $b TODO
*
* @return TODO
*/
public function reverseCompareKeys($a, $b)
{
return strcoll(Horde_String::lower($b, true, 'UTF-8'), Horde_String::lower($a, true, 'UTF-8'));
}
}

View File

@ -1,178 +0,0 @@
<?php
/**
* Copyright 2005-2008 Matthew Fonda <mfonda@php.net>
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Provides blowfish encryption/decryption, with or without a secret key,
* for PHP strings.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2008 Matthew Fonda
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*
* @property string $cipher The cipher block mode ('ecb' or 'cbc').
* @property string $key The encryption key in use.
* @property mixed $iv The initialization vector (false if using 'ecb').
*/
class Horde_Crypt_Blowfish
{
// Constants for 'ignore' parameter of constructor.
const IGNORE_OPENSSL = 1;
const IGNORE_MCRYPT = 2;
// Block size for Blowfish
const BLOCKSIZE = 8;
// Maximum key size for Blowfish
const MAXKEYSIZE = 56;
// IV Length for CBC
const IV_LENGTH = 8;
/**
* Blowfish crypt driver.
*
* @var Horde_Crypt_Blowfish_Base
*/
protected $_crypt;
/**
* Constructor.
*
* @param string $key Encryption key.
* @param array $opts Additional options:
* - cipher: (string) Either 'ecb' or 'cbc'.
* - ignore: (integer) A mask of drivers to ignore (IGNORE_* constants).
* - iv: (string) IV to use.
*/
public function __construct($key, array $opts = array())
{
$opts = array_merge(array(
'cipher' => 'ecb',
'ignore' => 0,
'iv' => null
), $opts);
if (!($opts['ignore'] & self::IGNORE_OPENSSL) &&
Horde_Crypt_Blowfish_Openssl::supported()) {
$this->_crypt = new Horde_Crypt_Blowfish_Openssl($opts['cipher']);
} elseif (!($opts['ignore'] & self::IGNORE_MCRYPT) &&
Horde_Crypt_Blowfish_Mcrypt::supported()) {
$this->_crypt = new Horde_Crypt_Blowfish_Mcrypt($opts['cipher']);
} else {
$this->_crypt = new Horde_Crypt_Blowfish_Php($opts['cipher']);
}
$this->setKey($key, $opts['iv']);
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'cipher':
case 'key':
case 'iv':
return $this->_crypt->$name;
}
}
/**
* Encrypts a string.
*
* @param string $text The string to encrypt.
*
* @return string The ciphertext.
* @throws Horde_Crypt_Blowfish_Exception
*/
public function encrypt($text)
{
if (!is_string($text)) {
throw new Horde_Crypt_Blowfish_Exception('Data to encrypt must be a string.');
}
return $this->_crypt->encrypt($text);
}
/**
* Decrypts a string.
*
* @param string $text The string to decrypt.
*
* @return string The plaintext.
* @throws Horde_Crypt_Blowfish_Exception
*/
public function decrypt($text)
{
if (!is_string($text)) {
throw new Horde_Crypt_Blowfish_Exception('Data to decrypt must be a string.');
}
return $this->_crypt->decrypt($text);
}
/**
* Sets the secret key.
*
* The key must be non-zero, and less than or equal to MAXKEYSIZE
* characters (bytes) in length.
*
* @param string $key Key must be non-empty and less than MAXKEYSIZE
* bytes in length.
* @param string $iv The initialization vector to use. Only needed for
* 'cbc' cipher. If null, an IV is automatically
* generated.
*
* @throws Horde_Crypt_Blowfish_Exception
*/
public function setKey($key, $iv = null)
{
if (!is_string($key)) {
throw new Horde_Crypt_Blowfish_Exception('Encryption key must be a string.');
}
$len = strlen($key);
if (($len > self::MAXKEYSIZE) || ($len == 0)) {
throw new Horde_Crypt_Blowfish_Exception(sprintf('Encryption key must be less than %d characters (bytes) and non-zero. Supplied key length: %d', self::MAXKEYSIZE, $len));
}
$this->_crypt->key = $key;
switch ($this->_crypt->cipher) {
case 'cbc':
if (is_null($iv)) {
if (is_null($this->iv)) {
$this->_crypt->setIv();
}
} else {
$iv = substr($iv, 0, self::IV_LENGTH);
if (($len = strlen($iv)) < self::IV_LENGTH) {
$iv .= str_repeat(chr(0), self::IV_LENGTH - $len);
}
$this->_crypt->setIv($iv);
}
break;
case 'ecb':
$this->iv = false;
break;
}
}
}

View File

@ -1,128 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Abstract base driver class for blowfish encryption.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
abstract class Horde_Crypt_Blowfish_Base
{
/**
* Cipher method.
*
* @var string
*/
public $cipher;
/**
* Initialization vector.
*
* @var string
*/
public $iv = null;
/**
* Encryption key.
*
* @var string
*/
public $key;
/**
* Is this driver supported on this system?
*
* @return boolean True if supported.
*/
public static function supported()
{
return true;
}
/**
* Constructor.
*
* @param string $cipher Either 'ecb' or 'cbc'.
*/
public function __construct($cipher)
{
$this->cipher = $cipher;
}
/**
* Encrypts a string.
*
* @param string $text The string to encrypt.
*
* @return string The ciphertext.
* @throws Horde_Crypt_Blowfish_Exception
*/
abstract public function encrypt($text);
/**
* Decrypts a string.
*
* @param string $text The string to encrypt.
*
* @return string The ciphertext.
* @throws Horde_Crypt_Blowfish_Exception
*/
abstract public function decrypt($text);
/**
* Sets the initialization vector (required for CBC mode).
*
* @param string $iv Initialization vector.
*/
public function setIv($iv = null)
{
$this->iv = is_null($iv)
? substr(new Horde_Support_Randomid(), 0, 8)
: $iv;
}
/**
* Pad text to match blocksize length.
*
* @param string $text Unpadded text.
* @param boolean $ignore Don't pad if already at blocksize length.
*
* @return string Padded text.
*/
protected function _pad($text, $ignore = false)
{
$blocksize = Horde_Crypt_Blowfish::BLOCKSIZE;
$padding = $blocksize - (strlen($text) % $blocksize);
return ($ignore && ($padding == $blocksize))
? $text
: $text . str_repeat(chr($padding), $padding);
}
/**
* Unpad text from blocksize boundary.
*
* @param string $text Padded text.
*
* @return string Unpadded text.
*/
protected function _unpad($text)
{
return substr($text, 0, ord(substr($text, -1)) * -1);
}
}

View File

@ -1,25 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Exception object for the Horde_Crypt_Blowfish package.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
class Horde_Crypt_Blowfish_Exception extends Horde_Exception_Wrapped
{
}

View File

@ -1,87 +0,0 @@
<?php
/**
* Copyright 2005-2008 Matthew Fonda <mfonda@php.net>
* Copyright 2008 Philippe Jausions <jausions@php.net>
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Mcrypt driver for blowfish encryption.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2008 Matthew Fonda
* @copyright 2008 Philippe Jausions
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
class Horde_Crypt_Blowfish_Mcrypt extends Horde_Crypt_Blowfish_Base
{
/**
* Mcrypt resource.
*
* @var resource
*/
private $_mcrypt;
/**
*/
public static function supported()
{
return PHP_VERSION_ID < 70100 && extension_loaded('mcrypt');
}
/**
*/
public function __construct($cipher)
{
parent::__construct($cipher);
$this->_mcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $cipher, '');
}
/**
*/
public function encrypt($text)
{
mcrypt_generic_init($this->_mcrypt, $this->key, empty($this->iv) ? str_repeat('0', Horde_Crypt_Blowfish::IV_LENGTH) : $this->iv);
$out = mcrypt_generic($this->_mcrypt, $this->_pad($text));
mcrypt_generic_deinit($this->_mcrypt);
return $out;
}
/**
*/
public function decrypt($text)
{
mcrypt_generic_init($this->_mcrypt, $this->key, empty($this->iv) ? str_repeat('0', Horde_Crypt_Blowfish::IV_LENGTH) : $this->iv);
$out = mdecrypt_generic($this->_mcrypt, $this->_pad($text, true));
mcrypt_generic_deinit($this->_mcrypt);
return $this->_unpad($out);
}
/**
*/
public function setIv($iv = null)
{
$this->iv = is_null($iv)
? mcrypt_create_iv(Horde_Crypt_Blowfish::IV_LENGTH, MCRYPT_RAND)
: $iv;
}
}

View File

@ -1,61 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Openssl driver for blowfish encryption.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
class Horde_Crypt_Blowfish_Openssl extends Horde_Crypt_Blowfish_Base
{
/**
*/
public static function supported()
{
if (extension_loaded('openssl')) {
$ciphers = openssl_get_cipher_methods();
return in_array('bf-ecb', $ciphers) && in_array('bf-cbc', $ciphers);
}
return false;
}
/**
*/
public function encrypt($text)
{
if (PHP_VERSION_ID <= 50302) {
return @openssl_encrypt($text, 'bf-' . $this->cipher, $this->key, true);
} elseif (PHP_VERSION_ID == 50303) {
// Need to mask error output, since an invalid warning message was
// issued prior to 5.3.4 for empty IVs in ECB mode.
return @openssl_encrypt($text, 'bf-' . $this->cipher, $this->key, true, strval($this->iv));
}
return openssl_encrypt($text, 'bf-' . $this->cipher, $this->key, true, strval($this->iv));
}
/**
*/
public function decrypt($text)
{
return (PHP_VERSION_ID <= 50302)
? openssl_decrypt($text, 'bf-' . $this->cipher, $this->key, true)
: openssl_decrypt($text, 'bf-' . $this->cipher, $this->key, true, strval($this->iv));
}
}

View File

@ -1,128 +0,0 @@
<?php
/**
* Copyright 2015-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* PBKDF2 (Password-Based Key Derivation Function 2) implementation (RFC
* 2898; PKCS #5 v2.0).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2015-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
* @link https://defuse.ca/php-pbkdf2.htm pbkdf2 code released to the
* public domain.
*/
class Horde_Crypt_Blowfish_Pbkdf2
{
/**
* Hash algorithm used to create key.
*
* @var string
*/
public $hashAlgo;
/**
* Number of iterations to use.
*
* @var integer
*/
public $iterations;
/**
* Salt.
*
* @var string
*/
public $salt;
/**
* The derived key.
*
* @var string
*/
protected $_key;
/**
* Constructor.
*
* @param string $pass The password.
* @param string $key_length Length of the derived key (in bytes).
* @param array $opts Additional options:
* - algo: (string) Hash algorithm.
* - i_count: (integer) Iteration count.
* - salt: (string) The salt to use.
*/
public function __construct($pass, $key_length, array $opts = array())
{
$this->iterations = isset($opts['i_count'])
? $opts['i_count']
: 16384;
if (($key_length <= 0) || ($this->iterations <= 0)) {
throw new InvalidArgumentException('Invalid arguments');
}
$this->hashAlgo = isset($opts['algo'])
? $opts['algo']
: 'SHA256';
/* Nice to have, but salt does not need to be cryptographically
* secure random value. */
$this->salt = isset($opts['salt'])
? $opts['salt']
: (function_exists('openssl_random_pseudo_bytes')
? openssl_random_pseudo_bytes($key_length)
: substr(hash('sha512', new Horde_Support_Randomid(), true), 0, $key_length));
if (function_exists('hash_pbkdf2')) {
$this->_key = hash_pbkdf2(
$this->hashAlgo,
$pass,
$this->salt,
$this->iterations,
$key_length,
true
);
return;
}
$hash_length = strlen(hash($this->hashAlgo, '', true));
$block_count = ceil($key_length / $hash_length);
$hash = '';
for ($i = 1; $i <= $block_count; ++$i) {
// $i encoded as 4 bytes, big endian.
$last = $this->salt . pack('N', $i);
for ($j = 0; $j < $this->iterations; $j++) {
$last = hash_hmac($this->hashAlgo, $last, $pass, true);
if ($j) {
$xorsum ^= $last;
} else {
$xorsum = $last;
}
}
$hash .= $xorsum;
}
$this->_key = substr($hash, 0, $key_length);
}
/**
*/
public function __toString()
{
return $this->_key;
}
}

View File

@ -1,75 +0,0 @@
<?php
/**
* Copyright 2005-2008 Matthew Fonda <mfonda@php.net>
* Copyright 2008 Philippe Jausions <jausions@php.net>
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Native PHP driver for blowfish encryption.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2008 Matthew Fonda
* @copyright 2008 Philippe Jausions
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
class Horde_Crypt_Blowfish_Php extends Horde_Crypt_Blowfish_Base
{
/**
* Subclass object.
*
* @var Horde_Crypt_Blowfish_Php_Base
*/
protected $_ob;
/**
*/
public function encrypt($text)
{
$this->_init();
return $this->_ob->encrypt($this->_pad($text), $this->iv);
}
/**
*/
public function decrypt($text)
{
$this->_init();
return $this->_unpad($this->_ob->decrypt($this->_pad($text, true), $this->iv));
}
/**
* Initialize the subclass.
*/
protected function _init()
{
if (!isset($this->_ob) ||
($this->_ob->md5 != hash('md5', $this->key))) {
switch ($this->cipher) {
case 'cbc':
$this->_ob = new Horde_Crypt_Blowfish_Php_Cbc($this->key);
break;
case 'ecb':
$this->_ob = new Horde_Crypt_Blowfish_Php_Ecb($this->key);
break;
}
}
}
}

View File

@ -1,459 +0,0 @@
<?php
/**
* Copyright 2005-2008 Matthew Fonda <mfonda@php.net>
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* Base subclass for the PHP driver.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2008 Matthew Fonda
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
abstract class Horde_Crypt_Blowfish_Php_Base
{
/**
* MD5 sum of the key used.
*
* @var string
*/
public $md5;
/**
* P-Array contains 18 32-bit subkeys.
*
* @var array
*/
protected $_P = array(
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
0x9216D5D9, 0x8979FB1B
);
/**
* Array of four S-Blocks each containing 256 32-bit entries.
*
* @var array
*/
protected $_S = array(
array(
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
), array(
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
), array(
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
), array(
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
)
);
/**
* Constructor.
*
* @param string $key Encrpytion key.
*/
public function __construct($key)
{
$data = $datal = $datar = $k = 0;
$len = strlen($key);
for ($i = 0; $i < 18; ++$i) {
$data = 0;
for ($j = 4; $j > 0; --$j) {
$data = $data << 8 | ord($key[$k]);
$k = ($k + 1) % $len;
}
$this->_P[$i] ^= $data;
}
for ($i = 0; $i <= 16; $i += 2) {
$this->_encipher($datal, $datar);
$this->_P[$i] = $datal;
$this->_P[$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[0][$i] = $datal;
$this->_S[0][$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[1][$i] = $datal;
$this->_S[1][$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[2][$i] = $datal;
$this->_S[2][$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[3][$i] = $datal;
$this->_S[3][$i+1] = $datar;
}
$this->md5 = hash('md5', $key);
}
/**
*/
abstract public function encrypt($text, $iv);
/**
*/
abstract public function decrypt($text, $iv);
/**
* Workaround for XOR on certain systems.
*
* @param integer|float $l
* @param integer|float $r
*
* @return float
*/
protected function _binxor($l, $r)
{
$x = (($l < 0) ? (float)($l + 4294967296) : (float)$l)
^ (($r < 0) ? (float)($r + 4294967296) : (float)$r);
return (float)(($x < 0) ? $x + 4294967296 : $x);
}
/**
* Enciphers a single 64-bit block.
*
* @param int &$Xl
* @param int &$Xr
*/
protected function _encipher(&$Xl, &$Xr)
{
if ($Xl < 0) {
$Xl += 4294967296;
}
if ($Xr < 0) {
$Xr += 4294967296;
}
for ($i = 0; $i < 16; ++$i) {
$temp = $Xl ^ $this->_P[$i];
if ($temp < 0) {
$temp += 4294967296;
}
$Xl = fmod((fmod($this->_S[0][($temp >> 24) & 255]
+ $this->_S[1][($temp >> 16) & 255], 4294967296)
^ $this->_S[2][($temp >> 8) & 255])
+ $this->_S[3][$temp & 255], 4294967296) ^ $Xr;
$Xr = $temp;
}
$Xr = $this->_binxor($Xl, $this->_P[16]);
$Xl = $this->_binxor($temp, $this->_P[17]);
}
/**
* Deciphers a single 64-bit block.
*
* @param int &$Xl
* @param int &$Xr
*/
protected function _decipher(&$Xl, &$Xr)
{
if ($Xl < 0) {
$Xl += 4294967296;
}
if ($Xr < 0) {
$Xr += 4294967296;
}
for ($i = 17; $i > 1; --$i) {
$temp = $Xl ^ $this->_P[$i];
if ($temp < 0) {
$temp += 4294967296;
}
$Xl = fmod((fmod($this->_S[0][($temp >> 24) & 255]
+ $this->_S[1][($temp >> 16) & 255], 4294967296)
^ $this->_S[2][($temp >> 8) & 255])
+ $this->_S[3][$temp & 255], 4294967296) ^ $Xr;
$Xr = $temp;
}
$Xr = $this->_binxor($Xl, $this->_P[1]);
$Xl = $this->_binxor($temp, $this->_P[0]);
}
}

View File

@ -1,73 +0,0 @@
<?php
/**
* Copyright 2005-2008 Matthew Fonda <mfonda@php.net>
* Copyright 2008 Philippe Jausions <jausions@php.net>
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* PHP implementation of the Blowfish algorithm in CBC mode.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2008 Matthew Fonda
* @copyright 2008 Philippe Jausions
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
class Horde_Crypt_Blowfish_Php_Cbc extends Horde_Crypt_Blowfish_Php_Base
{
/**
*/
public function encrypt($text, $iv)
{
$cipherText = '';
$len = strlen($text);
list(, $Xl, $Xr) = unpack('N2', substr($text, 0, 8) ^ $iv);
$this->_encipher($Xl, $Xr);
$cipherText .= pack('N2', $Xl, $Xr);
for ($i = 8; $i < $len; $i += 8) {
list(, $Xl, $Xr) = unpack('N2', substr($text, $i, 8) ^ substr($cipherText, $i - 8, 8));
$this->_encipher($Xl, $Xr);
$cipherText .= pack('N2', $Xl, $Xr);
}
return $cipherText;
}
/**
*/
public function decrypt($text, $iv)
{
$plainText = '';
$len = strlen($text);
list(, $Xl, $Xr) = unpack('N2', substr($text, 0, 8));
$this->_decipher($Xl, $Xr);
$plainText .= (pack('N2', $Xl, $Xr) ^ $iv);
for ($i = 8; $i < $len; $i += 8) {
list(, $Xl, $Xr) = unpack('N2', substr($text, $i, 8));
$this->_decipher($Xl, $Xr);
$plainText .= (pack('N2', $Xl, $Xr) ^ substr($text, $i - 8, 8));
}
return $plainText;
}
}

View File

@ -1,65 +0,0 @@
<?php
/**
* Copyright 2005-2008 Matthew Fonda <mfonda@php.net>
* Copyright 2008 Philippe Jausions <jausions@php.net>
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* PHP implementation of the Blowfish algorithm in ECB mode.
*
* @author Matthew Fonda <mfonda@php.net>
* @author Philippe Jausions <jausions@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2008 Matthew Fonda
* @copyright 2008 Philippe Jausions
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
class Horde_Crypt_Blowfish_Php_Ecb extends Horde_Crypt_Blowfish_Php_Base
{
/**
*/
public function encrypt($text, $iv)
{
$cipherText = '';
$len = strlen($text);
for ($i = 0; $i < $len; $i += 8) {
list(, $Xl, $Xr) = unpack('N2', substr($text, $i, 8));
$this->_encipher($Xl, $Xr);
$cipherText .= pack('N2', $Xl, $Xr);
}
return $cipherText;
}
/**
*/
public function decrypt($text, $iv)
{
$plainText = '';
$len = strlen($text);
for ($i = 0; $i < $len; $i += 8) {
list(, $Xl, $Xr) = unpack('N2', substr($text, $i, 8));
$this->_decipher($Xl, $Xr);
$plainText .= pack('N2', $Xl, $Xr);
}
return $plainText;
}
}

View File

@ -1,341 +0,0 @@
<?php
/**
* Copyright 2010-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2010-2017 Horde LLC
* @package Util
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
*/
/**
* Parse DOM data from HTML strings.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2010-2017 Horde LLC
* @package Util
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
*/
class Horde_Domhtml implements Iterator
{
/**
* DOM object.
*
* @var DOMDocument
*/
public $dom;
/**
* Iterator status.
*
* @var array
*/
protected $_iterator = null;
/**
* Original charset of data.
*
* @var string
*/
protected $_origCharset;
/**
* Encoding tag added to beginning of output.
*
* @var string
*/
protected $_xmlencoding = '';
/**
* Constructor.
*
* @param string $text The text of the HTML document.
* @param string $charset The charset of the HTML document.
*
* @throws Exception
*/
public function __construct($text, $charset = null)
{
if (!extension_loaded('dom')) {
throw new Exception('DOM extension is not available.');
}
// Bug #9616: Make sure we have valid HTML input.
if (!strlen($text)) {
$text = '<html></html>';
}
$old_error = libxml_use_internal_errors(true);
$this->dom = new DOMDocument();
if (is_null($charset)) {
/* If no charset given, charset is whatever libxml tells us the
* encoding should be defaulting to 'iso-8859-1'. */
$this->_loadHTML($text);
$this->_origCharset = $this->dom->encoding
? $this->dom->encoding
: 'iso-8859-1';
} else {
/* Convert/try with UTF-8 first. */
$this->_origCharset = Horde_String::lower($charset);
$this->_xmlencoding = '<?xml encoding="UTF-8"?>';
$this->_loadHTML(
$this->_xmlencoding . Horde_String::convertCharset($text, $charset, 'UTF-8')
);
if ($this->dom->encoding &&
(Horde_String::lower($this->dom->encoding) != 'utf-8')) {
/* Convert charset to what the HTML document says it SHOULD
* be. */
$this->_loadHTML(
Horde_String::convertCharset($text, $charset, $this->dom->encoding)
);
$this->_xmlencoding = '';
}
}
if ($old_error) {
libxml_use_internal_errors(false);
}
/* Sanity checking: make sure we have the documentElement object. */
if (!$this->dom->documentElement) {
$this->dom->appendChild($this->dom->createElement('html'));
}
/* Remove old charset information. */
$xpath = new DOMXPath($this->dom);
$domlist = $xpath->query('/html/head/meta[@http-equiv="content-type"]');
for ($i = $domlist->length; $i > 0; --$i) {
$meta = $domlist->item($i - 1);
$meta->parentNode->removeChild($meta);
}
}
/**
* Returns the HEAD element, or creates one if it doesn't exist.
*
* @return DOMElement HEAD element.
*/
public function getHead()
{
$head = $this->dom->getElementsByTagName('head');
if ($head->length) {
return $head->item(0);
}
$headelt = $this->dom->createElement('head');
$this->dom->documentElement->insertBefore($headelt, $this->dom->documentElement->firstChild);
return $headelt;
}
/**
* Returns the BODY element, or creates one if it doesn't exist.
*
* @since 2.2.0
*
* @return DOMElement BODY element.
*/
public function getBody()
{
$body = $this->dom->getElementsByTagName('body');
if ($body->length) {
return $body->item(0);
}
$bodyelt = $this->dom->createElement('body');
$this->dom->documentElement->appendChild($bodyelt);
return $bodyelt;
}
/**
* Returns the full HTML text in the original charset.
*
* @param array $opts Additional options: (since 2.1.0)
* - charset: (string) Return using this charset. If set but empty, will
* return as currently stored in the DOM object.
* - metacharset: (boolean) If true, will add a META tag containing the
* charset information.
*
* @return string HTML text.
*/
public function returnHtml(array $opts = array())
{
$curr_charset = $this->getCharset();
if (strcasecmp($curr_charset, 'US-ASCII') === 0) {
$curr_charset = 'UTF-8';
}
$charset = array_key_exists('charset', $opts)
? (empty($opts['charset']) ? $curr_charset : $opts['charset'])
: $this->_origCharset;
if (empty($opts['metacharset'])) {
$text = $this->dom->saveHTML();
} else {
/* Add placeholder for META tag. Can't add charset yet because DOM
* extension will alter output if it exists. */
$meta = $this->dom->createElement('meta');
$meta->setAttribute('http-equiv', 'content-type');
$meta->setAttribute('horde_dom_html_charset', '');
$head = $this->getHead();
$head->insertBefore($meta, $head->firstChild);
$text = str_replace(
'horde_dom_html_charset=""',
'content="text/html; charset=' . $charset . '"',
$this->dom->saveHTML()
);
$head->removeChild($meta);
}
if (strcasecmp($curr_charset, $charset) !== 0) {
$text = Horde_String::convertCharset($text, $curr_charset, $charset);
}
if (!$this->_xmlencoding ||
(($pos = strpos($text, $this->_xmlencoding)) === false)) {
return $text;
}
return substr_replace($text, '', $pos, strlen($this->_xmlencoding));
}
/**
* Returns the body text in the original charset.
*
* @return string HTML text.
*/
public function returnBody()
{
$body = $this->getBody();
$text = '';
if ($body->hasChildNodes()) {
foreach ($body->childNodes as $child) {
$text .= $this->dom->saveXML($child);
}
}
return Horde_String::convertCharset($text, 'UTF-8', $this->_origCharset);
}
/**
* Get the charset of the DOM data.
*
* @since 2.1.0
*
* @return string Charset of DOM data.
*/
public function getCharset()
{
return $this->dom->encoding
? $this->dom->encoding
: ($this->_xmlencoding ? 'UTF-8' : $this->_origCharset);
}
/**
* Loads the HTML data.
*
* @param string $html HTML data.
*/
protected function _loadHTML($html)
{
if (version_compare(PHP_VERSION, '5.4', '>=')) {
$mask = defined('LIBXML_PARSEHUGE')
? LIBXML_PARSEHUGE
: 0;
$mask |= defined('LIBXML_COMPACT')
? LIBXML_COMPACT
: 0;
$this->dom->loadHTML($html, $mask);
} else {
$this->dom->loadHTML($html);
}
}
/* Iterator methods. */
/**
*/
#[ReturnTypeWillChange]
public function current()
{
if ($this->_iterator instanceof DOMDocument) {
return $this->_iterator;
}
$curr = end($this->_iterator);
return $curr['list']->item($curr['i']);
}
/**
*/
#[ReturnTypeWillChange]
public function key()
{
return 0;
}
/**
*/
#[ReturnTypeWillChange]
public function next()
{
/* Iterate in the reverse direction through the node list. This allows
* alteration of the original list without breaking things (foreach()
* w/removeChild() may exit iteration after removal is complete. */
if ($this->_iterator instanceof DOMDocument) {
$this->_iterator = array();
$curr = array();
$node = $this->dom;
} elseif (empty($this->_iterator)) {
$this->_iterator = null;
return;
} else {
$curr = &$this->_iterator[count($this->_iterator) - 1];
$node = $curr['list']->item($curr['i']);
}
if (empty($curr['child']) &&
($node instanceof DOMNode) &&
$node->hasChildNodes()) {
$curr['child'] = true;
$this->_iterator[] = array(
'child' => false,
'i' => $node->childNodes->length - 1,
'list' => $node->childNodes
);
} elseif (--$curr['i'] < 0) {
array_pop($this->_iterator);
$this->next();
} else {
$curr['child'] = false;
}
}
/**
*/
#[ReturnTypeWillChange]
public function rewind()
{
$this->_iterator = $this->dom;
}
/**
*/
#[ReturnTypeWillChange]
public function valid()
{
return !is_null($this->_iterator);
}
}

View File

@ -1,73 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
* @package Exception
*/
/**
* Horde base exception class.
*
* @author
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
* @package Exception
*/
class Horde_Exception extends Exception
{
/**
* Error details that should not be part of the main exception message,
* e.g. any additional debugging information.
*
* @var string
*/
public $details;
/**
* Has this exception been logged?
*
* @var boolean
*/
public $logged = false;
/**
* The log level to use. A Horde_Log constant.
*
* @var integer
*/
protected $_logLevel = 0;
/**
* Get the log level.
*
* @return integer The Horde_Log constant for the log level.
*/
public function getLogLevel()
{
return $this->_logLevel;
}
/**
* Sets the log level.
*
* @param mixed $level The log level.
*/
public function setLogLevel($level = 0)
{
if (is_string($level)) {
$level = defined('Horde_Log::' . $level)
? constant('Horde_Log::' . $level)
: 0;
}
$this->_logLevel = $level;
}
}

View File

@ -1,55 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
/**
* Horde exception class that accepts output of error_get_last() as $code and
* mask itself as that error.
*
* @author
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
class Horde_Exception_LastError extends Horde_Exception
{
/**
* Exception constructor
*
* If $lasterror is passed the return value of error_get_last() (or a
* matching format), the exception will be rewritten to have its file and
* line parameters match that of the array, and any message in the array
* will be appended to $message.
*
* @param mixed $message The exception message, a PEAR_Error
* object, or an Exception object.
* @param mixed $code_or_lasterror Either a numeric error code, or
* an array from error_get_last().
*/
public function __construct($message = null, $code_or_lasterror = null)
{
if (is_array($code_or_lasterror)) {
if ($message) {
$message .= $code_or_lasterror['message'];
} else {
$message = $code_or_lasterror['message'];
}
parent::__construct($message, $code_or_lasterror['type']);
$this->file = $code_or_lasterror['file'];
$this->line = $code_or_lasterror['line'];
} else {
parent::__construct($message, $code_or_lasterror ?? 0);
}
}
}

View File

@ -1,41 +0,0 @@
<?php
/**
* Copyright 2010-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
/**
* Exception thrown if an object wasn't found.
*
* @author
* @category Horde
* @copyright 2010-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
class Horde_Exception_NotFound extends Horde_Exception
{
/**
* Constructor.
*
* @see Horde_Exception::__construct()
*
* @param mixed $message The exception message, a PEAR_Error
* object, or an Exception object.
* @param integer $code A numeric error code.
*/
public function __construct($message = null, $code = null)
{
if (is_null($message)) {
$message = Horde_Exception_Translation::t("Not Found");
}
parent::__construct($message, $code);
}
}

View File

@ -1,93 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
/**
* Horde exception class that converts PEAR errors to exceptions.
*
* @author
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
class Horde_Exception_Pear extends Horde_Exception
{
/**
* The class name for generated exceptions.
*
* @var string
*/
protected static $_class = __CLASS__;
/**
* Exception constructor.
*
* @param PEAR_Error $error The PEAR error.
*/
public function __construct(PEAR_Error $error)
{
parent::__construct($error->getMessage(), $error->getCode());
$this->details = $this->_getPearTrace($error);
}
/**
* Return a trace for the PEAR error.
*
* @param PEAR_Error $error The PEAR error.
*
* @return string The backtrace as a string.
*/
private function _getPearTrace(PEAR_Error $error)
{
$pear_error = '';
$backtrace = $error->getBacktrace();
if (!empty($backtrace)) {
$pear_error .= 'PEAR backtrace:' . "\n\n";
foreach ($backtrace as $frame) {
$pear_error .=
(isset($frame['class']) ? $frame['class'] : '')
. (isset($frame['type']) ? $frame['type'] : '')
. (isset($frame['function']) ? $frame['function'] : 'unkown') . ' '
. (isset($frame['file']) ? $frame['file'] : 'unkown') . ':'
. (isset($frame['line']) ? $frame['line'] : 'unkown') . "\n";
}
}
$userinfo = $error->getUserInfo();
if (!empty($userinfo)) {
$pear_error .= "\n" . 'PEAR user info:' . "\n\n";
if (is_string($userinfo)) {
$pear_error .= $userinfo;
} else {
$pear_error .= print_r($userinfo, true);
}
}
return $pear_error;
}
/**
* Exception handling.
*
* @param mixed $result The result to be checked for a PEAR_Error.
*
* @return mixed Returns the original result if it was no PEAR_Error.
*
* @throws Horde_Exception_Pear In case the result was a PEAR_Error.
*/
public static function catchError($result)
{
if ($result instanceof PEAR_Error) {
throw new self::$_class($result);
}
return $result;
}
}

View File

@ -1,41 +0,0 @@
<?php
/**
* Copyright 2010-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
/**
* Exception thrown if any access without sufficient permissions occured.
*
* @author
* @category Horde
* @copyright 2010-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
class Horde_Exception_PermissionDenied extends Horde_Exception
{
/**
* Constructor.
*
* @see Horde_Exception::__construct()
*
* @param string|Exception $message The exception message, a PEAR_Error
* object, or an Exception object.
* @param integer $code A numeric error code.
*/
public function __construct($message = null, $code = null)
{
if (is_null($message)) {
$message = Horde_Exception_Translation::t("Permission Denied");
}
parent::__construct($message, $code);
}
}

View File

@ -1,38 +0,0 @@
<?php
/**
* Copyright 2010-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
/**
* Horde_Exception_Translation is the translation wrapper class for Horde_Exception.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @copyright 2010-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
class Horde_Exception_Translation extends Horde_Translation_Autodetect
{
/**
* The translation domain
*
* @var string
*/
protected static $_domain = 'Horde_Exception';
/**
* The absolute PEAR path to the translations for the default gettext handler.
*
* @var string
*/
protected static $_pearDirectory = '@data_dir@';
}

View File

@ -1,56 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
/**
* Horde exception class that can wrap and set its details from PEAR_Error,
* Exception, and other objects with similar interfaces.
*
* @author
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @package Exception
*/
class Horde_Exception_Wrapped extends Horde_Exception
{
/**
* Exception constructor.
*
* @param mixed $message The exception message, a PEAR_Error
* object, or an Exception object.
* @param int $code A numeric error code.
*/
public function __construct($message = null, $code = 0)
{
$previous = null;
if (is_object($message) &&
method_exists($message, 'getMessage')) {
if (empty($code) &&
method_exists($message, 'getCode')) {
$code = (int)$message->getCode();
}
if ($message instanceof Exception) {
$previous = $message;
}
if (method_exists($message, 'getUserinfo') &&
$details = $message->getUserinfo()) {
$this->details = $details;
} elseif (!empty($message->details)) {
$this->details = $message->details;
}
$message = (string)$message->getMessage();
}
parent::__construct($message, $code, $previous);
}
}

View File

@ -1,178 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (BSD). If you
* did not receive this file, see http://www.horde.org/licenses/bsd.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
/**
* Provide normalized encoding/decoding support for IDNA strings.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
class Horde_Idna
{
/**
* The backend to use.
*
* @var mixed
*/
protected static $_backend;
/**
* @throws Horde_Idna_Exception
*/
public static function encode($data)
{
switch ($backend = static::_getBackend()) {
case 'INTL':
if ($data === null) {
return false;
}
return idn_to_ascii($data);
case 'INTL_UTS46':
if ($data === null) {
return false;
}
$result = idn_to_ascii($data, 0, INTL_IDNA_VARIANT_UTS46, $info);
self::_checkForError($info);
return $result;
default:
return $backend->encode($data);
}
}
/**
* @throws Horde_Idna_Exception
*/
public static function decode($data)
{
switch ($backend = static::_getBackend()) {
case 'INTL':
case 'INTL_UTS46':
$parts = explode('.', $data);
foreach ($parts as &$part) {
if (strpos($part, 'xn--') === 0) {
switch ($backend) {
case 'INTL':
$part = idn_to_utf8($part);
break;
case 'INTL_UTS46':
$part = idn_to_utf8($part, 0, INTL_IDNA_VARIANT_UTS46, $info);
self::_checkForError($info);
break;
}
}
}
return implode('.', $parts);
default:
return $backend->decode($data);
}
}
/**
* Checks if the $idna_info parameter of idn_to_ascii() or idn_to_utf8()
* contains errors.
*
* @param array $info Fourth parameter to idn_to_ascii() or idn_to_utf8().
*
* @throws Horde_Idna_Exception
*/
protected static function _checkForError($info)
{
if (!isset($info['errors'])) {
return;
}
switch (true) {
case $info['errors'] & IDNA_ERROR_EMPTY_LABEL:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Domain name is empty"
));
case $info['errors'] & IDNA_ERROR_LABEL_TOO_LONG:
case $info['errors'] & IDNA_ERROR_DOMAIN_NAME_TOO_LONG:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Domain name is too long"
));
case $info['errors'] & IDNA_ERROR_LEADING_HYPHEN:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Starts with a hyphen"
));
case $info['errors'] & IDNA_ERROR_TRAILING_HYPHEN:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Ends with a hyphen"
));
case $info['errors'] & IDNA_ERROR_HYPHEN_3_4:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Contains hyphen in the third and fourth positions"
));
case $info['errors'] & IDNA_ERROR_LEADING_COMBINING_MARK:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Starts with a combining mark"
));
case $info['errors'] & IDNA_ERROR_DISALLOWED:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Contains disallowed characters"
));
case $info['errors'] & IDNA_ERROR_PUNYCODE:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Starts with \"xn--\" but does not contain valid Punycode"
));
case $info['errors'] & IDNA_ERROR_LABEL_HAS_DOT:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Contains a dot"
));
case $info['errors'] & IDNA_ERROR_INVALID_ACE_LABEL:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"ACE label does not contain a valid label string"
));
case $info['errors'] & IDNA_ERROR_BIDI:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Does not meet the IDNA BiDi requirements (for right-to-left characters)"
));
case $info['errors'] & IDNA_ERROR_CONTEXTJ:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Does not meet the IDNA CONTEXTJ requirements"
));
case $info['errors']:
throw new Horde_Idna_Exception(Horde_Idna_Translation::t(
"Unknown error"
));
}
}
/**
* Return the IDNA backend.
*
* @return mixed IDNA backend (false if none available).
*/
protected static function _getBackend()
{
if (!isset(self::$_backend)) {
if (extension_loaded('intl')) {
/* Only available in PHP > 5.4.0 */
self::$_backend = defined('INTL_IDNA_VARIANT_UTS46')
? 'INTL_UTS46'
: 'INTL';
} else {
self::$_backend = new Horde_Idna_Punycode();
}
}
return self::$_backend;
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (BSD). If you
* did not receive this file, see http://www.horde.org/licenses/bsd.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
/**
* Exception class for the Horde_Idna package.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
class Horde_Idna_Exception extends Horde_Exception
{}

View File

@ -1,354 +0,0 @@
<?php
/**
* Copyright 2014 TrueServer B.V.
* Copyright 2015-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (BSD). If you
* did not receive this file, see http://www.horde.org/licenses/bsd.
*
* @author Renan Gonçalves <renan.saddam@gmail.com>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
/**
* Punycode implementation as described in RFC 3492.
*
* Original code (v1.0.1; released under the MIT License):
* https://github.com/true/php-punycode/
*
* @author Renan Gonçalves <renan.saddam@gmail.com>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014 TrueServer B.V.
* @copyright 2015-2017 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
* @link http://tools.ietf.org/html/rfc3492
*/
class Horde_Idna_Punycode
{
/**
* Bootstring parameter values.
*/
const BASE = 36;
const TMIN = 1;
const TMAX = 26;
const SKEW = 38;
const DAMP = 700;
const INITIAL_BIAS = 72;
const INITIAL_N = 128;
const PREFIX = 'xn--';
const DELIMITER = '-';
/**
* Encode table.
*
* @param array
*/
protected static $_encodeTable = array(
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
);
/**
* Decode table.
*
* @param array
*/
protected static $_decodeTable = array(
'a' => 0, 'b' => 1, 'c' => 2, 'd' => 3, 'e' => 4, 'f' => 5,
'g' => 6, 'h' => 7, 'i' => 8, 'j' => 9, 'k' => 10, 'l' => 11,
'm' => 12, 'n' => 13, 'o' => 14, 'p' => 15, 'q' => 16, 'r' => 17,
's' => 18, 't' => 19, 'u' => 20, 'v' => 21, 'w' => 22, 'x' => 23,
'y' => 24, 'z' => 25, '0' => 26, '1' => 27, '2' => 28, '3' => 29,
'4' => 30, '5' => 31, '6' => 32, '7' => 33, '8' => 34, '9' => 35
);
/**
* Encode a domain to its Punycode version.
*
* @param string $input Domain name in Unicde to be encoded.
*
* @return string Punycode representation in ASCII.
*/
public function encode($input)
{
$parts = explode('.', $input);
foreach ($parts as &$part) {
$part = $this->_encodePart($part);
}
return implode('.', $parts);
}
/**
* Encode a part of a domain name, such as tld, to its Punycode version.
*
* @param string $input Part of a domain name.
*
* @return string Punycode representation of a domain part.
*/
protected function _encodePart($input)
{
$codePoints = $this->_codePoints($input);
$n = static::INITIAL_N;
$bias = static::INITIAL_BIAS;
$delta = 0;
$h = $b = count($codePoints['basic']);
$output = '';
foreach ($codePoints['basic'] as $code) {
$output .= $this->_codePointToChar($code);
}
if ($input === $output) {
return $output;
}
if ($b > 0) {
$output .= static::DELIMITER;
}
$codePoints['nonBasic'] = array_unique($codePoints['nonBasic']);
sort($codePoints['nonBasic']);
$i = 0;
$length = Horde_String::length($input, 'UTF-8');
while ($h < $length) {
$m = $codePoints['nonBasic'][$i++];
$delta = $delta + ($m - $n) * ($h + 1);
$n = $m;
foreach ($codePoints['all'] as $c) {
if (($c < $n) || ($c < static::INITIAL_N)) {
++$delta;
}
if ($c === $n) {
$q = $delta;
for ($k = static::BASE; ; $k += static::BASE) {
$t = $this->_calculateThreshold($k, $bias);
if ($q < $t) {
break;
}
$code = $t + (($q - $t) % (static::BASE - $t));
$output .= static::$_encodeTable[$code];
$q = ($q - $t) / (static::BASE - $t);
}
$output .= static::$_encodeTable[$q];
$bias = $this->_adapt($delta, $h + 1, ($h === $b));
$delta = 0;
++$h;
}
}
++$delta;
++$n;
}
return static::PREFIX . $output;
}
/**
* Decode a Punycode domain name to its Unicode counterpart.
*
* @param string $input Domain name in Punycode
*
* @return string Unicode domain name.
*/
public function decode($input)
{
$parts = explode('.', $input);
foreach ($parts as &$part) {
if (strpos($part, static::PREFIX) === 0) {
$part = $this->_decodePart(
substr($part, strlen(static::PREFIX))
);
}
}
return implode('.', $parts);
}
/**
* Decode a part of domain name, such as tld.
*
* @param string $input Part of a domain name.
*
* @return string Unicode domain part.
*/
protected function _decodePart($input)
{
$n = static::INITIAL_N;
$i = 0;
$bias = static::INITIAL_BIAS;
$output = '';
$pos = strrpos($input, static::DELIMITER);
if ($pos !== false) {
$output = substr($input, 0, $pos++);
} else {
$pos = 0;
}
$outputLength = strlen($output);
$inputLength = strlen($input);
/* Punycode lookup is case-insensitive. */
$input = Horde_String::lower($input);
while ($pos < $inputLength) {
$oldi = $i;
$w = 1;
for ($k = static::BASE; ; $k += static::BASE) {
$digit = static::$_decodeTable[$input[$pos++]];
$i = $i + ($digit * $w);
$t = $this->_calculateThreshold($k, $bias);
if ($digit < $t) {
break;
}
$w = $w * (static::BASE - $t);
}
$bias = $this->_adapt($i - $oldi, ++$outputLength, ($oldi === 0));
$n = $n + (int) ($i / $outputLength);
$i = $i % ($outputLength);
$output = Horde_String::substr($output, 0, $i, 'UTF-8') .
$this->_codePointToChar($n) .
Horde_String::substr($output, $i, $outputLength - 1, 'UTF-8');
++$i;
}
return $output;
}
/**
* Calculate the bias threshold to fall between TMIN and TMAX.
*
* @param integer $k
* @param integer $bias
*
* @return integer
*/
protected function _calculateThreshold($k, $bias)
{
if ($k <= ($bias + static::TMIN)) {
return static::TMIN;
} elseif ($k >= ($bias + static::TMAX)) {
return static::TMAX;
}
return $k - $bias;
}
/**
* Bias adaptation.
*
* @param integer $delta
* @param integer $numPoints
* @param boolean $firstTime
*
* @return integer
*/
protected function _adapt($delta, $numPoints, $firstTime)
{
$delta = (int) (
($firstTime)
? $delta / static::DAMP
: $delta / 2
);
$delta += (int) ($delta / $numPoints);
$k = 0;
while ($delta > ((static::BASE - static::TMIN) * static::TMAX) / 2) {
$delta = (int) ($delta / (static::BASE - static::TMIN));
$k = $k + static::BASE;
}
$k = $k + (int) (((static::BASE - static::TMIN + 1) * $delta) / ($delta + static::SKEW));
return $k;
}
/**
* List code points for a given input.
*
* @param string $input
*
* @return array Multi-dimension array with basic, non-basic and
* aggregated code points.
*/
protected function _codePoints($input)
{
$codePoints = array(
'all' => array(),
'basic' => array(),
'nonBasic' => array()
);
$len = Horde_String::length($input, 'UTF-8');
for ($i = 0; $i < $len; ++$i) {
$char = Horde_String::substr($input, $i, 1, 'UTF-8');
$code = $this->_charToCodePoint($char);
if ($code < 128) {
$codePoints['all'][] = $codePoints['basic'][] = $code;
} else {
$codePoints['all'][] = $codePoints['nonBasic'][] = $code;
}
}
return $codePoints;
}
/**
* Convert a single or multi-byte character to its code point.
*
* @param string $char
*
* @return integer
*/
protected function _charToCodePoint($char)
{
$code = ord($char[0]);
if ($code < 128) {
return $code;
} elseif ($code < 224) {
return (($code - 192) * 64) + (ord($char[1]) - 128);
} elseif ($code < 240) {
return (($code - 224) * 4096) + ((ord($char[1]) - 128) * 64) + (ord($char[2]) - 128);
}
return (($code - 240) * 262144) + ((ord($char[1]) - 128) * 4096) + ((ord($char[2]) - 128) * 64) + (ord($char[3]) - 128);
}
/**
* Convert a code point to its single or multi-byte character
*
* @param integer $code
*
* @return string
*/
protected function _codePointToChar($code)
{
if ($code <= 0x7F) {
return chr($code);
} elseif ($code <= 0x7FF) {
return chr(($code >> 6) + 192) . chr(($code & 63) + 128);
} elseif ($code <= 0xFFFF) {
return chr(($code >> 12) + 224) . chr((($code >> 6) & 63) + 128) . chr(($code & 63) + 128);
}
return chr(($code >> 18) + 240) . chr((($code >> 12) & 63) + 128) . chr((($code >> 6) & 63) + 128) . chr(($code & 63) + 128);
}
}

View File

@ -1,40 +0,0 @@
<?php
/**
* Copyright 2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (BSD). If you
* did not receive this file, see http://www.horde.org/licenses/bsd.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
/**
* Horde_Idna_Translation is the translation wrapper class for
* Horde_Idna.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @copyright 2017 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
* @since Horde_Idna 1.1.0
*/
class Horde_Idna_Translation extends Horde_Translation_Autodetect
{
/**
* The translation domain
*
* @var string
*/
protected static $_domain = 'Horde_Idna';
/**
* The absolute PEAR path to the translations for the default gettext handler.
*
* @var string
*/
protected static $_pearDirectory = '@data_dir@';
}

View File

@ -1,203 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Base class for Horde_Imap_Client package. Defines common constants for use
* in the package.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client
{
/* Constants for openMailbox() */
const OPEN_READONLY = 1;
const OPEN_READWRITE = 2;
const OPEN_AUTO = 3;
/* Constants for listMailboxes() */
const MBOX_SUBSCRIBED = 1;
const MBOX_SUBSCRIBED_EXISTS = 2;
const MBOX_UNSUBSCRIBED = 3;
const MBOX_ALL = 4;
/* @since 2.23.0 */
const MBOX_ALL_SUBSCRIBED = 5;
/* Constants for status() */
const STATUS_MESSAGES = 1;
const STATUS_RECENT = 2;
const STATUS_UIDNEXT = 4;
const STATUS_UIDVALIDITY = 8;
const STATUS_UNSEEN = 16;
const STATUS_ALL = 32;
const STATUS_FIRSTUNSEEN = 64;
const STATUS_FLAGS = 128;
const STATUS_PERMFLAGS = 256;
const STATUS_HIGHESTMODSEQ = 512;
const STATUS_SYNCMODSEQ = 1024;
const STATUS_SYNCFLAGUIDS = 2048;
const STATUS_UIDNOTSTICKY = 4096;
const STATUS_UIDNEXT_FORCE = 8192;
const STATUS_SYNCVANISHED = 16384;
/* @since 2.12.0 */
const STATUS_RECENT_TOTAL = 32768;
/* @since 2.14.0 */
const STATUS_FORCE_REFRESH = 65536;
/* Constants for search() */
const SORT_ARRIVAL = 1;
const SORT_CC = 2;
const SORT_DATE = 3;
const SORT_FROM = 4;
const SORT_REVERSE = 5;
const SORT_SIZE = 6;
const SORT_SUBJECT = 7;
const SORT_TO = 8;
/* SORT_THREAD provided for completeness - it is not a valid sort criteria
* for search() (use thread() instead). */
const SORT_THREAD = 9;
/* Sort criteria defined in RFC 5957 */
const SORT_DISPLAYFROM = 10;
const SORT_DISPLAYTO = 11;
/* SORT_SEQUENCE does a simple numerical sort on the returned
* UIDs/sequence numbers. */
const SORT_SEQUENCE = 12;
/* Fuzzy sort criteria defined in RFC 6203 */
const SORT_RELEVANCY = 13;
/* @since 2.4.0 */
const SORT_DISPLAYFROM_FALLBACK = 14;
/* @since 2.4.0 */
const SORT_DISPLAYTO_FALLBACK = 15;
/* Search results constants */
const SEARCH_RESULTS_COUNT = 1;
const SEARCH_RESULTS_MATCH = 2;
const SEARCH_RESULTS_MAX = 3;
const SEARCH_RESULTS_MIN = 4;
const SEARCH_RESULTS_SAVE = 5;
/* Fuzzy sort criteria defined in RFC 6203 */
const SEARCH_RESULTS_RELEVANCY = 6;
/* Constants for thread() */
const THREAD_ORDEREDSUBJECT = 1;
const THREAD_REFERENCES = 2;
const THREAD_REFS = 3;
/* Fetch criteria constants. */
const FETCH_STRUCTURE = 1;
const FETCH_FULLMSG = 2;
const FETCH_HEADERTEXT = 3;
const FETCH_BODYTEXT = 4;
const FETCH_MIMEHEADER = 5;
const FETCH_BODYPART = 6;
const FETCH_BODYPARTSIZE = 7;
const FETCH_HEADERS = 8;
const FETCH_ENVELOPE = 9;
const FETCH_FLAGS = 10;
const FETCH_IMAPDATE = 11;
const FETCH_SIZE = 12;
const FETCH_UID = 13;
const FETCH_SEQ = 14;
const FETCH_MODSEQ = 15;
/* @since 2.11.0 */
const FETCH_DOWNGRADED = 16;
/* Namespace constants. @deprecated */
const NS_PERSONAL = 1;
const NS_OTHER = 2;
const NS_SHARED = 3;
/* ACL constants (RFC 4314 [2.1]). */
const ACL_LOOKUP = 'l';
const ACL_READ = 'r';
const ACL_SEEN = 's';
const ACL_WRITE = 'w';
const ACL_INSERT = 'i';
const ACL_POST = 'p';
const ACL_CREATEMBOX = 'k';
const ACL_DELETEMBOX = 'x';
const ACL_DELETEMSGS = 't';
const ACL_EXPUNGE = 'e';
const ACL_ADMINISTER = 'a';
// Old constants (RFC 2086 [3]; RFC 4314 [2.1.1])
const ACL_CREATE = 'c';
const ACL_DELETE = 'd';
/* System flags. */
// RFC 3501 [2.3.2]
const FLAG_ANSWERED = '\\answered';
const FLAG_DELETED = '\\deleted';
const FLAG_DRAFT = '\\draft';
const FLAG_FLAGGED = '\\flagged';
const FLAG_RECENT = '\\recent';
const FLAG_SEEN = '\\seen';
// RFC 3503 [3.3]
const FLAG_MDNSENT = '$mdnsent';
// RFC 5550 [2.8]
const FLAG_FORWARDED = '$forwarded';
// RFC 5788 registered keywords:
// http://www.ietf.org/mail-archive/web/morg/current/msg00441.html
const FLAG_JUNK = '$junk';
const FLAG_NOTJUNK = '$notjunk';
/* Special-use mailbox attributes (RFC 6154 [2]). */
const SPECIALUSE_ALL = '\\All';
const SPECIALUSE_ARCHIVE = '\\Archive';
const SPECIALUSE_DRAFTS = '\\Drafts';
const SPECIALUSE_FLAGGED = '\\Flagged';
const SPECIALUSE_JUNK = '\\Junk';
const SPECIALUSE_SENT = '\\Sent';
const SPECIALUSE_TRASH = '\\Trash';
/* Constants for sync(). */
const SYNC_UIDVALIDITY = 0;
const SYNC_FLAGS = 1;
const SYNC_FLAGSUIDS = 2;
const SYNC_NEWMSGS = 4;
const SYNC_NEWMSGSUIDS = 8;
const SYNC_VANISHED = 16;
const SYNC_VANISHEDUIDS = 32;
const SYNC_ALL = 64;
/**
* Capability dependencies.
*
* @deprecated
*
* @var array
*/
public static $capability_deps = array(
// RFC 7162 [3.2]
'QRESYNC' => array(
// QRESYNC requires CONDSTORE, but the latter is implied and is
// not required to be listed.
'ENABLE'
),
// RFC 5182 [2.1]
'SEARCHRES' => array(
'ESEARCH'
),
// RFC 5255 [3.1]
'LANGUAGE' => array(
'NAMESPACE'
),
// RFC 5957 [1]
'SORT=DISPLAY' => array(
'SORT'
)
);
}

View File

@ -1,189 +0,0 @@
<?php
/**
* Copyright (c) 2002-2003 Richard Heyes
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* This code is based on the original code contained in the PEAR Auth_SASL
* package (v0.5.1):
* $Id: DigestMD5.php 294702 2010-02-07 16:03:55Z cweiske $
*
* That code is covered by the BSD 3-Clause license, as set forth below:
* +-----------------------------------------------------------------------+
* | Copyright (c) 2002-2003 Richard Heyes |
* | All rights reserved. |
* | |
* | Redistribution and use in source and binary forms, with or without |
* | modification, are permitted provided that the following conditions |
* | are met: |
* | |
* | o Redistributions of source code must retain the above copyright |
* | notice, this list of conditions and the following disclaimer. |
* | o Redistributions in binary form must reproduce the above copyright |
* | notice, this list of conditions and the following disclaimer in the |
* | documentation and/or other materials provided with the distribution.|
* | o The names of the authors may not be used to endorse or promote |
* | products derived from this software without specific prior written |
* | permission. |
* | |
* | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
* | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
* | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
* | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
* | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* +-----------------------------------------------------------------------+
*
* @category Horde
* @copyright 2002-2003 Richard Heyes
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Provides the code needed to authenticate via the DIGEST-MD5 SASL mechanism
* (defined in RFC 2831). This method has been obsoleted by RFC 6331, but
* still is in use on legacy servers.
*
* @author Richard Heyes <richard@php.net>
* @author Michael Slusarz <slusarz@horde.org>
* @copyright 2002-2003 Richard Heyes
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Auth_DigestMD5
{
/**
* Digest response components.
*
* @var string
*/
protected $_response;
/**
* Generate the Digest-MD5 response.
*
* @param string $id Authentication id (username).
* @param string $pass Password.
* @param string $challenge The digest challenge sent by the server.
* @param string $hostname The hostname of the machine connecting to.
* @param string $service The service name (e.g. 'imap', 'pop3').
*
* @throws Horde_Imap_Client_Exception
*/
public function __construct($id, $pass, $challenge, $hostname, $service)
{
$challenge = $this->_parseChallenge($challenge);
$cnonce = $this->_getCnonce();
$digest_uri = sprintf('%s/%s', $service, $hostname);
/* Get response value. */
$A1 = sprintf('%s:%s:%s', pack('H32', hash('md5', sprintf('%s:%s:%s', $id, $challenge['realm'], $pass))), $challenge['nonce'], $cnonce);
$A2 = 'AUTHENTICATE:' . $digest_uri;
$response_value = hash('md5', sprintf('%s:%s:00000001:%s:auth:%s', hash('md5', $A1), $challenge['nonce'], $cnonce, hash('md5', $A2)));
$this->_response = array(
'cnonce' => '"' . $cnonce . '"',
'digest-uri' => '"' . $digest_uri . '"',
'maxbuf' => $challenge['maxbuf'],
'nc' => '00000001',
'nonce' => '"' . $challenge['nonce'] . '"',
'qop' => 'auth',
'response' => $response_value,
'username' => '"' . $id . '"'
);
if (strlen($challenge['realm'])) {
$this->_response['realm'] = '"' . $challenge['realm'] . '"';
}
}
/**
* Cooerce to string.
*
* @return string The digest response (not base64 encoded).
*/
public function __toString()
{
$out = array();
foreach ($this->_response as $key => $val) {
$out[] = $key . '=' . $val;
}
return implode(',', $out);
}
/**
* Return specific digest response directive.
*
* @return mixed Requested directive, or null if it does not exist.
*/
public function __get($name)
{
return isset($this->_response[$name])
? $this->_response[$name]
: null;
}
/**
* Parses and verifies the digest challenge.
*
* @param string $challenge The digest challenge
*
* @return array The parsed challenge as an array with directives as keys.
*
* @throws Horde_Imap_Client_Exception
*/
protected function _parseChallenge($challenge)
{
$tokens = array(
'maxbuf' => 65536,
'realm' => ''
);
preg_match_all('/([a-z-]+)=("[^"]+(?<!\\\)"|[^,]+)/i', $challenge, $matches, PREG_SET_ORDER);
foreach ($matches as $val) {
$tokens[$val[1]] = trim($val[2], '"');
}
// Required directives.
if (!isset($tokens['nonce']) || !isset($tokens['algorithm'])) {
throw new Horde_Imap_Client_Exception(
Horde_Imap_Client_Translation::r("Authentication failure."),
Horde_Imap_Client_Exception::SERVER_CONNECT
);
}
return $tokens;
}
/**
* Creates the client nonce for the response
*
* @return string The cnonce value.
*/
protected function _getCnonce()
{
if ((@is_readable('/dev/urandom') &&
($fd = @fopen('/dev/urandom', 'r'))) ||
(@is_readable('/dev/random') &&
($fd = @fopen('/dev/random', 'r')))) {
$str = fread($fd, 32);
fclose($fd);
} else {
$str = '';
for ($i = 0; $i < 32; ++$i) {
$str .= chr(mt_rand(0, 255));
}
}
return base64_encode($str);
}
}

View File

@ -1,270 +0,0 @@
<?php
/**
* Copyright 2015-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2015-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Provides authentication via the SCRAM SASL mechanism (RFC 5802 [3]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2015-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.29.0
*/
class Horde_Imap_Client_Auth_Scram
{
/**
* AuthMessage (RFC 5802 [3]).
*
* @var string
*/
protected $_authmsg;
/**
* Hash name.
*
* @var string
*/
protected $_hash;
/**
* Number of Hi iterations (RFC 5802 [2]).
*
* @var integer
*/
protected $_iterations;
/**
* Nonce.
*
* @var string
*/
protected $_nonce;
/**
* Password.
*
* @var string
*/
protected $_pass;
/**
* Server salt.
*
* @var string
*/
protected $_salt;
/**
* Calculated server signature value.
*
* @var string
*/
protected $_serversig;
/**
* Username.
*
* @var string
*/
protected $_user;
/**
* Constructor.
*
* @param string $user Username.
* @param string $pass Password.
* @param string $hash Hash name.
*
* @throws Horde_Imap_Client_Exception
*/
public function __construct($user, $pass, $hash = 'SHA1')
{
$error = false;
$this->_hash = $hash;
try {
if (!class_exists('Horde_Stringprep') ||
!class_exists('Horde_Crypt_Blowfish_Pbkdf2')) {
throw new Exception();
}
Horde_Stringprep::autoload();
$saslprep = new Znerol\Component\Stringprep\Profile\SASLprep();
$this->_user = $saslprep->apply(
$user,
'UTF-8',
Znerol\Component\Stringprep\Profile::MODE_QUERY
);
$this->_pass = $saslprep->apply(
$pass,
'UTF-8',
Znerol\Component\Stringprep\Profile::MODE_STORE
);
} catch (Znerol\Component\Stringprep\ProfileException $e) {
$error = true;
} catch (Exception $e) {
$error = true;
}
if ($error) {
throw new Horde_Imap_Client_Exception(
Horde_Imap_Client_Translation::r("Authentication failure."),
Horde_Imap_Client_Exception::LOGIN_AUTHORIZATIONFAILED
);
}
/* Generate nonce. (Done here so this can be overwritten for
* testing purposes.) */
$this->_nonce = strval(new Horde_Support_Randomid());
}
/**
* Return the initial client message.
*
* @return string Initial client message.
*/
public function getClientFirstMessage()
{
/* n: client doesn't support channel binding,
* <empty>,
* n=<user>: SASLprepped username with "," and "=" escaped,
* r=<nonce>: Random nonce */
$this->_authmsg = 'n=' . str_replace(
array(',', '='),
array('=2C', '=3D'),
$this->_user
) . ',r=' . $this->_nonce;
return 'n,,' . $this->_authmsg;
}
/**
* Process the initial server message response.
*
* @param string $msg Initial server response.
*
* @return boolean False if authentication failed at this stage.
*/
public function parseServerFirstMessage($msg)
{
$i = $r = $s = false;
foreach (explode(',', $msg) as $val) {
list($attr, $aval) = array_map('trim', explode('=', $val, 2));
switch ($attr) {
case 'i':
$this->_iterations = intval($aval);
$i = true;
break;
case 'r':
/* Beginning of server-provided nonce MUST be the same as the
* nonce we provided. */
if (strpos($aval, $this->_nonce) !== 0) {
return false;
}
$this->_nonce = $aval;
$r = true;
break;
case 's':
$this->_salt = base64_decode($aval);
$s = true;
break;
}
}
if ($i && $r && $s) {
$this->_authmsg .= ',' . $msg;
return true;
}
return false;
}
/**
* Return the final client message.
*
* @return string Final client message.
*/
public function getClientFinalMessage()
{
$final_msg = 'c=biws,r=' . $this->_nonce;
/* Salted password. */
$s_pass = strval(new Horde_Crypt_Blowfish_Pbkdf2(
$this->_pass,
strlen(hash($this->_hash, '', true)),
array(
'algo' => $this->_hash,
'i_count' => $this->_iterations,
'salt' => $this->_salt
)
));
/* Client key. */
$c_key = hash_hmac($this->_hash, 'Client Key', $s_pass, true);
/* Stored key. */
$s_key = hash($this->_hash, $c_key, true);
/* Client signature. */
$auth_msg = $this->_authmsg . ',' . $final_msg;
$c_sig = hash_hmac($this->_hash, $auth_msg, $s_key, true);
/* Proof. */
$proof = $c_key ^ $c_sig;
/* Server signature. */
$this->_serversig = hash_hmac(
$this->_hash,
$auth_msg,
hash_hmac($this->_hash, 'Server Key', $s_pass, true),
true
);
/* c=biws: channel-binding ("biws" = base64('n,,')),
* p=<proof>: base64 encoded ClientProof,
* r=<nonce>: Nonce as returned from the server. */
return $final_msg . ',p=' . base64_encode($proof);
}
/**
* Process the final server message response.
*
* @param string $msg Final server response.
*
* @return boolean False if authentication failed.
*/
public function parseServerFinalMessage($msg)
{
foreach (explode(',', $msg) as $val) {
list($attr, $aval) = array_map('trim', explode('=', $val, 2));
switch ($attr) {
case 'e':
return false;
case 'v':
return (base64_decode($aval) === $this->_serversig);
}
}
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,105 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Handle IMAP alerts sent from the server.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.24.0
*/
class Horde_Imap_Client_Base_Alerts
implements SplSubject
{
/**
* Alert data.
*
* @var object
*/
protected $_alert;
/**
* Observers.
*
* @var array
*/
protected $_observers = array();
/**
* Add an alert.
*
* @param string $alert The alert string.
* @param string $type The alert type.
*/
public function add($alert, $type = null)
{
$this->_alert = new stdClass;
$this->_alert->alert = $alert;
if (!is_null($type)) {
$this->_alert->type = $type;
}
$this->notify();
}
/**
* Returns the last alert received.
*
* @return object Alert information. Object with these properties:
* <pre>
* - alert: (string) Alert string.
* - type: (string) [OPTIONAL] Alert type.
* </pre>
*/
public function getLast()
{
return $this->_alert;
}
/* SplSubject methods. */
/**
*/
#[ReturnTypeWillChange]
public function attach(SplObserver $observer)
{
$this->detach($observer);
$this->_observers[] = $observer;
}
/**
*/
#[ReturnTypeWillChange]
public function detach(SplObserver $observer)
{
if (($key = array_search($observer, $this->_observers, true)) !== false) {
unset($this->_observers[$key]);
}
}
/**
* Notification is triggered internally whenever the object's internal
* data storage is altered.
*/
#[ReturnTypeWillChange]
public function notify()
{
foreach ($this->_observers as $val) {
$val->update($this);
}
}
}

View File

@ -1,152 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object allowing management of debugging output within a
* Horde_Imap_Client_Base object.
*
* NOTE: This class is NOT intended to be accessed outside of a Base object.
* There is NO guarantees that the API of this class will not change across
* versions.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @internal
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Base_Debug
{
/** Time, in seconds, to be labeled a slow command. */
const SLOW_CMD = 5;
/**
* Is debugging active?
*
* @var boolean
*/
public $debug = true;
/**
* The debug stream.
*
* @var resource
*/
protected $_stream;
/**
* Timestamp of last command.
*
* @var integer
*/
protected $_time = null;
/**
* Constructor.
*
* @param mixed $debug The debug target.
*/
public function __construct($debug)
{
$this->_stream = is_resource($debug)
? $debug
: @fopen($debug, 'a');
register_shutdown_function(array($this, 'shutdown'));
}
/**
* Shutdown function.
*/
public function shutdown()
{
if (is_resource($this->_stream)) {
fflush($this->_stream);
fclose($this->_stream);
$this->_stream = null;
}
}
/**
* Write client output to debug log.
*
* @param string $msg Debug message.
*/
public function client($msg)
{
$this->_write($msg . "\n", 'C: ');
}
/**
* Write informational message to debug log.
*
* @param string $msg Debug message.
*/
public function info($msg)
{
$this->_write($msg . "\n", '>> ');
}
/**
* Write server output to debug log.
*
* @param string $msg Debug message.
*/
public function raw($msg)
{
$this->_write($msg);
}
/**
* Write server output to debug log.
*
* @param string $msg Debug message.
*/
public function server($msg)
{
$this->_write($msg . "\n", 'S: ');
}
/**
* Write debug information to the output stream.
*
* @param string $msg Debug data.
*/
protected function _write($msg, $pre = null)
{
if (!$this->debug || !$this->_stream) {
return;
}
if (!is_null($pre)) {
$new_time = microtime(true);
if (is_null($this->_time)) {
fwrite(
$this->_stream,
str_repeat('-', 30) . "\n" . '>> ' . date('r') . "\n"
);
} elseif (($diff = ($new_time - $this->_time)) > self::SLOW_CMD) {
fwrite(
$this->_stream,
'>> Slow Command: ' . round($diff, 3) . " seconds\n"
);
}
$this->_time = $new_time;
}
fwrite($this->_stream, $pre . $msg);
}
}

View File

@ -1,109 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Class containing deprecated Horde_Imap_Client_Base methods that will be
* removed in version 3.0.
*
* NOTE: This class is NOT intended to be accessed outside of a Base object.
* There is NO guarantees that the API of this class will not change across
* versions.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @internal
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Base_Deprecated
{
/**
* Returns a unique identifier for the current mailbox status.
*
* @param Horde_Imap_Client_Base $base_ob The base driver object.
* @param mixed $mailbox A mailbox. Either a
* Horde_Imap_Client_Mailbox
* object or a string (UTF-8).
* @param boolean $condstore Is CONDSTORE enabled?
* @param array $addl Additional cache info to add to
* the cache ID string.
*
* @return string The cache ID string, which will change when the
* composition of the mailbox changes. The uidvalidity
* will always be the first element, and will be delimited
* by the '|' character.
*
* @throws Horde_Imap_Client_Exception
*/
public static function getCacheId($base_ob, $mailbox, $condstore,
array $addl = array())
{
$query = Horde_Imap_Client::STATUS_UIDVALIDITY | Horde_Imap_Client::STATUS_MESSAGES | Horde_Imap_Client::STATUS_UIDNEXT;
/* Use MODSEQ as cache ID if CONDSTORE extension is available. */
if ($condstore) {
$query |= Horde_Imap_Client::STATUS_HIGHESTMODSEQ;
} else {
$query |= Horde_Imap_Client::STATUS_UIDNEXT_FORCE;
}
$status = $base_ob->status($mailbox, $query);
if (empty($status['highestmodseq'])) {
$parts = array(
'V' . $status['uidvalidity'],
'U' . $status['uidnext'],
'M' . $status['messages']
);
} else {
$parts = array(
'V' . $status['uidvalidity'],
'H' . $status['highestmodseq']
);
}
return implode('|', array_merge($parts, $addl));
}
/**
* Parses a cacheID created by getCacheId().
*
* @param string $id The cache ID.
*
* @return array An array with the following information:
* - highestmodseq: (integer)
* - messages: (integer)
* - uidnext: (integer)
* - uidvalidity: (integer) Always present
*/
public static function parseCacheId($id)
{
$data = array(
'H' => 'highestmodseq',
'M' => 'messages',
'U' => 'uidnext',
'V' => 'uidvalidity'
);
$info = array();
foreach (explode('|', $id) as $part) {
if (isset($data[$part[0]])) {
$info[$data[$part[0]]] = intval(substr($part, 1));
}
}
return $info;
}
}

View File

@ -1,187 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object allowing management of mailbox state within a
* Horde_Imap_Client_Base object.
*
* NOTE: This class is NOT intended to be accessed outside of a Base object.
* There is NO guarantees that the API of this class will not change across
* versions.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @internal
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Base_Mailbox
{
/**
* Mapping object.
*
* @var Horde_Imap_Client_Ids_Map
*/
public $map;
/**
* Is mailbox opened?
*
* @var boolean
*/
public $open;
/**
* Is mailbox sync'd with remote server (via CONDSTORE/QRESYNC)?
*
* @var boolean
*/
public $sync;
/**
* Status information.
*
* @var array
*/
protected $_status = array();
/**
* Constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* Get status information for the mailbox.
*
* @param integer $entry STATUS_* constant.
*
* @return mixed Status information.
*/
public function getStatus($entry)
{
if (isset($this->_status[$entry])) {
return $this->_status[$entry];
}
switch ($entry) {
case Horde_Imap_Client::STATUS_FLAGS:
case Horde_Imap_Client::STATUS_SYNCFLAGUIDS:
case Horde_Imap_Client::STATUS_SYNCVANISHED:
return array();
case Horde_Imap_Client::STATUS_FIRSTUNSEEN:
/* If we know there are no messages in the current mailbox, we
* know there are no unseen messages. */
return empty($this->_status[Horde_Imap_Client::STATUS_MESSAGES])
? false
: null;
case Horde_Imap_Client::STATUS_RECENT_TOTAL:
case Horde_Imap_Client::STATUS_SYNCMODSEQ:
return 0;
case Horde_Imap_Client::STATUS_PERMFLAGS:
/* If PERMFLAGS is not returned by server, must assume that all
* flags can be changed permanently (RFC 3501 [6.3.1]). */
$flags = isset($this->_status[Horde_Imap_Client::STATUS_FLAGS])
? $this->_status[Horde_Imap_Client::STATUS_FLAGS]
: array();
$flags[] = "\\*";
return $flags;
case Horde_Imap_Client::STATUS_UIDNOTSTICKY:
/* In the absence of explicit uidnotsticky identification, assume
* that UIDs are sticky. */
return false;
case Horde_Imap_Client::STATUS_UNSEEN:
/* If we know there are no messages in the current mailbox, we
* know there are no unseen messages . */
return empty($this->_status[Horde_Imap_Client::STATUS_MESSAGES])
? 0
: null;
default:
return null;
}
}
/**
* Set status information for the mailbox.
*
* @param integer $entry STATUS_* constant.
* @param mixed $value Status information.
*/
public function setStatus($entry, $value)
{
switch ($entry) {
case Horde_Imap_Client::STATUS_FIRSTUNSEEN:
case Horde_Imap_Client::STATUS_HIGHESTMODSEQ:
case Horde_Imap_Client::STATUS_MESSAGES:
case Horde_Imap_Client::STATUS_UNSEEN:
case Horde_Imap_Client::STATUS_UIDNEXT:
case Horde_Imap_Client::STATUS_UIDVALIDITY:
$value = intval($value);
break;
case Horde_Imap_Client::STATUS_RECENT:
/* Keep track of RECENT_TOTAL information. */
$this->_status[Horde_Imap_Client::STATUS_RECENT_TOTAL] = isset($this->_status[Horde_Imap_Client::STATUS_RECENT_TOTAL])
? ($this->_status[Horde_Imap_Client::STATUS_RECENT_TOTAL] + $value)
: intval($value);
break;
case Horde_Imap_Client::STATUS_SYNCMODSEQ:
/* This is only set once per access. */
if (isset($this->_status[$entry])) {
return;
}
$value = intval($value);
break;
case Horde_Imap_Client::STATUS_SYNCFLAGUIDS:
case Horde_Imap_Client::STATUS_SYNCVANISHED:
if (!isset($this->_status[$entry])) {
$this->_status[$entry] = array();
}
$this->_status[$entry] = array_merge($this->_status[$entry], $value);
return;
}
$this->_status[$entry] = $value;
}
/**
* Reset the mailbox information.
*/
public function reset()
{
$keep = array(
Horde_Imap_Client::STATUS_SYNCFLAGUIDS,
Horde_Imap_Client::STATUS_SYNCMODSEQ,
Horde_Imap_Client::STATUS_SYNCVANISHED
);
foreach (array_diff(array_keys($this->_status), $keep) as $val) {
unset($this->_status[$val]);
}
$this->map = new Horde_Imap_Client_Ids_Map();
$this->open = $this->sync = false;
}
}

View File

@ -1,33 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Interface to allow dynamic generation of server password.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.14.0
*/
interface Horde_Imap_Client_Base_Password
{
/**
* Return the password to use for the server connection.
*
* @return string The password.
*/
public function getPassword();
}

View File

@ -1,263 +0,0 @@
<?php
/**
* Copyright 2005-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2005-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An interface to cache data retrieved from the IMAP server.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Cache
{
/**
* Base client object.
*
* @var Horde_Imap_Client_Base
*/
protected $_baseob;
/**
* Storage backend.
*
* @var Horde_Imap_Client_Cache_Backend
*/
protected $_backend;
/**
* Debug output.
*
* @var Horde_Imap_Client_Base_Debug
*/
protected $_debug = false;
/**
* The configuration params.
*
* @var array
*/
protected $_params = array();
/**
* Constructor.
*
* @param array $params Configuration parameters:
* <pre>
* - REQUIRED Parameters:
* - backend: (Horde_Imap_Client_Cache_Backend) The cache backend.
* - baseob: (Horde_Imap_Client_Base) The base client object.
*
* - Optional Parameters:
* - debug: (Horde_Imap_Client_Base_Debug) Debug object.
* DEFAULT: No debug output
* </pre>
*/
public function __construct(array $params = array())
{
$this->_backend = $params['backend'];
$this->_baseob = $params['baseob'];
$this->_backend->setParams(array(
'hostspec' => $this->_baseob->getParam('hostspec'),
'port' => $this->_baseob->getParam('port'),
'username' => $this->_baseob->getParam('username')
));
if (isset($params['debug']) &&
($params['debug'] instanceof Horde_Imap_Client_Base_Debug)) {
$this->_debug = $params['debug'];
$this->_debug->info(sprintf(
'CACHE: Using the %s storage driver.',
get_class($this->_backend)
));
}
}
/**
* Get information from the cache.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $uids The list of message UIDs to retrieve
* information for. If empty, returns the list
* of cached UIDs.
* @param array $fields An array of fields to retrieve. If empty,
* returns all cached fields.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*
* @return array An array of arrays with the UID of the message as the
* key (if found) and the fields as values (will be
* undefined if not found). If $uids is empty, returns the
* full (unsorted) list of cached UIDs.
*/
public function get($mailbox, array $uids = array(), $fields = array(),
$uidvalid = null)
{
$mailbox = strval($mailbox);
if (empty($uids)) {
$ret = $this->_backend->getCachedUids($mailbox, $uidvalid);
} else {
$ret = $this->_backend->get($mailbox, $uids, $fields, $uidvalid);
if ($this->_debug && !empty($ret)) {
$this->_debug->info(sprintf(
'CACHE: Retrieved messages (%s [%s; %s])',
empty($fields) ? 'ALL' : implode(',', $fields),
$mailbox,
$this->_baseob->getIdsOb(array_keys($ret))->tostring_sort
));
}
}
return $ret;
}
/**
* Store information in cache.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $data The list of data to save. The keys are the
* UIDs, the values are an array of information
* to save. If empty, do a check to make sure
* the uidvalidity is still valid.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*/
public function set($mailbox, $data, $uidvalid)
{
$mailbox = strval($mailbox);
if (empty($data)) {
$this->_backend->getMetaData($mailbox, $uidvalid, array('uidvalid'));
} else {
$this->_backend->set($mailbox, $data, $uidvalid);
if ($this->_debug) {
$this->_debug->info(sprintf(
'CACHE: Stored messages [%s; %s]',
$mailbox,
$this->_baseob->getIdsOb(array_keys($data))->tostring_sort
));
}
}
}
/**
* Get metadata information for a mailbox.
*
* @param string $mailbox An IMAP mailbox string.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
* @param array $entries An array of entries to return. If empty,
* returns all metadata.
*
* @return array The requested metadata. Requested entries that do not
* exist will be undefined. The following entries are
* defaults and always present:
* - uidvalid: (integer) The UIDVALIDITY of the mailbox.
*/
public function getMetaData($mailbox, $uidvalid = null,
array $entries = array())
{
return $this->_backend->getMetaData(strval($mailbox), $uidvalid, $entries);
}
/**
* Set metadata information for a mailbox.
*
* @param string $mailbox An IMAP mailbox string.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
* @param array $data The list of data to save. The keys are the
* metadata IDs, the values are the associated
* data. The following labels are reserved:
* 'uidvalid'.
*/
public function setMetaData($mailbox, $uidvalid, array $data = array())
{
unset($data['uidvalid']);
if (!empty($data)) {
if (!empty($uidvalid)) {
$data['uidvalid'] = $uidvalid;
}
$mailbox = strval($mailbox);
$this->_backend->setMetaData($mailbox, $data);
if ($this->_debug) {
$this->_debug->info(sprintf(
'CACHE: Stored metadata (%s [%s])',
implode(',', array_keys($data)),
$mailbox
));
}
}
}
/**
* Delete messages in the cache.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $uids The list of message UIDs to delete.
*/
public function deleteMsgs($mailbox, $uids)
{
if (empty($uids)) {
return;
}
$mailbox = strval($mailbox);
$this->_backend->deleteMsgs($mailbox, $uids);
if ($this->_debug) {
$this->_debug->info(sprintf(
'CACHE: Deleted messages [%s; %s]',
$mailbox,
$this->_baseob->getIdsOb($uids)->tostring_sort
));
}
}
/**
* Delete a mailbox from the cache.
*
* @param string $mbox The mailbox to delete.
*/
public function deleteMailbox($mbox)
{
$mbox = strval($mbox);
$this->_backend->deleteMailbox($mbox);
if ($this->_debug) {
$this->_debug->info(sprintf(
'CACHE: Deleted mailbox [%s]',
$mbox
));
}
}
/**
* Clear the cache.
*
* @since 2.9.0
*
* @param integer $lifetime Only delete entries older than this (in
* seconds). If null, deletes all entries.
*/
public function clear($lifetime = null)
{
$this->_backend->clear($lifetime);
}
}

View File

@ -1,177 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* The abstract backend class for storing IMAP cached data.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
abstract class Horde_Imap_Client_Cache_Backend implements Serializable
{
/**
* Configuration paramters.
* Values set by the base Cache object: hostspec, port, username
*
* @var array
*/
protected $_params = array();
/**
* Constructor.
*
* @param array $params Configuration parameters.
*/
public function __construct(array $params = array())
{
$this->setParams($params);
$this->_initOb();
}
/**
* Initialization tasks.
*/
protected function _initOb()
{
}
/**
* Add configuration parameters.
*
* @param array $params Configuration parameters.
*/
public function setParams(array $params = array())
{
$this->_params = array_merge($this->_params, $params);
}
/**
* Get information from the cache for a set of UIDs.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $uids The list of message UIDs to retrieve
* information for.
* @param array $fields An array of fields to retrieve. If empty,
* returns all cached fields.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*
* @return array An array of arrays with the UID of the message as the
* key (if found) and the fields as values (will be
* undefined if not found).
*/
abstract public function get($mailbox, $uids, $fields, $uidvalid);
/**
* Get the list of cached UIDs.
*
* @param string $mailbox An IMAP mailbox string.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*
* @return array The (unsorted) list of cached UIDs.
*/
abstract public function getCachedUids($mailbox, $uidvalid);
/**
* Store data in cache.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $data The list of data to save. The keys are the
* UIDs, the values are an array of information
* to save.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*/
abstract public function set($mailbox, $data, $uidvalid);
/**
* Get metadata information for a mailbox.
*
* @param string $mailbox An IMAP mailbox string.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
* @param array $entries An array of entries to return. If empty,
* returns all metadata.
*
* @return array The requested metadata. Requested entries that do not
* exist will be undefined. The following entries are
* defaults and always present:
* - uidvalid: (integer) The UIDVALIDITY of the mailbox.
*/
abstract public function getMetaData($mailbox, $uidvalid, $entries);
/**
* Set metadata information for a mailbox.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $data The list of data to save. The keys are the
* metadata IDs, the values are the associated
* data. (If present, uidvalidity appears as
* the 'uidvalid' key in $data.)
*/
abstract public function setMetaData($mailbox, $data);
/**
* Delete messages in the cache.
*
* @param string $mailbox An IMAP mailbox string.
* @param array $uids The list of message UIDs to delete.
*/
abstract public function deleteMsgs($mailbox, $uids);
/**
* Delete a mailbox from the cache.
*
* @param string $mailbox The mailbox to delete.
*/
abstract public function deleteMailbox($mailbox);
/**
* Clear the cache.
*
* @param integer $lifetime Only delete entries older than this (in
* seconds). If null, deletes all entries.
*/
abstract public function clear($lifetime);
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$this->__unserialize(unserialize($data));
}
/**
* @return array
*/
public function __serialize()
{
return $this->_params;
}
public function __unserialize(array $data)
{
$this->_params = $data;
}
}

View File

@ -1,514 +0,0 @@
<?php
/**
* Copyright 2005-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2005-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* A Horde_Cache implementation for caching IMAP/POP data.
* Requires the Horde_Cache package.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Cache_Backend_Cache
extends Horde_Imap_Client_Cache_Backend
{
/** Cache structure version. */
const VERSION = 3;
/**
* The cache object.
*
* @var Horde_Cache
*/
protected $_cache;
/**
* The working data for the current pageload. All changes take place to
* this data.
*
* @var array
*/
protected $_data = array();
/**
* The list of cache slices loaded.
*
* @var array
*/
protected $_loaded = array();
/**
* The mapping of UIDs to slices.
*
* @var array
*/
protected $_slicemap = array();
/**
* The list of items to update:
* - add: (array) List of IDs that were added.
* - slice: (array) List of slices that were modified.
* - slicemap: (boolean) Was slicemap info changed?
*
* @var array
*/
protected $_update = array();
/**
* Constructor.
*
* @param array $params Configuration parameters:
* <pre>
* - REQUIRED Parameters:
* - cacheob: (Horde_Cache) The cache object to use.
*
* - Optional Parameters:
* - lifetime: (integer) The lifetime of the cache data (in seconds).
* DEFAULT: 1 week (604800 seconds)
* - slicesize: (integer) The slicesize to use.
* DEFAULT: 50
* </pre>
*/
public function __construct(array $params = array())
{
// Default parameters.
$params = array_merge(array(
'lifetime' => 604800,
'slicesize' => 50
), array_filter($params));
if (!isset($params['cacheob'])) {
throw new InvalidArgumentException('Missing cacheob parameter.');
}
foreach (array('lifetime', 'slicesize') as $val) {
$params[$val] = intval($params[$val]);
}
parent::__construct($params);
}
/**
* Initialization tasks.
*/
protected function _initOb()
{
$this->_cache = $this->_params['cacheob'];
register_shutdown_function(array($this, 'save'));
}
/**
* Updates the cache.
*/
public function save()
{
$lifetime = $this->_params['lifetime'];
foreach ($this->_update as $mbox => $val) {
$s = &$this->_slicemap[$mbox];
try {
if (!empty($val['add'])) {
if ($s['c'] <= $this->_params['slicesize']) {
$val['slice'][] = $s['i'];
$this->_loadSlice($mbox, $s['i']);
}
$val['slicemap'] = true;
foreach (array_keys(array_flip($val['add'])) as $uid) {
if ($s['c']++ > $this->_params['slicesize']) {
$s['c'] = 0;
$val['slice'][] = ++$s['i'];
$this->_loadSlice($mbox, $s['i']);
}
$s['s'][$uid] = $s['i'];
}
}
if (!empty($val['slice'])) {
$d = &$this->_data[$mbox];
$val['slicemap'] = true;
foreach (array_keys(array_flip($val['slice'])) as $slice) {
$data = array();
foreach (moodle_array_keys_filter($s['s'], $slice) as $uid) {
$data[$uid] = is_array($d[$uid])
? serialize($d[$uid])
: $d[$uid];
}
$this->_cache->set($this->_getCid($mbox, $slice), serialize($data), $lifetime);
}
}
if (!empty($val['slicemap'])) {
$this->_cache->set($this->_getCid($mbox, 'slicemap'), serialize($s), $lifetime);
}
} catch (Horde_Exception $e) {
}
}
$this->_update = array();
}
/**
*/
public function get($mailbox, $uids, $fields, $uidvalid)
{
$ret = array();
$this->_loadUids($mailbox, $uids, $uidvalid);
if (empty($this->_data[$mailbox])) {
return $ret;
}
if (!empty($fields)) {
$fields = array_flip($fields);
}
$ptr = &$this->_data[$mailbox];
foreach (array_intersect($uids, array_keys($ptr)) as $val) {
if (is_string($ptr[$val])) {
try {
$ptr[$val] = @unserialize($ptr[$val]);
} catch (Exception $e) {}
}
$ret[$val] = (empty($fields) || empty($ptr[$val]))
? $ptr[$val]
: array_intersect_key($ptr[$val], $fields);
}
return $ret;
}
/**
*/
public function getCachedUids($mailbox, $uidvalid)
{
$this->_loadSliceMap($mailbox, $uidvalid);
return array_unique(array_merge(
array_keys($this->_slicemap[$mailbox]['s']),
(isset($this->_update[$mailbox]) ? $this->_update[$mailbox]['add'] : array())
));
}
/**
*/
public function set($mailbox, $data, $uidvalid)
{
$update = array_keys($data);
try {
$this->_loadUids($mailbox, $update, $uidvalid);
} catch (Horde_Imap_Client_Exception $e) {
// Ignore invalidity - just start building the new cache
}
$d = &$this->_data[$mailbox];
$s = &$this->_slicemap[$mailbox]['s'];
$add = $updated = array();
foreach ($data as $k => $v) {
if (isset($d[$k])) {
if (is_string($d[$k])) {
try {
$d[$k] = @unserialize($d[$k]);
} catch (Exception $e) {}
}
$d[$k] = is_array($d[$k])
? array_merge($d[$k], $v)
: $v;
if (isset($s[$k])) {
$updated[$s[$k]] = true;
}
} else {
$d[$k] = $v;
$add[] = $k;
}
}
$this->_toUpdate($mailbox, 'add', $add);
$this->_toUpdate($mailbox, 'slice', array_keys($updated));
}
/**
*/
public function getMetaData($mailbox, $uidvalid, $entries)
{
$this->_loadSliceMap($mailbox, $uidvalid);
return empty($entries)
? $this->_slicemap[$mailbox]['d']
: array_intersect_key($this->_slicemap[$mailbox]['d'], array_flip($entries));
}
/**
*/
public function setMetaData($mailbox, $data)
{
$this->_loadSliceMap($mailbox, isset($data['uidvalid']) ? $data['uidvalid'] : null);
$this->_slicemap[$mailbox]['d'] = array_merge($this->_slicemap[$mailbox]['d'], $data);
$this->_toUpdate($mailbox, 'slicemap', true);
}
/**
*/
public function deleteMsgs($mailbox, $uids)
{
if (empty($uids)) {
return;
}
$this->_loadSliceMap($mailbox);
$slicemap = &$this->_slicemap[$mailbox];
$deleted = array_intersect_key($slicemap['s'], array_flip($uids));
if (isset($this->_update[$mailbox])) {
$this->_update[$mailbox]['add'] = array_diff(
$this->_update[$mailbox]['add'],
$uids
);
}
if (empty($deleted)) {
return;
}
$this->_loadUids($mailbox, array_keys($deleted));
$d = &$this->_data[$mailbox];
foreach (array_keys($deleted) as $id) {
unset($d[$id], $slicemap['s'][$id]);
}
foreach (array_unique($deleted) as $slice) {
/* Get rid of slice if less than 10% of capacity. */
if (($slice != $slicemap['i']) &&
($slice_uids = moodle_array_keys_filter($slicemap['s'], $slice)) &&
($this->_params['slicesize'] * 0.1) > count($slice_uids)) {
$this->_toUpdate($mailbox, 'add', $slice_uids);
$this->_cache->expire($this->_getCid($mailbox, $slice));
foreach ($slice_uids as $val) {
unset($slicemap['s'][$val]);
}
} else {
$this->_toUpdate($mailbox, 'slice', array($slice));
}
}
}
/**
*/
public function deleteMailbox($mailbox)
{
$this->_loadSliceMap($mailbox);
$this->_deleteMailbox($mailbox);
}
/**
*/
public function clear($lifetime)
{
$this->_cache->clear();
$this->_data = $this->_loaded = $this->_slicemap = $this->_update = array();
}
/**
* Create the unique ID used to store the data in the cache.
*
* @param string $mailbox The mailbox to cache.
* @param string $slice The cache slice.
*
* @return string The cache ID.
*/
protected function _getCid($mailbox, $slice)
{
return implode('|', array(
'horde_imap_client',
$this->_params['username'],
$mailbox,
$this->_params['hostspec'],
$this->_params['port'],
$slice,
self::VERSION
));
}
/**
* Delete a mailbox from the cache.
*
* @param string $mbox The mailbox to delete.
*/
protected function _deleteMailbox($mbox)
{
foreach (array_merge(array_keys(array_flip($this->_slicemap[$mbox]['s'])), array('slicemap')) as $slice) {
$cid = $this->_getCid($mbox, $slice);
$this->_cache->expire($cid);
unset($this->_loaded[$cid]);
}
unset(
$this->_data[$mbox],
$this->_slicemap[$mbox],
$this->_update[$mbox]
);
}
/**
* Load UIDs by regenerating from the cache.
*
* @param string $mailbox The mailbox to load.
* @param array $uids The UIDs to load.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*/
protected function _loadUids($mailbox, $uids, $uidvalid = null)
{
if (!isset($this->_data[$mailbox])) {
$this->_data[$mailbox] = array();
}
$this->_loadSliceMap($mailbox, $uidvalid);
if (!empty($uids)) {
foreach (array_unique(array_intersect_key($this->_slicemap[$mailbox]['s'], array_flip($uids))) as $slice) {
$this->_loadSlice($mailbox, $slice);
}
}
}
/**
* Load UIDs from a cache slice.
*
* @param string $mailbox The mailbox to load.
* @param integer $slice The slice to load.
*/
protected function _loadSlice($mailbox, $slice)
{
$cache_id = $this->_getCid($mailbox, $slice);
if (!empty($this->_loaded[$cache_id])) {
return;
}
if (($data = $this->_cache->get($cache_id, 0)) !== false) {
try {
$data = @unserialize($data);
} catch (Exception $e) {}
}
if (($data !== false) && is_array($data)) {
$this->_data[$mailbox] += $data;
$this->_loaded[$cache_id] = true;
} else {
$ptr = &$this->_slicemap[$mailbox];
// Slice data is corrupt; remove from slicemap.
foreach (moodle_array_keys_filter($ptr['s'], $slice) as $val) {
unset($ptr['s'][$val]);
}
if ($slice == $ptr['i']) {
$ptr['c'] = 0;
}
}
}
/**
* Load the slicemap for a given mailbox. The slicemap contains
* the uidvalidity information, the UIDs->slice lookup table, and any
* metadata that needs to be saved for the mailbox.
*
* @param string $mailbox The mailbox.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*/
protected function _loadSliceMap($mailbox, $uidvalid = null)
{
if (!isset($this->_slicemap[$mailbox]) &&
(($data = $this->_cache->get($this->_getCid($mailbox, 'slicemap'), 0)) !== false)) {
try {
if (($slice = @unserialize($data)) &&
is_array($slice)) {
$this->_slicemap[$mailbox] = $slice;
}
} catch (Exception $e) {}
}
if (isset($this->_slicemap[$mailbox])) {
$ptr = &$this->_slicemap[$mailbox];
if (is_null($ptr['d']['uidvalid'])) {
$ptr['d']['uidvalid'] = $uidvalid;
return;
} elseif (!is_null($uidvalid) &&
($ptr['d']['uidvalid'] != $uidvalid)) {
$this->_deleteMailbox($mailbox);
} else {
return;
}
}
$this->_slicemap[$mailbox] = array(
// Tracking count for purposes of determining slices
'c' => 0,
// Metadata storage
// By default includes UIDVALIDITY of mailbox.
'd' => array('uidvalid' => $uidvalid),
// The ID of the last slice.
'i' => 0,
// The slice list.
's' => array()
);
}
/**
* Add update entry for a mailbox.
*
* @param string $mailbox The mailbox.
* @param string $type 'add', 'slice', or 'slicemap'.
* @param mixed $data The data to update.
*/
protected function _toUpdate($mailbox, $type, $data)
{
if (!isset($this->_update[$mailbox])) {
$this->_update[$mailbox] = array(
'add' => array(),
'slice' => array()
);
}
$this->_update[$mailbox][$type] = ($type == 'slicemap')
? $data
: array_merge($this->_update[$mailbox][$type], $data);
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return $this->__serialize();
}
/**
* @return array
*/
public function __serialize()
{
$this->save();
return parent::__serialize();
}
}

View File

@ -1,407 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* A SQL database implementation for caching IMAP/POP data.
* Requires the Horde_Db package.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Cache_Backend_Db
extends Horde_Imap_Client_Cache_Backend
{
/** SQL table names. */
const BASE_TABLE = 'horde_imap_client_data';
const MD_TABLE = 'horde_imap_client_metadata';
const MSG_TABLE = 'horde_imap_client_message';
/**
* Handle for the database connection.
*
* @var Horde_Db_Adapter
*/
protected $_db;
/**
* Constructor.
*
* @param array $params Configuration parameters:
* <pre>
* - REQUIRED Parameters:
* - db: (Horde_Db_Adapter) DB object.
* </pre>
*/
public function __construct(array $params = array())
{
if (!isset($params['db'])) {
throw new InvalidArgumentException('Missing db parameter.');
}
parent::__construct($params);
}
/**
*/
protected function _initOb()
{
$this->_db = $this->_params['db'];
}
/**
*/
public function get($mailbox, $uids, $fields, $uidvalid)
{
$this->getMetaData($mailbox, $uidvalid, array('uidvalid'));
$query = $this->_baseSql($mailbox, self::MSG_TABLE);
$query[0] = 'SELECT t.data, t.msguid ' . $query[0];
$uid_query = array();
foreach ($uids as $val) {
$uid_query[] = 't.msguid = ?';
$query[1][] = strval($val);
}
$query[0] .= ' AND (' . implode(' OR ', $uid_query) . ')';
$compress = new Horde_Compress_Fast();
$out = array();
try {
$columns = $this->_db->columns(self::MSG_TABLE);
$res = $this->_db->select($query[0], $query[1]);
foreach ($res as $row) {
try {
$out[$row['msguid']] = @unserialize($compress->decompress(
$columns['data']->binaryToString($row['data'])
));
} catch (Exception $e) {}
}
} catch (Horde_Db_Exception $e) {}
return $out;
}
/**
*/
public function getCachedUids($mailbox, $uidvalid)
{
$this->getMetaData($mailbox, $uidvalid, array('uidvalid'));
$query = $this->_baseSql($mailbox, self::MSG_TABLE);
$query[0] = 'SELECT DISTINCT t.msguid ' . $query[0];
try {
return $this->_db->selectValues($query[0], $query[1]);
} catch (Horde_Db_Exception $e) {
return array();
}
}
/**
*/
public function set($mailbox, $data, $uidvalid)
{
if ($uid = $this->_getUid($mailbox)) {
$res = $this->get($mailbox, array_keys($data), array(), $uidvalid);
} else {
$res = array();
$uid = $this->_createUid($mailbox);
}
$compress = new Horde_Compress_Fast();
foreach ($data as $key => $val) {
if (isset($res[$key])) {
try {
/* Update */
$this->_db->updateBlob(
self::MSG_TABLE,
array('data' => new Horde_Db_Value_Binary($compress->compress(serialize(array_merge($res[$key], $val))))),
array(
'messageid = ? AND msguid = ?',
array($uid, strval($key))
)
);
} catch (Horde_Db_Exception $e) {}
} else {
/* Insert */
try {
$this->_db->insertBlob(
self::MSG_TABLE,
array(
'data' => new Horde_Db_Value_Binary($compress->compress(serialize($val))),
'msguid' => strval($key),
'messageid' => $uid
)
);
} catch (Horde_Db_Exception $e) {}
}
}
/* Update modified time. */
try {
$this->_db->update(
sprintf(
'UPDATE %s SET modified = ? WHERE messageid = ?',
self::BASE_TABLE
),
array(time(), $uid)
);
} catch (Horde_Db_Exception $e) {}
/* Update uidvalidity. */
$this->setMetaData($mailbox, array('uidvalid' => $uidvalid));
}
/**
*/
public function getMetaData($mailbox, $uidvalid, $entries)
{
$query = $this->_baseSql($mailbox, self::MD_TABLE);
$query[0] = 'SELECT t.field, t.data ' . $query[0];
if (!empty($entries)) {
$entries[] = 'uidvalid';
$entry_query = array();
foreach (array_unique($entries) as $val) {
$entry_query[] = 't.field = ?';
$query[1][] = $val;
}
$query[0] .= ' AND (' . implode(' OR ', $entry_query) . ')';
}
try {
if ($res = $this->_db->selectAssoc($query[0], $query[1])) {
$columns = $this->_db->columns(self::MD_TABLE);
foreach ($res as $key => $val) {
switch ($key) {
case 'uidvalid':
$res[$key] = $columns['data']->binaryToString($val);
break;
default:
try {
$res[$key] = @unserialize(
$columns['data']->binaryToString($val)
);
} catch (Exception $e) {}
break;
}
}
if (is_null($uidvalid) ||
!isset($res['uidvalid']) ||
($res['uidvalid'] == $uidvalid)) {
return $res;
}
$this->deleteMailbox($mailbox);
}
} catch (Horde_Db_Exception $e) {}
return array();
}
/**
*/
public function setMetaData($mailbox, $data)
{
if (!($uid = $this->_getUid($mailbox))) {
$uid = $this->_createUid($mailbox);
}
$query = sprintf('SELECT field FROM %s where messageid = ?', self::MD_TABLE);
$values = array($uid);
try {
$fields = $this->_db->selectValues($query, $values);
} catch (Horde_Db_Exception $e) {
return;
}
foreach ($data as $key => $val) {
$val = new Horde_Db_Value_Binary(($key == 'uidvalid') ? $val : serialize($val));
if (in_array($key, $fields)) {
/* Update */
try {
$this->_db->updateBlob(
self::MD_TABLE,
array('data' => $val),
array('field = ? AND messageid = ?', array($key, $uid))
);
} catch (Horde_Db_Exception $e) {}
} else {
/* Insert */
try {
$this->_db->insertBlob(
self::MD_TABLE,
array('data' => $val, 'field' => $key, 'messageid' => $uid)
);
} catch (Horde_Db_Exception $e) {}
}
}
}
/**
*/
public function deleteMsgs($mailbox, $uids)
{
if (empty($uids)) {
return;
}
$query = $this->_baseSql($mailbox);
$query[0] = sprintf(
'DELETE FROM %s WHERE messageid IN (SELECT messageid ' . $query[0] . ')',
self::MSG_TABLE
);
$uid_query = array();
foreach ($uids as $val) {
$uid_query[] = 'msguid = ?';
$query[1][] = strval($val);
}
$query[0] .= ' AND (' . implode(' OR ', $uid_query) . ')';
try {
$this->_db->delete($query[0], $query[1]);
} catch (Horde_Db_Exception $e) {}
}
/**
*/
public function deleteMailbox($mailbox)
{
if (is_null($uid = $this->_getUid($mailbox))) {
return;
}
foreach (array(self::BASE_TABLE, self::MD_TABLE, self::MSG_TABLE) as $val) {
try {
$this->_db->delete(
sprintf('DELETE FROM %s WHERE messageid = ?', $val),
array($uid)
);
} catch (Horde_Db_Exception $e) {}
}
}
/**
*/
public function clear($lifetime)
{
if (is_null($lifetime)) {
try {
$this->_db->delete(sprintf('DELETE FROM %s', self::BASE_TABLE));
$this->_db->delete(sprintf('DELETE FROM %s', self::MD_TABLE));
$this->_db->delete(sprintf('DELETE FROM %s', self::MSG_TABLE));
} catch (Horde_Db_Exception $e) {}
return;
}
$purge = time() - $lifetime;
$sql = 'DELETE FROM %s WHERE messageid IN (SELECT messageid FROM %s WHERE modified < ?)';
foreach (array(self::MD_TABLE, self::MSG_TABLE) as $val) {
try {
$this->_db->delete(
sprintf($sql, $val, self::BASE_TABLE),
array($purge)
);
} catch (Horde_Db_Exception $e) {
}
}
try {
$this->_db->delete(
sprintf('DELETE FROM %s WHERE modified < ?', self::BASE_TABLE),
array($purge)
);
} catch (Horde_Db_Exception $e) {
}
}
/**
* Prepare the base SQL query.
*
* @param string $mailbox The mailbox.
* @param string $join The table to join with the base table.
*
* @return array SQL query and bound parameters.
*/
protected function _baseSql($mailbox, $join = null)
{
$sql = sprintf('FROM %s d', self::BASE_TABLE);
if (!is_null($join)) {
$sql .= sprintf(' INNER JOIN %s t ON d.messageid = t.messageid', $join);
}
return array(
$sql . ' WHERE d.hostspec = ? AND d.port = ? AND d.username = ? AND d.mailbox = ?',
array(
$this->_params['hostspec'],
$this->_params['port'],
$this->_params['username'],
$mailbox
)
);
}
/**
* @param string $mailbox
*
* @return string UID from base table.
*/
protected function _getUid($mailbox)
{
$query = $this->_baseSql($mailbox);
$query[0] = 'SELECT d.messageid ' . $query[0];
try {
return $this->_db->selectValue($query[0], $query[1]);
} catch (Horde_Db_Exception $e) {
return null;
}
}
/**
* @param string $mailbox
*
* @return string UID from base table.
*/
protected function _createUid($mailbox)
{
return $this->_db->insert(
sprintf(
'INSERT INTO %s (hostspec, mailbox, port, username) ' .
'VALUES (?, ?, ?, ?)',
self::BASE_TABLE
),
array(
$this->_params['hostspec'],
$mailbox,
$this->_params['port'],
$this->_params['username']
)
);
}
}

View File

@ -1,421 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* A Horde_HashTable implementation for caching IMAP/POP data.
* Requires the Horde_HashTable and Horde_Pack packages.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.17.0
*/
class Horde_Imap_Client_Cache_Backend_Hashtable
extends Horde_Imap_Client_Cache_Backend
{
/** Separator for CID between mailbox and UID. */
const CID_SEPARATOR = '|';
/**
* The working data for the current pageload. All changes take place to
* this data.
*
* @var array
*/
protected $_data = array();
/**
* HashTable object.
*
* @var Horde_HashTable
*/
protected $_hash;
/**
* Mailbox level data.
*
* @var array
*/
protected $_mbox = array();
/**
* Horde_Pack singleton object.
*
* @var Horde_Pack
*/
protected $_pack;
/**
* List of mailbox/UIDs to update.
* Keys are mailboxes. Values are arrays with three possible keys:
* <pre>
* - d: UIDs to delete
* - m: Was metadata updated?
* - u: UIDs to update
* </pre>
*
* @var array
*/
protected $_update = array();
/**
* Constructor.
*
* @param array $params Configuration parameters:
* <pre>
* - REQUIRED parameters:
* - hashtable: (Horde_HashTable) A HashTable object.
*
* - Optional Parameters:
* - lifetime: (integer) The lifetime of the cache data (in seconds).
* DEFAULT: 604800 seconds (1 week) [@since 2.19.0]
* </pre>
*/
public function __construct(array $params = array())
{
if (!isset($params['hashtable'])) {
throw new InvalidArgumentException('Missing hashtable parameter.');
}
parent::__construct(array_merge(array(
'lifetime' => 604800
), $params));
}
/**
*/
protected function _initOb()
{
$this->_hash = $this->_params['hashtable'];
$this->_pack = new Horde_Pack();
register_shutdown_function(array($this, 'save'));
}
/**
*/
public function get($mailbox, $uids, $fields, $uidvalid)
{
$ret = array();
if (empty($uids)) {
return $ret;
}
$this->_loadUids($mailbox, $uids, $uidvalid);
if (empty($this->_data[$mailbox])) {
return $ret;
}
if (!empty($fields)) {
$fields = array_flip($fields);
}
$ptr = &$this->_data[$mailbox];
$to_delete = array();
foreach ($uids as $val) {
if (isset($ptr[$val])) {
if (is_string($ptr[$val])) {
try {
$ptr[$val] = $this->_pack->unpack($ptr[$val]);
} catch (Horde_Pack_Exception $e) {
$to_delete[] = $val;
continue;
}
}
$ret[$val] = (empty($fields) || empty($ptr[$val]))
? $ptr[$val]
: array_intersect_key($ptr[$val], $fields);
} else {
$to_delete[] = $val;
}
}
$this->deleteMsgs($mailbox, $to_delete);
return $ret;
}
/**
*/
public function getCachedUids($mailbox, $uidvalid)
{
$this->_loadMailbox($mailbox, $uidvalid);
return $this->_mbox[$mailbox]['u']->ids;
}
/**
*/
public function set($mailbox, $data, $uidvalid)
{
$this->_loadUids($mailbox, array_keys($data), $uidvalid);
$d = &$this->_data[$mailbox];
$to_add = array();
foreach ($data as $k => $v) {
if (isset($d[$k]) && is_string($d[$k])) {
try {
$d[$k] = $this->_pack->unpack($d[$k]);
} catch (Horde_Pack_Exception $e) {
continue;
}
}
$d[$k] = (isset($d[$k]) && is_array($d[$k]))
? array_merge($d[$k], $v)
: $v;
$this->_update[$mailbox]['u'][$k] = true;
unset($this->_update[$mailbox]['d'][$k]);
$to_add[] = $k;
}
if (!empty($to_add)) {
$this->_mbox[$mailbox]['u']->add($to_add);
$this->_update[$mailbox]['m'] = true;
}
}
/**
*/
public function getMetaData($mailbox, $uidvalid, $entries)
{
$this->_loadMailbox($mailbox, $uidvalid);
return empty($entries)
? $this->_mbox[$mailbox]['d']
: array_intersect_key($this->_mbox[$mailbox]['d'], array_flip($entries));
}
/**
*/
public function setMetaData($mailbox, $data)
{
$this->_loadMailbox($mailbox, isset($data['uidvalid']) ? $data['uidvalid'] : null);
$this->_mbox[$mailbox]['d'] = array_merge(
$this->_mbox[$mailbox]['d'],
$data
);
$this->_update[$mailbox]['m'] = true;
}
/**
*/
public function deleteMsgs($mailbox, $uids)
{
if (empty($uids)) {
return;
}
$this->_loadMailbox($mailbox);
foreach ($uids as $val) {
unset(
$this->_data[$mailbox][$val],
$this->_update[$mailbox]['u'][$val]
);
$this->_update[$mailbox]['d'][$val] = true;
}
$this->_mbox[$mailbox]['u']->remove($uids);
$this->_update[$mailbox]['m'] = true;
}
/**
*/
public function deleteMailbox($mailbox)
{
/* Do this action immediately, instead of at shutdown. Makes coding
* simpler. */
$this->_loadMailbox($mailbox);
$this->_hash->delete(array_merge(
array($this->_getCid($mailbox)),
array_values($this->_getMsgCids($mailbox, $this->_mbox[$mailbox]['u']))
));
unset(
$this->_data[$mailbox],
$this->_mbox[$mailbox],
$this->_update[$mailbox]
);
}
/**
*/
public function clear($lifetime)
{
/* Only can clear mailboxes we know about. */
foreach (array_keys($this->_mbox) as $val) {
$this->deleteMailbox($val);
}
$this->_data = $this->_mbox = $this->_update = array();
}
/**
* Updates the cache.
*/
public function save()
{
foreach ($this->_update as $mbox => $val) {
try {
if (!empty($val['u'])) {
$ptr = &$this->_data[$mbox];
foreach ($this->_getMsgCids($mbox, array_keys($val['u'])) as $k2 => $v2) {
try {
$this->_hash->set(
$v2,
$this->_pack->pack($ptr[$k2]),
array('expire' => $this->_params['lifetime'])
);
} catch (Horde_Pack_Exception $e) {
$this->deleteMsgs($mbox, array($v2));
$val['d'][] = $v2;
}
}
}
if (!empty($val['d'])) {
$this->_hash->delete(array_values(
$this->_getMsgCids($mbox, $val['d'])
));
}
if (!empty($val['m'])) {
try {
$this->_hash->set(
$this->_getCid($mbox),
$this->_pack->pack($this->_mbox[$mbox]),
array('expire' => $this->_params['lifetime'])
);
} catch (Horde_Pack_Exception $e) {}
}
} catch (Horde_Exception $e) {
}
}
$this->_update = array();
}
/**
* Loads basic mailbox information.
*
* @param string $mailbox The mailbox to load.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*/
protected function _loadMailbox($mailbox, $uidvalid = null)
{
if (!isset($this->_mbox[$mailbox]) &&
($ob = $this->_hash->get($this->_getCid($mailbox)))) {
try {
$this->_mbox[$mailbox] = $this->_pack->unpack($ob);
} catch (Horde_Pack_Exception $e) {}
}
if (isset($this->_mbox[$mailbox])) {
if (is_null($uidvalid) ||
($uidvalid == $this->_mbox[$mailbox]['d']['uidvalid'])) {
return;
}
$this->deleteMailbox($mailbox);
}
$this->_mbox[$mailbox] = array(
// Metadata storage
// By default includes UIDVALIDITY of mailbox.
'd' => array('uidvalid' => $uidvalid),
// List of UIDs
'u' => new Horde_Imap_Client_Ids()
);
}
/**
* Load UIDs by regenerating from the cache.
*
* @param string $mailbox The mailbox to load.
* @param array $uids The UIDs to load.
* @param integer $uidvalid The IMAP uidvalidity value of the mailbox.
*/
protected function _loadUids($mailbox, $uids, $uidvalid = null)
{
if (!isset($this->_data[$mailbox])) {
$this->_data[$mailbox] = array();
}
$this->_loadMailbox($mailbox, $uidvalid);
if (empty($uids)) {
return;
}
$ptr = &$this->_data[$mailbox];
$load = array_flip(
array_diff_key(
$this->_getMsgCids(
$mailbox,
array_unique(array_intersect($this->_mbox[$mailbox]['u']->ids, $uids))
),
$this->_data[$mailbox]
)
);
foreach (array_filter($this->_hash->get(array_keys($load))) as $key => $val) {
$ptr[$load[$key]] = $val;
}
}
/**
* Create the unique ID used to store the mailbox data in the cache.
*
* @param string $mailbox The mailbox to cache.
*
* @return string The cache ID.
*/
protected function _getCid($mailbox)
{
return implode(self::CID_SEPARATOR, array(
'horde_imap_client',
$this->_params['username'],
$mailbox,
$this->_params['hostspec'],
$this->_params['port']
));
}
/**
* Return a list of cache IDs for mailbox/UID pairs.
*
* @param string $mailbox The mailbox to cache.
* @param array $ids The UID list.
*
* @return array List of UIDs => cache IDs.
*/
protected function _getMsgCids($mailbox, $ids)
{
$cid = $this->_getCid($mailbox);
$out = array();
foreach ($ids as $val) {
$out[$val] = $cid . self::CID_SEPARATOR . $val;
}
return $out;
}
}

View File

@ -1,440 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* A MongoDB database implementation for caching IMAP/POP data.
*
* Requires the Horde_Mongo class.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Cache_Backend_Mongo
extends Horde_Imap_Client_Cache_Backend
implements Horde_Mongo_Collection_Index
{
/** Mongo collection names. */
const BASE = 'horde_imap_client_cache_data';
const MD = 'horde_imap_client_cache_metadata';
const MSG = 'horde_imap_client_cache_message';
/** Mongo field names: BASE collection. */
const BASE_HOSTSPEC = 'hostspec';
const BASE_MAILBOX = 'mailbox';
const BASE_MODIFIED = 'modified';
const BASE_PORT = 'port';
const BASE_UID = 'data';
const BASE_USERNAME = 'username';
/** Mongo field names: MD collection. */
const MD_DATA = 'data';
const MD_FIELD = 'field';
const MD_UID = 'uid';
/** Mongo field names: MSG collection. */
const MSG_DATA = 'data';
const MSG_MSGUID = 'msguid';
const MSG_UID = 'uid';
/**
* The MongoDB object for the cache data.
*
* @var MongoDB
*/
protected $_db;
/**
* The list of indices.
*
* @var array
*/
protected $_indices = array(
self::BASE => array(
'base_index_1' => array(
self::BASE_HOSTSPEC => 1,
self::BASE_MAILBOX => 1,
self::BASE_PORT => 1,
self::BASE_USERNAME => 1,
)
),
self::MSG => array(
'msg_index_1' => array(
self::MSG_MSGUID => 1,
self::MSG_UID => 1
)
)
);
/**
* Constructor.
*
* @param array $params Configuration parameters:
* <pre>
* - REQUIRED parameters:
* - mongo_db: (Horde_Mongo_Client) A MongoDB client object.
* </pre>
*/
public function __construct(array $params = array())
{
if (!isset($params['mongo_db'])) {
throw new InvalidArgumentException('Missing mongo_db parameter.');
}
parent::__construct($params);
}
/**
*/
protected function _initOb()
{
$this->_db = $this->_params['mongo_db']->selectDB(null);
}
/**
*/
public function get($mailbox, $uids, $fields, $uidvalid)
{
$this->getMetaData($mailbox, $uidvalid, array('uidvalid'));
if (!($uid = $this->_getUid($mailbox))) {
return array();
}
$out = array();
$query = array(
self::MSG_MSGUID => array('$in' => array_map('strval', $uids)),
self::MSG_UID => $uid
);
try {
$cursor = $this->_db->selectCollection(self::MSG)->find(
$query,
array(self::MSG_DATA => true, self::MSG_MSGUID => true)
);
foreach ($cursor as $val) {
try {
$out[$val[self::MSG_MSGUID]] = $this->_value($val[self::MSG_DATA]);
} catch (Exception $e) {}
}
} catch (MongoException $e) {}
return $out;
}
/**
*/
public function getCachedUids($mailbox, $uidvalid)
{
$this->getMetaData($mailbox, $uidvalid, array('uidvalid'));
if (!($uid = $this->_getUid($mailbox))) {
return array();
}
$out = array();
$query = array(
self::MSG_UID => $uid
);
try {
$cursor = $this->_db->selectCollection(self::MSG)->find(
$query, array(self::MSG_MSGUID => true)
);
foreach ($cursor as $val) {
$out[] = $val[self::MSG_MSGUID];
}
} catch (MongoException $e) {}
return $out;
}
/**
*/
public function set($mailbox, $data, $uidvalid)
{
if ($uid = $this->_getUid($mailbox)) {
$res = $this->get($mailbox, array_keys($data), array(), $uidvalid);
} else {
$res = array();
$uid = $this->_createUid($mailbox);
}
$coll = $this->_db->selectCollection(self::MSG);
foreach ($data as $key => $val) {
try {
if (isset($res[$key])) {
$coll->update(array(
self::MSG_MSGUID => strval($key),
self::MSG_UID => $uid
), array(
self::MSG_DATA => $this->_value(array_merge($res[$key], $val)),
self::MSG_MSGUID => strval($key),
self::MSG_UID => $uid
));
} else {
$doc = array(
self::MSG_DATA => $this->_value($val),
self::MSG_MSGUID => strval($key),
self::MSG_UID => $uid
);
$coll->insert($doc);
}
} catch (MongoException $e) {}
}
/* Update modified time. */
try {
$this->_db->selectCollection(self::BASE)->update(
array(self::BASE_UID => $uid),
array(self::BASE_MODIFIED => time())
);
} catch (MongoException $e) {}
/* Update uidvalidity. */
$this->setMetaData($mailbox, array('uidvalid' => $uidvalid));
}
/**
*/
public function getMetaData($mailbox, $uidvalid, $entries)
{
if (!($uid = $this->_getUid($mailbox))) {
return array();
}
$out = array();
$query = array(
self::MD_UID => $uid
);
if (!empty($entries)) {
$entries[] = 'uidvalid';
$query[self::MD_FIELD] = array(
'$in' => array_unique($entries)
);
}
try {
$cursor = $this->_db->selectCollection(self::MD)->find(
$query,
array(self::MD_DATA => true, self::MD_FIELD => true)
);
foreach ($cursor as $val) {
try {
$out[$val[self::MD_FIELD]] = $this->_value($val[self::MD_DATA]);
} catch (Exception $e) {}
}
if (is_null($uidvalid) ||
!isset($out['uidvalid']) ||
($out['uidvalid'] == $uidvalid)) {
return $out;
}
$this->deleteMailbox($mailbox);
} catch (MongoException $e) {}
return array();
}
/**
*/
public function setMetaData($mailbox, $data)
{
if (!($uid = $this->_getUid($mailbox))) {
$uid = $this->_createUid($mailbox);
}
$coll = $this->_db->selectCollection(self::MD);
foreach ($data as $key => $val) {
try {
$coll->update(
array(
self::MD_FIELD => $key,
self::MD_UID => $uid
),
array(
self::MD_DATA => $this->_value($val),
self::MD_FIELD => $key,
self::MD_UID => $uid
),
array('upsert' => true)
);
} catch (MongoException $e) {}
}
}
/**
*/
public function deleteMsgs($mailbox, $uids)
{
if (!empty($uids) && ($uid = $this->_getUid($mailbox))) {
try {
$this->_db->selectCollection(self::MSG)->remove(array(
self::MSG_MSGUID => array(
'$in' => array_map('strval', $uids)
),
self::MSG_UID => $uid
));
} catch (MongoException $e) {}
}
}
/**
*/
public function deleteMailbox($mailbox)
{
if (!($uid = $this->_getUid($mailbox))) {
return;
}
foreach (array(self::BASE, self::MD, self::MSG) as $val) {
try {
$this->_db->selectCollection($val)
->remove(array('uid' => $uid));
} catch (MongoException $e) {}
}
}
/**
*/
public function clear($lifetime)
{
if (is_null($lifetime)) {
foreach (array(self::BASE, self::MD, self::MSG) as $val) {
$this->_db->selectCollection($val)->drop();
}
return;
}
$query = array(
self::BASE_MODIFIED => array('$lt' => (time() - $lifetime))
);
$uids = array();
try {
$cursor = $this->_db->selectCollection(self::BASE)->find($query);
foreach ($cursor as $val) {
$uids[] = strval($val['_id']);
}
} catch (MongoException $e) {}
if (empty($uids)) {
return;
}
foreach (array(self::BASE, self::MD, self::MSG) as $val) {
try {
$this->_db->selectCollection($val)
->remove(array('uid' => array('$in' => $uids)));
} catch (MongoException $e) {}
}
}
/**
* Return the UID for a mailbox/user/server combo.
*
* @param string $mailbox Mailbox name.
*
* @return string UID from base table.
*/
protected function _getUid($mailbox)
{
$query = array(
self::BASE_HOSTSPEC => $this->_params['hostspec'],
self::BASE_MAILBOX => $mailbox,
self::BASE_PORT => $this->_params['port'],
self::BASE_USERNAME => $this->_params['username']
);
try {
if ($result = $this->_db->selectCollection(self::BASE)->findOne($query)) {
return strval($result['_id']);
}
} catch (MongoException $e) {}
return null;
}
/**
* Create and return the UID for a mailbox/user/server combo.
*
* @param string $mailbox Mailbox name.
*
* @return string UID from base table.
*/
protected function _createUid($mailbox)
{
$doc = array(
self::BASE_HOSTSPEC => $this->_params['hostspec'],
self::BASE_MAILBOX => $mailbox,
self::BASE_PORT => $this->_params['port'],
self::BASE_USERNAME => $this->_params['username']
);
$this->_db->selectCollection(self::BASE)->insert($doc);
return $this->_getUid($mailbox);
}
/**
* Convert data from/to storage format.
*
* @param mixed|MongoBinData $data The data object.
*
* @return mixed|MongoBinData The converted data.
*/
protected function _value($data)
{
static $compress;
if (!isset($compress)) {
$compress = new Horde_Compress_Fast();
}
return ($data instanceof MongoBinData)
? @unserialize($compress->decompress($data->bin))
: new MongoBinData(
$compress->compress(serialize($data)), MongoBinData::BYTE_ARRAY
);
}
/* Horde_Mongo_Collection_Index methods. */
/**
*/
public function checkMongoIndices()
{
foreach ($this->_indices as $key => $val) {
if (!$this->_params['mongo_db']->checkIndices($key, $val)) {
return false;
}
}
return true;
}
/**
*/
public function createMongoIndices()
{
foreach ($this->_indices as $key => $val) {
$this->_params['mongo_db']->createIndices($key, $val);
}
}
}

View File

@ -1,79 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* A null backend class for storing cached IMAP/POP data.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Cache_Backend_Null
extends Horde_Imap_Client_Cache_Backend
{
/**
*/
public function get($mailbox, $uids, $fields, $uidvalid)
{
return array();
}
/**
*/
public function getCachedUids($mailbox, $uidvalid)
{
return array();
}
/**
*/
public function set($mailbox, $data, $uidvalid)
{
}
/**
*/
public function getMetaData($mailbox, $uidvalid, $entries)
{
return array(
'uidvalid' => 0
);
}
/**
*/
public function setMetaData($mailbox, $data)
{
}
/**
*/
public function deleteMsgs($mailbox, $uids)
{
}
/**
*/
public function deleteMailbox($mailbox)
{
}
/**
*/
public function clear($lifetime)
{
}
}

View File

@ -1,188 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* ACL rights for a mailbox (see RFC 2086/4314).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Acl extends Horde_Imap_Client_Data_AclCommon implements ArrayAccess, IteratorAggregate, Serializable
{
/**
* ACL rights.
*
* @var array
*/
protected $_rights;
/**
* Constructor.
*
* @param string $rights The rights (see RFC 4314 [2.1]).
*/
public function __construct($rights = '')
{
$this->_rights = str_split($rights);
$this->_normalize();
}
/**
* String representation of the ACL.
*
* @return string String representation (RFC 4314 compliant).
*/
public function __toString()
{
return implode('', $this->_rights);
}
/**
* Computes the difference to another rights string.
* Virtual rights are ignored.
*
* @param string $rights The rights to compute against.
*
* @return array Two element array: added and removed.
*/
public function diff($rights)
{
$rlist = array_diff(str_split($rights), array_keys($this->_virtual));
return array(
'added' => implode('', array_diff($rlist, $this->_rights)),
'removed' => implode('', array_diff($this->_rights, $rlist))
);
}
/**
* Normalize virtual rights (see RFC 4314 [2.1.1]).
*/
protected function _normalize()
{
/* Clients conforming to RFC 4314 MUST ignore the virtual ACL_CREATE
* and ACL_DELETE rights. See RFC 4314 [2.1]. However, we still need
* to handle these rights when dealing with RFC 2086 servers since
* we are abstracting out use of ACL_CREATE/ACL_DELETE to their
* component RFC 4314 rights. */
foreach ($this->_virtual as $key => $val) {
foreach ($val as $right) {
if ($this[$right]) {
foreach (array_keys($this->_virtual) as $virtual) {
unset($this[$virtual]);
}
return;
}
}
}
foreach ($this->_virtual as $key => $val) {
if ($this[$key]) {
unset($this[$key]);
$this->_rights = array_unique(array_merge($this->_rights, $val));
}
}
}
/* ArrayAccess methods. */
/**
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return $this[$offset];
}
/**
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
return in_array($offset, $this->_rights);
}
/**
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
if ($value) {
if (!$this[$offset]) {
$this->_rights[] = $offset;
$this->_normalize();
}
} elseif ($this[$offset]) {
if (isset($this->_virtual[$offset])) {
foreach ($this->_virtual[$offset] as $val) {
unset($this[$val]);
}
}
unset($this[$offset]);
}
}
/**
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
$this->_rights = array_values(array_diff($this->_rights, array($offset)));
}
/* IteratorAggregate method. */
#[ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->_rights);
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version changed.');
}
$this->__unserialize($data);
}
/**
* @return array
*/
public function __serialize()
{
return array(
'rights' => $this->_rights
);
}
public function __unserialize(array $data)
{
$this->_rights = $data['rights'];
}
}

View File

@ -1,72 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Provides common methods shared in all ACL classes (see RFC 2086/4314).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_AclCommon
{
/** Constants for getString(). */
const RFC_2086 = 1;
const RFC_4314 = 2;
/**
* List of virtual rights (RFC 4314 [2.1.1]).
*
* @var array
*/
protected $_virtual = array(
Horde_Imap_Client::ACL_CREATE => array(
Horde_Imap_Client::ACL_CREATEMBOX,
Horde_Imap_Client::ACL_DELETEMBOX
),
Horde_Imap_Client::ACL_DELETE => array(
Horde_Imap_Client::ACL_DELETEMSGS,
// Don't put this first - we do checks on the existence of the
// first element in this array to determine the RFC type, and this
// is duplicate of right contained in ACL_CREATE.
Horde_Imap_Client::ACL_DELETEMBOX,
Horde_Imap_Client::ACL_EXPUNGE
)
);
/**
* Returns the raw string to use in IMAP server calls.
*
* @param integer $type The RFC type to use (RFC_* constant).
*
* @return string The string representation of the ACL.
*/
public function getString($type = self::RFC_4314)
{
$acl = strval($this);
if ($type == self::RFC_2086) {
foreach ($this->_virtual as $key => $val) {
$acl = str_replace($val, '', $acl, $count);
if ($count) {
$acl .= $key;
}
}
}
return $acl;
}
}

View File

@ -1,25 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* ACL *negative* rights for a mailbox (see RFC 2086/4314 [2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_AclNegative extends Horde_Imap_Client_Data_Acl
{
}

View File

@ -1,231 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Available ACL rights for a mailbox/identifier (see RFC 2086/4314).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_AclRights extends Horde_Imap_Client_Data_AclCommon implements ArrayAccess, Iterator, Serializable
{
/**
* ACL optional rights.
*
* @var array
*/
protected $_optional = array();
/**
* ACL required rights.
*
* @var array
*/
protected $_required = array();
/**
* Constructor.
*
* @param array $required The required rights (see RFC 4314 [2.1]).
* @param array $optional The optional rights (see RFC 4314 [2.1]).
*/
public function __construct(array $required = array(),
array $optional = array())
{
$this->_required = $required;
foreach ($optional as $val) {
foreach (str_split($val) as $right) {
$this->_optional[$right] = $val;
}
}
$this->_normalize();
}
/**
* String representation of the ACL.
*
* @return string String representation (RFC 4314 compliant).
*
*/
public function __toString()
{
return implode('', array_keys(array_flip(array_merge(array_values($this->_required), array_keys($this->_optional)))));
}
/**
* Normalize virtual rights (see RFC 4314 [2.1.1]).
*/
protected function _normalize()
{
/* Clients conforming to RFC 4314 MUST ignore the virtual ACL_CREATE
* and ACL_DELETE rights. See RFC 4314 [2.1]. However, we still need
* to handle these rights when dealing with RFC 2086 servers since
* we are abstracting out use of ACL_CREATE/ACL_DELETE to their
* component RFC 4314 rights. */
foreach ($this->_virtual as $key => $val) {
if (isset($this->_optional[$key])) {
unset($this->_optional[$key]);
foreach ($val as $val2) {
$this->_optional[$val2] = implode('', $val);
}
} elseif (($pos = array_search($key, $this->_required)) !== false) {
unset($this->_required[$pos]);
$this->_required = array_unique(array_merge($this->_required, $val));
}
}
}
/* ArrayAccess methods. */
/**
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return (bool)$this[$offset];
}
/**
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
if (isset($this->_optional[$offset])) {
return $this->_optional[$offset];
}
$pos = array_search($offset, $this->_required);
return ($pos === false)
? null
: $this->_required[$pos];
}
/**
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->_optional[$offset] = $value;
$this->_normalize();
}
/**
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->_optional[$offset]);
$this->_required = array_values(array_diff($this->_required, array($offset)));
if (isset($this->_virtual[$offset])) {
foreach ($this->_virtual[$offset] as $val) {
unset($this[$val]);
}
}
}
/* Iterator methods. */
/**
*/
#[ReturnTypeWillChange]
public function current()
{
$val = current($this->_required);
return is_null($val)
? current($this->_optional)
: $val;
}
/**
*/
#[ReturnTypeWillChange]
public function key()
{
$key = key($this->_required);
return is_null($key)
? key($this->_optional)
: $key;
}
/**
*/
#[ReturnTypeWillChange]
public function next()
{
if (key($this->_required) === null) {
next($this->_optional);
} else {
next($this->_required);
}
}
/**
*/
#[ReturnTypeWillChange]
public function rewind()
{
reset($this->_required);
reset($this->_optional);
}
/**
*/
#[ReturnTypeWillChange]
public function valid()
{
return ((key($this->_required) !== null) ||
(key($this->_optional) !== null));
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version changed.');
}
$this->__unserialize($data);
}
/**
* @return array
*/
public function __serialize()
{
return [$this->_required, $this->_optional];
}
public function __unserialize(array $data)
{
list($this->_required, $this->_optional) = $data;
}
}

View File

@ -1,231 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* getBaseSubject() code adapted from imap-base-subject.c (Dovecot 1.2)
* Original code released under the LGPL-2.1
* Copyright (c) 2002-2008 Timo Sirainen <tss@iki.fi>
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2002-2008 Timo Sirainen
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Determines the "base subject" of a string (RFC 5256 [2.1]).
*
* @author Timo Sirainen <tss@iki.fi>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2002-2008 Timo Sirainen
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_BaseSubject
{
/**
* The base subject.
*
* @var string
*/
protected $_subject;
/**
* Constructor.
*
* @param string $str The subject string.
* @param array $opts Additional options:
* - keepblob: (boolean) Don't remove any "blob" information (i.e. text
* leading text between square brackets) from string.
*
* @return string The cleaned up subject string.
*/
public function __construct($str, array $opts = array())
{
// Rule 1a: MIME decode.
$str = Horde_Mime::decode($str);
// Rule 1b: Remove superfluous whitespace.
$str = preg_replace("/[\t\r\n ]+/", ' ', $str);
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($opts['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($opts['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));
$this->_subject = strval($str);
}
/**
* Return the "base subject" defined in RFC 5256 [2.1].
*
* @return string The base subject.
*/
public function __toString()
{
return $this->_subject;
}
/**
* 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 (!strlen($str)) {
return $ret;
}
if ($len = strspn($str, " \t")) {
$str = substr($str, $len);
$ret = true;
}
$i = 0;
if (!$keepblob) {
while (isset($str[$i]) && ($str[$i] === '[')) {
if (($i = $this->_removeBlob($str, $i)) === false) {
return $ret;
}
}
}
if (stripos($str, 're', $i) === 0) {
$i += 2;
} elseif (stripos($str, 'fw', $i) === 0) {
$i += (stripos($str, 'fwd', $i) === 0) ? 3 : 2;
} else {
return $ret;
}
$i += strspn($str, " \t", $i);
if (!$keepblob) {
while (isset($str[$i]) && ($str[$i] === '[')) {
if (($i = $this->_removeBlob($str, $i)) === false) {
return $ret;
}
}
}
if (!isset($str[$i]) || ($str[$i] !== ':')) {
return $ret;
}
$str = substr($str, ++$i);
return true;
}
/**
* Remove "[...]" text.
*
* @param string $str The subject string.
* @param integer $i Current position.
*
* @return boolean|integer False if blob was not found, otherwise the
* string position of the first non-blob char.
*/
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;
}
}

View File

@ -1,234 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Query the capabilities of a server.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.24.0
*/
class Horde_Imap_Client_Data_Capability
implements Serializable, SplSubject
{
/**
* Capability data.
*
* @var array
*/
protected $_data = array();
/**
* Observers.
*
* @var array
*/
protected $_observers = array();
/**
* Add a capability (and optional parameters).
*
* @param string $capability The capability to add.
* @param mixed $params A parameter (or array of parameters) to add.
*/
public function add($capability, $params = null)
{
$capability = Horde_String::upper($capability);
if (is_null($params)) {
if (isset($this->_data[$capability])) {
return;
}
$params = true;
} else {
if (!is_array($params)) {
$params = array($params);
}
$params = array_map('Horde_String::upper', $params);
if (isset($this->_data[$capability]) &&
is_array($this->_data[$capability])) {
$params = array_merge($this->_data[$capability], $params);
}
}
$this->_data[$capability] = $params;
$this->notify();
}
/**
* Remove a capability.
*
* @param string $capability The capability to remove.
* @param string $params A parameter (or array of parameters) to
* remove from the capability.
*/
public function remove($capability, $params = null)
{
$capability = Horde_String::upper($capability);
if (is_null($params)) {
unset($this->_data[$capability]);
} elseif (isset($this->_data[$capability])) {
if (!is_array($params)) {
$params = array($params);
}
$params = array_map('Horde_String::upper', $params);
$this->_data[$capability] = is_array($this->_data[$capability])
? array_diff($this->_data[$capability], $params)
: array();
if (empty($this->_data[$capability])) {
unset($this->_data[$capability]);
}
}
$this->notify();
}
/**
* Returns whether the server supports the given capability.
*
* @param string $capability The capability string to query.
* @param string $parameter If set, require the parameter to exist.
*
* @return boolean True if the capability (and parameter) exist.
*/
public function query($capability, $parameter = null)
{
$capability = Horde_String::upper($capability);
if (!isset($this->_data[$capability])) {
return false;
}
return is_null($parameter) ?:
(is_array($this->_data[$capability]) &&
in_array(Horde_String::upper($parameter), $this->_data[$capability]));
}
/**
* Return the list of parameters for an extension.
*
* @param string $capability The capability string to query.
*
* @return array An array of parameters if the extension exists and
* supports parameters. Otherwise, an empty array.
*/
public function getParams($capability)
{
return ($this->query($capability) && is_array($out = $this->_data[Horde_String::upper($capability)]))
? $out
: array();
}
/**
* Is the extension enabled?
*
* @param string $capability The extension (+ parameter) to query. If
* null, returns all enabled extensions.
*
* @return mixed If $capability is null, return all enabled extensions.
* Otherwise, true if the extension (+ parameter) is
* enabled.
*/
public function isEnabled($capability = null)
{
return is_null($capability)
? array()
: false;
}
/**
* Returns the raw data.
*
* @deprecated
*
* @return array Capability data.
*/
public function toArray()
{
return $this->_data;
}
/* SplSubject methods. */
/**
*/
#[ReturnTypeWillChange]
public function attach(SplObserver $observer)
{
$this->detach($observer);
$this->_observers[] = $observer;
}
/**
*/
#[ReturnTypeWillChange]
public function detach(SplObserver $observer)
{
if (($key = array_search($observer, $this->_observers, true)) !== false) {
unset($this->_observers[$key]);
}
}
/**
* Notification is triggered internally whenever the object's internal
* data storage is altered.
*/
#[ReturnTypeWillChange]
public function notify()
{
foreach ($this->_observers as $val) {
$val->update($this);
}
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version change.');
}
$this->__unserialize();
}
/**
* @return array
*/
public function __serialize()
{
return $this->_data;
}
public function __unserialize(array $data)
{
$this->_data = $data;
}
}

View File

@ -1,117 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Query the capabilities of an IMAP server.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.24.0
*
* @property-read integer $cmdlength Allowable command length (in octets).
*/
class Horde_Imap_Client_Data_Capability_Imap
extends Horde_Imap_Client_Data_Capability
{
/**
* The list of enabled extensions.
*
* @var array
*/
protected $_enabled = array();
/**
*/
public function __get($name)
{
switch ($name) {
case 'cmdlength':
/* RFC 2683 [3.2.1.5] originally recommended that lines should
* be limited to "approximately 1000 octets". However, servers
* should allow a command line of at least "8000 octets".
* RFC 7162 [4] updates the recommendation to 8192 octets.
* As a compromise, assume all modern IMAP servers handle
* ~2000 octets and, if CONDSTORE/QRESYNC is supported, assume
* they can handle ~8000 octets. (Don't need dependency support
* checks here - the simple presence of CONDSTORE/QRESYNC is
* enough to trigger.) */
return (isset($this->_data['CONDSTORE']) || isset($this->_data['QRESYNC']))
? 8000
: 2000;
}
}
/**
*/
public function query($capability, $parameter = null)
{
if (parent::query($capability, $parameter)) {
return true;
}
switch (Horde_String::upper($capability)) {
case 'CONDSTORE':
case 'ENABLE':
/* RFC 7162 [3.2.3] - QRESYNC implies CONDSTORE and ENABLE. */
return (is_null($parameter) && $this->query('QRESYNC'));
case 'UTF8':
/* RFC 6855 [3] - UTF8=ONLY implies UTF8=ACCEPT. */
return ((Horde_String::upper($parameter) === 'ACCEPT') &&
$this->query('UTF8', 'ONLY'));
}
return false;
}
/**
*/
public function isEnabled($capability = null)
{
return is_null($capability)
? $this->_enabled
: in_array(Horde_String::upper($capability), $this->_enabled);
}
/**
* Set a capability as enabled/disabled.
*
* @param array $capability A capability (+ parameter).
* @param boolean $enable If true, enables the capability.
*/
public function enable($capability, $enable = true)
{
$capability = Horde_String::upper($capability);
$enabled = $this->isEnabled($capability);
if ($enable && !$enabled) {
switch ($capability) {
case 'QRESYNC':
/* RFC 7162 [3.2.3] - Enabling QRESYNC also implies enabling
* of CONDSTORE. */
$this->enable('CONDSTORE');
break;
}
$this->_enabled[] = $capability;
$this->notify();
} elseif (!$enable && $enabled) {
$this->_enabled = array_diff($this->_enabled, array($capability));
$this->notify();
}
}
}

View File

@ -1,238 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Envelope data as returned by the IMAP FETCH command (RFC 3501 [7.4.2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*
* @todo $date should return null if it doesn't exist.
*
* @property Horde_Mail_Rfc822_List $bcc Bcc address(es).
* @property Horde_Mail_Rfc822_List $cc Cc address(es).
* @property Horde_Imap_Client_DateTime $date Message date.
* @property Horde_Mail_Rfc822_List $from From address(es).
* @property string $in_reply_to Message-ID of the message replied to.
* @property string $message_id Message-ID of the message.
* @property Horde_Mail_Rfc822_List $reply_to Reply-to address(es).
* @property Horde_Mail_Rfc822_List $sender Sender address.
* @property string $subject Subject.
* @property Horde_Mail_Rfc822_List $to To address(es).
*/
class Horde_Imap_Client_Data_Envelope implements Serializable
{
/* Serializable version. */
const VERSION = 3;
/**
* Data object.
*
* @var Horde_Mime_Headers
*/
protected $_data;
/**
* Constructor.
*
* @var array $data An array of property names (keys) and values to set
* in this object.
*/
public function __construct(array $data = array())
{
$this->_data = new Horde_Mime_Headers();
foreach ($data as $key => $val) {
$this->$key = $val;
}
}
/**
*/
public function __get($name)
{
$name = $this->_normalizeProperty($name);
switch ($name) {
case 'bcc':
case 'cc':
case 'from':
case 'reply-to':
case 'sender':
case 'to':
if ($h = $this->_data[$name]) {
return $h->getAddressList(true);
}
if (in_array($name, array('sender', 'reply-to'))) {
return $this->from;
}
break;
case 'date':
if ($val = $this->_data['date']) {
return new Horde_Imap_Client_DateTime($val->value);
}
break;
case 'in-reply-to':
case 'message-id':
case 'subject':
if ($val = $this->_data[$name]) {
return $val->value;
}
break;
}
// Default values.
switch ($name) {
case 'bcc':
case 'cc':
case 'from':
case 'to':
return new Horde_Mail_Rfc822_List();
case 'date':
return new Horde_Imap_Client_DateTime();
case 'in-reply-to':
case 'message-id':
case 'subject':
return '';
}
return null;
}
/**
*/
public function __set($name, $value)
{
if (!strlen($value)) {
return;
}
$name = $this->_normalizeProperty($name);
switch ($name) {
case 'bcc':
case 'cc':
case 'date':
case 'from':
case 'in-reply-to':
case 'message-id':
case 'reply-to':
case 'sender':
case 'subject':
case 'to':
switch ($name) {
case 'from':
if ($this->reply_to->match($value)) {
unset($this->_data['reply-to']);
}
if ($this->sender->match($value)) {
unset($this->_data['sender']);
}
break;
case 'reply-to':
case 'sender':
if ($this->from->match($value)) {
unset($this->_data[$name]);
return;
}
break;
}
$this->_data->addHeader($name, $value);
break;
}
}
/**
*/
public function __isset($name)
{
$name = $this->_normalizeProperty($name);
switch ($name) {
case 'reply-to':
case 'sender':
if (isset($this->_data[$name])) {
return true;
}
$name = 'from';
break;
}
return isset($this->_data[$name]);
}
/**
*/
protected function _normalizeProperty($name)
{
switch ($name) {
case 'in_reply_to':
return 'in-reply-to';
case 'message_id':
return 'message-id';
case 'reply_to':
return 'reply-to';
}
return $name;
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$this->__unserialize(@unserialize($data));
}
/**
* @return array
*/
public function __serialize()
{
return array(
'd' => $this->_data,
'v' => self::VERSION,
);
}
public function __unserialize(array $data)
{
if (empty($data['v']) || $data['v'] != self::VERSION) {
throw new Exception('Cache version change');
}
$this->_data = $data['d'];
}
}

View File

@ -1,666 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object containing data returned by the Horde_Imap_Client_Base#fetch()
* command.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Fetch
{
/** Header formatting constants. */
const HEADER_PARSE = 1;
const HEADER_STREAM = 2;
/**
* Internal data array.
*
* @var array
*/
protected $_data = array();
/**
*/
public function __clone()
{
$this->_data = unserialize(serialize($this->_data));
}
/**
* Set the full message property.
*
* @param mixed $msg The full message text, as either a string or stream
* resource.
*/
public function setFullMsg($msg)
{
$this->_data[Horde_Imap_Client::FETCH_FULLMSG] = $this->_setMixed($msg);
}
/**
* Returns the full message.
*
* @param boolean $stream Return as a stream?
*
* @return mixed The full text of the entire message.
*/
public function getFullMsg($stream = false)
{
return $this->_msgText(
$stream,
isset($this->_data[Horde_Imap_Client::FETCH_FULLMSG])
? $this->_data[Horde_Imap_Client::FETCH_FULLMSG]
: null
);
}
/**
* Set the message structure.
*
* @param Horde_Mime_Part $structure The base MIME part of the message.
*/
public function setStructure(Horde_Mime_Part $structure)
{
$this->_data[Horde_Imap_Client::FETCH_STRUCTURE] = $structure;
}
/**
* Get the message structure.
*
* @return Horde_Mime_Part $structure The base MIME part of the message.
*/
public function getStructure()
{
return isset($this->_data[Horde_Imap_Client::FETCH_STRUCTURE])
? clone $this->_data[Horde_Imap_Client::FETCH_STRUCTURE]
: new Horde_Mime_Part();
}
/**
* Set a header entry.
*
* @param string $label The search label.
* @param mixed $data Either a Horde_Mime_Headers object or the raw
* header text.
*/
public function setHeaders($label, $data)
{
if ($data instanceof Horde_Stream) {
$data = $data->stream;
}
$this->_data[Horde_Imap_Client::FETCH_HEADERS][$label] = $data;
}
/**
* Get a header entry.
*
* @param string $label The search label.
* @param integer $format The return format. If self::HEADER_PARSE,
* returns a Horde_Mime_Headers object. If
* self::HEADER_STREAM, returns a stream.
* Otherwise, returns header text.
*
* @return mixed See $format.
*/
public function getHeaders($label, $format = 0)
{
return $this->_getHeaders(
$label,
$format,
Horde_Imap_Client::FETCH_HEADERS
);
}
/**
* Set a header text entry.
*
* @param string $id The MIME ID.
* @param mixed $text The header text, as either a string or stream
* resource.
*/
public function setHeaderText($id, $text)
{
$this->_data[Horde_Imap_Client::FETCH_HEADERTEXT][$id] = $this->_setMixed($text);
}
/**
* Get a header text entry.
*
* @param string $id The MIME ID.
* @param integer $format The return format. If self::HEADER_PARSE,
* returns a Horde_Mime_Headers object. If
* self::HEADER_STREAM, returns a stream.
* Otherwise, returns header text.
*
* @return mixed See $format.
*/
public function getHeaderText($id = 0, $format = 0)
{
return $this->_getHeaders(
$id,
$format,
Horde_Imap_Client::FETCH_HEADERTEXT
);
}
/**
* Set a MIME header entry.
*
* @param string $id The MIME ID.
* @param mixed $text The header text, as either a string or stream
* resource.
*/
public function setMimeHeader($id, $text)
{
$this->_data[Horde_Imap_Client::FETCH_MIMEHEADER][$id] = $this->_setMixed($text);
}
/**
* Get a MIME header entry.
*
* @param string $id The MIME ID.
* @param integer $format The return format. If self::HEADER_PARSE,
* returns a Horde_Mime_Headers object. If
* self::HEADER_STREAM, returns a stream.
* Otherwise, returns header text.
*
* @return mixed See $format.
*/
public function getMimeHeader($id, $format = 0)
{
return $this->_getHeaders(
$id,
$format,
Horde_Imap_Client::FETCH_MIMEHEADER
);
}
/**
* Set a body part entry.
*
* @param string $id The MIME ID.
* @param mixed $text The body part text, as either a string or stream
* resource.
* @param string $decode Either '8bit', 'binary', or null.
*/
public function setBodyPart($id, $text, $decode = null)
{
$this->_data[Horde_Imap_Client::FETCH_BODYPART][$id] = array(
'd' => $decode,
't' => $this->_setMixed($text)
);
}
/**
* Get a body part entry.
*
* @param string $id The MIME ID.
* @param boolean $stream Return as a stream?
*
* @return mixed The full text of the body part.
*/
public function getBodyPart($id, $stream = false)
{
return $this->_msgText(
$stream,
isset($this->_data[Horde_Imap_Client::FETCH_BODYPART][$id])
? $this->_data[Horde_Imap_Client::FETCH_BODYPART][$id]['t']
: null
);
}
/**
* Determines if/how a body part was MIME decoded on the server.
*
* @param string $id The MIME ID.
*
* @return string Either '8bit', 'binary', or null.
*/
public function getBodyPartDecode($id)
{
return isset($this->_data[Horde_Imap_Client::FETCH_BODYPART][$id])
? $this->_data[Horde_Imap_Client::FETCH_BODYPART][$id]['d']
: null;
}
/**
* Set the body part size for a body part.
*
* @param string $id The MIME ID.
* @param integer $size The size (in bytes).
*/
public function setBodyPartSize($id, $size)
{
$this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id] = intval($size);
}
/**
* Returns the body part size, if returned by the server.
*
* @param string $id The MIME ID.
*
* @return integer The body part size, in bytes.
*/
public function getBodyPartSize($id)
{
return isset($this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id])
? $this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id]
: null;
}
/**
* Set a body text entry.
*
* @param string $id The MIME ID.
* @param mixed $text The body part text, as either a string or stream
* resource.
*/
public function setBodyText($id, $text)
{
$this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id] = $this->_setMixed($text);
}
/**
* Get a body text entry.
*
* @param string $id The MIME ID.
* @param boolean $stream Return as a stream?
*
* @return mixed The full text of the body text.
*/
public function getBodyText($id = 0, $stream = false)
{
return $this->_msgText(
$stream,
isset($this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id])
? $this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id]
: null
);
}
/**
* Set envelope data.
*
* @param array $data The envelope data to pass to the Envelope object
* constructor, or an Envelope object.
*/
public function setEnvelope($data)
{
$this->_data[Horde_Imap_Client::FETCH_ENVELOPE] = is_array($data)
? new Horde_Imap_Client_Data_Envelope($data)
: $data;
}
/**
* Get envelope data.
*
* @return Horde_Imap_Client_Data_Envelope An envelope object.
*/
public function getEnvelope()
{
return isset($this->_data[Horde_Imap_Client::FETCH_ENVELOPE])
? clone $this->_data[Horde_Imap_Client::FETCH_ENVELOPE]
: new Horde_Imap_Client_Data_Envelope();
}
/**
* Set IMAP flags.
*
* @param array $flags An array of IMAP flags.
*/
public function setFlags(array $flags)
{
$this->_data[Horde_Imap_Client::FETCH_FLAGS] = array_map(
'Horde_String::lower',
array_map('trim', $flags)
);
}
/**
* Get IMAP flags.
*
* @return array An array of IMAP flags (all flags in lowercase).
*/
public function getFlags()
{
return isset($this->_data[Horde_Imap_Client::FETCH_FLAGS])
? $this->_data[Horde_Imap_Client::FETCH_FLAGS]
: array();
}
/**
* Set IMAP internal date.
*
* @param mixed $date Either a Horde_Imap_Client_DateTime object or a
* date string.
*/
public function setImapDate($date)
{
$this->_data[Horde_Imap_Client::FETCH_IMAPDATE] = is_object($date)
? $date
: new Horde_Imap_Client_DateTime($date);
}
/**
* Get internal IMAP date.
*
* @return Horde_Imap_Client_DateTime A date object.
*/
public function getImapDate()
{
return isset($this->_data[Horde_Imap_Client::FETCH_IMAPDATE])
? clone $this->_data[Horde_Imap_Client::FETCH_IMAPDATE]
: new Horde_Imap_Client_DateTime();
}
/**
* Set message size.
*
* @param integer $size The size of the message, in bytes.
*/
public function setSize($size)
{
$this->_data[Horde_Imap_Client::FETCH_SIZE] = intval($size);
}
/**
* Get message size.
*
* @return integer The size of the message, in bytes.
*/
public function getSize()
{
return isset($this->_data[Horde_Imap_Client::FETCH_SIZE])
? $this->_data[Horde_Imap_Client::FETCH_SIZE]
: 0;
}
/**
* Set UID.
*
* @param integer $uid The message UID.
*/
public function setUid($uid)
{
$this->_data[Horde_Imap_Client::FETCH_UID] = intval($uid);
}
/**
* Get UID.
*
* @return integer The message UID.
*/
public function getUid()
{
return isset($this->_data[Horde_Imap_Client::FETCH_UID])
? $this->_data[Horde_Imap_Client::FETCH_UID]
: null;
}
/**
* Set message sequence number.
*
* @param integer $seq The message sequence number.
*/
public function setSeq($seq)
{
$this->_data[Horde_Imap_Client::FETCH_SEQ] = intval($seq);
}
/**
* Get message sequence number.
*
* @return integer The message sequence number.
*/
public function getSeq()
{
return isset($this->_data[Horde_Imap_Client::FETCH_SEQ])
? $this->_data[Horde_Imap_Client::FETCH_SEQ]
: null;
}
/**
* Set the modified sequence value for the message.
*
* @param integer $modseq The modseq value.
*/
public function setModSeq($modseq)
{
$this->_data[Horde_Imap_Client::FETCH_MODSEQ] = intval($modseq);
}
/**
* Get the modified sequence value for the message.
*
* @return integer The modseq value.
*/
public function getModSeq()
{
return isset($this->_data[Horde_Imap_Client::FETCH_MODSEQ])
? $this->_data[Horde_Imap_Client::FETCH_MODSEQ]
: null;
}
/**
* Set the internationalized downgraded status for the message.
*
* @since 2.11.0
*
* @param boolean $downgraded True if at least one message component has
* been downgraded.
*/
public function setDowngraded($downgraded)
{
if ($downgraded) {
$this->_data[Horde_Imap_Client::FETCH_DOWNGRADED] = true;
} else {
unset($this->_data[Horde_Imap_Client::FETCH_DOWNGRADED]);
}
}
/**
* Does the message contain internationalized downgraded data (i.e. it
* is a "surrogate" message)?
*
* @since 2.11.0
*
* @return boolean True if at least one message components has been
* downgraded.
*/
public function isDowngraded()
{
return !empty($this->_data[Horde_Imap_Client::FETCH_DOWNGRADED]);
}
/**
* Return the internal representation of the data.
*
* @return array The data array.
*/
public function getRawData()
{
return $this->_data;
}
/**
* Merge a fetch object into this one.
*
* @param Horde_Imap_Client_Data_Fetch $data A fetch object.
*/
public function merge(Horde_Imap_Client_Data_Fetch $data)
{
$this->_data = array_replace_recursive(
$this->_data,
$data->getRawData()
);
}
/**
* Does this object containing cacheable data of the given type?
*
* @param integer $type The type to query.
*
* @return boolean True if the type is cacheable.
*/
public function exists($type)
{
return isset($this->_data[$type]);
}
/**
* Does this object contain only default values for all fields?
*
* @return boolean True if object contains default data.
*/
public function isDefault()
{
return empty($this->_data);
}
/**
* Return text representation of a field.
*
* @param boolean $stream Return as a stream?
* @param mixed $data The field data (string or resource) or null if
* field does not exist.
*
* @return mixed Requested text representation.
*/
protected function _msgText($stream, $data)
{
if ($data instanceof Horde_Stream) {
if ($stream) {
$data->rewind();
return $data->stream;
}
return strval($data);
}
if (is_resource($data)) {
rewind($data);
return $stream
? $data
: stream_get_contents($data);
}
if (!$stream) {
return strval($data);
}
$tmp = fopen('php://temp', 'w+');
if (!is_null($data)) {
fwrite($tmp, $data);
rewind($tmp);
}
return $tmp;
}
/**
* Return representation of a header field.
*
* @param string $id The header id.
* @param integer $format The return format. If self::HEADER_PARSE,
* returns a Horde_Mime_Headers object. If
* self::HEADER_STREAM, returns a stream.
* Otherwise, returns header text.
* @param integer $key The array key where the data is stored in the
* internal array.
*
* @return mixed The data in the format specified by $format.
*/
protected function _getHeaders($id, $format, $key)
{
switch ($format) {
case self::HEADER_STREAM:
if (!isset($this->_data[$key][$id])) {
$data = null;
} elseif (is_object($this->_data[$key][$id])) {
switch ($key) {
case Horde_Imap_Client::FETCH_HEADERS:
$data = $this->_getHeaders($id, 0, $key);
break;
case Horde_Imap_Client::FETCH_HEADERTEXT:
case Horde_Imap_Client::FETCH_MIMEHEADER:
$data = $this->_data[$key][$id];
break;
}
} else {
$data = $this->_data[$key][$id];
}
return $this->_msgText(true, $data);
case self::HEADER_PARSE:
if (!isset($this->_data[$key][$id])) {
return new Horde_Mime_Headers();
} elseif (is_object($this->_data[$key][$id])) {
switch ($key) {
case Horde_Imap_Client::FETCH_HEADERS:
return clone $this->_data[$key][$id];
case Horde_Imap_Client::FETCH_HEADERTEXT:
case Horde_Imap_Client::FETCH_MIMEHEADER:
return Horde_Mime_Headers::parseHeaders($this->_data[$key][$id]);
}
} else {
$hdrs = $this->_getHeaders($id, self::HEADER_STREAM, $key);
$parsed = Horde_Mime_Headers::parseHeaders($hdrs);
fclose($hdrs);
return $parsed;
}
}
if (!isset($this->_data[$key][$id])) {
return '';
}
if (is_object($this->_data[$key][$id])) {
switch ($key) {
case Horde_Imap_Client::FETCH_HEADERS:
return $this->_data[$key][$id]->toString(
array('nowrap' => true)
);
case Horde_Imap_Client::FETCH_HEADERTEXT:
case Horde_Imap_Client::FETCH_MIMEHEADER:
return strval($this->_data[$key][$id]);
}
}
return $this->_msgText(false, $this->_data[$key][$id]);
}
/**
* Converts mixed input (string or resource) to the correct internal
* representation.
*
* @param mixed $data Mixed data (string, resource, Horde_Stream object).
*
* @return mixed The internal representation of that data.
*/
protected function _setMixed($data)
{
return is_resource($data)
? new Horde_Stream_Existing(array('stream' => $data))
: $data;
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object containg POP3 fetch data.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Fetch_Pop3 extends Horde_Imap_Client_Data_Fetch
{
/**
* Set UID.
*
* @param string $uid The message UID. Unlike IMAP, this UID does not
* have to be an integer.
*/
public function setUid($uid)
{
$this->_data[Horde_Imap_Client::FETCH_UID] = strval($uid);
}
}

View File

@ -1,83 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP data format (RFC 3501 [4]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format
{
/**
* Data.
*
* @var mixed
*/
protected $_data;
/**
* Constructor.
*
* @param mixed $data Data.
*/
public function __construct($data)
{
$this->_data = is_resource($data)
? stream_get_contents($data, -1, 0)
: $data;
}
/**
* Returns the string value of the raw data.
*
* @return string String value.
*/
public function __toString()
{
return strval($this->_data);
}
/**
* Returns the raw data.
*
* @return mixed Raw data.
*/
public function getData()
{
return $this->_data;
}
/**
* Returns the data formatted for output to the IMAP server.
*
* @return string IMAP escaped string.
*/
public function escape()
{
return strval($this);
}
/**
* Verify the data.
*
* @throws Horde_Imap_Client_Data_Format_Exception
*/
public function verify()
{
}
}

View File

@ -1,32 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP astring (atom or string) (RFC 3501 [4.3]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Astring extends Horde_Imap_Client_Data_Format_String
{
/**
*/
public function quoted()
{
return $this->_filter->quoted || !$this->_data->length();
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Extend astring element to allow for non-ASCII characters.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.25.0
*/
class Horde_Imap_Client_Data_Format_Astring_Nonascii
extends Horde_Imap_Client_Data_Format_Astring
implements Horde_Imap_Client_Data_Format_String_Support_Nonascii
{
}

View File

@ -1,57 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP atom (RFC 3501 [4.1]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Atom extends Horde_Imap_Client_Data_Format
{
/**
*/
public function escape()
{
return strlen($this->_data)
? parent::escape()
: '""';
}
/**
*/
public function verify()
{
if (strlen($this->_data) !== strlen($this->stripNonAtomCharacters())) {
throw new Horde_Imap_Client_Data_Format_Exception('Illegal character in IMAP atom.');
}
}
/**
* Strip out any characters that are not allowed in an IMAP atom.
*
* @return string The atom data disallowed characters removed.
*/
public function stripNonAtomCharacters()
{
return str_replace(
array('(', ')', '{', ' ', '%', '*', '"', '\\', ']'),
'',
preg_replace('/[^\x20-\x7e]/', '', $this->_data)
);
}
}

View File

@ -1,49 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP date string (RFC 3501 [9]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Date extends Horde_Imap_Client_Data_Format
{
/**
* Constructor.
*
* @param mixed $data Either a DateTime object, or a date format that
* can be converted to a DateTime object.
*
* @throws Exception
*/
public function __construct($data)
{
if (!($data instanceof DateTime)) {
$data = new Horde_Imap_Client_DateTime($data);
}
parent::__construct($data);
}
/**
*/
public function __toString()
{
return $this->_data->format('j-M-Y');
}
}

View File

@ -1,39 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP date-time string (RFC 3501 [9]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_DateTime extends Horde_Imap_Client_Data_Format_Date
{
/**
*/
public function __toString()
{
return $this->_data->format('j-M-Y H:i:s O');
}
/**
*/
public function escape()
{
return '"' . strval($this) . '"';
}
}

View File

@ -1,25 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception object for IMAP data format errors.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Exception extends Horde_Exception_Wrapped
{
}

View File

@ -1,66 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Stream filter to output a quoted IMAP string.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Filter_Quote extends php_user_filter
{
/**
* Has the initial quote been prepended?
*
* @var boolean
*/
protected $_prepend;
/**
*/
#[ReturnTypeWillChange]
public function onCreate()
{
$this->_prepend = false;
}
/**
* @see stream_filter_register()
*/
#[ReturnTypeWillChange]
public function filter($in, $out, &$consumed, $closing)
{
if (!$this->_prepend) {
stream_bucket_append($out, stream_bucket_new($this->stream, '"'));
$this->_prepend = true;
}
while ($bucket = stream_bucket_make_writeable($in)) {
$consumed += $bucket->datalen;
$bucket->data = addcslashes($bucket->data, '"\\');
stream_bucket_append($out, $bucket);
}
/* feof() call needed due to:
* http://news.php.net/php.internals/80363 */
if ($closing || feof($this->stream)) {
stream_bucket_append($out, stream_bucket_new($this->stream, '"'));
}
return PSFS_PASS_ON;
}
}

View File

@ -1,122 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Stream filter to analyze an IMAP string to determine how to send to the
* server.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Filter_String extends php_user_filter
{
/**
* Skip status.
*
* @var boolean
*/
protected $_skip = false;
/**
* @see stream_filter_register()
*/
#[ReturnTypeWillChange]
public function onCreate()
{
$this->params->binary = false;
$this->params->literal = false;
$this->params->nonascii = false;
// no_quote_list is used below as a config option
$this->params->quoted = false;
return true;
}
/**
* @see stream_filter_register()
*/
#[ReturnTypeWillChange]
public function filter($in, $out, &$consumed, $closing)
{
$p = $this->params;
while ($bucket = stream_bucket_make_writeable($in)) {
if (!$this->_skip) {
$len = $bucket->datalen;
$str = $bucket->data;
for ($i = 0; $i < $len; ++$i) {
$chr = ord($str[$i]);
switch ($chr) {
case 0: // null
$p->binary = true;
$p->literal = true;
// No need to scan input anymore.
$this->_skip = true;
break 2;
case 10: // LF
case 13: // CR
$p->literal = true;
break;
case 32: // SPACE
case 34: // "
case 40: // (
case 41: // )
case 92: // \
case 123: // {
case 127: // DEL
// These are all invalid ATOM characters.
$p->quoted = true;
break;
case 37: // %
case 42: // *
// These are not quoted if being used as wildcards.
if (empty($p->no_quote_list)) {
$p->quoted = true;
}
break;
default:
if ($chr < 32) {
// CTL characters must be, at a minimum, quoted.
$p->quoted = true;
} elseif ($chr > 127) {
$p->nonascii = true;
// 8-bit chars must be in a literal.
$p->literal = true;
}
break;
}
}
}
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
if ($p->literal) {
$p->quoted = false;
}
return PSFS_PASS_ON;
}
}

View File

@ -1,108 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP parenthesized list (RFC 3501 [4.4]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_List extends Horde_Imap_Client_Data_Format implements Countable, IteratorAggregate
{
/**
* @see add()
*/
public function __construct($data = null)
{
parent::__construct(array());
if (!is_null($data)) {
$this->add($data);
}
}
/**
* Add an element to the list.
*
* @param mixed $data The data element(s) to add. Either a
* Horde_Imap_Client_Data_Format object, a string
* value that will be treated as an IMAP atom, or
* an array (or iterable object) of objects to add.
* @param boolean $merge Merge the contents of any container objects,
* instead of adding the objects themselves?
*
* @return Horde_Imap_Client_Data_Format_List This object to allow for
* chainable calls (since
* 2.10.0).
*/
public function add($data, $merge = false)
{
if (is_array($data) || ($merge && ($data instanceof Traversable))) {
foreach ($data as $val) {
$this->add($val);
}
} elseif (is_object($data)) {
$this->_data[] = $data;
} elseif (!is_null($data)) {
$this->_data[] = new Horde_Imap_Client_Data_Format_Atom($data);
}
return $this;
}
/**
*/
public function __toString()
{
$out = '';
foreach ($this as $val) {
if ($val instanceof $this) {
$out .= '(' . $val->escape() . ') ';
} elseif (($val instanceof Horde_Imap_Client_Data_Format_String) &&
$val->literal()) {
/* ERROR: Requires literal output. */
return '';
} else {
$out .= $val->escape() . ' ';
}
}
return rtrim($out);
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_data);
}
/* IteratorAggregate method. */
/**
* Iterator loops through the data elements contained in this list.
*/
#[ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->_data);
}
}

View File

@ -1,38 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP mailbox string used in a LIST command.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_ListMailbox
extends Horde_Imap_Client_Data_Format_Mailbox
{
/**
*/
protected function _filterParams()
{
$ob = parent::_filterParams();
/* Don't quote % or * characters. */
$ob->no_quote_list = true;
return $ob;
}
}

View File

@ -1,39 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP mailbox string used in a LIST command
* when UTF8=ACCEPT is supported/enabled on the server (RFC 6855 [3]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_ListMailbox_Utf8
extends Horde_Imap_Client_Data_Format_Mailbox_Utf8
{
/**
*/
protected function _filterParams()
{
$ob = parent::_filterParams();
/* Don't quote % or * characters. */
$ob->no_quote_list = true;
return $ob;
}
}

View File

@ -1,99 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP mailbox string (RFC 3501 [9]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Mailbox
extends Horde_Imap_Client_Data_Format_Astring
{
/**
* Mailbox encoding.
*
* @var string
*/
protected $_encoding = 'utf7imap';
/**
* Mailbox object.
*
* @var Horde_Imap_Client_Mailbox
*/
protected $_mailbox;
/**
* @param mixed $data Either a mailbox object or a UTF-8 mailbox name.
*/
public function __construct($data)
{
$this->_mailbox = Horde_Imap_Client_Mailbox::get($data);
parent::__construct($this->_mailbox->{$this->_encoding});
}
/**
*/
public function __toString()
{
return strval($this->_mailbox);
}
/**
*/
public function getData()
{
return $this->_mailbox;
}
/**
* @throws Horde_Imap_Client_Exception
*/
public function binary()
{
if (parent::binary()) {
// Mailbox data can NEVER be sent as binary.
/* @todo: Disable until Horde_Imap_Client 3.0 */
// throw new Horde_Imap_Client_Exception(
// 'Client error: can not send mailbox to IMAP server as binary data.'
// );
// Temporary fix: send a blank mailbox string.
$this->_mailbox = Horde_Imap_Client_Mailbox::get('');
}
return false;
}
/**
*/
public function length()
{
return strlen($this->_mailbox->{$this->_encoding});
}
/**
*/
public function getStream()
{
$stream = new Horde_Stream_Temp();
$stream->add($this->_mailbox->{$this->_encoding});
return $stream;
}
}

View File

@ -1,57 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP mailbox string allowed when UTF8=ACCEPT
* is supported/enabled on the server (RFC 6855 [3]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Mailbox_Utf8
extends Horde_Imap_Client_Data_Format_Mailbox
implements Horde_Imap_Client_Data_Format_String_Support_Nonascii
{
/**
*/
protected $_encoding = 'utf8';
/**
*/
public function __construct($data)
{
parent::__construct($data);
/* RFC 3501 allows any US-ASCII character, except null (\0), in
* mailbox data.
* RFC 6855 [3] institutes additional limitations on valid mailbox
* characters, to comply with RFC 5198 [2] (Net-Unicode Definition):
* "MUST NOT contain control characters (U+0000-U+001F and
* U+0080-U+009F), a delete character (U+007F), a line separator
* (U+2028), or a paragraph separator (U+2029)." */
if ($this->quoted() &&
preg_match('/[\x00-\x1f\x7f\x80-\x9f\x{2028}\x{2029}]/u', strval($this))) {
throw new Horde_Imap_Client_Data_Format_Exception(
'Invalid character found in mailbox data.'
);
}
if ($this->literal()) {
$this->forceQuoted();
}
}
}

View File

@ -1,46 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP NIL (RFC 3501 [4.5]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Nil extends Horde_Imap_Client_Data_Format
{
/**
*/
public function __construct($data = null)
{
// Don't store any data in object.
}
/**
*/
public function __toString()
{
return '';
}
/**
*/
public function escape()
{
return 'NIL';
}
}

View File

@ -1,93 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP nstring (NIL or string) (RFC 3501 [4.5]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Nstring extends Horde_Imap_Client_Data_Format_String
{
/**
*/
public function __construct($data = null)
{
/* Data can be null (NIL) here. */
if (is_null($data)) {
$this->_data = null;
} else {
parent::__construct($data);
}
}
/**
*/
public function __toString()
{
return is_null($this->_data)
? ''
: parent::__toString();
}
/**
*/
public function escape()
{
return is_null($this->_data)
? 'NIL'
: parent::escape();
}
public function escapeStream()
{
if (is_null($this->_data)) {
$stream = new Horde_Stream_Temp();
$stream->add('NIL', true);
return $stream->stream;
}
return parent::escapeStream();
}
/**
*/
public function quoted()
{
return is_null($this->_data)
? false
: parent::quoted();
}
/**
*/
public function length()
{
return is_null($this->_data)
? 0
: parent::length();
}
/**
*/
public function getStream()
{
return is_null($this->_data)
? new Horde_Stream_Temp()
: parent::getStream();
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Extend nstring element to allow for non-ASCII characters.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.25.0
*/
class Horde_Imap_Client_Data_Format_Nstring_Nonascii
extends Horde_Imap_Client_Data_Format_Nstring
implements Horde_Imap_Client_Data_Format_String_Support_Nonascii
{
}

View File

@ -1,41 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP number (RFC 3501 [4.2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_Number extends Horde_Imap_Client_Data_Format
{
/**
*/
public function __toString()
{
return strval(intval($this->_data));
}
/**
*/
public function verify()
{
if (!is_numeric($this->_data)) {
throw new Horde_Imap_Client_Data_Format_Exception('Illegal character in IMAP number.');
}
}
}

View File

@ -1,219 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representation of an IMAP string (RFC 3501 [4.3]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Format_String
extends Horde_Imap_Client_Data_Format
{
/**
* String filter parameters.
*
* @var string
*/
protected $_filter;
/**
* @param array $opts Additional options:
* - eol: (boolean) If true, normalize EOLs in input. @since 2.2.0
* - skipscan: (boolean) If true, don't scan input for
* binary/literal/quoted data. @since 2.2.0
*
* @throws Horde_Imap_Client_Data_Format_Exception
*/
public function __construct($data, array $opts = array())
{
/* String data is stored in a stream. */
$this->_data = new Horde_Stream_Temp();
if (empty($opts['skipscan'])) {
$this->_filter = $this->_filterParams();
stream_filter_register('horde_imap_client_string', 'Horde_Imap_Client_Data_Format_Filter_String');
$res = stream_filter_append($this->_data->stream, 'horde_imap_client_string', STREAM_FILTER_WRITE, $this->_filter);
} else {
$res = null;
}
if (empty($opts['eol'])) {
$res2 = null;
} else {
stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol');
$res2 = stream_filter_append($this->_data->stream, 'horde_eol', STREAM_FILTER_WRITE);
}
$this->_data->add($data);
if (!is_null($res)) {
stream_filter_remove($res);
}
if (!is_null($res2)) {
stream_filter_remove($res2);
}
if (isset($this->_filter) &&
$this->_filter->nonascii &&
!($this instanceof Horde_Imap_Client_Data_Format_String_Support_Nonascii)) {
throw new Horde_Imap_Client_Data_Format_Exception(
'String contains non-ASCII characters.'
);
}
}
/**
* Return the base string filter parameters.
*
* @return object Filter parameters.
*/
protected function _filterParams()
{
return new stdClass;
}
/**
*/
public function __toString()
{
return $this->_data->getString(0);
}
/**
*/
public function escape()
{
if ($this->literal()) {
throw new Horde_Imap_Client_Data_Format_Exception('String requires literal to output.');
}
return $this->quoted()
? stream_get_contents($this->escapeStream())
: $this->_data->getString(0);
}
/**
* Return the escaped string as a stream.
*
* @return resource The IMAP escaped stream.
*/
public function escapeStream()
{
if ($this->literal()) {
throw new Horde_Imap_Client_Data_Format_Exception('String requires literal to output.');
}
rewind($this->_data->stream);
$stream = new Horde_Stream_Temp();
$stream->add($this->_data, true);
stream_filter_register('horde_imap_client_string_quote', 'Horde_Imap_Client_Data_Format_Filter_Quote');
stream_filter_append($stream->stream, 'horde_imap_client_string_quote', STREAM_FILTER_READ);
return $stream->stream;
}
/**
* Does this data item require quoted string output?
*
* @return boolean True if quoted output is required.
*/
public function quoted()
{
/* IMAP strings MUST be quoted if they are not a literal. */
return (!isset($this->_filter) || !$this->_filter->literal);
}
/**
* Force item to be output quoted.
*/
public function forceQuoted()
{
$this->_filter = $this->_filterParams();
$this->_filter->binary = false;
$this->_filter->literal = false;
$this->_filter->quoted = true;
}
/**
* Does this data item require literal string output?
*
* @return boolean True if literal output is required.
*/
public function literal()
{
return (isset($this->_filter) && $this->_filter->literal);
}
/**
* Force item to be output as a literal.
*/
public function forceLiteral()
{
$this->_filter = $this->_filterParams();
// Keep binary status, if set
$this->_filter->literal = true;
$this->_filter->quoted = false;
}
/**
* If literal output, is the data binary?
*
* @return boolean True if the literal output is binary.
*/
public function binary()
{
return (isset($this->_filter) && !empty($this->_filter->binary));
}
/**
* Force item to be output as a binary literal.
*/
public function forceBinary()
{
$this->_filter = $this->_filterParams();
$this->_filter->binary = true;
$this->_filter->literal = true;
$this->_filter->quoted = false;
}
/**
* Return the length of the data.
*
* @since 2.2.0
*
* @return integer Data length.
*/
public function length()
{
return $this->_data->length();
}
/**
* Return the contents of the string as a stream object.
*
* @since 2.3.0
*
* @return Horde_Stream The stream object.
*/
public function getStream()
{
return $this->_data;
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Extend string element to allow for non-ASCII characters.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.25.0
*/
class Horde_Imap_Client_Data_Format_String_Nonascii
extends Horde_Imap_Client_Data_Format_String
implements Horde_Imap_Client_Data_Format_String_Support_Nonascii
{
}

View File

@ -1,27 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Interface a Horde_Imap_Client_Data_Format_String object should extend if
* it supports non-ASCII output (RFC 3501 [4.3.1]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.25.0
*/
interface Horde_Imap_Client_Data_Format_String_Support_Nonascii
{
}

View File

@ -1,160 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Namespace data.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.21.0
*
* @property-read string $base The namespace base ($name without trailing
* delimiter) (UTF-8).
* @property string $delimiter The namespace delimiter.
* @property boolean $hidden Is this a hidden namespace?
* @property string $name The namespace name (UTF-8).
* @property string $translation Returns the translated name of the namespace
* (UTF-8).
* @property integer $type The namespace type. Either self::NS_PERSONAL,
* self::NS_OTHER, or self::NS_SHARED.
*/
class Horde_Imap_Client_Data_Namespace implements Serializable
{
/* Namespace type constants. */
const NS_PERSONAL = 1;
const NS_OTHER = 2;
const NS_SHARED = 3;
/**
* Data object.
*
* @var array
*/
protected $_data = array();
/**
* Strips namespace information from the given mailbox name.
*
* @param string $mbox Mailbox name.
*
* @return string Mailbox name with namespace prefix stripped.
*/
public function stripNamespace($mbox)
{
$mbox = strval($mbox);
$name = $this->name;
return (strlen($name) && (strpos($mbox, $name) === 0))
? substr($mbox, strlen($name))
: $mbox;
}
/**
*/
public function __get($name)
{
if (isset($this->_data[$name])) {
return $this->_data[$name];
}
switch ($name) {
case 'base':
return rtrim($this->name, $this->delimiter);
case 'delimiter':
case 'name':
case 'translation':
return '';
case 'hidden':
return false;
case 'type':
return self::NS_PERSONAL;
}
return null;
}
/**
*/
public function __set($name, $value)
{
switch ($name) {
case 'delimiter':
case 'name':
case 'translation':
$this->_data[$name] = strval($value);
break;
case 'hidden':
$this->_data[$name] = (bool)$value;
break;
case 'type':
$this->_data[$name] = intval($value);
break;
}
}
/**
*/
public function __isset($name)
{
return isset($this->_data[$name]);
}
/**
*/
public function __toString()
{
return $this->name;
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version change.');
}
$this->__unserialize($data);
}
/**
* @return array
*/
public function __serialize()
{
return $this->_data;
}
public function __unserialize(array $data)
{
$this->_data = $data;
}
}

View File

@ -1,198 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Query the search charsets available on a server.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.24.0
*
* @property-read array $charsets The list of valid charsets that have been
* discovered on the server.
*/
class Horde_Imap_Client_Data_SearchCharset
implements Serializable, SplSubject
{
/**
* Base client object.
*
* @var Horde_Imap_Client_Base
*/
protected $_baseob;
/**
* Charset data.
*
* @var array
*/
protected $_charsets = array(
'US-ASCII' => true
);
/**
* Observers.
*
* @var array
*/
protected $_observers = array();
/**
*/
public function __get($name)
{
switch ($name) {
case 'charsets':
return array_keys(array_filter($this->_charsets));
}
}
/**
*/
public function setBaseOb(Horde_Imap_Client_Base $ob)
{
$this->_baseob = $ob;
}
/**
* Query the validity of a charset.
*
* @param string $charset The charset to query.
* @param boolean $cached If true, only query cached values.
*
* @return boolean True if the charset is valid for searching.
*/
public function query($charset, $cached = false)
{
$charset = Horde_String::upper($charset);
if (isset($this->_charsets[$charset])) {
return $this->_charsets[$charset];
} elseif ($cached) {
return null;
}
if (!$this->_baseob) {
throw new RuntimeException(
'Base object needs to be defined to query for charset.'
);
}
/* Use a dummy search query and search for BADCHARSET response. */
$query = new Horde_Imap_Client_Search_Query();
$query->charset($charset, false);
$query->ids($this->_baseob->getIdsOb(1, true));
$query->text('a');
try {
$this->_baseob->search('INBOX', $query, array(
'nocache' => true,
'sequence' => true
));
$this->_charsets[$charset] = true;
} catch (Horde_Imap_Client_Exception $e) {
$this->_charsets[$charset] = ($e->getCode() !== Horde_Imap_Client_Exception::BADCHARSET);
}
$this->notify();
return $this->_charsets[$charset];
}
/**
* Set the validity of a given charset.
*
* @param string $charset The charset.
* @param boolean $valid Is charset valid?
*/
public function setValid($charset, $valid = true)
{
$charset = Horde_String::upper($charset);
$valid = (bool)$valid;
if (!isset($this->_charsets[$charset]) ||
($this->_charsets[$charset] !== $valid)) {
$this->_charsets[$charset] = $valid;
$this->notify();
}
}
/* SplSubject methods. */
/**
*/
#[ReturnTypeWillChange]
public function attach(SplObserver $observer)
{
$this->detach($observer);
$this->_observers[] = $observer;
}
/**
*/
#[ReturnTypeWillChange]
public function detach(SplObserver $observer)
{
if (($key = array_search($observer, $this->_observers, true)) !== false) {
unset($this->_observers[$key]);
}
}
/**
* Notification is triggered internally whenever the object's internal
* data storage is altered.
*/
#[ReturnTypeWillChange]
public function notify()
{
foreach ($this->_observers as $val) {
$val->update($this);
}
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version change');
}
$this->__unserialize($data);
}
/**
* @return array
*/
public function __serialize()
{
return $this->_charsets;
}
public function __unserialize(array $data)
{
$this->_charsets = $data;
}
}

View File

@ -1,78 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Query the search charsets available on a server that supports the UTF-8
* IMAP extension (RFC 6855).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.24.0
*/
class Horde_Imap_Client_Data_SearchCharset_Utf8
extends Horde_Imap_Client_Data_SearchCharset
{
/**
* Charset data.
*
* @var array
*/
protected $_charsets = array(
'US-ASCII' => true,
'UTF-8' => true
);
/**
*/
public function query($charset, $cached = false)
{
return isset($this->_charsets[Horde_String::upper($charset)]);
}
/**
*/
public function setValid($charset, $valid = true)
{
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return '';
}
/**
*/
public function unserialize($data)
{
}
/**
* @return array
*/
public function __serialize()
{
return array();
}
public function __unserialize(array $data)
{
}
}

View File

@ -1,267 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Mailbox synchronization results.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.2.0
*
* @property-read Horde_Imap_Client_Ids $flagsuids List of messages with flag
* changes.
* @property-read Horde_Imap_Client_Ids $newmsgsuids List of new messages.
* @property-read Horde_Imap_Client_Ids $vanisheduids List of messages that
* have vanished.
*/
class Horde_Imap_Client_Data_Sync
{
/**
* Mappings of status() values to sync keys.
*
* @since 2.8.0
*
* @var array
*/
public static $map = array(
'H' => 'highestmodseq',
'M' => 'messages',
'U' => 'uidnext',
'V' => 'uidvalidity'
);
/**
* Are there messages that have had flag changes?
*
* @var boolean
*/
public $flags = null;
/**
* The previous value of HIGHESTMODSEQ.
*
* @since 2.8.0
*
* @var integer
*/
public $highestmodseq = null;
/**
* The synchronized mailbox.
*
* @var Horde_Imap_Client_Mailbox
*/
public $mailbox;
/**
* The previous number of messages in the mailbox.
*
* @since 2.8.0
*
* @var integer
*/
public $messages = null;
/**
* Are there new messages?
*
* @var boolean
*/
public $newmsgs = null;
/**
* The previous value of UIDNEXT.
*
* @since 2.8.0
*
* @var integer
*/
public $uidnext = null;
/**
* The previous value of UIDVALIDITY.
*
* @since 2.8.0
*
* @var integer
*/
public $uidvalidity = null;
/**
* The UIDs of messages that are guaranteed to have vanished. This list is
* only guaranteed to be available if the server supports QRESYNC or a
* list of known UIDs is passed to the sync() method.
*
* @var Horde_Imap_Client_Ids
*/
public $vanished = null;
/**
* UIDs of messages that have had flag changes.
*
* @var Horde_Imap_Client_Ids
*/
protected $_flagsuids;
/**
* UIDs of new messages.
*
* @var Horde_Imap_Client_Ids
*/
protected $_newmsgsuids;
/**
* UIDs of messages that have vanished.
*
* @var Horde_Imap_Client_Ids
*/
protected $_vanisheduids;
/**
* Constructor.
*
* @param Horde_Imap_Client_Base $base_ob Base driver object.
* @param mixed $mailbox Mailbox to sync.
* @param array $sync Token sync data.
* @param array $curr Current sync data.
* @param integer $criteria Mask of criteria to return.
* @param Horde_Imap_Client_Ids $ids List of known UIDs.
*
* @throws Horde_Imap_Client_Exception
* @throws Horde_Imap_Client_Exception_Sync
*/
public function __construct(Horde_Imap_Client_Base $base_ob, $mailbox,
$sync, $curr, $criteria, $ids)
{
foreach (self::$map as $key => $val) {
if (isset($sync[$key])) {
$this->$val = $sync[$key];
}
}
/* Check uidvalidity. */
if (!$this->uidvalidity || ($curr['V'] != $this->uidvalidity)) {
throw new Horde_Imap_Client_Exception_Sync('UIDs in cached mailbox have changed.', Horde_Imap_Client_Exception_Sync::UIDVALIDITY_CHANGED);
}
$this->mailbox = $mailbox;
/* This was a UIDVALIDITY check only. */
if (!$criteria) {
return;
}
$sync_all = ($criteria & Horde_Imap_Client::SYNC_ALL);
/* New messages. */
if ($sync_all ||
($criteria & Horde_Imap_Client::SYNC_NEWMSGS) ||
($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
$this->newmsgs = empty($this->uidnext)
? !empty($curr['U'])
: (!empty($curr['U']) && ($curr['U'] > $this->uidnext));
if ($this->newmsgs &&
($sync_all ||
($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS))) {
$new_ids = empty($this->uidnext)
? Horde_Imap_Client_Ids::ALL
: ($this->uidnext . ':' . $curr['U']);
$squery = new Horde_Imap_Client_Search_Query();
$squery->ids(new Horde_Imap_Client_Ids($new_ids));
$sres = $base_ob->search($mailbox, $squery);
$this->_newmsgsuids = $sres['match'];
}
}
/* Do single status call to get all necessary data. */
if ($this->highestmodseq &&
($sync_all ||
($criteria & Horde_Imap_Client::SYNC_FLAGS) ||
($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) ||
($criteria & Horde_Imap_Client::SYNC_VANISHED) ||
($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS))) {
$status_sync = $base_ob->status($mailbox, Horde_Imap_Client::STATUS_SYNCMODSEQ | Horde_Imap_Client::STATUS_SYNCFLAGUIDS | Horde_Imap_Client::STATUS_SYNCVANISHED);
if (!is_null($ids)) {
$ids = $base_ob->resolveIds($mailbox, $ids);
}
}
/* Flag changes. */
if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGS)) {
$this->flags = $this->highestmodseq
? ($this->highestmodseq != $curr['H'])
: true;
}
if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
if ($this->highestmodseq) {
if ($this->highestmodseq == $status_sync['syncmodseq']) {
$this->_flagsuids = is_null($ids)
? $status_sync['syncflaguids']
: $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncflaguids']->ids));
} else {
$squery = new Horde_Imap_Client_Search_Query();
$squery->modseq($this->highestmodseq + 1);
$sres = $base_ob->search($mailbox, $squery, array(
'ids' => $ids
));
$this->_flagsuids = $sres['match'];
}
} else {
/* Without MODSEQ, need to mark all FLAGS as changed. */
$this->_flagsuids = $base_ob->resolveIds($mailbox, is_null($ids) ? $base_ob->getIdsOb(Horde_Imap_Client_Ids::ALL) : $ids);
}
}
/* Vanished messages. */
if ($sync_all ||
($criteria & Horde_Imap_Client::SYNC_VANISHED) ||
($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
if ($this->highestmodseq &&
($this->highestmodseq == $status_sync['syncmodseq'])) {
$vanished = is_null($ids)
? $status_sync['syncvanished']
: $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncvanished']->ids));
} else {
$vanished = $base_ob->vanished($mailbox, $this->highestmodseq ? $this->highestmodseq : 1, array(
'ids' => $ids
));
}
$this->vanished = (bool)count($vanished);
$this->_vanisheduids = $vanished;
}
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'flagsuids':
case 'newmsgsuids':
case 'vanisheduids':
return empty($this->{'_' . $name})
? new Horde_Imap_Client_Ids()
: $this->{'_' . $name};
}
}
}

View File

@ -1,231 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Object representing the threaded sort results from
* Horde_Imap_Client_Base#thread().
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Data_Thread implements Countable, Serializable
{
/**
* Internal thread data structure. Keys are base values, values are arrays
* with keys as the ID and values as the level.
*
* @var array
*/
protected $_thread = array();
/**
* The index type.
*
* @var string
*/
protected $_type;
/**
* Constructor.
*
* @param array $data See $_thread.
* @param string $type Either 'sequence' or 'uid'.
*/
public function __construct($data, $type)
{
$this->_thread = $data;
$this->_type = $type;
}
/**
* Return the ID type.
*
* @return string Either 'sequence' or 'uid'.
*/
public function getType()
{
return $this->_type;
}
/**
* Return the sorted list of messages indices.
*
* @return Horde_Imap_Client_Ids The sorted list of messages.
*/
public function messageList()
{
return new Horde_Imap_Client_Ids($this->_getAllIndices(), $this->getType() == 'sequence');
}
/**
* Returns the list of messages in a thread.
*
* @param integer $index An index contained in the thread.
*
* @return array Keys are indices, values are objects with the following
* properties:
* - base: (integer) Base ID of the thread. If null, thread is a single
* message.
* - last: (boolean) If true, this is the last index in the sublevel.
* - level: (integer) The sublevel of the index.
*/
public function getThread($index)
{
foreach ($this->_thread as $v) {
if (isset($v[$index])) {
reset($v);
$ob = new stdClass;
$ob->base = (count($v) > 1) ? key($v) : null;
$ob->last = false;
$levels = $out = array();
$last = 0;
while (($v2 = current($v)) !== false) {
$k2 = key($v);
$ob2 = clone $ob;
$ob2->level = $v2;
$out[$k2] = $ob2;
if (($last < $v2) && isset($levels[$v2])) {
$out[$levels[$v2]]->last = true;
}
$levels[$v2] = $k2;
$last = $v2;
next($v);
}
foreach ($levels as $v) {
$out[$v]->last = true;
}
return $out;
}
}
return array();
}
/**
* Returns array of all threads.
*
* @return array Keys of thread arrays are indices, values are objects with the following
* properties:
* - base: (integer) Base ID of the thread. If null, thread is a single
* message.
* - last: (boolean) If true, this is the last index in the sublevel.
* - level: (integer) The sublevel of the index.
*/
public function getThreads()
{
$data = array();
foreach ($this->_thread as $v) {
reset($v);
$ob = new stdClass;
$ob->base = (count($v) > 1) ? key($v) : null;
$ob->last = false;
$levels = $out = array();
$last = 0;
while (($v2 = current($v)) !== false) {
$k2 = key($v);
$ob2 = clone $ob;
$ob2->level = $v2;
$out[$k2] = $ob2;
if (($last < $v2) && isset($levels[$v2])) {
$out[$levels[$v2]]->last = true;
}
$levels[$v2] = $k2;
$last = $v2;
next($v);
}
foreach ($levels as $v) {
$out[$v]->last = true;
}
$data[] = $out;
}
return $data;
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_getAllIndices());
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version changed.');
}
$this->__unserialize($data);
}
/**
* @return array
*/
public function __serialize()
{
return [$this->_thread, $this->_type];
}
public function __unserialize(array $data)
{
list($this->_thread, $this->_type) = $data;
}
/* Protected methods. */
/**
* Return all indices.
*
* @return array An array of indices.
*/
protected function _getAllIndices()
{
$out = array();
foreach ($this->_thread as $val) {
$out += $val;
}
return array_keys($out);
}
}

View File

@ -1,119 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* A wrapper around PHP's native DateTime class that handles improperly
* formatted dates and adds a few features missing from the base object
* (string representation; doesn't fail on bad date input).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_DateTime extends DateTime
{
/**
*/
public function __construct($time = null, $tz = null)
{
/* See https://bugs.php.net/bug.php?id=67118 */
$bug_67118 = (version_compare(PHP_VERSION, '5.6', '>=')) ||
in_array(PHP_VERSION, array('5.4.29', '5.5.13'));
$tz = new DateTimeZone('UTC');
/* Bug #14381 Catch malformed offset - which doesn't cause
DateTime to throw exception. */
if ($time !== null && substr(rtrim($time), -5) === ' 0000') {
$time = substr(trim($time), 0, strlen(trim($time)) - 5) . ' +0000';
try {
if ($bug_67118) {
new DateTime($time, $tz);
}
parent::__construct($time, $tz);
return;
} catch (Exception $e) {}
}
try {
if ($bug_67118) {
new DateTime($time === null ? 'now' : $time, $tz);
}
parent::__construct($time === null ? 'now' : $time, $tz);
return;
} catch (Exception $e) {}
/* Check for malformed day-of-week parts, usually incorrectly
* localized. E.g. Fr, 15 Apr 2016 15:15:09 +0000 */
if ($time !== null && !preg_match("/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun),/", $time)) {
$time = preg_replace("/^(\S*,)/", '', $time, 1, $i);
if ($i) {
try {
if ($bug_67118) {
new DateTime($time, $tz);
}
parent::__construct($time, $tz);
return;
} catch (Exception $e) {}
}
}
/* Bug #5717 - Check for UT vs. UTC. */
if ($time !== null && substr(rtrim($time), -3) === ' UT') {
try {
if ($bug_67118) {
new DateTime($time . 'C', $tz);
}
parent::__construct($time . 'C', $tz);
return;
} catch (Exception $e) {}
}
/* Bug #9847 - Catch paranthesized timezone information at end of date
* string. */
$date = preg_replace("/\s*\([^\)]+\)\s*$/", '', $time, -1, $i);
if ($i) {
try {
if ($bug_67118) {
new DateTime($date, $tz);
}
parent::__construct($date, $tz);
return;
} catch (Exception $e) {}
}
parent::__construct('@-1', $tz);
}
/**
* String representation: UNIX timestamp.
*/
public function __toString()
{
return $this->error()
? '0'
: strval($this->getTimestamp());
}
/**
* Was this an unparseable date?
*
* @return boolean True if unparseable.
*/
public function error()
{
return ($this->getTimestamp() === -1);
}
}

View File

@ -1,303 +0,0 @@
<?php
/**
* Copyright 2008-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception handler for the Horde_Imap_Client package.
*
* Additional server debug information MAY be found in the $details
* property.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2008-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Exception extends Horde_Exception_Wrapped
{
/* Error message codes. */
/**
* Unspecified error (DEFAULT).
*/
const UNSPECIFIED = 0;
/**
* There was an unrecoverable error in UTF7IMAP -> UTF8 conversion.
*/
const UTF7IMAP_CONVERSION = 3;
/**
* The server ended the connection.
*/
const DISCONNECT = 4;
/**
* The charset used in the search query is not supported on the
* server. */
const BADCHARSET = 5;
/**
* There were errors parsing the MIME/RFC 2822 header of the part.
*/
const PARSEERROR = 6;
/**
* The server could not decode the MIME part (see RFC 3516).
*/
const UNKNOWNCTE = 7;
/**
* The comparator specified by setComparator() was not recognized by the
* IMAP server
*/
const BADCOMPARATOR = 9;
/**
* RFC 7162 [3.1.2.2] - All mailboxes are not required to support
* mod-sequences.
*/
const MBOXNOMODSEQ = 10;
/**
* Thrown if server denies the network connection.
*/
const SERVER_CONNECT = 11;
/**
* Thrown if read error for server response.
*/
const SERVER_READERROR = 12;
/**
* Thrown if write error in server interaction.
*/
const SERVER_WRITEERROR = 16;
/**
* Thrown on CATENATE if the URL is invalid.
*/
const CATENATE_BADURL = 13;
/**
* Thrown on CATENATE if the message was too big.
*/
const CATENATE_TOOBIG = 14;
/**
* Thrown on CREATE if special-use attribute is not supported.
*/
const USEATTR = 15;
/**
* The user did not have permissions to carry out the operation.
*/
const NOPERM = 17;
/**
* The operation was not successful because another user is holding
* a necessary resource. The operation may succeed if attempted later.
*/
const INUSE = 18;
/**
* The operation failed because data on the server was corrupt.
*/
const CORRUPTION = 19;
/**
* The operation failed because it exceeded some limit on the server.
*/
const LIMIT = 20;
/**
* The operation failed because the user is over their quota.
*/
const OVERQUOTA = 21;
/**
* The operation failed because the requested creation object already
* exists.
*/
const ALREADYEXISTS = 22;
/**
* The operation failed because the requested deletion object did not
* exist.
*/
const NONEXISTENT = 23;
/**
* Setting metadata failed because the size of its value is too large.
* The maximum octet count the server is willing to accept will be
* in the exception message string.
*/
const METADATA_MAXSIZE = 24;
/**
* Setting metadata failed because the maximum number of allowed
* annotations has already been reached.
*/
const METADATA_TOOMANY = 25;
/**
* Setting metadata failed because the server does not support private
* annotations on one of the specified mailboxes.
*/
const METADATA_NOPRIVATE = 26;
/**
* Invalid metadata entry.
*/
const METADATA_INVALID = 27;
// Login failures
/**
* Could not start mandatory TLS connection.
*/
const LOGIN_TLSFAILURE = 100;
/**
* Could not find an available authentication method.
*/
const LOGIN_NOAUTHMETHOD = 101;
/**
* Generic authentication failure.
*/
const LOGIN_AUTHENTICATIONFAILED = 102;
/**
* Remote server is unavailable.
*/
const LOGIN_UNAVAILABLE = 103;
/**
* Authentication succeeded, but authorization failed.
*/
const LOGIN_AUTHORIZATIONFAILED = 104;
/**
* Authentication is no longer permitted with this passphrase.
*/
const LOGIN_EXPIRED = 105;
/**
* Login requires privacy.
*/
const LOGIN_PRIVACYREQUIRED = 106;
/**
* Server verification failed (SCRAM authentication).
*/
const LOGIN_SERVER_VERIFICATION_FAILED = 107;
// Mailbox access failures
/**
* Could not open/access mailbox
*/
const MAILBOX_NOOPEN = 200;
/**
* Could not complete the command because the mailbox is read-only
*/
const MAILBOX_READONLY = 201;
// POP3 specific error codes
/**
* Temporary issue. Generally, there is no need to alarm the user for
* errors of this type.
*/
const POP3_TEMP_ERROR = 300;
/**
* Permanent error indicated by server.
*/
const POP3_PERM_ERROR = 301;
// Unsupported feature error codes
/**
* Function/feature is not supported on this server.
*/
const NOT_SUPPORTED = 400;
/**
* Raw error message (in English).
*
* @since 2.18.0
*
* @var string
*/
public $raw_msg = '';
/**
* Constructor.
*
* @param string $message Error message (non-translated).
* @param int $code Error code.
*/
public function __construct($message = null, $code = null)
{
parent::__construct($message, $code);
$this->raw_msg = $this->message;
try {
$this->message = Horde_Imap_Client_Translation::t($this->message);
} catch (Horde_Translation_Exception $e) {}
}
/**
* Allow the error message to be altered.
*
* @param string $msg Error message.
*/
public function setMessage($msg)
{
$this->message = strval($msg);
}
/**
* Allow the error code to be altered.
*
* @param integer $code Error code.
*/
public function setCode($code)
{
$this->code = intval($code);
}
/**
* Perform substitution of variables in the error message.
*
* Needed to allow for correct translation of error message.
*
* @since 2.22.0
*
* @param array $args Arguments used for substitution.
*/
public function messagePrintf(array $args = array())
{
$this->raw_msg = vsprintf($this->raw_msg, $args);
$this->message = vsprintf($this->message, $args);
}
}

View File

@ -1,54 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception thrown for non-supported server extensions.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Exception_NoSupportExtension
extends Horde_Imap_Client_Exception
{
/**
* The extension not supported on the server.
*
* @var string
*/
public $extension;
/**
* Constructor.
*
* @param string $extension The extension not supported on the server.
* @param string $msg A non-standard error message to use instead
* of the default.
*/
public function __construct($extension, $msg = null)
{
$this->extension = $extension;
if (is_null($msg)) {
$msg = sprintf(
Horde_Imap_Client_Translation::r("The server does not support the %s extension."),
$extension
);
}
parent::__construct($msg, self::NOT_SUPPORTED);
}
}

View File

@ -1,40 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception thrown for non-supported IMAP features on POP3 servers.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Exception_NoSupportPop3
extends Horde_Imap_Client_Exception
{
/**
* Constructor.
*
* @param string $feature The feature not supported in POP3.
*/
public function __construct($feature)
{
parent::__construct(
Horde_Imap_Client_Translation::r("%s not supported on POP3 servers."),
self::NOT_SUPPORTED
);
$this->messagePrintf(array($feature));
}
}

View File

@ -1,50 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception thrown if search query text cannot be converted to different
* charset.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Exception_SearchCharset
extends Horde_Imap_Client_Exception
{
/**
* Charset that was attempted to be converted to.
*
* @var string
*/
public $charset;
/**
* Constructor.
*
* @param string $charset The charset that was attempted to be converted
* to.
*/
public function __construct($charset)
{
$this->charset = $charset;
parent::__construct(
Horde_Imap_Client_Translation::r("Cannot convert search query text to new charset"),
self::BADCHARSET
);
}
}

View File

@ -1,88 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception thrown for server error responses.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*
* @property-read string $command The command that caused the BAD/NO error
* status.
* @property-read array $resp_data The response data array.
* @property-read integer $status Server error status.
*/
class Horde_Imap_Client_Exception_ServerResponse extends Horde_Imap_Client_Exception
{
/**
* Pipeline object.
*
* @var Horde_Imap_Client_Interaction_Pipeline
*/
protected $_pipeline;
/**
* Server response object.
*
* @var Horde_Imap_Client_Interaction_Server
*/
protected $_server;
/**
* Constructor.
*
* @param string|null $msg Error message.
* @param integer $code Error code.
* @param Horde_Imap_Client_Interaction_Server $server Server ob.
* @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline ob.
*/
public function __construct(
$msg,
$code,
Horde_Imap_Client_Interaction_Server $server,
Horde_Imap_Client_Interaction_Pipeline $pipeline
)
{
$this->details = strval($server->token);
$this->_pipeline = $pipeline;
$this->_server = $server;
parent::__construct($msg, $code);
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'command':
return ($this->_server instanceof Horde_Imap_Client_Interaction_Server_Tagged)
? $this->_pipeline->getCmd($this->_server->tag)->getCommand()
: null;
case 'resp_data':
return $this->_pipeline->data;
case 'status':
return $this->_server->status;
default:
return parent::__get($name);
}
}
}

View File

@ -1,37 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Exception thrown for mailbox synchronization errors.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Exception_Sync extends Horde_Exception_Wrapped
{
/* Error message codes. */
/**
* Token could not be parsed.
*/
const BAD_TOKEN = 1;
/**
* UIDVALIDITY of the mailbox changed.
*/
const UIDVALIDITY_CHANGED = 2;
}

View File

@ -1,393 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Fetch query object for use with Horde_Imap_Client_Base#fetch().
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Fetch_Query implements ArrayAccess, Countable, Iterator
{
/**
* Internal data array.
*
* @var array
*/
protected $_data = array();
/**
* Get the full text of the message.
*
* @param array $opts The following options are available:
* - length: (integer) The length of the substring to return.
* DEFAULT: The entire text is returned.
* - peek: (boolean) If set, does not set the '\Seen' flag on the
* message.
* DEFAULT: The seen flag is set.
* - start: (integer) If a portion of the full text is desired to be
* returned, the starting position is identified here.
* DEFAULT: The entire text is returned.
*/
public function fullText(array $opts = array())
{
$this->_data[Horde_Imap_Client::FETCH_FULLMSG] = $opts;
}
/**
* Return header text.
*
* Header text is defined only for the base RFC 2822 message or
* message/rfc822 parts.
*
* @param array $opts The following options are available:
* - id: (string) The MIME ID to obtain the header text for.
* DEFAULT: The header text for the base message will be
* returned.
* - length: (integer) The length of the substring to return.
* DEFAULT: The entire text is returned.
* - peek: (boolean) If set, does not set the '\Seen' flag on the
* message.
* DEFAULT: The seen flag is set.
* - start: (integer) If a portion of the full text is desired to be
* returned, the starting position is identified here.
* DEFAULT: The entire text is returned.
*/
public function headerText(array $opts = array())
{
$id = isset($opts['id'])
? $opts['id']
: 0;
$this->_data[Horde_Imap_Client::FETCH_HEADERTEXT][$id] = $opts;
}
/**
* Return body text.
*
* Body text is defined only for the base RFC 2822 message or
* message/rfc822 parts.
*
* @param array $opts The following options are available:
* - id: (string) The MIME ID to obtain the body text for.
* DEFAULT: The body text for the entire message will be
* returned.
* - length: (integer) The length of the substring to return.
* DEFAULT: The entire text is returned.
* - peek: (boolean) If set, does not set the '\Seen' flag on the
* message.
* DEFAULT: The seen flag is set.
* - start: (integer) If a portion of the full text is desired to be
* returned, the starting position is identified here.
* DEFAULT: The entire text is returned.
*/
public function bodyText(array $opts = array())
{
$id = isset($opts['id'])
? $opts['id']
: 0;
$this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id] = $opts;
}
/**
* Return MIME header text.
*
* MIME header text is defined only for non-RFC 2822 messages and
* non-message/rfc822 parts.
*
* @param string $id The MIME ID to obtain the MIME header text for.
* @param array $opts The following options are available:
* - length: (integer) The length of the substring to return.
* DEFAULT: The entire text is returned.
* - peek: (boolean) If set, does not set the '\Seen' flag on the
* message.
* DEFAULT: The seen flag is set.
* - start: (integer) If a portion of the full text is desired to be
* returned, the starting position is identified here.
* DEFAULT: The entire text is returned.
*/
public function mimeHeader($id, array $opts = array())
{
$this->_data[Horde_Imap_Client::FETCH_MIMEHEADER][$id] = $opts;
}
/**
* Return the body part data for a MIME ID.
*
* @param string $id The MIME ID to obtain the body part text for.
* @param array $opts The following options are available:
* - decode: (boolean) Attempt to server-side decode the bodypart data
* if it is MIME transfer encoded.
* DEFAULT: false
* - length: (integer) The length of the substring to return.
* DEFAULT: The entire text is returned.
* - peek: (boolean) If set, does not set the '\Seen' flag on the
* message.
* DEFAULT: The seen flag is set.
* - start: (integer) If a portion of the full text is desired to be
* returned, the starting position is identified here.
* DEFAULT: The entire text is returned.
*/
public function bodyPart($id, array $opts = array())
{
$this->_data[Horde_Imap_Client::FETCH_BODYPART][$id] = $opts;
}
/**
* Returns the decoded body part size for a MIME ID.
*
* @param string $id The MIME ID to obtain the decoded body part size
* for.
*/
public function bodyPartSize($id)
{
$this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id] = true;
}
/**
* Returns RFC 2822 header text that matches a search string.
*
* This header search work only with the base RFC 2822 message or
* message/rfc822 parts.
*
* @param string $label A unique label associated with this particular
* search. This is how the results are stored.
* @param array $search The search string(s) (case-insensitive).
* @param array $opts The following options are available:
* - cache: (boolean) If true, and 'peek' is also true, will cache
* the result of this call.
* DEFAULT: false
* - id: (string) The MIME ID to search.
* DEFAULT: The base message part
* - length: (integer) The length of the substring to return.
* DEFAULT: The entire text is returned.
* - notsearch: (boolean) Do a 'NOT' search on the headers.
* DEFAULT: false
* - peek: (boolean) If set, does not set the '\Seen' flag on the
* message.
* DEFAULT: The seen flag is set.
* - start: (integer) If a portion of the full text is desired to be
* returned, the starting position is identified here.
* DEFAULT: The entire text is returned.
*/
public function headers($label, $search, array $opts = array())
{
$this->_data[Horde_Imap_Client::FETCH_HEADERS][$label] = array_merge(
$opts,
array(
'headers' => array_map('strval', $search)
)
);
}
/**
* Return MIME structure information.
*/
public function structure()
{
$this->_data[Horde_Imap_Client::FETCH_STRUCTURE] = true;
}
/**
* Return envelope header data.
*/
public function envelope()
{
$this->_data[Horde_Imap_Client::FETCH_ENVELOPE] = true;
}
/**
* Return flags set for the message.
*/
public function flags()
{
$this->_data[Horde_Imap_Client::FETCH_FLAGS] = true;
}
/**
* Return the internal (IMAP) date of the message.
*/
public function imapDate()
{
$this->_data[Horde_Imap_Client::FETCH_IMAPDATE] = true;
}
/**
* Return the size (in bytes) of the message.
*/
public function size()
{
$this->_data[Horde_Imap_Client::FETCH_SIZE] = true;
}
/**
* Return the unique ID of the message.
*/
public function uid()
{
$this->_data[Horde_Imap_Client::FETCH_UID] = true;
}
/**
* Return the sequence number of the message.
*/
public function seq()
{
$this->_data[Horde_Imap_Client::FETCH_SEQ] = true;
}
/**
* Return the mod-sequence value for the message.
*
* The server must support the CONDSTORE IMAP extension, and the mailbox
* must support mod-sequences.
*/
public function modseq()
{
$this->_data[Horde_Imap_Client::FETCH_MODSEQ] = true;
}
/**
* Does the query contain the given criteria?
*
* @param integer $criteria The criteria to remove.
*
* @return boolean True if the query contains the given criteria.
*/
public function contains($criteria)
{
return isset($this->_data[$criteria]);
}
/**
* Remove an entry under a given criteria.
*
* @param integer $criteria Criteria ID.
* @param string $key The key to remove.
*/
public function remove($criteria, $key)
{
if (isset($this->_data[$criteria]) &&
is_array($this->_data[$criteria])) {
unset($this->_data[$criteria][$key]);
if (empty($this->_data[$criteria])) {
unset($this->_data[$criteria]);
}
}
}
/**
* Returns a hash of the current query object.
*
* @return string Hash.
*/
public function hash()
{
return hash('md5', serialize($this));
}
/* ArrayAccess methods. */
/**
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->_data[$offset]);
}
/**
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
return isset($this->_data[$offset])
? $this->_data[$offset]
: null;
}
/**
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->_data[$offset] = $value;
}
/**
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->_data[$offset]);
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_data);
}
/* Iterator methods. */
/**
*/
#[ReturnTypeWillChange]
public function current()
{
$opts = current($this->_data);
return (!empty($opts) && ($this->key() == Horde_Imap_Client::FETCH_BODYPARTSIZE))
? array_keys($opts)
: $opts;
}
/**
*/
#[ReturnTypeWillChange]
public function key()
{
return key($this->_data);
}
/**
*/
#[ReturnTypeWillChange]
public function next()
{
next($this->_data);
}
/**
*/
#[ReturnTypeWillChange]
public function rewind()
{
reset($this->_data);
}
/**
*/
#[ReturnTypeWillChange]
public function valid()
{
return !is_null($this->key());
}
}

View File

@ -1,188 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Fetch results object for use with Horde_Imap_Client_Base#fetch().
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*
* @property-read integer $key_type The key type (sequence or UID).
*/
class Horde_Imap_Client_Fetch_Results
implements ArrayAccess, Countable, IteratorAggregate
{
/**
* Key type constants.
*/
const SEQUENCE = 1;
const UID = 2;
/**
* Internal data array.
*
* @var array
*/
protected $_data = array();
/**
* Key type.
*
* @var integer
*/
protected $_keyType;
/**
* Class to use when creating a new fetch object.
*
* @var string
*/
protected $_obClass;
/**
* Constructor.
*
* @param string $ob_class Class to use when creating a new fetch
* object.
* @param integer $key_type Key type.
*/
public function __construct($ob_class = 'Horde_Imap_Client_Data_Fetch',
$key_type = self::UID)
{
$this->_obClass = $ob_class;
$this->_keyType = $key_type;
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'key_type':
return $this->_keyType;
}
}
/**
* Return a fetch object, creating and storing an empty object in the
* results set if it doesn't currently exist.
*
* @param string $key The key to retrieve.
*
* @return Horde_Imap_Client_Data_Fetch The fetch object.
*/
public function get($key)
{
if (!isset($this->_data[$key])) {
$this->_data[$key] = new $this->_obClass();
}
return $this->_data[$key];
}
/**
* Return the list of IDs.
*
* @return array ID list.
*/
public function ids()
{
ksort($this->_data);
return array_keys($this->_data);
}
/**
* Return the first fetch object in the results, if there is only one
* object.
*
* @return null|Horde_Imap_Client_Data_Fetch The fetch object if there is
* only one object, or null.
*/
public function first()
{
return (count($this->_data) === 1)
? reset($this->_data)
: null;
}
/**
* Clears all fetch results.
*
* @since 2.6.0
*/
public function clear()
{
$this->_data = array();
}
/* ArrayAccess methods. */
/**
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->_data[$offset]);
}
/**
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
return isset($this->_data[$offset])
? $this->_data[$offset]
: null;
}
/**
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->_data[$offset] = $value;
}
/**
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->_data[$offset]);
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_data);
}
/* IteratorAggregate methods. */
/**
*/
#[ReturnTypeWillChange]
public function getIterator()
{
ksort($this->_data);
return new ArrayIterator($this->_data);
}
}

View File

@ -1,511 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object that provides a way to identify a list of IMAP indices.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*
* @property-read boolean $all Does this represent an ALL message set?
* @property-read array $ids The list of IDs.
* @property-read boolean $largest Does this represent the largest ID in use?
* @property-read string $max The largest ID (@since 2.20.0).
* @property-read string $min The smallest ID (@since 2.20.0).
* @property-read string $range_string Generates a range string consisting of
* all messages between begin and end of
* ID list.
* @property-read boolean $search_res Does this represent a search result?
* @property-read boolean $sequence Are these sequence IDs? If false, these
* are UIDs.
* @property-read boolean $special True if this is a "special" ID
* representation.
* @property-read string $tostring Return the non-sorted string
* representation.
* @property-read string $tostring_sort Return the sorted string
* representation.
*/
class Horde_Imap_Client_Ids implements Countable, Iterator, Serializable
{
/**
* "Special" representation constants.
*/
const ALL = "\01";
const SEARCH_RES = "\02";
const LARGEST = "\03";
/**
* Allow duplicate IDs?
*
* @var boolean
*/
public $duplicates = false;
/**
* List of IDs.
*
* @var mixed
*/
protected $_ids = array();
/**
* Are IDs message sequence numbers?
*
* @var boolean
*/
protected $_sequence = false;
/**
* Are IDs sorted?
*
* @var boolean
*/
protected $_sorted = false;
/**
* Constructor.
*
* @param mixed $ids See self::add().
* @param boolean $sequence Are $ids message sequence numbers?
*/
public function __construct($ids = null, $sequence = false)
{
$this->add($ids);
$this->_sequence = $sequence;
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'all':
return ($this->_ids === self::ALL);
case 'ids':
return is_array($this->_ids)
? $this->_ids
: array();
case 'largest':
return ($this->_ids === self::LARGEST);
case 'max':
$this->sort();
return end($this->_ids);
case 'min':
$this->sort();
return reset($this->_ids);
case 'range_string':
if (!count($this)) {
return '';
}
$min = $this->min;
$max = $this->max;
return ($min == $max)
? $min
: $min . ':' . $max;
case 'search_res':
return ($this->_ids === self::SEARCH_RES);
case 'sequence':
return (bool)$this->_sequence;
case 'special':
return is_string($this->_ids);
case 'tostring':
case 'tostring_sort':
if ($this->all) {
return '1:*';
} elseif ($this->largest) {
return '*';
} elseif ($this->search_res) {
return '$';
}
return strval($this->_toSequenceString($name == 'tostring_sort'));
}
}
/**
*/
public function __toString()
{
return $this->tostring;
}
/**
* Add IDs to the current object.
*
* @param mixed $ids Either self::ALL, self::SEARCH_RES, self::LARGEST,
* Horde_Imap_Client_Ids object, array, or sequence
* string.
*/
public function add($ids)
{
if (!is_null($ids)) {
if (is_string($ids) &&
in_array($ids, array(self::ALL, self::SEARCH_RES, self::LARGEST))) {
$this->_ids = $ids;
} elseif ($add = $this->_resolveIds($ids)) {
if (is_array($this->_ids) && !empty($this->_ids)) {
foreach ($add as $val) {
$this->_ids[] = $val;
}
} else {
$this->_ids = $add;
}
if (!$this->duplicates) {
$this->_ids = (count($this->_ids) > 25000)
? array_unique($this->_ids)
: array_keys(array_flip($this->_ids));
}
}
$this->_sorted = is_array($this->_ids) && (count($this->_ids) === 1);
}
}
/**
* Removed IDs from the current object.
*
* @since 2.17.0
*
* @param mixed $ids Either Horde_Imap_Client_Ids object, array, or
* sequence string.
*/
public function remove($ids)
{
if (!$this->isEmpty() &&
($remove = $this->_resolveIds($ids))) {
$this->_ids = array_diff($this->_ids, array_unique($remove));
}
}
/**
* Is this object empty (i.e. does not contain IDs)?
*
* @return boolean True if object is empty.
*/
public function isEmpty()
{
return (is_array($this->_ids) && !count($this->_ids));
}
/**
* Reverses the order of the IDs.
*/
public function reverse()
{
if (is_array($this->_ids)) {
$this->_ids = array_reverse($this->_ids);
}
}
/**
* Sorts the IDs.
*/
public function sort()
{
if (!$this->_sorted && is_array($this->_ids)) {
$this->_sort($this->_ids);
$this->_sorted = true;
}
}
/**
* Sorts the IDs numerically.
*
* @param array $ids The array list.
*/
protected function _sort(&$ids)
{
sort($ids, SORT_NUMERIC);
}
/**
* Split the sequence string at an approximate length.
*
* @since 2.7.0
*
* @param integer $length Length to split.
*
* @return array A list containing individual sequence strings.
*/
public function split($length)
{
$id = new Horde_Stream_Temp();
$id->add($this->tostring_sort, true);
$out = array();
do {
$out[] = $id->substring(0, $length) . $id->getToChar(',');
} while (!$id->eof());
return $out;
}
/**
* Resolve the $ids input to add() and remove().
*
* @param mixed $ids Either Horde_Imap_Client_Ids object, array, or
* sequence string.
*
* @return array An array of IDs.
*/
protected function _resolveIds($ids)
{
if ($ids instanceof Horde_Imap_Client_Ids) {
return $ids->ids;
} elseif (is_array($ids)) {
return $ids;
} elseif (is_string($ids) || is_integer($ids)) {
return is_numeric($ids)
? array($ids)
: $this->_fromSequenceString($ids);
}
return array();
}
/**
* Create an IMAP message sequence string from a list of indices.
*
* Index Format: range_start:range_end,uid,uid2,...
*
* @param boolean $sort Numerically sort the IDs before creating the
* range?
*
* @return string The IMAP message sequence string.
*/
protected function _toSequenceString($sort = true)
{
if (empty($this->_ids)) {
return '';
}
$in = $this->_ids;
if ($sort && !$this->_sorted) {
$this->_sort($in);
}
$first = $last = array_shift($in);
$i = count($in) - 1;
$out = array();
foreach ($in as $key => $val) {
if (($last + 1) == $val) {
$last = $val;
}
if (($i == $key) || ($last != $val)) {
if ($last == $first) {
$out[] = $first;
if ($i == $key) {
$out[] = $val;
}
} else {
$out[] = $first . ':' . $last;
if (($i == $key) && ($last != $val)) {
$out[] = $val;
}
}
$first = $last = $val;
}
}
return empty($out)
? $first
: implode(',', $out);
}
/**
* Parse an IMAP message sequence string into a list of indices.
*
* @see _toSequenceString()
*
* @param string $str The IMAP message sequence string.
*
* @return array An array of indices.
*/
protected function _fromSequenceString($str)
{
$ids = array();
$str = trim($str);
if (!strlen($str)) {
return $ids;
}
$idarray = explode(',', $str);
foreach ($idarray as $val) {
$range = explode(':', $val);
if (isset($range[1])) {
for ($i = min($range), $j = max($range); $i <= $j; ++$i) {
$ids[] = $i;
}
} else {
$ids[] = $val;
}
}
return $ids;
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return is_array($this->_ids)
? count($this->_ids)
: 0;
}
/* Iterator methods. */
/**
*/
#[ReturnTypeWillChange]
public function current()
{
return is_array($this->_ids)
? current($this->_ids)
: null;
}
/**
*/
#[ReturnTypeWillChange]
public function key()
{
return is_array($this->_ids)
? key($this->_ids)
: null;
}
/**
*/
#[ReturnTypeWillChange]
public function next()
{
if (is_array($this->_ids)) {
next($this->_ids);
}
}
/**
*/
#[ReturnTypeWillChange]
public function rewind()
{
if (is_array($this->_ids)) {
reset($this->_ids);
}
}
/**
*/
#[ReturnTypeWillChange]
public function valid()
{
return !is_null($this->key());
}
public function serialize()
{
return serialize($this->__serialize());
}
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version change.');
}
$this->__unserialize($data);
}
/**
*/
public function __serialize()
{
$save = array();
if ($this->duplicates) {
$save['d'] = 1;
}
if ($this->_sequence) {
$save['s'] = 1;
}
if ($this->_sorted) {
$save['is'] = 1;
}
switch ($this->_ids) {
case self::ALL:
$save['a'] = true;
break;
case self::LARGEST:
$save['l'] = true;
break;
case self::SEARCH_RES:
$save['sr'] = true;
break;
default:
$save['i'] = strval($this);
break;
}
return $save;
}
/**
*/
public function __unserialize($data)
{
$this->duplicates = !empty($data['d']);
$this->_sequence = !empty($data['s']);
$this->_sorted = !empty($data['is']);
if (isset($data['a'])) {
$this->_ids = self::ALL;
} elseif (isset($data['l'])) {
$this->_ids = self::LARGEST;
} elseif (isset($data['sr'])) {
$this->_ids = self::SEARCH_RES;
} elseif (isset($data['i'])) {
$this->add($data['i']);
}
}
}

View File

@ -1,256 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object implementing lookups between UIDs and message sequence numbers.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.1.0
*
* @property-read array $map The raw ID mapping data.
* @property-read Horde_Imap_Client_Ids $seq The sorted sequence values.
* @property-read Horde_Imap_Client_Ids $uids The sorted UIDs.
*/
class Horde_Imap_Client_Ids_Map implements Countable, IteratorAggregate, Serializable
{
/**
* Sequence -> UID mapping.
*
* @var array
*/
protected $_ids = array();
/**
* Is the array sorted?
*
* @var boolean
*/
protected $_sorted = true;
/**
* Constructor.
*
* @param array $ids Array of sequence -> UID mapping.
*/
public function __construct(array $ids = array())
{
$this->update($ids);
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'map':
return $this->_ids;
case 'seq':
$this->sort();
return new Horde_Imap_Client_Ids(array_keys($this->_ids), true);
case 'uids':
$this->sort();
return new Horde_Imap_Client_Ids($this->_ids);
}
}
/**
* Updates the mapping.
*
* @param array $ids Array of sequence -> UID mapping.
*
* @return boolean True if the mapping changed.
*/
public function update($ids)
{
if (empty($ids)) {
return false;
} elseif (empty($this->_ids)) {
$this->_ids = $ids;
$change = true;
} else {
$change = false;
foreach ($ids as $k => $v) {
if (!isset($this->_ids[$k]) || ($this->_ids[$k] != $v)) {
$this->_ids[$k] = $v;
$change = true;
}
}
}
if ($change) {
$this->_sorted = false;
}
return $change;
}
/**
* Create a Sequence <-> UID lookup table.
*
* @param Horde_Imap_Client_Ids $ids IDs to lookup.
*
* @return array Keys are sequence numbers, values are UIDs.
*/
public function lookup(Horde_Imap_Client_Ids $ids)
{
if ($ids->all) {
return $this->_ids;
} elseif ($ids->sequence) {
return array_intersect_key($this->_ids, array_flip($ids->ids));
}
return array_intersect($this->_ids, $ids->ids);
}
/**
* Removes messages from the ID mapping.
*
* @param Horde_Imap_Client_Ids $ids IDs to remove.
*/
public function remove(Horde_Imap_Client_Ids $ids)
{
/* For sequence numbers, we need to reindex anytime we have an index
* that appears equal to or after a previously seen index. If an IMAP
* server is smart, it will expunge in reverse order instead. */
if ($ids->sequence) {
$remove = $ids->ids;
} else {
$ids->sort();
$remove = array_reverse(array_keys($this->lookup($ids)));
}
if (empty($remove)) {
return;
}
$this->sort();
if (count($remove) == count($this->_ids) &&
!array_diff($remove, array_keys($this->_ids))) {
$this->_ids = array();
return;
}
/* Find the minimum sequence number to remove. We know entries before
* this are untouched so no need to process them multiple times. */
$first = min($remove);
$edit = $newids = array();
foreach (array_keys($this->_ids) as $i => $seq) {
if ($seq >= $first) {
$i += (($seq == $first) ? 0 : 1);
$newids = array_slice($this->_ids, 0, $i, true);
$edit = array_slice($this->_ids, $i + (($seq == $first) ? 0 : 1), null, true);
break;
}
}
if (!empty($edit)) {
foreach ($remove as $val) {
$found = false;
$tmp = array();
foreach (array_keys($edit) as $i => $seq) {
if ($found) {
$tmp[$seq - 1] = $edit[$seq];
} elseif ($seq >= $val) {
$tmp = array_slice($edit, 0, ($seq == $val) ? $i : $i + 1, true);
$found = true;
}
}
$edit = $tmp;
}
}
$this->_ids = $newids + $edit;
}
/**
* Sort the map.
*/
public function sort()
{
if (!$this->_sorted) {
ksort($this->_ids, SORT_NUMERIC);
$this->_sorted = true;
}
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_ids);
}
/* IteratorAggregate method. */
/**
*/
#[ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->_ids);
}
/* Serializable methods. */
public function serialize()
{
return serialize($this->__serialize());
}
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache version change.');
}
$this->__unserialize($data);
}
/**
*/
public function __serialize()
{
/* Sort before storing; provides more compressible representation. */
$this->sort();
return [
strval(new Horde_Imap_Client_Ids(array_keys($this->_ids))),
strval(new Horde_Imap_Client_Ids(array_values($this->_ids)))
];
}
/**
*/
public function __unserialize($data)
{
$keys = new Horde_Imap_Client_Ids($data[0]);
$vals = new Horde_Imap_Client_Ids($data[1]);
$this->_ids = array_combine($keys->ids, $vals->ids);
/* Guaranteed to be sorted if unserializing. */
$this->_sorted = true;
}
}

View File

@ -1,64 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Wrapper around Ids object that correctly handles POP3 UID strings.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Ids_Pop3 extends Horde_Imap_Client_Ids
{
/**
*/
protected function _sort(&$ids)
{
/* There is no guarantee of POP3 UIDL order - IDs need to be unique,
* but there is no requirement they need be incrementing. RFC
* 1939[7] */
}
/**
* Create a POP3 message sequence string.
*
* Index Format: UID1[SPACE]UID2...
*
* @param boolean $sort Not used in this class.
*
* @return string The POP3 message sequence string.
*/
protected function _toSequenceString($sort = true)
{
/* $sort is ignored - see _sort(). */
/* Use space as delimiter as it is the only printable ASCII character
* that is not allowed as part of the UID (RFC 1939 [7]). */
return implode(' ', count($this->_ids) > 25000 ? array_unique($this->_ids) : array_keys(array_flip($this->_ids)));
}
/**
* Parse a POP3 message sequence string into a list of indices.
*
* @param string $str The POP3 message sequence string.
*
* @return array An array of UIDs.
*/
protected function _fromSequenceString($str)
{
return explode(' ', trim($str));
}
}

View File

@ -1,61 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing an IMAP client command interaction (RFC 3501
* [2.2.1]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2016 Horde LLC
* @deprecated
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Interaction_Client extends Horde_Imap_Client_Data_Format_List
{
/**
* The command tag.
*
* @var string
*/
public $tag;
/**
* Constructor.
*
* @param string $tag The tag to use. If not set, will be automatically
* generated.
*/
public function __construct($tag = null)
{
$this->tag = is_null($tag)
? substr(strval(new Horde_Support_Randomid()), 0, 10)
: strval($tag);
parent::__construct($this->tag);
}
/**
* Get the command.
*
* @return string The command.
*/
public function getCommand()
{
return isset($this->_data[1])
? $this->_data[1]
: null;
}
}

View File

@ -1,184 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing an IMAP command (RFC 3501 [2.2.1]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.10.0
*
* @property-read boolean $continuation True if the command requires a server
* continuation response.
*/
class Horde_Imap_Client_Interaction_Command
extends Horde_Imap_Client_Data_Format_List
{
/**
* Debug string(s) to use instead of command text.
*
* Multiple entries refer to the various steps in a continuation command.
*
* @var array
*/
public $debug = array();
/**
* Use LITERAL+ if available
*
* @var boolean
*/
public $literalplus = true;
/**
* Are literal8's available?
*
* @var boolean
*/
public $literal8 = false;
/**
* A callback to run on error.
*
* If callback returns true, the command will be treated as successful.
*
* @since 2.24.0
*
* @var callback
*/
public $on_error = null;
/**
* A callback to run on success.
*
* @since 2.28.0
*
* @var callback
*/
public $on_success = null;
/**
* Pipeline object associated with this command.
*
* @since 2.28.0
*
* @var Horde_Imap_Client_Interaction_Pipeline
*/
public $pipeline;
/**
* Server response.
*
* @var Horde_Imap_Client_Interaction_Server
*/
public $response;
/**
* The command tag.
*
* @var string
*/
public $tag;
/**
* Command timer.
*
* @var Horde_Support_Timer
*/
protected $_timer;
/**
* Constructor.
*
* @param string $cmd The IMAP command.
* @param string $tag The tag to use. If not set, will be automatically
* generated.
*/
public function __construct($cmd, $tag = null)
{
$this->tag = is_null($tag)
? substr(new Horde_Support_Randomid(), 0, 10)
: strval($tag);
parent::__construct($this->tag);
$this->add($cmd);
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'continuation':
return $this->_continuationCheck($this);
}
}
/**
* Get the command.
*
* @return string The command.
*/
public function getCommand()
{
return $this->_data[1];
}
/**
* Start the command timer.
*/
public function startTimer()
{
$this->_timer = new Horde_Support_Timer();
$this->_timer->push();
}
/**
* Return the timer data.
*
* @return mixed Null if timer wasn't started, or a float containing
* elapsed command time.
*/
public function getTimer()
{
return $this->_timer
? round($this->_timer->pop(), 4)
: null;
}
/**
* Recursive check for continuation functions.
*/
protected function _continuationCheck($list)
{
foreach ($list as $val) {
if (($val instanceof Horde_Imap_Client_Interaction_Command_Continuation) ||
(($val instanceof Horde_Imap_Client_Data_Format_String) &&
$val->literal())) {
return true;
}
if (($val instanceof Horde_Imap_Client_Data_Format_List) &&
$this->_continuationCheck($val)) {
return true;
}
}
return false;
}
}

View File

@ -1,74 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing a portion of an IMAP command that requires data
* sent in a continuation response (RFC 3501 [2.2.1]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.10.0
*/
class Horde_Imap_Client_Interaction_Command_Continuation
{
/**
* Is this an optional continuation request?
*
* @since 2.13.0
* @var boolean
*/
public $optional = false;
/**
* Closure function to run after continuation response.
*
* @var Closure
*/
protected $_closure;
/**
* Constructor.
*
* @param Closure $closure A function to run after the continuation
* response is received. It receives one
* argument - a Continuation object - and should
* return a list of arguments to send to the
* server (via a
* Horde_Imap_Client_Data_Format_List object).
*/
public function __construct($closure)
{
$this->_closure = $closure;
}
/**
* Calls the closure object.
*
* @param Horde_Imap_Client_Interaction_Server_Continuation $ob Continuation
* object.
*
* @return Horde_Imap_Client_Data_Format_List Further commands to issue
* to the server.
*/
public function getCommands(
Horde_Imap_Client_Interaction_Server_Continuation $ob
)
{
$closure = $this->_closure;
return $closure($ob);
}
}

View File

@ -1,162 +0,0 @@
<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing a series of IMAP client commands (RFC 3501 [2.2.1])
* to be processed at the same time.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.10.0
*
* @property-read boolean $finished True if all commands have finished.
*/
class Horde_Imap_Client_Interaction_Pipeline implements Countable, IteratorAggregate
{
/**
* Data storage from server responses.
*
* @var array
*/
public $data = array(
'modseqs' => array(),
'modseqs_nouid' => array()
);
/**
* Fetch results.
*
* @var Horde_Imap_Client_Fetch_Results
*/
public $fetch;
/**
* The list of commands.
*
* @var array
*/
protected $_commands = array();
/**
* The list of commands to complete.
*
* @var array
*/
protected $_todo = array();
/**
* Constructor.
*
* @param Horde_Imap_Client_Fetch_Results $fetch Fetch results object.
*/
public function __construct(Horde_Imap_Client_Fetch_Results $fetch)
{
$this->fetch = $fetch;
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'finished':
return empty($this->_todo);
}
}
/**
* Add a command to the pipeline.
*
* @param Horde_Imap_Client_Interaction_Command $cmd Command object.
* @param boolean $top Add command to top
* of queue?
*/
public function add(Horde_Imap_Client_Interaction_Command $cmd,
$top = false)
{
if ($top) {
// This won't re-index keys, which may be numerical.
$this->_commands = array($cmd->tag => $cmd) + $this->_commands;
} else {
$this->_commands[$cmd->tag] = $cmd;
}
$this->_todo[$cmd->tag] = true;
}
/**
* Mark a command as completed.
*
* @param Horde_Imap_Client_Interaction_Server_Tagged $resp Tagged server
* response.
*
* @return Horde_Imap_Client_Interaction_Command Command that was
* completed. Returns null
* if tagged response
* is not contained in this
* pipeline object.
*/
public function complete(Horde_Imap_Client_Interaction_Server_Tagged $resp)
{
if (isset($this->_commands[$resp->tag])) {
$cmd = $this->_commands[$resp->tag];
$cmd->response = $resp;
unset($this->_todo[$resp->tag]);
} else {
/* This can be reached if a previous pipeline action was aborted,
* e.g. via an Exception. */
$cmd = null;
}
return $cmd;
}
/**
* Return the command for a given tag.
*
* @param string $tag The command tag.
*
* @return Horde_Imap_Client_Interaction_Command A command object (or
* null if the tag does
* not exist).
*/
public function getCmd($tag)
{
return isset($this->_commands[$tag])
? $this->_commands[$tag]
: null;
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_commands);
}
/* IteratorAggregate methods. */
/**
*/
#[ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->_commands);
}
}

View File

@ -1,144 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing an IMAP server command interaction (RFC 3501
* [2.2.2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Interaction_Server
{
/**
* Response codes (RFC 3501 [7.1]).
*/
const BAD = 1;
const BYE = 2;
const NO = 3;
const OK = 4;
const PREAUTH = 5;
/**
* Check for status response?
*
* @var boolean
*/
protected $_checkStatus = true;
/**
* Response code (RFC 3501 [7.1]). Properties:
* - code: (string) Response code.
* - data: (array) Data associated with response.
*
* @var object
*/
public $responseCode = null;
/**
* Status response from the server.
*
* @var string
*/
public $status = null;
/**
* IMAP server data.
*
* @var Horde_Imap_Client_Tokenize
*/
public $token;
/**
* Auto-scan an incoming line to determine the response type.
*
* @param Horde_Imap_Client_Tokenize $t Tokenized data returned from the
* server.
*
* @return Horde_Imap_Client_Interaction_Server A server response object.
*/
public static function create(Horde_Imap_Client_Tokenize $t)
{
$t->rewind();
$tag = $t->next();
$t->next();
switch ($tag) {
case '+':
return new Horde_Imap_Client_Interaction_Server_Continuation($t);
case '*':
return new Horde_Imap_Client_Interaction_Server_Untagged($t);
default:
return new Horde_Imap_Client_Interaction_Server_Tagged($t, $tag);
}
}
/**
* Constructor.
*
* @param Horde_Imap_Client_Tokenize $token Tokenized data returned from
* the server.
*/
public function __construct(Horde_Imap_Client_Tokenize $token)
{
$this->token = $token;
/* Check for response status. */
$status = $token->current();
$valid = array('BAD', 'BYE', 'NO', 'OK', 'PREAUTH');
if (in_array($status, $valid)) {
$this->status = constant(__CLASS__ . '::' . $status);
$resp_text = $token->next();
/* Check for response code. Only occurs if there is a response
* status. */
if (is_string($resp_text) && ($resp_text[0] === '[')) {
$resp = new stdClass;
$resp->data = array();
if ($resp_text[strlen($resp_text) - 1] === ']') {
$resp->code = substr($resp_text, 1, -1);
} else {
$resp->code = substr($resp_text, 1);
while (($elt = $token->next()) !== false) {
if (is_string($elt) && $elt[strlen($elt) - 1] === ']') {
$resp->data[] = substr($elt, 0, -1);
break;
}
$resp->data[] = is_string($elt)
? $elt
: $token->flushIterator();
}
}
$token->next();
$this->responseCode = $resp;
}
}
}
/**
*/
public function __toString()
{
return strval($this->token);
}
}

View File

@ -1,25 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing an IMAP continuation response (RFC 3501 [2.2.2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Interaction_Server_Continuation extends Horde_Imap_Client_Interaction_Server
{
}

View File

@ -1,49 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing an IMAP tagged response (RFC 3501 [2.2.2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Interaction_Server_Tagged
extends Horde_Imap_Client_Interaction_Server
{
/**
* Tag.
*
* @var string
*/
public $tag;
/**
* @param string $tag Response tag.
*/
public function __construct(Horde_Imap_Client_Tokenize $token, $tag)
{
$this->tag = $tag;
parent::__construct($token);
if (is_null($this->status)) {
throw new Horde_Imap_Client_Exception(
Horde_Imap_Client_Translation::r("Bad tagged response.")
);
}
}
}

View File

@ -1,25 +0,0 @@
<?php
/**
* Copyright 2012-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object representing an IMAP untagged response (RFC 3501 [2.2.2]).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2012-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Interaction_Server_Untagged extends Horde_Imap_Client_Interaction_Server
{
}

View File

@ -1,164 +0,0 @@
<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* An object that provides a way to switch between UTF7-IMAP and
* human-readable representations of a mailbox name.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*
* @property-read string $list_escape Escapes mailbox for use in LIST
* command (UTF-8).
* @property-read string $utf7imap Mailbox in UTF7-IMAP.
* @property-read string $utf8 Mailbox in UTF-8.
*/
class Horde_Imap_Client_Mailbox implements Serializable
{
/**
* UTF7-IMAP representation of mailbox.
* If boolean true, it is identical to UTF-8 representation.
*
* @var mixed
*/
protected $_utf7imap;
/**
* UTF8 representation of mailbox.
*
* @var string
*/
protected $_utf8;
/**
* Shortcut to obtaining mailbox object.
*
* @param string $mbox The mailbox name.
* @param boolean $utf7imap Is mailbox UTF7-IMAP encoded? Otherwise,
* mailbox is assumed to be UTF-8.
*
* @return Horde_Imap_Client_Mailbox A mailbox object.
*/
public static function get($mbox, $utf7imap = false)
{
return ($mbox instanceof Horde_Imap_Client_Mailbox)
? $mbox
: new Horde_Imap_Client_Mailbox($mbox, $utf7imap);
}
/**
* Constructor.
*
* @param string $mbox The mailbox name.
* @param boolean $utf7imap Is mailbox UTF7-IMAP encoded (true).
* Otherwise, mailbox is assumed to be UTF-8
* encoded.
*/
public function __construct($mbox, $utf7imap = false)
{
if (strcasecmp($mbox, 'INBOX') === 0) {
$mbox = 'INBOX';
}
if ($utf7imap) {
$this->_utf7imap = $mbox;
} else {
$this->_utf8 = $mbox;
}
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'list_escape':
return preg_replace("/\*+/", '%', $this->utf8);
case 'utf7imap':
if (!isset($this->_utf7imap)) {
$n = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($this->_utf8);
$this->_utf7imap = ($n == $this->_utf8)
? true
: $n;
}
return ($this->_utf7imap === true)
? $this->_utf8
: $this->_utf7imap;
case 'utf8':
if (!isset($this->_utf8)) {
$this->_utf8 = Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($this->_utf7imap);
if ($this->_utf8 == $this->_utf7imap) {
$this->_utf7imap = true;
}
}
return (string)$this->_utf8;
}
}
/**
*/
public function __toString()
{
return $this->utf8;
}
/**
* Compares this mailbox to another mailbox string.
*
* @return boolean True if the items are equal.
*/
public function equals($mbox)
{
return ($this->utf8 == $mbox);
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize($this->__serialize());
}
/**
*/
public function unserialize($data)
{
$data = @unserialize($data);
if (!is_array($data)) {
throw new Exception('Cache value changed.');
}
$this->__unserialize($data);
}
/**
* @return array
*/
public function __serialize()
{
return [$this->_utf7imap, $this->_utf8];
}
public function __unserialize(array $data)
{
list($this->_utf7imap, $this->_utf8) = $data;
}
}

View File

@ -1,160 +0,0 @@
<?php
/**
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2004-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* Container of IMAP mailboxes.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2004-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
class Horde_Imap_Client_Mailbox_List implements Countable, IteratorAggregate
{
/**
* The delimiter character to use.
*
* @var string
*/
protected $_delimiter;
/**
* Mailbox list.
*
* @var array
*/
protected $_mboxes = array();
/**
* Should we sort with INBOX at the front of the list?
*
* @var boolean
*/
protected $_sortinbox;
/**
* Constructor.
*
* @param mixed $mboxes A mailbox or list of mailboxes.
*/
public function __construct($mboxes)
{
$this->_mboxes = is_array($mboxes)
? $mboxes
: array($mboxes);
}
/**
* Sort the list of mailboxes.
*
* @param array $opts Options:
* - delimiter: (string) The delimiter to use.
* DEFAULT: '.'
* - inbox: (boolean) Always put INBOX at the head of the list?
* DEFAULT: Yes
* - noupdate: (boolean) Do not update the object's mailbox list?
* DEFAULT: true
*
* @return array List of sorted mailboxes (index association is kept).
*/
public function sort(array $opts = array())
{
$this->_delimiter = isset($opts['delimiter'])
? $opts['delimiter']
: '.';
$this->_sortinbox = (!isset($opts['inbox']) || !empty($opts['inbox']));
if (empty($opts['noupdate'])) {
$mboxes = &$this->_mboxes;
} else {
$mboxes = $this->_mboxes;
}
uasort($mboxes, array($this, '_mboxCompare'));
return $mboxes;
}
/**
* Hierarchical folder sorting function (used with usort()).
*
* @param string $a Comparison item 1.
* @param string $b Comparison item 2.
*
* @return integer See usort().
*/
final protected function _mboxCompare($a, $b)
{
/* Always return INBOX as "smaller". */
if ($this->_sortinbox) {
if (strcasecmp($a, 'INBOX') === 0) {
return -1;
} elseif (strcasecmp($b, 'INBOX') === 0) {
return 1;
}
}
$a_parts = explode($this->_delimiter, $a);
$b_parts = explode($this->_delimiter, $b);
$a_count = count($a_parts);
$b_count = count($b_parts);
for ($i = 0, $iMax = min($a_count, $b_count); $i < $iMax; ++$i) {
if ($a_parts[$i] != $b_parts[$i]) {
/* If only one of the folders is under INBOX, return it as
* "smaller". */
if ($this->_sortinbox && ($i === 0)) {
$a_base = (strcasecmp($a_parts[0], 'INBOX') === 0);
$b_base = (strcasecmp($b_parts[0], 'INBOX') === 0);
if ($a_base && !$b_base) {
return -1;
} elseif (!$a_base && $b_base) {
return 1;
}
}
$cmp = strnatcasecmp($a_parts[$i], $b_parts[$i]);
return ($cmp === 0)
? strcmp($a_parts[$i], $b_parts[$i])
: $cmp;
} elseif ($a_parts[$i] !== $b_parts[$i]) {
return strlen($a_parts[$i]) - strlen($b_parts[$i]);
}
}
return ($a_count - $b_count);
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_mboxes);
}
/* IteratorAggregate methods. */
/**
*/
#[ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->_mboxes);
}
}

View File

@ -1,136 +0,0 @@
<?php
/**
* Copyright 2014-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
*/
/**
* List of namespaces.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2014-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Imap_Client
* @since 2.21.0
*/
class Horde_Imap_Client_Namespace_List
implements ArrayAccess, Countable, IteratorAggregate
{
/**
* The list of namespace objects.
*
* @var array
*/
protected $_ns = array();
/**
* Constructor.
*
* @param array $ns The list of namespace objects.
*/
public function __construct($ns = array())
{
foreach ($ns as $val) {
$this->_ns[strval($val)] = $val;
}
}
/**
* Get namespace info for a full mailbox path.
*
* @param string $mbox The mailbox path.
* @param boolean $personal If true, will return the empty namespace only
* if it is a personal namespace.
*
* @return mixed The Horde_Imap_Client_Data_Namespace object for the
* mailbox path, or null if the path doesn't exist.
*/
public function getNamespace($mbox, $personal = false)
{
$mbox = strval($mbox);
if ($ns = $this[$mbox]) {
return $ns;
}
foreach ($this->_ns as $val) {
$mbox = $mbox . $val->delimiter;
if (strlen($val->name) && (strpos($mbox, $val->name) === 0)) {
return $val;
}
}
return (($ns = $this['']) && (!$personal || ($ns->type === $ns::NS_PERSONAL)))
? $ns
: null;
}
/* ArrayAccess methods. */
/**
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->_ns[strval($offset)]);
}
/**
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
$offset = strval($offset);
return isset($this->_ns[$offset])
? $this->_ns[$offset]
: null;
}
/**
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
if ($value instanceof Horde_Imap_Client_Data_Namespace) {
$this->_ns[strval($value)] = $value;
}
}
/**
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->_ns[strval($offset)]);
}
/* Countable methods. */
/**
*/
#[ReturnTypeWillChange]
public function count()
{
return count($this->_ns);
}
/* IteratorAggregate methods. */
/**
*/
#[ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->_ns);
}
}

Some files were not shown because too many files have changed in this diff Show More