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

📄 maildir.php

📁 Bug tracker, and reporter.
💻 PHP
📖 第 1 页 / 共 3 页
字号:
	    }    }    /**     * 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);        // TODO: move file from new to cur        $new_filename = dirname($filedata['filename']) . 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'];    }}

⌨️ 快捷键说明

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