⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maildir.php

📁 希望此段源编码能给所有需要它的朋友带去快乐
💻 PHP
📖 第 1 页 / 共 3 页
字号:

        $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) {
            $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++
        // TODO: maybe we should support maildirsize or we just let the MDA do the work
        $size = filesize($old_file);
        if ($size) {
            $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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -