web/lib/Zend/Mail/Storage/Folder/Mbox.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Mail
       
    17  * @subpackage Storage
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Mbox.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    21  */
       
    22 
       
    23 
       
    24 /**
       
    25  * @see Zend_Mail_Storage_Folder
       
    26  */
       
    27 require_once 'Zend/Mail/Storage/Folder.php';
       
    28 
       
    29 /**
       
    30  * @see Zend_Mail_Storage_Folder_Interface
       
    31  */
       
    32 require_once 'Zend/Mail/Storage/Folder/Interface.php';
       
    33 
       
    34 /**
       
    35  * @see Zend_Mail_Storage_Mbox
       
    36  */
       
    37 require_once 'Zend/Mail/Storage/Mbox.php';
       
    38 
       
    39 
       
    40 /**
       
    41  * @category   Zend
       
    42  * @package    Zend_Mail
       
    43  * @subpackage Storage
       
    44  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    45  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    46  */
       
    47 class Zend_Mail_Storage_Folder_Mbox extends Zend_Mail_Storage_Mbox implements Zend_Mail_Storage_Folder_Interface
       
    48 {
       
    49     /**
       
    50      * Zend_Mail_Storage_Folder root folder for folder structure
       
    51      * @var Zend_Mail_Storage_Folder
       
    52      */
       
    53     protected $_rootFolder;
       
    54 
       
    55     /**
       
    56      * rootdir of folder structure
       
    57      * @var string
       
    58      */
       
    59     protected $_rootdir;
       
    60 
       
    61     /**
       
    62      * name of current folder
       
    63      * @var string
       
    64      */
       
    65     protected $_currentFolder;
       
    66 
       
    67     /**
       
    68      * Create instance with parameters
       
    69      *
       
    70      * Disallowed parameters are:
       
    71      *   - filename use Zend_Mail_Storage_Mbox for a single file
       
    72      * Supported parameters are:
       
    73      *   - dirname rootdir of mbox structure
       
    74      *   - folder intial selected folder, default is 'INBOX'
       
    75      *
       
    76      * @param  $params array mail reader specific parameters
       
    77      * @throws Zend_Mail_Storage_Exception
       
    78      */
       
    79     public function __construct($params)
       
    80     {
       
    81         if (is_array($params)) {
       
    82             $params = (object)$params;
       
    83         }
       
    84 
       
    85         if (isset($params->filename)) {
       
    86             /**
       
    87              * @see Zend_Mail_Storage_Exception
       
    88              */
       
    89             require_once 'Zend/Mail/Storage/Exception.php';
       
    90             throw new Zend_Mail_Storage_Exception('use Zend_Mail_Storage_Mbox for a single file');
       
    91         }
       
    92 
       
    93         if (!isset($params->dirname) || !is_dir($params->dirname)) {
       
    94             /**
       
    95              * @see Zend_Mail_Storage_Exception
       
    96              */
       
    97             require_once 'Zend/Mail/Storage/Exception.php';
       
    98             throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
       
    99         }
       
   100 
       
   101         $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
       
   102 
       
   103         $this->_buildFolderTree($this->_rootdir);
       
   104         $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
       
   105         $this->_has['top']      = true;
       
   106         $this->_has['uniqueid'] = false;
       
   107     }
       
   108 
       
   109     /**
       
   110      * find all subfolders and mbox files for folder structure
       
   111      *
       
   112      * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
       
   113      * $parentFolder and $parentGlobalName are only used internally for recursion.
       
   114      *
       
   115      * @param string $currentDir call with root dir, also used for recursion.
       
   116      * @param Zend_Mail_Storage_Folder|null $parentFolder used for recursion
       
   117      * @param string $parentGlobalName used for rescursion
       
   118      * @return null
       
   119      * @throws Zend_Mail_Storage_Exception
       
   120      */
       
   121     protected function _buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '')
       
   122     {
       
   123         if (!$parentFolder) {
       
   124             $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false);
       
   125             $parentFolder = $this->_rootFolder;
       
   126         }
       
   127 
       
   128         $dh = @opendir($currentDir);
       
   129         if (!$dh) {
       
   130             /**
       
   131              * @see Zend_Mail_Storage_Exception
       
   132              */
       
   133             require_once 'Zend/Mail/Storage/Exception.php';
       
   134             throw new Zend_Mail_Storage_Exception("can't read dir $currentDir");
       
   135         }
       
   136         while (($entry = readdir($dh)) !== false) {
       
   137             // ignore hidden files for mbox
       
   138             if ($entry[0] == '.') {
       
   139                 continue;
       
   140             }
       
   141             $absoluteEntry = $currentDir . $entry;
       
   142             $globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry;
       
   143             if (is_file($absoluteEntry) && $this->_isMboxFile($absoluteEntry)) {
       
   144                 $parentFolder->$entry = new Zend_Mail_Storage_Folder($entry, $globalName);
       
   145                 continue;
       
   146             }
       
   147             if (!is_dir($absoluteEntry) /* || $entry == '.' || $entry == '..' */) {
       
   148                 continue;
       
   149             }
       
   150             $folder = new Zend_Mail_Storage_Folder($entry, $globalName, false);
       
   151             $parentFolder->$entry = $folder;
       
   152             $this->_buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName);
       
   153         }
       
   154 
       
   155         closedir($dh);
       
   156     }
       
   157 
       
   158     /**
       
   159      * get root folder or given folder
       
   160      *
       
   161      * @param string $rootFolder get folder structure for given folder, else root
       
   162      * @return Zend_Mail_Storage_Folder root or wanted folder
       
   163      * @throws Zend_Mail_Storage_Exception
       
   164      */
       
   165     public function getFolders($rootFolder = null)
       
   166     {
       
   167         if (!$rootFolder) {
       
   168             return $this->_rootFolder;
       
   169         }
       
   170 
       
   171         $currentFolder = $this->_rootFolder;
       
   172         $subname = trim($rootFolder, DIRECTORY_SEPARATOR);
       
   173         while ($currentFolder) {
       
   174             @list($entry, $subname) = @explode(DIRECTORY_SEPARATOR, $subname, 2);
       
   175             $currentFolder = $currentFolder->$entry;
       
   176             if (!$subname) {
       
   177                 break;
       
   178             }
       
   179         }
       
   180 
       
   181         if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) {
       
   182             /**
       
   183              * @see Zend_Mail_Storage_Exception
       
   184              */
       
   185             require_once 'Zend/Mail/Storage/Exception.php';
       
   186             throw new Zend_Mail_Storage_Exception("folder $rootFolder not found");
       
   187         }
       
   188         return $currentFolder;
       
   189     }
       
   190 
       
   191     /**
       
   192      * select given folder
       
   193      *
       
   194      * folder must be selectable!
       
   195      *
       
   196      * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
       
   197      * @return null
       
   198      * @throws Zend_Mail_Storage_Exception
       
   199      */
       
   200     public function selectFolder($globalName)
       
   201     {
       
   202         $this->_currentFolder = (string)$globalName;
       
   203 
       
   204         // getting folder from folder tree for validation
       
   205         $folder = $this->getFolders($this->_currentFolder);
       
   206 
       
   207         try {
       
   208             $this->_openMboxFile($this->_rootdir . $folder->getGlobalName());
       
   209         } catch(Zend_Mail_Storage_Exception $e) {
       
   210             // check what went wrong
       
   211             if (!$folder->isSelectable()) {
       
   212                 /**
       
   213                  * @see Zend_Mail_Storage_Exception
       
   214                  */
       
   215                 require_once 'Zend/Mail/Storage/Exception.php';
       
   216                 throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable", 0, $e);
       
   217             }
       
   218             // seems like file has vanished; rebuilding folder tree - but it's still an exception
       
   219             $this->_buildFolderTree($this->_rootdir);
       
   220             /**
       
   221              * @see Zend_Mail_Storage_Exception
       
   222              */
       
   223             require_once 'Zend/Mail/Storage/Exception.php';
       
   224             throw new Zend_Mail_Storage_Exception('seems like the mbox file has vanished, I\'ve rebuild the ' .
       
   225                                                          'folder tree, search for an other folder and try again', 0, $e);
       
   226         }
       
   227     }
       
   228 
       
   229     /**
       
   230      * get Zend_Mail_Storage_Folder instance for current folder
       
   231      *
       
   232      * @return Zend_Mail_Storage_Folder instance of current folder
       
   233      * @throws Zend_Mail_Storage_Exception
       
   234      */
       
   235     public function getCurrentFolder()
       
   236     {
       
   237         return $this->_currentFolder;
       
   238     }
       
   239 
       
   240     /**
       
   241      * magic method for serialize()
       
   242      *
       
   243      * with this method you can cache the mbox class
       
   244      *
       
   245      * @return array name of variables
       
   246      */
       
   247     public function __sleep()
       
   248     {
       
   249         return array_merge(parent::__sleep(), array('_currentFolder', '_rootFolder', '_rootdir'));
       
   250     }
       
   251 
       
   252     /**
       
   253      * magic method for unserialize()
       
   254      *
       
   255      * with this method you can cache the mbox class
       
   256      *
       
   257      * @return null
       
   258      */
       
   259     public function __wakeup()
       
   260     {
       
   261         // if cache is stall selectFolder() rebuilds the tree on error
       
   262         parent::__wakeup();
       
   263     }
       
   264 }