Current File : /home/k/a/r/karenpetzb/www/items/category/Storage.tar |
File.php 0000604 00000026455 15071355645 0006157 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_OpenId
* @subpackage Zend_OpenId_Provider
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: File.php 8456 2008-02-29 11:01:12Z dmitry $
*/
/**
* @see Zend_OpenId_Provider_Storage
*/
require_once "Zend/OpenId/Provider/Storage.php";
/**
* External storage implemmentation using serialized files
*
* @category Zend
* @package Zend_OpenId
* @subpackage Zend_OpenId_Provider
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_OpenId_Provider_Storage_File extends Zend_OpenId_Provider_Storage
{
/**
* Directory name to store data files in
*
* @var string $_dir
*/
private $_dir;
/**
* Constructs storage object and creates storage directory
*
* @param string $dir directory name to store data files in
* @throws Zend_OpenId_Exception
*/
public function __construct($dir = null)
{
if (is_null($dir)) {
$tmp = getenv('TMP');
if (empty($tmp)) {
$tmp = getenv('TEMP');
if (empty($tmp)) {
$tmp = "/tmp";
}
}
$user = get_current_user();
if (is_string($user) && !empty($user)) {
$tmp .= '/' . $user;
}
$dir = $tmp . '/openid/provider';
}
$this->_dir = $dir;
if (!is_dir($this->_dir)) {
if (!@mkdir($this->_dir, 0700, 1)) {
throw new Zend_OpenId_Exception(
"Cannot access storage directory $dir",
Zend_OpenId_Exception::ERROR_STORAGE);
}
}
if (($f = fopen($this->_dir.'/assoc.lock', 'w+')) === null) {
throw new Zend_OpenId_Exception(
'Cannot create a lock file in the directory ' . $dir,
Zend_OpenId_Exception::ERROR_STORAGE);
}
fclose($f);
if (($f = fopen($this->_dir.'/user.lock', 'w+')) === null) {
throw new Zend_OpenId_Exception(
'Cannot create a lock file in the directory ' . $dir,
Zend_OpenId_Exception::ERROR_STORAGE);
}
fclose($f);
}
/**
* Stores information about session identified by $handle
*
* @param string $handle assiciation handle
* @param string $macFunc HMAC function (sha1 or sha256)
* @param string $secret shared secret
* @param string $expires expiration UNIX time
* @return bool
*/
public function addAssociation($handle, $macFunc, $secret, $expires)
{
$name = $this->_dir . '/assoc_' . md5($handle);
$lock = @fopen($this->_dir . '/assoc.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_EX)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'w+');
if ($f === false) {
fclose($lock);
return false;
}
$data = serialize(array($handle, $macFunc, $secret, $expires));
fwrite($f, $data);
fclose($f);
fclose($lock);
return true;
}
/**
* Gets information about association identified by $handle
* Returns true if given association found and not expired and false
* otherwise
*
* @param string $handle assiciation handle
* @param string &$macFunc HMAC function (sha1 or sha256)
* @param string &$secret shared secret
* @param string &$expires expiration UNIX time
* @return bool
*/
public function getAssociation($handle, &$macFunc, &$secret, &$expires)
{
$name = $this->_dir . '/assoc_' . md5($handle);
$lock = @fopen($this->_dir . '/assoc.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_EX)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'r');
if ($f === false) {
fclose($lock);
return false;
}
$ret = false;
$data = stream_get_contents($f);
if (!empty($data)) {
list($storedHandle, $macFunc, $secret, $expires) = unserialize($data);
if ($handle === $storedHandle && $expires > time()) {
$ret = true;
} else {
fclose($f);
@unlink($name);
fclose($lock);
return false;
}
}
fclose($f);
fclose($lock);
return $ret;
}
/**
* Removes information about association identified by $handle
*
* @param string $handle assiciation handle
* @return bool
*/
public function delAssociation($handle)
{
$name = $this->_dir . '/assoc_' . md5($handle);
$lock = @fopen($this->_dir . '/assoc.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_EX)) {
fclose($lock);
return false;
}
@unlink($name);
fclose($lock);
return true;
}
/**
* Register new user with given $id and $password
* Returns true in case of success and false if user with given $id already
* exists
*
* @param string $id user identity URL
* @param string $password encoded user password
* @return bool
*/
public function addUser($id, $password)
{
$name = $this->_dir . '/user_' . md5($id);
$lock = @fopen($this->_dir . '/user.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_EX)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'x');
if ($f === false) {
fclose($lock);
return false;
}
$data = serialize(array($id, $password, array()));
fwrite($f, $data);
fclose($f);
fclose($lock);
return true;
}
/**
* Returns true if user with given $id exists and false otherwise
*
* @param string $id user identity URL
* @return bool
*/
public function hasUser($id)
{
$name = $this->_dir . '/user_' . md5($id);
$lock = @fopen($this->_dir . '/user.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_SH)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'r');
if ($f === false) {
fclose($lock);
return false;
}
$ret = false;
$data = stream_get_contents($f);
if (!empty($data)) {
list($storedId, $storedPassword, $trusted) = unserialize($data);
if ($id === $storedId) {
$ret = true;
}
}
fclose($f);
fclose($lock);
return $ret;
}
/**
* Verify if user with given $id exists and has specified $password
*
* @param string $id user identity URL
* @param string $password user password
* @return bool
*/
public function checkUser($id, $password)
{
$name = $this->_dir . '/user_' . md5($id);
$lock = @fopen($this->_dir . '/user.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_SH)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'r');
if ($f === false) {
fclose($lock);
return false;
}
$ret = false;
$data = stream_get_contents($f);
if (!empty($data)) {
list($storedId, $storedPassword, $trusted) = unserialize($data);
if ($id === $storedId && $password === $storedPassword) {
$ret = true;
}
}
fclose($f);
fclose($lock);
return $ret;
}
/**
* Removes information abou specified user
*
* @param string $id user identity URL
* @return bool
*/
public function delUser($id)
{
$name = $this->_dir . '/user_' . md5($id);
$lock = @fopen($this->_dir . '/user.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_EX)) {
fclose($lock);
return false;
}
@unlink($name);
fclose($lock);
return true;
}
/**
* Returns array of all trusted/untrusted sites for given user identified
* by $id
*
* @param string $id user identity URL
* @return array
*/
public function getTrustedSites($id)
{
$name = $this->_dir . '/user_' . md5($id);
$lock = @fopen($this->_dir . '/user.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_SH)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'r');
if ($f === false) {
fclose($lock);
return false;
}
$ret = false;
$data = stream_get_contents($f);
if (!empty($data)) {
list($storedId, $storedPassword, $trusted) = unserialize($data);
if ($id === $storedId) {
$ret = $trusted;
}
}
fclose($f);
fclose($lock);
return $ret;
}
/**
* Stores information about trusted/untrusted site for given user
*
* @param string $id user identity URL
* @param string $site site URL
* @param mixed $trusted trust data from extension or just a boolean value
* @return bool
*/
public function addSite($id, $site, $trusted)
{
$name = $this->_dir . '/user_' . md5($id);
$lock = @fopen($this->_dir . '/user.lock', 'w+');
if ($lock === false) {
return false;
}
if (!flock($lock, LOCK_EX)) {
fclose($lock);
return false;
}
$f = @fopen($name, 'r+');
if ($f === false) {
fclose($lock);
return false;
}
$ret = false;
$data = stream_get_contents($f);
if (!empty($data)) {
list($storedId, $storedPassword, $sites) = unserialize($data);
if ($id === $storedId) {
if (is_null($trusted)) {
unset($sites[$site]);
} else {
$sites[$site] = $trusted;
}
rewind($f);
ftruncate($f, 0);
$data = serialize(array($id, $storedPassword, $sites));
fwrite($f, $data);
$ret = true;
}
}
fclose($f);
fclose($lock);
return $ret;
}
}
Directory.php 0000604 00000006736 15071406030 0007225 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Search_Lucene_Storage_Directory
{
/**
* Closes the store.
*
* @return void
*/
abstract public function close();
/**
* Returns an array of strings, one for each file in the directory.
*
* @return array
*/
abstract public function fileList();
/**
* Creates a new, empty file in the directory with the given $filename.
*
* @param string $filename
* @return Zend_Search_Lucene_Storage_File
*/
abstract public function createFile($filename);
/**
* Removes an existing $filename in the directory.
*
* @param string $filename
* @return void
*/
abstract public function deleteFile($filename);
/**
* Purge file if it's cached by directory object
*
* Method is used to prevent 'too many open files' error
*
* @param string $filename
* @return void
*/
abstract public function purgeFile($filename);
/**
* Returns true if a file with the given $filename exists.
*
* @param string $filename
* @return boolean
*/
abstract public function fileExists($filename);
/**
* Returns the length of a $filename in the directory.
*
* @param string $filename
* @return integer
*/
abstract public function fileLength($filename);
/**
* Returns the UNIX timestamp $filename was last modified.
*
* @param string $filename
* @return integer
*/
abstract public function fileModified($filename);
/**
* Renames an existing file in the directory.
*
* @param string $from
* @param string $to
* @return void
*/
abstract public function renameFile($from, $to);
/**
* Sets the modified time of $filename to now.
*
* @param string $filename
* @return void
*/
abstract public function touchFile($filename);
/**
* Returns a Zend_Search_Lucene_Storage_File object for a given $filename in the directory.
*
* If $shareHandler option is true, then file handler can be shared between File Object
* requests. It speed-ups performance, but makes problems with file position.
* Shared handler are good for short atomic requests.
* Non-shared handlers are useful for stream file reading (especial for compound files).
*
* @param string $filename
* @param boolean $shareHandler
* @return Zend_Search_Lucene_Storage_File
*/
abstract public function getFileObject($filename, $shareHandler = true);
}
File/Filesystem.php 0000604 00000013163 15071406030 0010254 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Search_Lucene_Storage_File */
require_once 'Zend/Search/Lucene/Storage/File.php';
/** Zend_Search_Lucene_Exception */
require_once 'Zend/Search/Lucene/Exception.php';
/**
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Search_Lucene_Storage_File_Filesystem extends Zend_Search_Lucene_Storage_File
{
/**
* Resource of the open file
*
* @var resource
*/
protected $_fileHandle;
/**
* Class constructor. Open the file.
*
* @param string $filename
* @param string $mode
*/
public function __construct($filename, $mode='r+b')
{
global $php_errormsg;
if (strpos($mode, 'w') === false && !is_readable($filename)) {
// opening for reading non-readable file
throw new Zend_Search_Lucene_Exception('File \'' . $filename . '\' is not readable.');
}
$trackErrors = ini_get('track_errors');
ini_set('track_errors', '1');
$this->_fileHandle = @fopen($filename, $mode);
if ($this->_fileHandle === false) {
ini_set('track_errors', $trackErrors);
throw new Zend_Search_Lucene_Exception($php_errormsg);
}
ini_set('track_errors', $trackErrors);
}
/**
* Sets the file position indicator and advances the file pointer.
* The new position, measured in bytes from the beginning of the file,
* is obtained by adding offset to the position specified by whence,
* whose values are defined as follows:
* SEEK_SET - Set position equal to offset bytes.
* SEEK_CUR - Set position to current location plus offset.
* SEEK_END - Set position to end-of-file plus offset. (To move to
* a position before the end-of-file, you need to pass a negative value
* in offset.)
* SEEK_CUR is the only supported offset type for compound files
*
* Upon success, returns 0; otherwise, returns -1
*
* @param integer $offset
* @param integer $whence
* @return integer
*/
public function seek($offset, $whence=SEEK_SET)
{
return fseek($this->_fileHandle, $offset, $whence);
}
/**
* Get file position.
*
* @return integer
*/
public function tell()
{
return ftell($this->_fileHandle);
}
/**
* Flush output.
*
* Returns true on success or false on failure.
*
* @return boolean
*/
public function flush()
{
return fflush($this->_fileHandle);
}
/**
* Close File object
*/
public function close()
{
if ($this->_fileHandle !== null ) {
@fclose($this->_fileHandle);
$this->_fileHandle = null;
}
}
/**
* Get the size of the already opened file
*
* @return integer
*/
public function size()
{
$position = ftell($this->_fileHandle);
fseek($this->_fileHandle, 0, SEEK_END);
$size = ftell($this->_fileHandle);
fseek($this->_fileHandle,$position);
return $size;
}
/**
* Read a $length bytes from the file and advance the file pointer.
*
* @param integer $length
* @return string
*/
protected function _fread($length=1)
{
if ($length == 0) {
return '';
}
if ($length < 1024) {
return fread($this->_fileHandle, $length);
}
$data = '';
while ( $length > 0 && ($nextBlock = fread($this->_fileHandle, $length)) != false ) {
$data .= $nextBlock;
$length -= strlen($nextBlock);
}
return $data;
}
/**
* Writes $length number of bytes (all, if $length===null) to the end
* of the file.
*
* @param string $data
* @param integer $length
*/
protected function _fwrite($data, $length=null)
{
if ($length === null ) {
fwrite($this->_fileHandle, $data);
} else {
fwrite($this->_fileHandle, $data, $length);
}
}
/**
* Lock file
*
* Lock type may be a LOCK_SH (shared lock) or a LOCK_EX (exclusive lock)
*
* @param integer $lockType
* @param boolean $nonBlockingLock
* @return boolean
*/
public function lock($lockType, $nonBlockingLock = false)
{
if ($nonBlockingLock) {
return flock($this->_fileHandle, $lockType | LOCK_NB);
} else {
return flock($this->_fileHandle, $lockType);
}
}
/**
* Unlock file
*
* Returns true on success
*
* @return boolean
*/
public function unlock()
{
if ($this->_fileHandle !== null ) {
return flock($this->_fileHandle, LOCK_UN);
} else {
return true;
}
}
}
File/Memory.php 0000604 00000037461 15071406030 0007407 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Search_Lucene_Storage_File */
require_once 'Zend/Search/Lucene/Storage/File.php';
/** Zend_Search_Lucene_Exception */
require_once 'Zend/Search/Lucene/Exception.php';
/**
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Search_Lucene_Storage_File_Memory extends Zend_Search_Lucene_Storage_File
{
/**
* FileData
*
* @var string
*/
private $_data;
/**
* File Position
*
* @var integer
*/
private $_position = 0;
/**
* Object constractor
*
* @param string $data
*/
public function __construct($data)
{
$this->_data = $data;
}
/**
* Reads $length number of bytes at the current position in the
* file and advances the file pointer.
*
* @param integer $length
* @return string
*/
protected function _fread($length = 1)
{
$returnValue = substr($this->_data, $this->_position, $length);
$this->_position += $length;
return $returnValue;
}
/**
* Sets the file position indicator and advances the file pointer.
* The new position, measured in bytes from the beginning of the file,
* is obtained by adding offset to the position specified by whence,
* whose values are defined as follows:
* SEEK_SET - Set position equal to offset bytes.
* SEEK_CUR - Set position to current location plus offset.
* SEEK_END - Set position to end-of-file plus offset. (To move to
* a position before the end-of-file, you need to pass a negative value
* in offset.)
* Upon success, returns 0; otherwise, returns -1
*
* @param integer $offset
* @param integer $whence
* @return integer
*/
public function seek($offset, $whence=SEEK_SET)
{
switch ($whence) {
case SEEK_SET:
$this->_position = $offset;
break;
case SEEK_CUR:
$this->_position += $offset;
break;
case SEEK_END:
$this->_position = strlen($this->_data);
$this->_position += $offset;
break;
default:
break;
}
}
/**
* Get file position.
*
* @return integer
*/
public function tell()
{
return $this->_position;
}
/**
* Flush output.
*
* Returns true on success or false on failure.
*
* @return boolean
*/
public function flush()
{
// Do nothing
return true;
}
/**
* Writes $length number of bytes (all, if $length===null) to the end
* of the file.
*
* @param string $data
* @param integer $length
*/
protected function _fwrite($data, $length=null)
{
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
if ($length !== null) {
$this->_data .= substr($data, 0, $length);
} else {
$this->_data .= $data;
}
$this->_position = strlen($this->_data);
}
/**
* Lock file
*
* Lock type may be a LOCK_SH (shared lock) or a LOCK_EX (exclusive lock)
*
* @param integer $lockType
* @return boolean
*/
public function lock($lockType, $nonBlockinLock = false)
{
// Memory files can't be shared
// do nothing
return true;
}
/**
* Unlock file
*/
public function unlock()
{
// Memory files can't be shared
// do nothing
}
/**
* Reads a byte from the current position in the file
* and advances the file pointer.
*
* @return integer
*/
public function readByte()
{
return ord($this->_data[$this->_position++]);
}
/**
* Writes a byte to the end of the file.
*
* @param integer $byte
*/
public function writeByte($byte)
{
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
$this->_data .= chr($byte);
$this->_position = strlen($this->_data);
return 1;
}
/**
* Read num bytes from the current position in the file
* and advances the file pointer.
*
* @param integer $num
* @return string
*/
public function readBytes($num)
{
$returnValue = substr($this->_data, $this->_position, $num);
$this->_position += $num;
return $returnValue;
}
/**
* Writes num bytes of data (all, if $num===null) to the end
* of the string.
*
* @param string $data
* @param integer $num
*/
public function writeBytes($data, $num=null)
{
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
if ($num !== null) {
$this->_data .= substr($data, 0, $num);
} else {
$this->_data .= $data;
}
$this->_position = strlen($this->_data);
}
/**
* Reads an integer from the current position in the file
* and advances the file pointer.
*
* @return integer
*/
public function readInt()
{
$str = substr($this->_data, $this->_position, 4);
$this->_position += 4;
return ord($str[0]) << 24 |
ord($str[1]) << 16 |
ord($str[2]) << 8 |
ord($str[3]);
}
/**
* Writes an integer to the end of file.
*
* @param integer $value
*/
public function writeInt($value)
{
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
settype($value, 'integer');
$this->_data .= chr($value>>24 & 0xFF) .
chr($value>>16 & 0xFF) .
chr($value>>8 & 0xFF) .
chr($value & 0xFF);
$this->_position = strlen($this->_data);
}
/**
* Returns a long integer from the current position in the file
* and advances the file pointer.
*
* @return integer
* @throws Zend_Search_Lucene_Exception
*/
public function readLong()
{
$str = substr($this->_data, $this->_position, 8);
$this->_position += 8;
/**
* Check, that we work in 64-bit mode.
* fseek() uses long for offset. Thus, largest index segment file size in 32bit mode is 2Gb
*/
if (PHP_INT_SIZE > 4) {
return ord($str[0]) << 56 |
ord($str[1]) << 48 |
ord($str[2]) << 40 |
ord($str[3]) << 32 |
ord($str[4]) << 24 |
ord($str[5]) << 16 |
ord($str[6]) << 8 |
ord($str[7]);
} else {
if ((ord($str[0]) != 0) ||
(ord($str[1]) != 0) ||
(ord($str[2]) != 0) ||
(ord($str[3]) != 0) ||
((ord($str[0]) & 0x80) != 0)) {
throw new Zend_Search_Lucene_Exception('Largest supported segment size (for 32-bit mode) is 2Gb');
}
return ord($str[4]) << 24 |
ord($str[5]) << 16 |
ord($str[6]) << 8 |
ord($str[7]);
}
}
/**
* Writes long integer to the end of file
*
* @param integer $value
* @throws Zend_Search_Lucene_Exception
*/
public function writeLong($value)
{
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
/**
* Check, that we work in 64-bit mode.
* fseek() and ftell() use long for offset. Thus, largest index segment file size in 32bit mode is 2Gb
*/
if (PHP_INT_SIZE > 4) {
settype($value, 'integer');
$this->_data .= chr($value>>56 & 0xFF) .
chr($value>>48 & 0xFF) .
chr($value>>40 & 0xFF) .
chr($value>>32 & 0xFF) .
chr($value>>24 & 0xFF) .
chr($value>>16 & 0xFF) .
chr($value>>8 & 0xFF) .
chr($value & 0xFF);
} else {
if ($value > 0x7FFFFFFF) {
throw new Zend_Search_Lucene_Exception('Largest supported segment size (for 32-bit mode) is 2Gb');
}
$this->_data .= chr(0) . chr(0) . chr(0) . chr(0) .
chr($value>>24 & 0xFF) .
chr($value>>16 & 0xFF) .
chr($value>>8 & 0xFF) .
chr($value & 0xFF);
}
$this->_position = strlen($this->_data);
}
/**
* Returns a variable-length integer from the current
* position in the file and advances the file pointer.
*
* @return integer
*/
public function readVInt()
{
$nextByte = ord($this->_data[$this->_position++]);
$val = $nextByte & 0x7F;
for ($shift=7; ($nextByte & 0x80) != 0; $shift += 7) {
$nextByte = ord($this->_data[$this->_position++]);
$val |= ($nextByte & 0x7F) << $shift;
}
return $val;
}
/**
* Writes a variable-length integer to the end of file.
*
* @param integer $value
*/
public function writeVInt($value)
{
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
settype($value, 'integer');
while ($value > 0x7F) {
$this->_data .= chr( ($value & 0x7F)|0x80 );
$value >>= 7;
}
$this->_data .= chr($value);
$this->_position = strlen($this->_data);
}
/**
* Reads a string from the current position in the file
* and advances the file pointer.
*
* @return string
*/
public function readString()
{
$strlen = $this->readVInt();
if ($strlen == 0) {
return '';
} else {
/**
* This implementation supports only Basic Multilingual Plane
* (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
* "supplementary characters" (characters whose code points are
* greater than 0xFFFF)
* Java 2 represents these characters as a pair of char (16-bit)
* values, the first from the high-surrogates range (0xD800-0xDBFF),
* the second from the low-surrogates range (0xDC00-0xDFFF). Then
* they are encoded as usual UTF-8 characters in six bytes.
* Standard UTF-8 representation uses four bytes for supplementary
* characters.
*/
$str_val = substr($this->_data, $this->_position, $strlen);
$this->_position += $strlen;
for ($count = 0; $count < $strlen; $count++ ) {
if (( ord($str_val[$count]) & 0xC0 ) == 0xC0) {
$addBytes = 1;
if (ord($str_val[$count]) & 0x20 ) {
$addBytes++;
// Never used. Java2 doesn't encode strings in four bytes
if (ord($str_val[$count]) & 0x10 ) {
$addBytes++;
}
}
$str_val .= substr($this->_data, $this->_position, $addBytes);
$this->_position += $addBytes;
$strlen += $addBytes;
// Check for null character. Java2 encodes null character
// in two bytes.
if (ord($str_val[$count]) == 0xC0 &&
ord($str_val[$count+1]) == 0x80 ) {
$str_val[$count] = 0;
$str_val = substr($str_val,0,$count+1)
. substr($str_val,$count+2);
}
$count += $addBytes;
}
}
return $str_val;
}
}
/**
* Writes a string to the end of file.
*
* @param string $str
* @throws Zend_Search_Lucene_Exception
*/
public function writeString($str)
{
/**
* This implementation supports only Basic Multilingual Plane
* (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
* "supplementary characters" (characters whose code points are
* greater than 0xFFFF)
* Java 2 represents these characters as a pair of char (16-bit)
* values, the first from the high-surrogates range (0xD800-0xDBFF),
* the second from the low-surrogates range (0xDC00-0xDFFF). Then
* they are encoded as usual UTF-8 characters in six bytes.
* Standard UTF-8 representation uses four bytes for supplementary
* characters.
*/
// We do not need to check if file position points to the end of "file".
// Only append operation is supported now
// convert input to a string before iterating string characters
settype($str, 'string');
$chars = $strlen = strlen($str);
$containNullChars = false;
for ($count = 0; $count < $strlen; $count++ ) {
/**
* String is already in Java 2 representation.
* We should only calculate actual string length and replace
* \x00 by \xC0\x80
*/
if ((ord($str[$count]) & 0xC0) == 0xC0) {
$addBytes = 1;
if (ord($str[$count]) & 0x20 ) {
$addBytes++;
// Never used. Java2 doesn't encode strings in four bytes
// and we dont't support non-BMP characters
if (ord($str[$count]) & 0x10 ) {
$addBytes++;
}
}
$chars -= $addBytes;
if (ord($str[$count]) == 0 ) {
$containNullChars = true;
}
$count += $addBytes;
}
}
if ($chars < 0) {
throw new Zend_Search_Lucene_Exception('Invalid UTF-8 string');
}
$this->writeVInt($chars);
if ($containNullChars) {
$this->_data .= str_replace($str, "\x00", "\xC0\x80");
} else {
$this->_data .= $str;
}
$this->_position = strlen($this->_data);
}
/**
* Reads binary data from the current position in the file
* and advances the file pointer.
*
* @return string
*/
public function readBinary()
{
$length = $this->readVInt();
$returnValue = substr($this->_data, $this->_position, $length);
$this->_position += $length;
return $returnValue;
}
}
Directory/Filesystem.php 0000604 00000023723 15071406030 0011344 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Search_Lucene_Storage_Directory */
require_once 'Zend/Search/Lucene/Storage/Directory.php';
/** Zend_Search_Lucene_Storage_File_Filesystem */
require_once 'Zend/Search/Lucene/Storage/File/Filesystem.php';
/**
* FileSystem implementation of Directory abstraction.
*
* @category Zend
* @package Zend_Search_Lucene
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Search_Lucene_Storage_Directory_Filesystem extends Zend_Search_Lucene_Storage_Directory
{
/**
* Filesystem path to the directory
*
* @var string
*/
protected $_dirPath = null;
/**
* Cache for Zend_Search_Lucene_Storage_File_Filesystem objects
* Array: filename => Zend_Search_Lucene_Storage_File object
*
* @var array
* @throws Zend_Search_Lucene_Exception
*/
protected $_fileHandlers;
/**
* Default file permissions
*
* @var integer
*/
protected static $_defaultFilePermissions = 0666;
/**
* Get default file permissions
*
* @return integer
*/
public static function getDefaultFilePermissions()
{
return self::$_defaultFilePermissions;
}
/**
* Set default file permissions
*
* @param integer $mode
*/
public static function setDefaultFilePermissions($mode)
{
self::$_defaultFilePermissions = $mode;
}
/**
* Utility function to recursive directory creation
*
* @param string $dir
* @param integer $mode
* @param boolean $recursive
* @return boolean
*/
public static function mkdirs($dir, $mode = 0777, $recursive = true)
{
if (is_null($dir) || $dir === '') {
return false;
}
if (is_dir($dir) || $dir === '/') {
return true;
}
if (self::mkdirs(dirname($dir), $mode, $recursive)) {
return mkdir($dir, $mode);
}
return false;
}
/**
* Object constructor
* Checks if $path is a directory or tries to create it.
*
* @param string $path
* @throws Zend_Search_Lucene_Exception
*/
public function __construct($path)
{
if (!is_dir($path)) {
if (file_exists($path)) {
require_once 'Zend/Search/Lucene/Exception.php';
throw new Zend_Search_Lucene_Exception('Path exists, but it\'s not a directory');
} else {
if (!self::mkdirs($path)) {
require_once 'Zend/Search/Lucene/Exception.php';
throw new Zend_Search_Lucene_Exception("Can't create directory '$path'.");
}
}
}
$this->_dirPath = $path;
$this->_fileHandlers = array();
}
/**
* Closes the store.
*
* @return void
*/
public function close()
{
foreach ($this->_fileHandlers as $fileObject) {
$fileObject->close();
}
$this->_fileHandlers = array();
}
/**
* Returns an array of strings, one for each file in the directory.
*
* @return array
*/
public function fileList()
{
$result = array();
$dirContent = opendir( $this->_dirPath );
while (($file = readdir($dirContent)) !== false) {
if (($file == '..')||($file == '.')) continue;
if( !is_dir($this->_dirPath . '/' . $file) ) {
$result[] = $file;
}
}
closedir($dirContent);
return $result;
}
/**
* Creates a new, empty file in the directory with the given $filename.
*
* @param string $filename
* @return Zend_Search_Lucene_Storage_File
* @throws Zend_Search_Lucene_Exception
*/
public function createFile($filename)
{
if (isset($this->_fileHandlers[$filename])) {
$this->_fileHandlers[$filename]->close();
}
unset($this->_fileHandlers[$filename]);
$this->_fileHandlers[$filename] = new Zend_Search_Lucene_Storage_File_Filesystem($this->_dirPath . '/' . $filename, 'w+b');
// Set file permissions, but don't care about any possible failures, since file may be already
// created by anther user which has to care about right permissions
@chmod($this->_dirPath . '/' . $filename, self::$_defaultFilePermissions);
return $this->_fileHandlers[$filename];
}
/**
* Removes an existing $filename in the directory.
*
* @param string $filename
* @return void
* @throws Zend_Search_Lucene_Exception
*/
public function deleteFile($filename)
{
if (isset($this->_fileHandlers[$filename])) {
$this->_fileHandlers[$filename]->close();
}
unset($this->_fileHandlers[$filename]);
global $php_errormsg;
$trackErrors = ini_get('track_errors'); ini_set('track_errors', '1');
if (!@unlink($this->_dirPath . '/' . $filename)) {
ini_set('track_errors', $trackErrors);
require_once 'Zend/Search/Lucene/Exception.php';
throw new Zend_Search_Lucene_Exception('Can\'t delete file: ' . $php_errormsg);
}
ini_set('track_errors', $trackErrors);
}
/**
* Purge file if it's cached by directory object
*
* Method is used to prevent 'too many open files' error
*
* @param string $filename
* @return void
*/
public function purgeFile($filename)
{
if (isset($this->_fileHandlers[$filename])) {
$this->_fileHandlers[$filename]->close();
}
unset($this->_fileHandlers[$filename]);
}
/**
* Returns true if a file with the given $filename exists.
*
* @param string $filename
* @return boolean
*/
public function fileExists($filename)
{
return isset($this->_fileHandlers[$filename]) ||
file_exists($this->_dirPath . '/' . $filename);
}
/**
* Returns the length of a $filename in the directory.
*
* @param string $filename
* @return integer
*/
public function fileLength($filename)
{
if (isset( $this->_fileHandlers[$filename] )) {
return $this->_fileHandlers[$filename]->size();
}
return filesize($this->_dirPath .'/'. $filename);
}
/**
* Returns the UNIX timestamp $filename was last modified.
*
* @param string $filename
* @return integer
*/
public function fileModified($filename)
{
return filemtime($this->_dirPath .'/'. $filename);
}
/**
* Renames an existing file in the directory.
*
* @param string $from
* @param string $to
* @return void
* @throws Zend_Search_Lucene_Exception
*/
public function renameFile($from, $to)
{
global $php_errormsg;
if (isset($this->_fileHandlers[$from])) {
$this->_fileHandlers[$from]->close();
}
unset($this->_fileHandlers[$from]);
if (isset($this->_fileHandlers[$to])) {
$this->_fileHandlers[$to]->close();
}
unset($this->_fileHandlers[$to]);
if (file_exists($this->_dirPath . '/' . $to)) {
if (!unlink($this->_dirPath . '/' . $to)) {
require_once 'Zend/Search/Lucene/Exception.php';
throw new Zend_Search_Lucene_Exception('Delete operation failed');
}
}
$trackErrors = ini_get('track_errors');
ini_set('track_errors', '1');
$success = @rename($this->_dirPath . '/' . $from, $this->_dirPath . '/' . $to);
if (!$success) {
ini_set('track_errors', $trackErrors);
require_once 'Zend/Search/Lucene/Exception.php';
throw new Zend_Search_Lucene_Exception($php_errormsg);
}
ini_set('track_errors', $trackErrors);
return $success;
}
/**
* Sets the modified time of $filename to now.
*
* @param string $filename
* @return void
*/
public function touchFile($filename)
{
return touch($this->_dirPath .'/'. $filename);
}
/**
* Returns a Zend_Search_Lucene_Storage_File object for a given $filename in the directory.
*
* If $shareHandler option is true, then file handler can be shared between File Object
* requests. It speed-ups performance, but makes problems with file position.
* Shared handler are good for short atomic requests.
* Non-shared handlers are useful for stream file reading (especial for compound files).
*
* @param string $filename
* @param boolean $shareHandler
* @return Zend_Search_Lucene_Storage_File
*/
public function getFileObject($filename, $shareHandler = true)
{
$fullFilename = $this->_dirPath . '/' . $filename;
if (!$shareHandler) {
return new Zend_Search_Lucene_Storage_File_Filesystem($fullFilename);
}
if (isset( $this->_fileHandlers[$filename] )) {
$this->_fileHandlers[$filename]->seek(0);
return $this->_fileHandlers[$filename];
}
$this->_fileHandlers[$filename] = new Zend_Search_Lucene_Storage_File_Filesystem($fullFilename);
return $this->_fileHandlers[$filename];
}
}
Exception.php 0000604 00000002227 15071422736 0007221 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 9101 2008-03-30 19:54:38Z thomas $
*/
/**
* @see Zend_Auth_Exception
*/
require_once 'Zend/Auth/Exception.php';
/**
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Auth_Storage_Exception extends Zend_Auth_Exception
{}
Folder/Interface.php 0000604 00000003513 15071422736 0010375 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 9098 2008-03-30 19:29:10Z thomas $
*/
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Mail_Storage_Folder_Interface
{
/**
* get root folder or given folder
*
* @param string $rootFolder get folder structure for given folder, else root
* @return Zend_Mail_Storage_Folder root or wanted folder
*/
public function getFolders($rootFolder = null);
/**
* select given folder
*
* folder must be selectable!
*
* @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function selectFolder($globalName);
/**
* get Zend_Mail_Storage_Folder instance for current folder
*
* @return Zend_Mail_Storage_Folder instance of current folder
* @throws Zend_Mail_Storage_Exception
*/
public function getCurrentFolder();
}
Folder/Maildir.php 0000604 00000021304 15071422736 0010054 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Maildir.php 9098 2008-03-30 19:29:10Z thomas $
*/
/**
* @see Zend_Mail_Storage_Folder
*/
require_once 'Zend/Mail/Storage/Folder.php';
/**
* @see Zend_Mail_Storage_Folder_Interface
*/
require_once 'Zend/Mail/Storage/Folder/Interface.php';
/**
* @see Zend_Mail_Storage_Maildir
*/
require_once 'Zend/Mail/Storage/Maildir.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Folder_Maildir extends Zend_Mail_Storage_Maildir implements Zend_Mail_Storage_Folder_Interface
{
/**
* Zend_Mail_Storage_Folder root folder for folder structure
* @var Zend_Mail_Storage_Folder
*/
protected $_rootFolder;
/**
* rootdir of folder structure
* @var string
*/
protected $_rootdir;
/**
* name of current folder
* @var string
*/
protected $_currentFolder;
/**
* delim char for subfolders
* @var string
*/
protected $_delim;
/**
* Create instance with parameters
* Supported parameters are:
* - dirname rootdir of maildir structure
* - delim delim char for folder structur, default is '.'
* - folder intial selected folder, default is 'INBOX'
*
* @param $params array mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
*/
public function __construct($params)
{
if (is_array($params)) {
$params = (object)$params;
}
if (!isset($params->dirname) || !is_dir($params->dirname)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
}
$this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$this->_delim = isset($params->delim) ? $params->delim : '.';
$this->_buildFolderTree();
$this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
$this->_has['top'] = true;
$this->_has['flags'] = true;
}
/**
* find all subfolders and mbox files for folder structure
*
* Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
* $parentFolder and $parentGlobalName are only used internally for recursion.
*
* @return null
* @throws Zend_Mail_Storage_Exception
*/
protected function _buildFolderTree()
{
$this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false);
$this->_rootFolder->INBOX = new Zend_Mail_Storage_Folder('INBOX', 'INBOX', true);
$dh = @opendir($this->_rootdir);
if (!$dh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("can't read folders in maildir");
}
$dirs = array();
while (($entry = readdir($dh)) !== false) {
// maildir++ defines folders must start with .
if ($entry[0] != '.' || $entry == '.' || $entry == '..') {
continue;
}
if ($this->_isMaildir($this->_rootdir . $entry)) {
$dirs[] = $entry;
}
}
closedir($dh);
sort($dirs);
$stack = array(null);
$folderStack = array(null);
$parentFolder = $this->_rootFolder;
$parent = '.';
foreach ($dirs as $dir) {
do {
if (strpos($dir, $parent) === 0) {
$local = substr($dir, strlen($parent));
if (strpos($local, $this->_delim) !== false) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('error while reading maildir');
}
array_push($stack, $parent);
$parent = $dir . $this->_delim;
$folder = new Zend_Mail_Storage_Folder($local, substr($dir, 1), true);
$parentFolder->$local = $folder;
array_push($folderStack, $parentFolder);
$parentFolder = $folder;
break;
} else if ($stack) {
$parent = array_pop($stack);
$parentFolder = array_pop($folderStack);
}
} while ($stack);
if (!$stack) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('error while reading maildir');
}
}
}
/**
* get root folder or given folder
*
* @param string $rootFolder get folder structure for given folder, else root
* @return Zend_Mail_Storage_Folder root or wanted folder
* @throws Zend_Mail_Storage_Exception
*/
public function getFolders($rootFolder = null)
{
if (!$rootFolder || $rootFolder == 'INBOX') {
return $this->_rootFolder;
}
// rootdir is same as INBOX in maildir
if (strpos($rootFolder, 'INBOX' . $this->_delim) === 0) {
$rootFolder = substr($rootFolder, 6);
}
$currentFolder = $this->_rootFolder;
$subname = trim($rootFolder, $this->_delim);
while ($currentFolder) {
@list($entry, $subname) = @explode($this->_delim, $subname, 2);
$currentFolder = $currentFolder->$entry;
if (!$subname) {
break;
}
}
if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->_delim)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("folder $rootFolder not found");
}
return $currentFolder;
}
/**
* select given folder
*
* folder must be selectable!
*
* @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function selectFolder($globalName)
{
$this->_currentFolder = (string)$globalName;
// getting folder from folder tree for validation
$folder = $this->getFolders($this->_currentFolder);
try {
$this->_openMaildir($this->_rootdir . '.' . $folder->getGlobalName());
} catch(Zend_Mail_Storage_Exception $e) {
// check what went wrong
if (!$folder->isSelectable()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable");
}
// seems like file has vanished; rebuilding folder tree - but it's still an exception
$this->_buildFolderTree($this->_rootdir);
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('seems like the maildir has vanished, I\'ve rebuild the ' .
'folder tree, search for an other folder and try again');
}
}
/**
* get Zend_Mail_Storage_Folder instance for current folder
*
* @return Zend_Mail_Storage_Folder instance of current folder
* @throws Zend_Mail_Storage_Exception
*/
public function getCurrentFolder()
{
return $this->_currentFolder;
}
}
Folder/Mbox.php 0000604 00000021001 15071422736 0007372 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Mbox.php 9098 2008-03-30 19:29:10Z thomas $
*/
/**
* @see Zend_Mail_Storage_Folder
*/
require_once 'Zend/Mail/Storage/Folder.php';
/**
* @see Zend_Mail_Storage_Folder_Interface
*/
require_once 'Zend/Mail/Storage/Folder/Interface.php';
/**
* @see Zend_Mail_Storage_Mbox
*/
require_once 'Zend/Mail/Storage/Mbox.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Folder_Mbox extends Zend_Mail_Storage_Mbox implements Zend_Mail_Storage_Folder_Interface
{
/**
* Zend_Mail_Storage_Folder root folder for folder structure
* @var Zend_Mail_Storage_Folder
*/
protected $_rootFolder;
/**
* rootdir of folder structure
* @var string
*/
protected $_rootdir;
/**
* name of current folder
* @var string
*/
protected $_currentFolder;
/**
* Create instance with parameters
*
* Disallowed parameters are:
* - filename use Zend_Mail_Storage_Mbox for a single file
* Supported parameters are:
* - dirname rootdir of mbox structure
* - folder intial selected folder, default is 'INBOX'
*
* @param $params array mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
*/
public function __construct($params)
{
if (is_array($params)) {
$params = (object)$params;
}
if (isset($params->filename)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('use Zend_Mail_Storage_Mbox for a single file');
}
if (!isset($params->dirname) || !is_dir($params->dirname)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
}
$this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$this->_buildFolderTree($this->_rootdir);
$this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
$this->_has['top'] = true;
$this->_has['uniqueid'] = false;
}
/**
* find all subfolders and mbox files for folder structure
*
* Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
* $parentFolder and $parentGlobalName are only used internally for recursion.
*
* @param string $currentDir call with root dir, also used for recursion.
* @param Zend_Mail_Storage_Folder|null $parentFolder used for recursion
* @param string $parentGlobalName used for rescursion
* @return null
* @throws Zend_Mail_Storage_Exception
*/
protected function _buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '')
{
if (!$parentFolder) {
$this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false);
$parentFolder = $this->_rootFolder;
}
$dh = @opendir($currentDir);
if (!$dh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("can't read dir $currentDir");
}
while (($entry = readdir($dh)) !== false) {
// ignore hidden files for mbox
if ($entry[0] == '.') {
continue;
}
$absoluteEntry = $currentDir . $entry;
$globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry;
if (is_file($absoluteEntry) && $this->_isMboxFile($absoluteEntry)) {
$parentFolder->$entry = new Zend_Mail_Storage_Folder($entry, $globalName);
continue;
}
if (!is_dir($absoluteEntry) /* || $entry == '.' || $entry == '..' */) {
continue;
}
$folder = new Zend_Mail_Storage_Folder($entry, $globalName, false);
$parentFolder->$entry = $folder;
$this->_buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName);
}
closedir($dh);
}
/**
* get root folder or given folder
*
* @param string $rootFolder get folder structure for given folder, else root
* @return Zend_Mail_Storage_Folder root or wanted folder
* @throws Zend_Mail_Storage_Exception
*/
public function getFolders($rootFolder = null)
{
if (!$rootFolder) {
return $this->_rootFolder;
}
$currentFolder = $this->_rootFolder;
$subname = trim($rootFolder, DIRECTORY_SEPARATOR);
while ($currentFolder) {
@list($entry, $subname) = @explode(DIRECTORY_SEPARATOR, $subname, 2);
$currentFolder = $currentFolder->$entry;
if (!$subname) {
break;
}
}
if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("folder $rootFolder not found");
}
return $currentFolder;
}
/**
* select given folder
*
* folder must be selectable!
*
* @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function selectFolder($globalName)
{
$this->_currentFolder = (string)$globalName;
// getting folder from folder tree for validation
$folder = $this->getFolders($this->_currentFolder);
try {
$this->_openMboxFile($this->_rootdir . $folder->getGlobalName());
} catch(Zend_Mail_Storage_Exception $e) {
// check what went wrong
if (!$folder->isSelectable()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable");
}
// seems like file has vanished; rebuilding folder tree - but it's still an exception
$this->_buildFolderTree($this->_rootdir);
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('seems like the mbox file has vanished, I\'ve rebuild the ' .
'folder tree, search for an other folder and try again');
}
}
/**
* get Zend_Mail_Storage_Folder instance for current folder
*
* @return Zend_Mail_Storage_Folder instance of current folder
* @throws Zend_Mail_Storage_Exception
*/
public function getCurrentFolder()
{
return $this->_currentFolder;
}
/**
* magic method for serialize()
*
* with this method you can cache the mbox class
*
* @return array name of variables
*/
public function __sleep()
{
return array_merge(parent::__sleep(), array('_currentFolder', '_rootFolder', '_rootdir'));
}
/**
* magic method for unserialize()
*
* with this method you can cache the mbox class
*
* @return null
*/
public function __wakeup()
{
// if cache is stall selectFolder() rebuilds the tree on error
parent::__wakeup();
}
}
Imap.php 0000604 00000052525 15071422736 0006157 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Imap.php 12519 2008-11-10 18:41:24Z alexander $
*/
/**
* @see Zend_Mail_Storage_Abstract
*/
require_once 'Zend/Mail/Storage/Abstract.php';
/**
* @see Zend_Mail_Protocol_Imap
*/
require_once 'Zend/Mail/Protocol/Imap.php';
/**
* @see Zend_Mail_Storage_Writable_Interface
*/
require_once 'Zend/Mail/Storage/Writable/Interface.php';
/**
* @see Zend_Mail_Storage_Folder_Interface
*/
require_once 'Zend/Mail/Storage/Folder/Interface.php';
/**
* @see Zend_Mail_Storage_Folder
*/
require_once 'Zend/Mail/Storage/Folder.php';
/**
* @see Zend_Mail_Message
*/
require_once 'Zend/Mail/Message.php';
/**
* @see Zend_Mail_Storage
*/
require_once 'Zend/Mail/Storage.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Imap extends Zend_Mail_Storage_Abstract
implements Zend_Mail_Storage_Folder_Interface, Zend_Mail_Storage_Writable_Interface
{
// TODO: with an internal cache we could optimize this class, or create an extra class with
// such optimizations. Especially the various fetch calls could be combined to one cache call
/**
* protocol handler
* @var null|Zend_Mail_Protocol_Imap
*/
protected $_protocol;
/**
* name of current folder
* @var string
*/
protected $_currentFolder = '';
/**
* imap flags to constants translation
* @var array
*/
protected static $_knownFlags = array('\Passed' => Zend_Mail_Storage::FLAG_PASSED,
'\Answered' => Zend_Mail_Storage::FLAG_ANSWERED,
'\Seen' => Zend_Mail_Storage::FLAG_SEEN,
'\Deleted' => Zend_Mail_Storage::FLAG_DELETED,
'\Draft' => Zend_Mail_Storage::FLAG_DRAFT,
'\Flagged' => Zend_Mail_Storage::FLAG_FLAGGED);
/**
* map flags to search criterias
* @var array
*/
protected static $_searchFlags = array('\Recent' => 'RECENT',
'\Answered' => 'ANSWERED',
'\Seen' => 'SEEN',
'\Deleted' => 'DELETED',
'\Draft' => 'DRAFT',
'\Flagged' => 'FLAGGED');
/**
* Count messages all messages in current box
*
* @return int number of messages
* @throws Zend_Mail_Storage_Exception
* @throws Zend_Mail_Protocol_Exception
*/
public function countMessages($flags = null)
{
if (!$this->_currentFolder) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('No selected folder to count');
}
if ($flags === null) {
return count($this->_protocol->search(array('ALL')));
}
$params = array();
foreach ((array)$flags as $flag) {
if (isset(self::$_searchFlags[$flag])) {
$params[] = self::$_searchFlags[$flag];
} else {
$params[] = 'KEYWORD';
$params[] = $this->_protocol->escapeString($flag);
}
}
return count($this->_protocol->search($params));
}
/**
* get a list of messages with number and size
*
* @param int $id number of message
* @return int|array size of given message of list with all messages as array(num => size)
* @throws Zend_Mail_Protocol_Exception
*/
public function getSize($id = 0)
{
if ($id) {
return $this->_protocol->fetch('RFC822.SIZE', $id);
}
return $this->_protocol->fetch('RFC822.SIZE', 1, INF);
}
/**
* Fetch a message
*
* @param int $id number of message
* @return Zend_Mail_Message
* @throws Zend_Mail_Protocol_Exception
*/
public function getMessage($id)
{
$data = $this->_protocol->fetch(array('FLAGS', 'RFC822.HEADER'), $id);
$header = $data['RFC822.HEADER'];
$flags = array();
foreach ($data['FLAGS'] as $flag) {
$flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
}
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $header, 'flags' => $flags));
}
/*
* Get raw header of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage header
* @param int $topLines include this many lines with header (after an empty line)
* @param int $topLines include this many lines with header (after an empty line)
* @return string raw header
* @throws Zend_Mail_Protocol_Exception
* @throws Zend_Mail_Storage_Exception
*/
public function getRawHeader($id, $part = null, $topLines = 0)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
// TODO: toplines
return $this->_protocol->fetch('RFC822.HEADER', $id);
}
/*
* Get raw content of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage content
* @return string raw content
* @throws Zend_Mail_Protocol_Exception
* @throws Zend_Mail_Storage_Exception
*/
public function getRawContent($id, $part = null)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
return $this->_protocol->fetch('RFC822.TEXT', $id);
}
/**
* create instance with parameters
* Supported paramters are
* - user username
* - host hostname or ip address of IMAP server [optional, default = 'localhost']
* - password password for user 'username' [optional, default = '']
* - port port for IMAP server [optional, default = 110]
* - ssl 'SSL' or 'TLS' for secure sockets
* - folder select this folder [optional, default = 'INBOX']
*
* @param array $params mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
* @throws Zend_Mail_Protocol_Exception
*/
public function __construct($params)
{
if (is_array($params)) {
$params = (object)$params;
}
$this->_has['flags'] = true;
if ($params instanceof Zend_Mail_Protocol_Imap) {
$this->_protocol = $params;
try {
$this->selectFolder('INBOX');
} catch(Zend_Mail_Storage_Exception $e) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot select INBOX, is this a valid transport?');
}
return;
}
if (!isset($params->user)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('need at least user in params');
}
$host = isset($params->host) ? $params->host : 'localhost';
$password = isset($params->password) ? $params->password : '';
$port = isset($params->port) ? $params->port : null;
$ssl = isset($params->ssl) ? $params->ssl : false;
$this->_protocol = new Zend_Mail_Protocol_Imap();
$this->_protocol->connect($host, $port, $ssl);
if (!$this->_protocol->login($params->user, $password)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot login, user or password wrong');
}
$this->selectFolder(isset($params->folder) ? $params->folder : 'INBOX');
}
/**
* Close resource for mail lib. If you need to control, when the resource
* is closed. Otherwise the destructor would call this.
*
* @return null
*/
public function close()
{
$this->_currentFolder = '';
$this->_protocol->logout();
}
/**
* Keep the server busy.
*
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function noop()
{
if (!$this->_protocol->noop()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('could not do nothing');
}
}
/**
* Remove a message from server. If you're doing that from a web enviroment
* you should be careful and use a uniqueid as parameter if possible to
* identify the message.
*
* @param int $id number of message
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeMessage($id)
{
if (!$this->_protocol->store(array(Zend_Mail_Storage::FLAG_DELETED), $id, null, '+')) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot set deleted flag');
}
// TODO: expunge here or at close? we can handle an error here better and are more fail safe
if (!$this->_protocol->expunge()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('message marked as deleted, but could not expunge');
}
}
/**
* get unique id for one or all messages
*
* if storage does not support unique ids it's the same as the message number
*
* @param int|null $id message number
* @return array|string message number for given message or all messages as array
* @throws Zend_Mail_Storage_Exception
*/
public function getUniqueId($id = null)
{
if ($id) {
return $this->_protocol->fetch('UID', $id);
}
return $this->_protocol->fetch('UID', 1, INF);
}
/**
* get a message number from a unique id
*
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
* as parameter and use this method to translate it to message number right before calling removeMessage()
*
* @param string $id unique id
* @return int message number
* @throws Zend_Mail_Storage_Exception
*/
public function getNumberByUniqueId($id)
{
// TODO: use search to find number directly
$ids = $this->getUniqueId();
foreach ($ids as $k => $v) {
if ($v == $id) {
return $k;
}
}
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('unique id not found');
}
/**
* get root folder or given folder
*
* @param string $rootFolder get folder structure for given folder, else root
* @return Zend_Mail_Storage_Folder root or wanted folder
* @throws Zend_Mail_Storage_Exception
* @throws Zend_Mail_Protocol_Exception
*/
public function getFolders($rootFolder = null)
{
$folders = $this->_protocol->listMailbox((string)$rootFolder);
if (!$folders) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('folder not found');
}
ksort($folders, SORT_STRING);
$root = new Zend_Mail_Storage_Folder('/', '/', false);
$stack = array(null);
$folderStack = array(null);
$parentFolder = $root;
$parent = '';
foreach ($folders as $globalName => $data) {
do {
if (!$parent || strpos($globalName, $parent) === 0) {
$pos = strrpos($globalName, $data['delim']);
if ($pos === false) {
$localName = $globalName;
} else {
$localName = substr($globalName, $pos + 1);
}
$selectable = !$data['flags'] || !in_array('\\Noselect', $data['flags']);
array_push($stack, $parent);
$parent = $globalName . $data['delim'];
$folder = new Zend_Mail_Storage_Folder($localName, $globalName, $selectable);
$parentFolder->$localName = $folder;
array_push($folderStack, $parentFolder);
$parentFolder = $folder;
break;
} else if ($stack) {
$parent = array_pop($stack);
$parentFolder = array_pop($folderStack);
}
} while ($stack);
if (!$stack) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('error while constructing folder tree');
}
}
return $root;
}
/**
* select given folder
*
* folder must be selectable!
*
* @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
* @return null
* @throws Zend_Mail_Storage_Exception
* @throws Zend_Mail_Protocol_Exception
*/
public function selectFolder($globalName)
{
$this->_currentFolder = $globalName;
if (!$this->_protocol->select($this->_currentFolder)) {
$this->_currentFolder = '';
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot change folder, maybe it does not exist');
}
}
/**
* get Zend_Mail_Storage_Folder instance for current folder
*
* @return Zend_Mail_Storage_Folder instance of current folder
* @throws Zend_Mail_Storage_Exception
*/
public function getCurrentFolder()
{
return $this->_currentFolder;
}
/**
* create a new folder
*
* This method also creates parent folders if necessary. Some mail storages may restrict, which folder
* may be used as parent or which chars may be used in the folder name
*
* @param string $name global name of folder, local name if $parentFolder is set
* @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function createFolder($name, $parentFolder = null)
{
// TODO: we assume / as the hierarchy delim - need to get that from the folder class!
if ($parentFolder instanceof Zend_Mail_Storage_Folder) {
$folder = $parentFolder->getGlobalName() . '/' . $name;
} else if ($parentFolder != null) {
$folder = $parentFolder . '/' . $name;
} else {
$folder = $name;
}
if (!$this->_protocol->create($folder)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot create folder');
}
}
/**
* remove a folder
*
* @param string|Zend_Mail_Storage_Folder $name name or instance of folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeFolder($name)
{
if ($name instanceof Zend_Mail_Storage_Folder) {
$name = $name->getGlobalName();
}
if (!$this->_protocol->delete($name)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot delete folder');
}
}
/**
* rename and/or move folder
*
* The new name has the same restrictions as in createFolder()
*
* @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder
* @param string $newName new global name of folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function renameFolder($oldName, $newName)
{
if ($oldName instanceof Zend_Mail_Storage_Folder) {
$oldName = $oldName->getGlobalName();
}
if (!$this->_protocol->rename($oldName, $newName)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot rename folder');
}
}
/**
* append a new message to mail storage
*
* @param string $message message as string or instance of message class
* @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
* @param null|array $flags set flags for new message, else a default set is used
* @throws Zend_Mail_Storage_Exception
*/
// not yet * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class
public function appendMessage($message, $folder = null, $flags = null)
{
if ($folder === null) {
$folder = $this->_currentFolder;
}
if ($flags === null) {
$flags = array(Zend_Mail_Storage::FLAG_SEEN);
}
// TODO: handle class instances for $message
if (!$this->_protocol->append($folder, $message, $flags)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot create message, please check if the folder exists and your flags');
}
}
/**
* copy an existing message
*
* @param int $id number of message
* @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function copyMessage($id, $folder)
{
if (!$this->_protocol->copy($folder, $id)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot copy message, does the folder exist?');
}
}
/**
* move an existing message
*
* NOTE: imap has no native move command, thus it's emulated with copy and delete
*
* @param int $id number of message
* @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function moveMessage($id, $folder) {
$this->copyMessage($id, $folder);
$this->removeMessage($id);
}
/**
* set flags for message
*
* NOTE: this method can't set the recent flag.
*
* @param int $id number of message
* @param array $flags new flags for message
* @throws Zend_Mail_Storage_Exception
*/
public function setFlags($id, $flags)
{
if (!$this->_protocol->store($flags, $id)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot set flags, have you tried to set the recent flag or special chars?');
}
}
}
Pop3.php 0000604 00000023076 15071422736 0006111 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Pop3.php 9099 2008-03-30 19:35:47Z thomas $
*/
/**
* @see Zend_Mail_Storage_Abstract
*/
require_once 'Zend/Mail/Storage/Abstract.php';
/**
* @see Zend_Mail_Protocol_Pop3
*/
require_once 'Zend/Mail/Protocol/Pop3.php';
/**
* @see Zend_Mail_Message
*/
require_once 'Zend/Mail/Message.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Pop3 extends Zend_Mail_Storage_Abstract
{
/**
* protocol handler
* @var null|Zend_Mail_Protocol_Pop3
*/
protected $_protocol;
/**
* Count messages all messages in current box
*
* @return int number of messages
* @throws Zend_Mail_Storage_Exception
* @throws Zend_Mail_Protocol_Exception
*/
public function countMessages()
{
$this->_protocol->status($count, $null);
return (int)$count;
}
/**
* get a list of messages with number and size
*
* @param int $id number of message
* @return int|array size of given message of list with all messages as array(num => size)
* @throws Zend_Mail_Protocol_Exception
*/
public function getSize($id = 0)
{
$id = $id ? $id : null;
return $this->_protocol->getList($id);
}
/**
* Fetch a message
*
* @param int $id number of message
* @return Zend_Mail_Message
* @throws Zend_Mail_Protocol_Exception
*/
public function getMessage($id)
{
$bodyLines = 0;
$message = $this->_protocol->top($id, $bodyLines, true);
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message,
'noToplines' => $bodyLines < 1));
}
/*
* Get raw header of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage header
* @param int $topLines include this many lines with header (after an empty line)
* @return string raw header
* @throws Zend_Mail_Protocol_Exception
* @throws Zend_Mail_Storage_Exception
*/
public function getRawHeader($id, $part = null, $topLines = 0)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
return $this->_protocol->top($id, 0, true);
}
/*
* Get raw content of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage content
* @return string raw content
* @throws Zend_Mail_Protocol_Exception
* @throws Zend_Mail_Storage_Exception
*/
public function getRawContent($id, $part = null)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
$content = $this->_protocol->retrieve($id);
// TODO: find a way to avoid decoding the headers
Zend_Mime_Decode::splitMessage($content, $null, $body);
return $body;
}
/**
* create instance with parameters
* Supported paramters are
* - host hostname or ip address of POP3 server
* - user username
* - password password for user 'username' [optional, default = '']
* - port port for POP3 server [optional, default = 110]
* - ssl 'SSL' or 'TLS' for secure sockets
*
* @param $params array mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
* @throws Zend_Mail_Protocol_Exception
*/
public function __construct($params)
{
if (is_array($params)) {
$params = (object)$params;
}
$this->_has['fetchPart'] = false;
$this->_has['top'] = null;
$this->_has['uniqueid'] = null;
if ($params instanceof Zend_Mail_Protocol_Pop3) {
$this->_protocol = $params;
return;
}
if (!isset($params->user)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('need at least user in params');
}
$host = isset($params->host) ? $params->host : 'localhost';
$password = isset($params->password) ? $params->password : '';
$port = isset($params->port) ? $params->port : null;
$ssl = isset($params->ssl) ? $params->ssl : false;
$this->_protocol = new Zend_Mail_Protocol_Pop3();
$this->_protocol->connect($host, $port, $ssl);
$this->_protocol->login($params->user, $password);
}
/**
* Close resource for mail lib. If you need to control, when the resource
* is closed. Otherwise the destructor would call this.
*
* @return null
*/
public function close()
{
$this->_protocol->logout();
}
/**
* Keep the server busy.
*
* @return null
* @throws Zend_Mail_Protocol_Exception
*/
public function noop()
{
return $this->_protocol->noop();
}
/**
* Remove a message from server. If you're doing that from a web enviroment
* you should be careful and use a uniqueid as parameter if possible to
* identify the message.
*
* @param int $id number of message
* @return null
* @throws Zend_Mail_Protocol_Exception
*/
public function removeMessage($id)
{
$this->_protocol->delete($id);
}
/**
* get unique id for one or all messages
*
* if storage does not support unique ids it's the same as the message number
*
* @param int|null $id message number
* @return array|string message number for given message or all messages as array
* @throws Zend_Mail_Storage_Exception
*/
public function getUniqueId($id = null)
{
if (!$this->hasUniqueid) {
if ($id) {
return $id;
}
$count = $this->countMessages();
if ($count < 1) {
return array();
}
$range = range(1, $count);
return array_combine($range, $range);
}
return $this->_protocol->uniqueid($id);
}
/**
* get a message number from a unique id
*
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
* as parameter and use this method to translate it to message number right before calling removeMessage()
*
* @param string $id unique id
* @return int message number
* @throws Zend_Mail_Storage_Exception
*/
public function getNumberByUniqueId($id)
{
if (!$this->hasUniqueid) {
return $id;
}
$ids = $this->getUniqueId();
foreach ($ids as $k => $v) {
if ($v == $id) {
return $k;
}
}
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('unique id not found');
}
/**
* Special handling for hasTop and hasUniqueid. The headers of the first message is
* retrieved if Top wasn't needed/tried yet.
*
* @see Zend_Mail_Storage_Abstract:__get()
* @param string $var
* @return string
* @throws Zend_Mail_Storage_Exception
*/
public function __get($var)
{
$result = parent::__get($var);
if ($result !== null) {
return $result;
}
if (strtolower($var) == 'hastop') {
if ($this->_protocol->hasTop === null) {
// need to make a real call, because not all server are honest in their capas
try {
$this->_protocol->top(1, 0, false);
} catch(Zend_Mail_Exception $e) {
// ignoring error
}
}
$this->_has['top'] = $this->_protocol->hasTop;
return $this->_protocol->hasTop;
}
if (strtolower($var) == 'hasuniqueid') {
$id = null;
try {
$id = $this->_protocol->uniqueid(1);
} catch(Zend_Mail_Exception $e) {
// ignoring error
}
$this->_has['uniqueid'] = $id ? true : false;
return $this->_has['uniqueid'];
}
return $result;
}
}
Folder.php 0000604 00000013151 15071422736 0006474 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Folder.php 9099 2008-03-30 19:35:47Z thomas $
*/
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Folder implements RecursiveIterator
{
/**
* subfolders of folder array(localName => Zend_Mail_Storage_Folder folder)
* @var array
*/
protected $_folders;
/**
* local name (name of folder in parent folder)
* @var string
*/
protected $_localName;
/**
* global name (absolute name of folder)
* @var string
*/
protected $_globalName;
/**
* folder is selectable if folder is able to hold messages, else it's just a parent folder
* @var bool
*/
protected $_selectable = true;
/**
* create a new mail folder instance
*
* @param string $localName name of folder in current subdirectory
* @param string $globalName absolute name of folder
* @param bool $selectable if true folder holds messages, if false it's just a parent for subfolders
* @param array $folders init with given instances of Zend_Mail_Storage_Folder as subfolders
*/
public function __construct($localName, $globalName = '', $selectable = true, array $folders = array())
{
$this->_localName = $localName;
$this->_globalName = $globalName ? $globalName : $localName;
$this->_selectable = $selectable;
$this->_folders = $folders;
}
/**
* implements RecursiveIterator::hasChildren()
*
* @return bool current element has children
*/
public function hasChildren()
{
$current = $this->current();
return $current && $current instanceof Zend_Mail_Storage_Folder && !$current->isLeaf();
}
/**
* implements RecursiveIterator::getChildren()
*
* @return Zend_Mail_Storage_Folder same as self::current()
*/
public function getChildren()
{
return $this->current();
}
/**
* implements Iterator::valid()
*
* @return bool check if there's a current element
*/
public function valid()
{
return key($this->_folders) !== null;
}
/**
* implements Iterator::next()
*
* @return null
*/
public function next()
{
next($this->_folders);
}
/**
* implements Iterator::key()
*
* @return string key/local name of current element
*/
public function key()
{
return key($this->_folders);
}
/**
* implements Iterator::current()
*
* @return Zend_Mail_Storage_Folder current folder
*/
public function current()
{
return current($this->_folders);
}
/**
* implements Iterator::rewind()
*
* @return null
*/
public function rewind()
{
reset($this->_folders);
}
/**
* get subfolder named $name
*
* @param string $name wanted subfolder
* @return Zend_Mail_Storage_Folder folder named $folder
* @throws Zend_Mail_Storage_Exception
*/
public function __get($name)
{
if (!isset($this->_folders[$name])) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("no subfolder named $name");
}
return $this->_folders[$name];
}
/**
* add or replace subfolder named $name
*
* @param string $name local name of subfolder
* @param Zend_Mail_Storage_Folder $folder instance for new subfolder
* @return null
*/
public function __set($name, Zend_Mail_Storage_Folder $folder)
{
$this->_folders[$name] = $folder;
}
/**
* remove subfolder named $name
*
* @param string $name local name of subfolder
* @return null
*/
public function __unset($name)
{
unset($this->_folders[$name]);
}
/**
* magic method for easy output of global name
*
* @return string global name of folder
*/
public function __toString()
{
return (string)$this->getGlobalName();
}
/**
* get local name
*
* @return string local name
*/
public function getLocalName()
{
return $this->_localName;
}
/**
* get global name
*
* @return string global name
*/
public function getGlobalName()
{
return $this->_globalName;
}
/**
* is this folder selectable?
*
* @return bool selectable
*/
public function isSelectable()
{
return $this->_selectable;
}
/**
* check if folder has no subfolder
*
* @return bool true if no subfolders
*/
public function isLeaf()
{
return empty($this->_folders);
}
}
Writable/Interface.php 0000604 00000007332 15071422736 0010736 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 9098 2008-03-30 19:29:10Z thomas $
*/
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Mail_Storage_Writable_Interface
{
/**
* create a new folder
*
* This method also creates parent folders if necessary. Some mail storages may restrict, which folder
* may be used as parent or which chars may be used in the folder name
*
* @param string $name global name of folder, local name if $parentFolder is set
* @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function createFolder($name, $parentFolder = null);
/**
* remove a folder
*
* @param string|Zend_Mail_Storage_Folder $name name or instance of folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeFolder($name);
/**
* rename and/or move folder
*
* The new name has the same restrictions as in createFolder()
*
* @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder
* @param string $newName new global name of folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function renameFolder($oldName, $newName);
/**
* append a new message to mail storage
*
* @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class
* @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
* @param null|array $flags set flags for new message, else a default set is used
* @throws Zend_Mail_Storage_Exception
*/
public function appendMessage($message, $folder = null, $flags = null);
/**
* copy an existing message
*
* @param int $id number of message
* @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function copyMessage($id, $folder);
/**
* move an existing message
*
* @param int $id number of message
* @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function moveMessage($id, $folder);
/**
* set flags for message
*
* NOTE: this method can't set the recent flag.
*
* @param int $id number of message
* @param array $flags new flags for message
* @throws Zend_Mail_Storage_Exception
*/
public function setFlags($id, $flags);
} Writable/Maildir.php 0000604 00000116147 15071422736 0010424 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Maildir.php 12519 2008-11-10 18:41:24Z alexander $
*/
/**
* @see Zend_Mail_Storage_Folder_Maildir
*/
require_once 'Zend/Mail/Storage/Folder/Maildir.php';
/**
* @see Zend_Mail_Storage_Writable_Interface
*/
require_once 'Zend/Mail/Storage/Writable/Interface.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Writable_Maildir extends Zend_Mail_Storage_Folder_Maildir
implements Zend_Mail_Storage_Writable_Interface
{
// TODO: init maildir (+ constructor option create if not found)
/**
* use quota and size of quota if given
* @var bool|int
*/
protected $_quota;
/**
* create a new maildir
*
* If the given dir is already a valid maildir this will not fail.
*
* @param string $dir directory for the new maildir (may already exist)
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public static function initMaildir($dir)
{
if (file_exists($dir)) {
if (!is_dir($dir)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('maildir must be a directory if already exists');
}
} else {
if (!mkdir($dir)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
$dir = dirname($dir);
if (!file_exists($dir)) {
throw new Zend_Mail_Storage_Exception("parent $dir not found");
} else if (!is_dir($dir)) {
throw new Zend_Mail_Storage_Exception("parent $dir not a directory");
} else {
throw new Zend_Mail_Storage_Exception('cannot create maildir');
}
}
}
foreach (array('cur', 'tmp', 'new') as $subdir) {
if (!@mkdir($dir . DIRECTORY_SEPARATOR . $subdir)) {
// ignore if dir exists (i.e. was already valid maildir or two processes try to create one)
if (!file_exists($dir . DIRECTORY_SEPARATOR . $subdir)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('could not create subdir ' . $subdir);
}
}
}
}
/**
* Create instance with parameters
* Additional parameters are (see parent for more):
* - create if true a new maildir is create if none exists
*
* @param $params array mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
*/
public function __construct($params) {
if (is_array($params)) {
$params = (object)$params;
}
if (!empty($params->create) && isset($params->dirname) && !file_exists($params->dirname . DIRECTORY_SEPARATOR . 'cur')) {
self::initMaildir($params->dirname);
}
parent::__construct($params);
}
/**
* create a new folder
*
* This method also creates parent folders if necessary. Some mail storages may restrict, which folder
* may be used as parent or which chars may be used in the folder name
*
* @param string $name global name of folder, local name if $parentFolder is set
* @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
* @return string only used internally (new created maildir)
* @throws Zend_Mail_Storage_Exception
*/
public function createFolder($name, $parentFolder = null)
{
if ($parentFolder instanceof Zend_Mail_Storage_Folder) {
$folder = $parentFolder->getGlobalName() . $this->_delim . $name;
} else if ($parentFolder != null) {
$folder = rtrim($parentFolder, $this->_delim) . $this->_delim . $name;
} else {
$folder = $name;
}
$folder = trim($folder, $this->_delim);
// first we check if we try to create a folder that does exist
$exists = null;
try {
$exists = $this->getFolders($folder);
} catch (Zend_Mail_Exception $e) {
// ok
}
if ($exists) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('folder already exists');
}
if (strpos($folder, $this->_delim . $this->_delim) !== false) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('invalid name - folder parts may not be empty');
}
if (strpos($folder, 'INBOX' . $this->_delim) === 0) {
$folder = substr($folder, 6);
}
$fulldir = $this->_rootdir . '.' . $folder;
// check if we got tricked and would create a dir outside of the rootdir or not as direct child
if (strpos($folder, DIRECTORY_SEPARATOR) !== false || strpos($folder, '/') !== false
|| dirname($fulldir) . DIRECTORY_SEPARATOR != $this->_rootdir) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('invalid name - no directory seprator allowed in folder name');
}
// has a parent folder?
$parent = null;
if (strpos($folder, $this->_delim)) {
// let's see if the parent folder exists
$parent = substr($folder, 0, strrpos($folder, $this->_delim));
try {
$this->getFolders($parent);
} catch (Zend_Mail_Exception $e) {
// does not - create parent folder
$this->createFolder($parent);
}
}
if (!@mkdir($fulldir) || !@mkdir($fulldir . DIRECTORY_SEPARATOR . 'cur')) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('error while creating new folder, may be created incompletly');
}
mkdir($fulldir . DIRECTORY_SEPARATOR . 'new');
mkdir($fulldir . DIRECTORY_SEPARATOR . 'tmp');
$localName = $parent ? substr($folder, strlen($parent) + 1) : $folder;
$this->getFolders($parent)->$localName = new Zend_Mail_Storage_Folder($localName, $folder, true);
return $fulldir;
}
/**
* remove a folder
*
* @param string|Zend_Mail_Storage_Folder $name name or instance of folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeFolder($name)
{
// TODO: This could fail in the middle of the task, which is not optimal.
// But there is no defined standard way to mark a folder as removed and there is no atomar fs-op
// to remove a directory. Also moving the folder to a/the trash folder is not possible, as
// all parent folders must be created. What we could do is add a dash to the front of the
// directory name and it should be ignored as long as other processes obey the standard.
if ($name instanceof Zend_Mail_Storage_Folder) {
$name = $name->getGlobalName();
}
$name = trim($name, $this->_delim);
if (strpos($name, 'INBOX' . $this->_delim) === 0) {
$name = substr($name, 6);
}
// check if folder exists and has no children
if (!$this->getFolders($name)->isLeaf()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('delete children first');
}
if ($name == 'INBOX' || $name == DIRECTORY_SEPARATOR || $name == '/') {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('wont delete INBOX');
}
if ($name == $this->getCurrentFolder()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('wont delete selected folder');
}
foreach (array('tmp', 'new', 'cur', '.') as $subdir) {
$dir = $this->_rootdir . '.' . $name . DIRECTORY_SEPARATOR . $subdir;
if (!file_exists($dir)) {
continue;
}
$dh = opendir($dir);
if (!$dh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("error opening $subdir");
}
while (($entry = readdir($dh)) !== false) {
if ($entry == '.' || $entry == '..') {
continue;
}
if (!unlink($dir . DIRECTORY_SEPARATOR . $entry)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("error cleaning $subdir");
}
}
closedir($dh);
if ($subdir !== '.') {
if (!rmdir($dir)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("error removing $subdir");
}
}
}
if (!rmdir($this->_rootdir . '.' . $name)) {
// at least we should try to make it a valid maildir again
mkdir($this->_rootdir . '.' . $name . DIRECTORY_SEPARATOR . 'cur');
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("error removing maindir");
}
$parent = strpos($name, $this->_delim) ? substr($name, 0, strrpos($name, $this->_delim)) : null;
$localName = $parent ? substr($name, strlen($parent) + 1) : $name;
unset($this->getFolders($parent)->$localName);
}
/**
* rename and/or move folder
*
* The new name has the same restrictions as in createFolder()
*
* @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder
* @param string $newName new global name of folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function renameFolder($oldName, $newName)
{
// TODO: This is also not atomar and has similar problems as removeFolder()
if ($oldName instanceof Zend_Mail_Storage_Folder) {
$oldName = $oldName->getGlobalName();
}
$oldName = trim($oldName, $this->_delim);
if (strpos($oldName, 'INBOX' . $this->_delim) === 0) {
$oldName = substr($oldName, 6);
}
$newName = trim($newName, $this->_delim);
if (strpos($newName, 'INBOX' . $this->_delim) === 0) {
$newName = substr($newName, 6);
}
if (strpos($newName, $oldName . $this->_delim) === 0) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('new folder cannot be a child of old folder');
}
// check if folder exists and has no children
$folder = $this->getFolders($oldName);
if ($oldName == 'INBOX' || $oldName == DIRECTORY_SEPARATOR || $oldName == '/') {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('wont rename INBOX');
}
if ($oldName == $this->getCurrentFolder()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('wont rename selected folder');
}
$newdir = $this->createFolder($newName);
if (!$folder->isLeaf()) {
foreach ($folder as $k => $v) {
$this->renameFolder($v->getGlobalName(), $newName . $this->_delim . $k);
}
}
$olddir = $this->_rootdir . '.' . $folder;
foreach (array('tmp', 'new', 'cur') as $subdir) {
$subdir = DIRECTORY_SEPARATOR . $subdir;
if (!file_exists($olddir . $subdir)) {
continue;
}
// using copy or moving files would be even better - but also much slower
if (!rename($olddir . $subdir, $newdir . $subdir)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('error while moving ' . $subdir);
}
}
// create a dummy if removing fails - otherwise we can't read it next time
mkdir($olddir . DIRECTORY_SEPARATOR . 'cur');
$this->removeFolder($oldName);
}
/**
* create a uniqueid for maildir filename
*
* This is nearly the format defined in the maildir standard. The microtime() call should already
* create a uniqueid, the pid is for multicore/-cpu machine that manage to call this function at the
* exact same time, and uname() gives us the hostname for multiple machines accessing the same storage.
*
* If someone disables posix we create a random number of the same size, so this method should also
* work on Windows - if you manage to get maildir working on Windows.
* Microtime could also be disabled, altough I've never seen it.
*
* @return string new uniqueid
*/
protected function _createUniqueId()
{
$id = '';
$id .= function_exists('microtime') ? microtime(true) : (time() . ' ' . rand(0, 100000));
$id .= '.' . (function_exists('posix_getpid') ? posix_getpid() : rand(50, 65535));
$id .= '.' . php_uname('n');
return $id;
}
/**
* open a temporary maildir file
*
* makes sure tmp/ exists and create a file with a unique name
* you should close the returned filehandle!
*
* @param string $folder name of current folder without leading .
* @return array array('dirname' => dir of maildir folder, 'uniq' => unique id, 'filename' => name of create file
* 'handle' => file opened for writing)
* @throws Zend_Mail_Storage_Exception
*/
protected function _createTmpFile($folder = 'INBOX')
{
if ($folder == 'INBOX') {
$tmpdir = $this->_rootdir . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
} else {
$tmpdir = $this->_rootdir . '.' . $folder . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
}
if (!file_exists($tmpdir)) {
if (!mkdir($tmpdir)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('problems creating tmp dir');
}
}
// we should retry to create a unique id if a file with the same name exists
// to avoid a script timeout we only wait 1 second (instead of 2) and stop
// after a defined retry count
// if you change this variable take into account that it can take up to $max_tries seconds
// normally we should have a valid unique name after the first try, we're just following the "standard" here
$max_tries = 5;
for ($i = 0; $i < $max_tries; ++$i) {
$uniq = $this->_createUniqueId();
if (!file_exists($tmpdir . $uniq)) {
// here is the race condition! - as defined in the standard
// to avoid having a long time between stat()ing the file and creating it we're opening it here
// to mark the filename as taken
$fh = fopen($tmpdir . $uniq, 'w');
if (!$fh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('could not open temp file');
}
break;
}
sleep(1);
}
if (!$fh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception("tried $max_tries unique ids for a temp file, but all were taken"
. ' - giving up');
}
return array('dirname' => $this->_rootdir . '.' . $folder, 'uniq' => $uniq, 'filename' => $tmpdir . $uniq,
'handle' => $fh);
}
/**
* create an info string for filenames with given flags
*
* @param array $flags wanted flags, with the reference you'll get the set flags with correct key (= char for flag)
* @return string info string for version 2 filenames including the leading colon
* @throws Zend_Mail_Storage_Exception
*/
protected function _getInfoString(&$flags)
{
// accessing keys is easier, faster and it removes duplicated flags
$wanted_flags = array_flip($flags);
if (isset($wanted_flags[Zend_Mail_Storage::FLAG_RECENT])) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('recent flag may not be set');
}
$info = ':2,';
$flags = array();
foreach (Zend_Mail_Storage_Maildir::$_knownFlags as $char => $flag) {
if (!isset($wanted_flags[$flag])) {
continue;
}
$info .= $char;
$flags[$char] = $flag;
unset($wanted_flags[$flag]);
}
if (!empty($wanted_flags)) {
$wanted_flags = implode(', ', array_keys($wanted_flags));
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('unknown flag(s): ' . $wanted_flags);
}
return $info;
}
/**
* append a new message to mail storage
*
* @param string|stream $message message as string or stream resource
* @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
* @param null|array $flags set flags for new message, else a default set is used
* @param bool $recent handle this mail as if recent flag has been set,
* should only be used in delivery
* @throws Zend_Mail_Storage_Exception
*/
// not yet * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class
public function appendMessage($message, $folder = null, $flags = null, $recent = false)
{
if ($this->_quota && $this->checkQuota()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('storage is over quota!');
}
if ($folder === null) {
$folder = $this->_currentFolder;
}
if (!($folder instanceof Zend_Mail_Storage_Folder)) {
$folder = $this->getFolders($folder);
}
if ($flags === null) {
$flags = array(Zend_Mail_Storage::FLAG_SEEN);
}
$info = $this->_getInfoString($flags);
$temp_file = $this->_createTmpFile($folder->getGlobalName());
// TODO: handle class instances for $message
if (is_resource($message) && get_resource_type($message) == 'stream') {
stream_copy_to_stream($message, $temp_file['handle']);
} else {
fputs($temp_file['handle'], $message);
}
fclose($temp_file['handle']);
// we're adding the size to the filename for maildir++
$size = filesize($temp_file['filename']);
if ($size !== false) {
$info = ',S=' . $size . $info;
}
$new_filename = $temp_file['dirname'] . DIRECTORY_SEPARATOR;
$new_filename .= $recent ? 'new' : 'cur';
$new_filename .= DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info;
// we're throwing any exception after removing our temp file and saving it to this variable instead
$exception = null;
if (!link($temp_file['filename'], $new_filename)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
$exception = new Zend_Mail_Storage_Exception('cannot link message file to final dir');
}
@unlink($temp_file['filename']);
if ($exception) {
throw $exception;
}
$this->_files[] = array('uniq' => $temp_file['uniq'],
'flags' => $flags,
'filename' => $new_filename);
if ($this->_quota) {
$this->_addQuotaEntry((int)$size, 1);
}
}
/**
* copy an existing message
*
* @param int $id number of message
* @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function copyMessage($id, $folder)
{
if ($this->_quota && $this->checkQuota()) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('storage is over quota!');
}
if (!($folder instanceof Zend_Mail_Storage_Folder)) {
$folder = $this->getFolders($folder);
}
$filedata = $this->_getFileData($id);
$old_file = $filedata['filename'];
$flags = $filedata['flags'];
// copied message can't be recent
while (($key = array_search(Zend_Mail_Storage::FLAG_RECENT, $flags)) !== false) {
unset($flags[$key]);
}
$info = $this->_getInfoString($flags);
// we're creating the copy as temp file before moving to cur/
$temp_file = $this->_createTmpFile($folder->getGlobalName());
// we don't write directly to the file
fclose($temp_file['handle']);
// we're adding the size to the filename for maildir++
$size = filesize($old_file);
if ($size !== false) {
$info = ',S=' . $size . $info;
}
$new_file = $temp_file['dirname'] . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info;
// we're throwing any exception after removing our temp file and saving it to this variable instead
$exception = null;
if (!copy($old_file, $temp_file['filename'])) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
$exception = new Zend_Mail_Storage_Exception('cannot copy message file');
} else if (!link($temp_file['filename'], $new_file)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
$exception = new Zend_Mail_Storage_Exception('cannot link message file to final dir');
}
@unlink($temp_file['filename']);
if ($exception) {
throw $exception;
}
if ($folder->getGlobalName() == $this->_currentFolder
|| ($this->_currentFolder == 'INBOX' && $folder->getGlobalName() == '/')) {
$this->_files[] = array('uniq' => $temp_file['uniq'],
'flags' => $flags,
'filename' => $new_file);
}
if ($this->_quota) {
$this->_addQuotaEntry((int)$size, 1);
}
}
/**
* move an existing message
*
* @param int $id number of message
* @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function moveMessage($id, $folder) {
if (!($folder instanceof Zend_Mail_Storage_Folder)) {
$folder = $this->getFolders($folder);
}
if ($folder->getGlobalName() == $this->_currentFolder
|| ($this->_currentFolder == 'INBOX' && $folder->getGlobalName() == '/')) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('target is current folder');
}
$filedata = $this->_getFileData($id);
$old_file = $filedata['filename'];
$flags = $filedata['flags'];
// moved message can't be recent
while (($key = array_search(Zend_Mail_Storage::FLAG_RECENT, $flags)) !== false) {
unset($flags[$key]);
}
$info = $this->_getInfoString($flags);
// reserving a new name
$temp_file = $this->_createTmpFile($folder->getGlobalName());
fclose($temp_file['handle']);
// we're adding the size to the filename for maildir++
$size = filesize($old_file);
if ($size !== false) {
$info = ',S=' . $size . $info;
}
$new_file = $temp_file['dirname'] . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info;
// we're throwing any exception after removing our temp file and saving it to this variable instead
$exception = null;
if (!rename($old_file, $new_file)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
$exception = new Zend_Mail_Storage_Exception('cannot move message file');
}
@unlink($temp_file['filename']);
if ($exception) {
throw $exception;
}
unset($this->_files[$id - 1]);
// remove the gap
$this->_files = array_values($this->_files);
}
/**
* set flags for message
*
* NOTE: this method can't set the recent flag.
*
* @param int $id number of message
* @param array $flags new flags for message
* @throws Zend_Mail_Storage_Exception
*/
public function setFlags($id, $flags)
{
$info = $this->_getInfoString($flags);
$filedata = $this->_getFileData($id);
// NOTE: double dirname to make sure we always move to cur. if recent flag has been set (message is in new) it will be moved to cur.
$new_filename = dirname(dirname($filedata['filename'])) . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . "$filedata[uniq]$info";
if (!@rename($filedata['filename'], $new_filename)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot rename file');
}
$filedata['flags'] = $flags;
$filedata['filename'] = $new_filename;
$this->_files[$id - 1] = $filedata;
}
/**
* stub for not supported message deletion
*
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeMessage($id)
{
$filename = $this->_getFileData($id, 'filename');
if ($this->_quota) {
$size = filesize($filename);
}
if (!@unlink($filename)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot remove message');
}
unset($this->_files[$id - 1]);
// remove the gap
$this->_files = array_values($this->_files);
if ($this->_quota) {
$this->_addQuotaEntry(0 - (int)$size, -1);
}
}
/**
* enable/disable quota and set a quota value if wanted or needed
*
* You can enable/disable quota with true/false. If you don't have
* a MDA or want to enforce a quota value you can also set this value
* here. Use array('size' => SIZE_QUOTA, 'count' => MAX_MESSAGE) do
* define your quota. Order of these fields does matter!
*
* @param bool|array $value new quota value
* @return null
*/
public function setQuota($value) {
$this->_quota = $value;
}
/**
* get currently set quota
*
* @see Zend_Mail_Storage_Writable_Maildir::setQuota()
*
* @return bool|array
*/
public function getQuota($fromStorage = false) {
if ($fromStorage) {
$fh = @fopen($this->_rootdir . 'maildirsize', 'r');
if (!$fh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot open maildirsize');
}
$definition = fgets($fh);
fclose($fh);
$definition = explode(',', trim($definition));
$quota = array();
foreach ($definition as $member) {
$key = $member[strlen($member) - 1];
if ($key == 'S' || $key == 'C') {
$key = $key == 'C' ? 'count' : 'size';
}
$quota[$key] = substr($member, 0, -1);
}
return $quota;
}
return $this->_quota;
}
/**
* @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating maildirsize"
*/
protected function _calculateMaildirsize() {
$timestamps = array();
$messages = 0;
$total_size = 0;
if (is_array($this->_quota)) {
$quota = $this->_quota;
} else {
try {
$quota = $this->getQuota(true);
} catch (Zend_Mail_Storage_Exception $e) {
throw new Zend_Mail_Storage_Exception('no quota defintion found');
}
}
$folders = new RecursiveIteratorIterator($this->getFolders(), RecursiveIteratorIterator::SELF_FIRST);
foreach ($folders as $folder) {
$subdir = $folder->getGlobalName();
if ($subdir == 'INBOX') {
$subdir = '';
} else {
$subdir = '.' . $subdir;
}
if ($subdir == 'Trash') {
continue;
}
foreach (array('cur', 'new') as $subsubdir) {
$dirname = $this->_rootdir . $subdir . DIRECTORY_SEPARATOR . $subsubdir . DIRECTORY_SEPARATOR;
if (!file_exists($dirname)) {
continue;
}
// NOTE: we are using mtime instead of "the latest timestamp". The latest would be atime
// and as we are accessing the directory it would make the whole calculation useless.
$timestamps[$dirname] = filemtime($dirname);
$dh = opendir($dirname);
// NOTE: Should have been checked in constructor. Not throwing an exception here, quotas will
// therefore not be fully enforeced, but next request will fail anyway, if problem persists.
if (!$dh) {
continue;
}
while (($entry = readdir()) !== false) {
if ($entry[0] == '.' || !is_file($dirname . $entry)) {
continue;
}
if (strpos($entry, ',S=')) {
strtok($entry, '=');
$filesize = strtok(':');
if (is_numeric($filesize)) {
$total_size += $filesize;
++$messages;
continue;
}
}
$size = filesize($dirname . $entry);
if ($size === false) {
// ignore, as we assume file got removed
continue;
}
$total_size += $size;
++$messages;
}
}
}
$tmp = $this->_createTmpFile();
$fh = $tmp['handle'];
$definition = array();
foreach ($quota as $type => $value) {
if ($type == 'size' || $type == 'count') {
$type = $type == 'count' ? 'C' : 'S';
}
$definition[] = $value . $type;
}
$definition = implode(',', $definition);
fputs($fh, "$definition\n");
fputs($fh, "$total_size $messages\n");
fclose($fh);
rename($tmp['filename'], $this->_rootdir . 'maildirsize');
foreach ($timestamps as $dir => $timestamp) {
if ($timestamp < filemtime($dir)) {
unlink($this->_rootdir . 'maildirsize');
break;
}
}
return array('size' => $total_size, 'count' => $messages, 'quota' => $quota);
}
/**
* @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating the quota for a Maildir++"
*/
protected function _calculateQuota($forceRecalc = false) {
$fh = null;
$total_size = 0;
$messages = 0;
$maildirsize = '';
if (!$forceRecalc && file_exists($this->_rootdir . 'maildirsize') && filesize($this->_rootdir . 'maildirsize') < 5120) {
$fh = fopen($this->_rootdir . 'maildirsize', 'r');
}
if ($fh) {
$maildirsize = fread($fh, 5120);
if (strlen($maildirsize) >= 5120) {
fclose($fh);
$fh = null;
$maildirsize = '';
}
}
if (!$fh) {
$result = $this->_calculateMaildirsize();
$total_size = $result['size'];
$messages = $result['count'];
$quota = $result['quota'];
} else {
$maildirsize = explode("\n", $maildirsize);
if (is_array($this->_quota)) {
$quota = $this->_quota;
} else {
$definition = explode(',', $maildirsize[0]);
$quota = array();
foreach ($definition as $member) {
$key = $member[strlen($member) - 1];
if ($key == 'S' || $key == 'C') {
$key = $key == 'C' ? 'count' : 'size';
}
$quota[$key] = substr($member, 0, -1);
}
}
unset($maildirsize[0]);
foreach ($maildirsize as $line) {
list($size, $count) = explode(' ', trim($line));
$total_size += $size;
$messages += $count;
}
}
$over_quota = false;
$over_quota = $over_quota || (isset($quota['size']) && $total_size > $quota['size']);
$over_quota = $over_quota || (isset($quota['count']) && $messages > $quota['count']);
// NOTE: $maildirsize equals false if it wasn't set (AKA we recalculated) or it's only
// one line, because $maildirsize[0] gets unsetted.
// Also we're using local time to calculate the 15 minute offset. Touching a file just for known the
// local time of the file storage isn't worth the hassle.
if ($over_quota && ($maildirsize || filemtime($this->_rootdir . 'maildirsize') > time() - 900)) {
$result = $this->_calculateMaildirsize();
$total_size = $result['size'];
$messages = $result['count'];
$quota = $result['quota'];
$over_quota = false;
$over_quota = $over_quota || (isset($quota['size']) && $total_size > $quota['size']);
$over_quota = $over_quota || (isset($quota['count']) && $messages > $quota['count']);
}
if ($fh) {
// TODO is there a safe way to keep the handle open for writing?
fclose($fh);
}
return array('size' => $total_size, 'count' => $messages, 'quota' => $quota, 'over_quota' => $over_quota);
}
protected function _addQuotaEntry($size, $count = 1) {
if (!file_exists($this->_rootdir . 'maildirsize')) {
// TODO: should get file handler from _calculateQuota
}
$size = (int)$size;
$count = (int)$count;
file_put_contents($this->_rootdir . 'maildirsize', "$size $count\n", FILE_APPEND);
}
/**
* check if storage is currently over quota
*
* @param bool $detailedResponse return known data of quota and current size and message count @see _calculateQuota()
* @return bool|array over quota state or detailed response
*/
public function checkQuota($detailedResponse = false, $forceRecalc = false) {
$result = $this->_calculateQuota($forceRecalc);
return $detailedResponse ? $result : $result['over_quota'];
}
}
Mbox.php 0000604 00000031701 15071422736 0006167 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Mbox.php 12519 2008-11-10 18:41:24Z alexander $
*/
/**
* @see Zend_Loader
* May be used in constructor, but commented out for now
*/
// require_once 'Zend/Loader.php';
/**
* @see Zend_Mail_Storage_Abstract
*/
require_once 'Zend/Mail/Storage/Abstract.php';
/**
* @see Zend_Mail_Message_File
*/
require_once 'Zend/Mail/Message/File.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Mbox extends Zend_Mail_Storage_Abstract
{
/**
* file handle to mbox file
* @var null|resource
*/
protected $_fh;
/**
* filename of mbox file for __wakeup
* @var string
*/
protected $_filename;
/**
* modification date of mbox file for __wakeup
* @var int
*/
protected $_filemtime;
/**
* start and end position of messages as array('start' => start, 'seperator' => headersep, 'end' => end)
* @var array
*/
protected $_positions;
/**
* used message class, change it in an extened class to extend the returned message class
* @var string
*/
protected $_messageClass = 'Zend_Mail_Message_File';
/**
* Count messages all messages in current box
*
* @return int number of messages
* @throws Zend_Mail_Storage_Exception
*/
public function countMessages()
{
return count($this->_positions);
}
/**
* Get a list of messages with number and size
*
* @param int|null $id number of message or null for all messages
* @return int|array size of given message of list with all messages as array(num => size)
*/
public function getSize($id = 0)
{
if ($id) {
$pos = $this->_positions[$id - 1];
return $pos['end'] - $pos['start'];
}
$result = array();
foreach ($this->_positions as $num => $pos) {
$result[$num + 1] = $pos['end'] - $pos['start'];
}
return $result;
}
/**
* Get positions for mail message or throw exeption if id is invalid
*
* @param int $id number of message
* @return array positions as in _positions
* @throws Zend_Mail_Storage_Exception
*/
protected function _getPos($id)
{
if (!isset($this->_positions[$id - 1])) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('id does not exist');
}
return $this->_positions[$id - 1];
}
/**
* Fetch a message
*
* @param int $id number of message
* @return Zend_Mail_Message_File
* @throws Zend_Mail_Storage_Exception
*/
public function getMessage($id)
{
// TODO that's ugly, would be better to let the message class decide
if (strtolower($this->_messageClass) == 'zend_mail_message_file' || is_subclass_of($this->_messageClass, 'zend_mail_message_file')) {
// TODO top/body lines
$messagePos = $this->_getPos($id);
return new $this->_messageClass(array('file' => $this->_fh, 'startPos' => $messagePos['start'],
'endPos' => $messagePos['end']));
}
$bodyLines = 0; // TODO: need a way to change that
$message = $this->getRawHeader($id);
// file pointer is after headers now
if ($bodyLines) {
$message .= "\n";
while ($bodyLines-- && ftell($this->_fh) < $this->_positions[$id - 1]['end']) {
$message .= fgets($this->_fh);
}
}
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message));
}
/*
* Get raw header of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage header
* @param int $topLines include this many lines with header (after an empty line)
* @return string raw header
* @throws Zend_Mail_Protocol_Exception
* @throws Zend_Mail_Storage_Exception
*/
public function getRawHeader($id, $part = null, $topLines = 0)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
$messagePos = $this->_getPos($id);
// TODO: toplines
return stream_get_contents($this->_fh, $messagePos['separator'] - $messagePos['start'], $messagePos['start']);
}
/*
* Get raw content of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage content
* @return string raw content
* @throws Zend_Mail_Protocol_Exception
* @throws Zend_Mail_Storage_Exception
*/
public function getRawContent($id, $part = null)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
$messagePos = $this->_getPos($id);
return stream_get_contents($this->_fh, $messagePos['end'] - $messagePos['separator'], $messagePos['separator']);
}
/**
* Create instance with parameters
* Supported parameters are:
* - filename filename of mbox file
*
* @param $params array mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
*/
public function __construct($params)
{
if (is_array($params)) {
$params = (object)$params;
}
if (!isset($params->filename) /* || Zend_Loader::isReadable($params['filename']) */) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('no valid filename given in params');
}
$this->_openMboxFile($params->filename);
$this->_has['top'] = true;
$this->_has['uniqueid'] = false;
}
/**
* check if given file is a mbox file
*
* if $file is a resource its file pointer is moved after the first line
*
* @param resource|string $file stream resource of name of file
* @param bool $fileIsString file is string or resource
* @return bool file is mbox file
*/
protected function _isMboxFile($file, $fileIsString = true)
{
if ($fileIsString) {
$file = @fopen($file, 'r');
if (!$file) {
return false;
}
} else {
fseek($file, 0);
}
$result = false;
$line = fgets($file);
if (strpos($line, 'From ') === 0) {
$result = true;
}
if ($fileIsString) {
@fclose($file);
}
return $result;
}
/**
* open given file as current mbox file
*
* @param string $filename filename of mbox file
* @return null
* @throws Zend_Mail_Storage_Exception
*/
protected function _openMboxFile($filename)
{
if ($this->_fh) {
$this->close();
}
$this->_fh = @fopen($filename, 'r');
if (!$this->_fh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot open mbox file');
}
$this->_filename = $filename;
$this->_filemtime = filemtime($this->_filename);
if (!$this->_isMboxFile($this->_fh, false)) {
@fclose($this->_fh);
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('file is not a valid mbox format');
}
$messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
while (($line = fgets($this->_fh)) !== false) {
if (strpos($line, 'From ') === 0) {
$messagePos['end'] = ftell($this->_fh) - strlen($line) - 2; // + newline
if (!$messagePos['separator']) {
$messagePos['separator'] = $messagePos['end'];
}
$this->_positions[] = $messagePos;
$messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
}
if (!$messagePos['separator'] && !trim($line)) {
$messagePos['separator'] = ftell($this->_fh);
}
}
$messagePos['end'] = ftell($this->_fh);
if (!$messagePos['separator']) {
$messagePos['separator'] = $messagePos['end'];
}
$this->_positions[] = $messagePos;
}
/**
* Close resource for mail lib. If you need to control, when the resource
* is closed. Otherwise the destructor would call this.
*
* @return void
*/
public function close()
{
@fclose($this->_fh);
$this->_positions = array();
}
/**
* Waste some CPU cycles doing nothing.
*
* @return void
*/
public function noop()
{
return true;
}
/**
* stub for not supported message deletion
*
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeMessage($id)
{
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('mbox is read-only');
}
/**
* get unique id for one or all messages
*
* Mbox does not support unique ids (yet) - it's always the same as the message number.
* That shouldn't be a problem, because we can't change mbox files. Therefor the message
* number is save enough.
*
* @param int|null $id message number
* @return array|string message number for given message or all messages as array
* @throws Zend_Mail_Storage_Exception
*/
public function getUniqueId($id = null)
{
if ($id) {
// check if id exists
$this->_getPos($id);
return $id;
}
$range = range(1, $this->countMessages());
return array_combine($range, $range);
}
/**
* get a message number from a unique id
*
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
* as parameter and use this method to translate it to message number right before calling removeMessage()
*
* @param string $id unique id
* @return int message number
* @throws Zend_Mail_Storage_Exception
*/
public function getNumberByUniqueId($id)
{
// check if id exists
$this->_getPos($id);
return $id;
}
/**
* magic method for serialize()
*
* with this method you can cache the mbox class
*
* @return array name of variables
*/
public function __sleep()
{
return array('_filename', '_positions', '_filemtime');
}
/**
* magic method for unserialize()
*
* with this method you can cache the mbox class
* for cache validation the mtime of the mbox file is used
*
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function __wakeup()
{
if ($this->_filemtime != @filemtime($this->_filename)) {
$this->close();
$this->_openMboxFile($this->_filename);
} else {
$this->_fh = @fopen($this->_filename, 'r');
if (!$this->_fh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot open mbox file');
}
}
}
}
Maildir.php 0000604 00000034324 15071422736 0006647 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Maildir.php 12519 2008-11-10 18:41:24Z alexander $
*/
/**
* @see Zend_Mail_Storage_Abstract
*/
require_once 'Zend/Mail/Storage/Abstract.php';
/**
* @see Zend_Mail_Message_File
*/
require_once 'Zend/Mail/Message/File.php';
/**
* @see Zend_Mail_Storage
*/
require_once 'Zend/Mail/Storage.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Storage_Maildir extends Zend_Mail_Storage_Abstract
{
/**
* used message class, change it in an extened class to extend the returned message class
* @var string
*/
protected $_messageClass = 'Zend_Mail_Message_File';
/**
* data of found message files in maildir dir
* @var array
*/
protected $_files = array();
/**
* known flag chars in filenames
*
* This list has to be in alphabetical order for setFlags()
*
* @var array
*/
protected static $_knownFlags = array('D' => Zend_Mail_Storage::FLAG_DRAFT,
'F' => Zend_Mail_Storage::FLAG_FLAGGED,
'P' => Zend_Mail_Storage::FLAG_PASSED,
'R' => Zend_Mail_Storage::FLAG_ANSWERED,
'S' => Zend_Mail_Storage::FLAG_SEEN,
'T' => Zend_Mail_Storage::FLAG_DELETED);
// TODO: getFlags($id) for fast access if headers are not needed (i.e. just setting flags)?
/**
* Count messages all messages in current box
*
* @return int number of messages
* @throws Zend_Mail_Storage_Exception
*/
public function countMessages($flags = null)
{
if ($flags === null) {
return count($this->_files);
}
$count = 0;
if (!is_array($flags)) {
foreach ($this->_files as $file) {
if (isset($file['flaglookup'][$flags])) {
++$count;
}
}
return $count;
}
$flags = array_flip($flags);
foreach ($this->_files as $file) {
foreach ($flags as $flag => $v) {
if (!isset($file['flaglookup'][$flag])) {
continue 2;
}
}
++$count;
}
return $count;
}
/**
* Get one or all fields from file structure. Also checks if message is valid
*
* @param int $id message number
* @param string|null $field wanted field
* @return string|array wanted field or all fields as array
* @throws Zend_Mail_Storage_Exception
*/
protected function _getFileData($id, $field = null)
{
if (!isset($this->_files[$id - 1])) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('id does not exist');
}
if (!$field) {
return $this->_files[$id - 1];
}
if (!isset($this->_files[$id - 1][$field])) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('field does not exist');
}
return $this->_files[$id - 1][$field];
}
/**
* Get a list of messages with number and size
*
* @param int|null $id number of message or null for all messages
* @return int|array size of given message of list with all messages as array(num => size)
* @throws Zend_Mail_Storage_Exception
*/
public function getSize($id = null)
{
if ($id !== null) {
$filedata = $this->_getFileData($id);
return isset($filedata['size']) ? $filedata['size'] : filesize($filedata['filename']);
}
$result = array();
foreach ($this->_files as $num => $data) {
$result[$num + 1] = isset($data['size']) ? $data['size'] : filesize($data['filename']);
}
return $result;
}
/**
* Fetch a message
*
* @param int $id number of message
* @return Zend_Mail_Message_File
* @throws Zend_Mail_Storage_Exception
*/
public function getMessage($id)
{
// TODO that's ugly, would be better to let the message class decide
if (strtolower($this->_messageClass) == 'zend_mail_message_file' || is_subclass_of($this->_messageClass, 'zend_mail_message_file')) {
return new $this->_messageClass(array('file' => $this->_getFileData($id, 'filename'),
'flags' => $this->_getFileData($id, 'flags')));
}
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $this->getRawHeader($id),
'flags' => $this->_getFileData($id, 'flags')));
}
/*
* Get raw header of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage header
* @param int $topLines include this many lines with header (after an empty line)
* @return string raw header
* @throws Zend_Mail_Storage_Exception
*/
public function getRawHeader($id, $part = null, $topLines = 0)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
$fh = fopen($this->_getFileData($id, 'filename'), 'r');
$content = '';
while (!feof($fh)) {
$line = fgets($fh);
if (!trim($line)) {
break;
}
$content .= $line;
}
fclose($fh);
return $content;
}
/*
* Get raw content of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage content
* @return string raw content
* @throws Zend_Mail_Storage_Exception
*/
public function getRawContent($id, $part = null)
{
if ($part !== null) {
// TODO: implement
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('not implemented');
}
$fh = fopen($this->_getFileData($id, 'filename'), 'r');
while (!feof($fh)) {
$line = fgets($fh);
if (!trim($line)) {
break;
}
}
$content = stream_get_contents($fh);
fclose($fh);
return $content;
}
/**
* Create instance with parameters
* Supported parameters are:
* - dirname dirname of mbox file
*
* @param $params array mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
*/
public function __construct($params)
{
if (is_array($params)) {
$params = (object)$params;
}
if (!isset($params->dirname) || !is_dir($params->dirname)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
}
if (!$this->_isMaildir($params->dirname)) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('invalid maildir given');
}
$this->_has['top'] = true;
$this->_has['flags'] = true;
$this->_openMaildir($params->dirname);
}
/**
* check if a given dir is a valid maildir
*
* @param string $dirname name of dir
* @return bool dir is valid maildir
*/
protected function _isMaildir($dirname)
{
if (file_exists($dirname . '/new') && !is_dir($dirname . '/new')) {
return false;
}
if (file_exists($dirname . '/tmp') && !is_dir($dirname . '/tmp')) {
return false;
}
return is_dir($dirname . '/cur');
}
/**
* open given dir as current maildir
*
* @param string $dirname name of maildir
* @return null
* @throws Zend_Mail_Storage_Exception
*/
protected function _openMaildir($dirname)
{
if ($this->_files) {
$this->close();
}
$dh = @opendir($dirname . '/cur/');
if (!$dh) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot open maildir');
}
$this->_getMaildirFiles($dh, $dirname . '/cur/');
closedir($dh);
$dh = @opendir($dirname . '/new/');
if ($dh) {
$this->_getMaildirFiles($dh, $dirname . '/new/', array(Zend_Mail_Storage::FLAG_RECENT));
closedir($dh);
} else if (file_exists($dirname . '/new/')) {
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot read recent mails in maildir');
}
}
/**
* find all files in opened dir handle and add to maildir files
*
* @param resource $dh dir handle used for search
* @param string $dirname dirname of dir in $dh
* @param array $default_flags default flags for given dir
* @return null
*/
protected function _getMaildirFiles($dh, $dirname, $default_flags = array())
{
while (($entry = readdir($dh)) !== false) {
if ($entry[0] == '.' || !is_file($dirname . $entry)) {
continue;
}
@list($uniq, $info) = explode(':', $entry, 2);
@list(,$size) = explode(',', $uniq, 2);
if ($size && $size[0] == 'S' && $size[1] == '=') {
$size = substr($size, 2);
}
if (!ctype_digit($size)) {
$size = null;
}
@list($version, $flags) = explode(',', $info, 2);
if ($version != 2) {
$flags = '';
}
$named_flags = $default_flags;
$length = strlen($flags);
for ($i = 0; $i < $length; ++$i) {
$flag = $flags[$i];
$named_flags[$flag] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
}
$data = array('uniq' => $uniq,
'flags' => $named_flags,
'flaglookup' => array_flip($named_flags),
'filename' => $dirname . $entry);
if ($size !== null) {
$data['size'] = (int)$size;
}
$this->_files[] = $data;
}
}
/**
* Close resource for mail lib. If you need to control, when the resource
* is closed. Otherwise the destructor would call this.
*
* @return void
*/
public function close()
{
$this->_files = array();
}
/**
* Waste some CPU cycles doing nothing.
*
* @return void
*/
public function noop()
{
return true;
}
/**
* stub for not supported message deletion
*
* @return null
* @throws Zend_Mail_Storage_Exception
*/
public function removeMessage($id)
{
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('maildir is (currently) read-only');
}
/**
* get unique id for one or all messages
*
* if storage does not support unique ids it's the same as the message number
*
* @param int|null $id message number
* @return array|string message number for given message or all messages as array
* @throws Zend_Mail_Storage_Exception
*/
public function getUniqueId($id = null)
{
if ($id) {
return $this->_getFileData($id, 'uniq');
}
$ids = array();
foreach ($this->_files as $num => $file) {
$ids[$num + 1] = $file['uniq'];
}
return $ids;
}
/**
* get a message number from a unique id
*
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
* as parameter and use this method to translate it to message number right before calling removeMessage()
*
* @param string $id unique id
* @return int message number
* @throws Zend_Mail_Storage_Exception
*/
public function getNumberByUniqueId($id)
{
foreach ($this->_files as $num => $file) {
if ($file['uniq'] == $id) {
return $num + 1;
}
}
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('unique id not found');
}
}
Abstract.php 0000604 00000022154 15071422736 0007027 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 9099 2008-03-30 19:35:47Z thomas $
*/
/**
* @category Zend
* @package Zend_Mail
* @subpackage Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Mail_Storage_Abstract implements Countable, ArrayAccess, SeekableIterator
{
/**
* class capabilities with default values
* @var array
*/
protected $_has = array('uniqueid' => true,
'delete' => false,
'create' => false,
'top' => false,
'fetchPart' => true,
'flags' => false);
/**
* current iteration position
* @var int
*/
protected $_iterationPos = 0;
/**
* maximum iteration position (= message count)
* @var null|int
*/
protected $_iterationMax = null;
/**
* used message class, change it in an extened class to extend the returned message class
* @var string
*/
protected $_messageClass = 'Zend_Mail_Message';
/**
* Getter for has-properties. The standard has properties
* are: hasFolder, hasUniqueid, hasDelete, hasCreate, hasTop
*
* The valid values for the has-properties are:
* - true if a feature is supported
* - false if a feature is not supported
* - null is it's not yet known or it can't be know if a feature is supported
*
* @param string $var property name
* @return bool supported or not
* @throws Zend_Mail_Storage_Exception
*/
public function __get($var)
{
if (strpos($var, 'has') === 0) {
$var = strtolower(substr($var, 3));
return isset($this->_has[$var]) ? $this->_has[$var] : null;
}
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception($var . ' not found');
}
/**
* Get a full list of features supported by the specific mail lib and the server
*
* @return array list of features as array(featurename => true|false[|null])
*/
public function getCapabilities()
{
return $this->_has;
}
/**
* Count messages messages in current box/folder
*
* @return int number of messages
* @throws Zend_Mail_Storage_Exception
*/
abstract public function countMessages();
/**
* Get a list of messages with number and size
*
* @param int $id number of message
* @return int|array size of given message of list with all messages as array(num => size)
*/
abstract public function getSize($id = 0);
/**
* Get a message with headers and body
*
* @param $id int number of message
* @return Zend_Mail_Message
*/
abstract public function getMessage($id);
/**
* Get raw header of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage header
* @param int $topLines include this many lines with header (after an empty line)
* @return string raw header
*/
abstract public function getRawHeader($id, $part = null, $topLines = 0);
/**
* Get raw content of message or part
*
* @param int $id number of message
* @param null|array|string $part path to part or null for messsage content
* @return string raw content
*/
abstract public function getRawContent($id, $part = null);
/**
* Create instance with parameters
*
* @param array $params mail reader specific parameters
* @throws Zend_Mail_Storage_Exception
*/
abstract public function __construct($params);
/**
* Destructor calls close() and therefore closes the resource.
*/
public function __destruct()
{
$this->close();
}
/**
* Close resource for mail lib. If you need to control, when the resource
* is closed. Otherwise the destructor would call this.
*
* @return null
*/
abstract public function close();
/**
* Keep the resource alive.
*
* @return null
*/
abstract public function noop();
/**
* delete a message from current box/folder
*
* @return null
*/
abstract public function removeMessage($id);
/**
* get unique id for one or all messages
*
* if storage does not support unique ids it's the same as the message number
*
* @param int|null $id message number
* @return array|string message number for given message or all messages as array
* @throws Zend_Mail_Storage_Exception
*/
abstract public function getUniqueId($id = null);
/**
* get a message number from a unique id
*
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
* as parameter and use this method to translate it to message number right before calling removeMessage()
*
* @param string $id unique id
* @return int message number
* @throws Zend_Mail_Storage_Exception
*/
abstract public function getNumberByUniqueId($id);
// interface implementations follows
/**
* Countable::count()
*
* @return int
*/
public function count()
{
return $this->countMessages();
}
/**
* ArrayAccess::offsetExists()
*
* @param int $id
* @return boolean
*/
public function offsetExists($id)
{
try {
if ($this->getMessage($id)) {
return true;
}
} catch(Zend_Mail_Storage_Exception $e) {}
return false;
}
/**
* ArrayAccess::offsetGet()
*
* @param int $id
* @return Zend_Mail_Message message object
*/
public function offsetGet($id)
{
return $this->getMessage($id);
}
/**
* ArrayAccess::offsetSet()
*
* @param id $id
* @param mixed $value
* @throws Zend_Mail_Storage_Exception
* @return void
*/
public function offsetSet($id, $value)
{
/**
* @see Zend_Mail_Storage_Exception
*/
require_once 'Zend/Mail/Storage/Exception.php';
throw new Zend_Mail_Storage_Exception('cannot write mail messages via array access');
}
/**
* ArrayAccess::offsetUnset()
*
* @param int $id
* @return boolean success
*/
public function offsetUnset($id)
{
return $this->removeMessage($id);
}
/**
* Iterator::rewind()
*
* Rewind always gets the new count from the storage. Thus if you use
* the interfaces and your scripts take long you should use reset()
* from time to time.
*
* @return void
*/
public function rewind()
{
$this->_iterationMax = $this->countMessages();
$this->_iterationPos = 1;
}
/**
* Iterator::current()
*
* @return Zend_Mail_Message current message
*/
public function current()
{
return $this->getMessage($this->_iterationPos);
}
/**
* Iterator::key()
*
* @return int id of current position
*/
public function key()
{
return $this->_iterationPos;
}
/**
* Iterator::next()
*
* @return void
*/
public function next()
{
++$this->_iterationPos;
}
/**
* Iterator::valid()
*
* @return boolean
*/
public function valid()
{
if ($this->_iterationMax === null) {
$this->_iterationMax = $this->countMessages();
}
return $this->_iterationPos && $this->_iterationPos <= $this->_iterationMax;
}
/**
* SeekableIterator::seek()
*
* @param int $pos
* @return void
* @throws OutOfBoundsException
*/
public function seek($pos)
{
if ($this->_iterationMax === null) {
$this->_iterationMax = $this->countMessages();
}
if ($pos > $this->_iterationMax) {
throw new OutOfBoundsException('this position does not exist');
}
$this->_iterationPos = $pos;
}
}
NonPersistent.php 0000604 00000005103 15071437006 0010066 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: NonPersistent.php 8862 2008-03-16 15:36:00Z thomas $
*/
/**
* @see Zend_Auth_Storage_Interface
*/
require_once 'Zend/Auth/Storage/Interface.php';
/**
* Non-Persistent Auth Storage
*
* Since HTTP Authentication happens again on each request, this will always be
* re-populated. So there's no need to use sessions, this simple value class
* will hold the data for rest of the current request.
*
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Auth_Storage_NonPersistent implements Zend_Auth_Storage_Interface
{
/**
* Holds the actual auth data
*/
protected $_data;
/**
* Returns true if and only if storage is empty
*
* @throws Zend_Auth_Storage_Exception If it is impossible to determine whether storage is empty
* @return boolean
*/
public function isEmpty()
{
return empty($this->_data);
}
/**
* Returns the contents of storage
* Behavior is undefined when storage is empty.
*
* @throws Zend_Auth_Storage_Exception If reading contents from storage is impossible
* @return mixed
*/
public function read()
{
return $this->_data;
}
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws Zend_Auth_Storage_Exception If writing $contents to storage is impossible
* @return void
*/
public function write($contents)
{
$this->_data = $contents;
}
/**
* Clears contents from storage
*
* @throws Zend_Auth_Storage_Exception If clearing contents from storage is impossible
* @return void
*/
public function clear()
{
$this->_data = null;
}
}
Interface.php 0000604 00000003722 15071437006 0007160 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 8862 2008-03-16 15:36:00Z thomas $
*/
/**
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Auth_Storage_Interface
{
/**
* Returns true if and only if storage is empty
*
* @throws Zend_Auth_Storage_Exception If it is impossible to determine whether storage is empty
* @return boolean
*/
public function isEmpty();
/**
* Returns the contents of storage
*
* Behavior is undefined when storage is empty.
*
* @throws Zend_Auth_Storage_Exception If reading contents from storage is impossible
* @return mixed
*/
public function read();
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws Zend_Auth_Storage_Exception If writing $contents to storage is impossible
* @return void
*/
public function write($contents);
/**
* Clears contents from storage
*
* @throws Zend_Auth_Storage_Exception If clearing contents from storage is impossible
* @return void
*/
public function clear();
}
Session.php 0000604 00000006402 15071437006 0006701 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Session.php 8862 2008-03-16 15:36:00Z thomas $
*/
/**
* @see Zend_Auth_Storage_Interface
*/
require_once 'Zend/Auth/Storage/Interface.php';
/**
* @see Zend_Session
*/
require_once 'Zend/Session.php';
/**
* @category Zend
* @package Zend_Auth
* @subpackage Zend_Auth_Storage
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Auth_Storage_Session implements Zend_Auth_Storage_Interface
{
/**
* Default session namespace
*/
const NAMESPACE_DEFAULT = 'Zend_Auth';
/**
* Default session object member name
*/
const MEMBER_DEFAULT = 'storage';
/**
* Object to proxy $_SESSION storage
*
* @var Zend_Session_Namespace
*/
protected $_session;
/**
* Session namespace
*
* @var mixed
*/
protected $_namespace;
/**
* Session object member
*
* @var mixed
*/
protected $_member;
/**
* Sets session storage options and initializes session namespace object
*
* @param mixed $namespace
* @param mixed $member
* @return void
*/
public function __construct($namespace = self::NAMESPACE_DEFAULT, $member = self::MEMBER_DEFAULT)
{
$this->_namespace = $namespace;
$this->_member = $member;
$this->_session = new Zend_Session_Namespace($this->_namespace);
}
/**
* Returns the session namespace
*
* @return string
*/
public function getNamespace()
{
return $this->_namespace;
}
/**
* Returns the name of the session object member
*
* @return string
*/
public function getMember()
{
return $this->_member;
}
/**
* Defined by Zend_Auth_Storage_Interface
*
* @return boolean
*/
public function isEmpty()
{
return !isset($this->_session->{$this->_member});
}
/**
* Defined by Zend_Auth_Storage_Interface
*
* @return mixed
*/
public function read()
{
return $this->_session->{$this->_member};
}
/**
* Defined by Zend_Auth_Storage_Interface
*
* @param mixed $contents
* @return void
*/
public function write($contents)
{
$this->_session->{$this->_member} = $contents;
}
/**
* Defined by Zend_Auth_Storage_Interface
*
* @return void
*/
public function clear()
{
unset($this->_session->{$this->_member});
}
}