Location: PHPKode > scripts > AfterLogic WebMail Lite PHP > afterlogic-webmail-lite-php/webmail/common/class_bodystructure.php
<?php


/*
 * AfterLogic WebMail Pro PHP by AfterLogic Corp. <hide@address.com>
 *
 * Copyright (C) 2002-2010  AfterLogic Corp. (www.afterlogic.com)
 * Distributed under the terms of the license described in COPYING
 *
 */

defined('WM_ROOTPATH') || define('WM_ROOTPATH', (dirname(__FILE__) . '/'));

define('BODYSTRUCTURE_TYPE_NONE', 0);
define('BODYSTRUCTURE_TYPE_TEXT_PLAIN', 1);
define('BODYSTRUCTURE_TYPE_TEXT_HTML', 2);
define('BODYSTRUCTURE_TYPE_ATTACHMENT', 3);

define('BODYSTRUCTURE_KEY_CHARSET', 'charset');
define('BODYSTRUCTURE_KEY_NAME', 'name');
define('BODYSTRUCTURE_KEY_FULLNAME', 'fullname');
define('BODYSTRUCTURE_KEY_ENCODE_TYPE', 'encode_type');

class CBodyStructureObject
{
	/**
	 * @var string
	 */
	var $_responseSourse;

	/**
	 * @var array
	 */
	var $_responseArray;

	/**
	 * @var array
	 */
	var $_bodyParts;

	/**
	 * @var array
	 */
	var $_plainIndexs;

	/**
	 * @var array
	 */
	var $_htmlIndexs;

	/**
	 * @var array
	 */
	var $_attachmentIndexs;

	/**
	 * @var string
	 */
	var $_fullHeaders;

	/**
	 * @var string
	 */
	var $_html;

	/**
	 * @var string
	 */
	var $_plain;

	/**
	 * @var int
	 */
	var $_size;

	/**
	 * @var int
	 */
	var $_uid;

	/**
	 * @var string
	 */
	var $_flags;

	function CBodyStructureObject($bodyStructureResponse)
	{
		$this->_responseArray = null;
		$this->_plainIndexs = array();
		$this->_htmlIndexs = array();
		$this->_attachmentIndexs = array();
		$this->_bodyParts = array();
		$this->_parseResponse($bodyStructureResponse);
	}

	function _parseResponse($bodyStructureResponse)
	{
		$this->_responseSourse = $bodyStructureResponse;

		$endOfline = strpos($this->_responseSourse, "\n");
		$firstLine = (false === $endOfline) ? $this->_responseSourse : substr($this->_responseSourse, 0, $endOfline);

		$aFlags = $aUid = $aSize = array();
		preg_match('/FLAGS \(([^\)]*)\)/', $firstLine, $aFlags);
		preg_match('/UID ([\d]+)/', $firstLine, $aUid);
		preg_match('/RFC822\.SIZE ([\d]+)/', $firstLine, $aSize);

		$this->_flags = isset($aFlags[1]) ? trim(trim($aFlags[1]), '()') : '';
		$this->_uid = isset($aUid[1]) ? (int) $aUid[1] : -1;
		$this->_size = isset($aSize[1]) ? (int) $aSize[1] : 0;

		$clearResponseA = explode('BODYSTRUCTURE', $this->_responseSourse, 2);
		if (count($clearResponseA) == 2)
		{
			$clearResponseS = substr(trim($clearResponseA[1]), 0, -1);
			$this->_responseArray = CBodyStructureParser::GetArray($clearResponseS);
			$this->_fillIndexs();
		}
	}

	function _fillIndexs()
	{
		if (is_array($this->_responseArray))
		{
			$this->_plainIndexs = array();
			$this->_htmlIndexs = array();
			$this->_attachmentIndexs = array();
			$this->_recFillIndexs($this->_responseArray);
		}
	}

	function _recFillIndexs($array, $parentKey = null)
	{
		foreach ($array as $key => $variable)
		{
			if (isset($variable[0]))
			{
				$idx = (null !== $parentKey) ? $parentKey.'.'.($key + 1) : (string) ($key + 1);
				if (is_array($variable[0]))
				{
					$this->_recFillIndexs($variable, $idx);
				}
				else
				{
					$type = CBodyStructureParser::GetBodyStructurePartType($variable);
					switch ($type)
					{
						case BODYSTRUCTURE_TYPE_TEXT_PLAIN:
							$this->_plainIndexs[] = $idx;
							break;
						case BODYSTRUCTURE_TYPE_TEXT_HTML:
							$this->_htmlIndexs[] = $idx;
							break;
						case BODYSTRUCTURE_TYPE_ATTACHMENT:
							$this->_attachmentIndexs[] = $idx;
							break;
					}
				}
			}
		}
	}

	/**
	* @return int
	*/
	function ClassType()
	{
		return (int) (count($this->_htmlIndexs) > 0) << 1 | (int) (count($this->_plainIndexs) > 0);
	}

	function GetPartByKey($key)
	{
		$return = null;
		$keyArray = explode('.', $key);
		if (is_array($keyArray))
		{
			$searchArray = $this->_responseArray;
			foreach ($keyArray as $idx)
			{
				$idx = (int) $idx;
				if ($idx > 0)
				{
					$idx--;
				}
				$return = $searchArray[$idx];
				$searchArray = $return;
			}
		}

		return $return;
	}

	/**
	 * @return array
	 */
	function GetPlainBodyTextIndexs()
	{
		return $this->_plainIndexs;
	}

	/**
	 * @return array
	 */
	function GetHtmlBodyTextIndexs()
	{
		return $this->_htmlIndexs;
	}

	/**
	 * @return array
	 */
	function GetAttachmentIndexs()
	{
		return $this->_attachmentIndexs;
	}

	function GetRequestByMode($mode)
	{
		$request = '';
		if (($mode & 1) == 1 || ($mode & 128) == 128)
		{
			$request .= ' BODY.PEEK[HEADER]';
		}

		$arrH = $this->GetHtmlBodyTextIndexs();
		$arrP = $this->GetPlainBodyTextIndexs();

		$isHtmlExist = count($arrH) > 0;
		$isPlainExist = count($arrP) > 0;

		if ($isPlainExist && (($mode & 4) == 4 || ($mode & 16) == 16 || ($mode & 64) == 64 || (($mode & 2) == 2 && !$isHtmlExist)))
		{
			foreach ($arrP as $idx)
			{
				$request .= ' BODY.PEEK['.$idx.']';
			}
		}

		if ($isHtmlExist && (($mode & 2) == 2 || ($mode & 8) == 8 || ($mode & 16) == 16 || ($mode & 32) == 32))
		{
			foreach ($arrH as $idx)
			{
				$request .= ' BODY.PEEK['.$idx.']';
			}
		}

		if (false)
		{
			$arr = $this->GetAttachmentIndexs();
			if (count($arr) > 0)
			{
				foreach ($arr as $idx)
				{
					$request .= ' BODY.PEEK['.$idx.']';
				}
			}
		}

		return trim($request);
	}

	function GetSize()
	{
		return $this->_size;
	}

	function GetFlags()
	{
		return $this->_flags;
	}

	function GetUid()
	{
		return $this->_uid;
	}

	function GetFullHeaders()
	{
		return $this->_fullHeaders;
	}

	function SetFullHeaders($headers)
	{
		$this->_fullHeaders = $headers;
	}

	function SetBodyPart($key, $text)
	{
		$this->_bodyParts[$key] = $text;
	}

	function GetBodyPart($key)
	{
		return isset($this->_bodyParts[$key]) ? $this->_bodyParts[$key] : '';
	}

	function &GetBodyPartsAsArray()
	{
		return $this->_bodyParts;
	}
}

class CBodyStructureParser
{
	function GetCharsetFromPart($arr)
	{
		return CBodyStructureParser::_getParamFromPart($arr, 'charset', 2);
	}

	function GetNameFromPart($arr)
	{
		$name = CBodyStructureParser::_getParamFromPart($arr, 'name', 2);
		if (strlen($name) == 0 && !CBodyStructureParser::IsMessageRfc822Part($arr))
		{
			$name = CBodyStructureParser::_getParamFromPart($arr, 'name', 8);
		}
		return $name;
	}

	function GetFileNameFromPart($arr)
	{
		$fileName = CBodyStructureParser::_getParamFromPart($arr, 'filename', 2);
		if (strlen($fileName) == 0 && !CBodyStructureParser::IsMessageRfc822Part($arr))
		{
			$fileName = CBodyStructureParser::_getParamFromPart($arr, 'filename', 8);
		}
		return $fileName;
	}

	function GetEncodeFromPart($arr)
	{
		$return = CBodyStructureParser::_getRootParamFromPart($arr, 5);
		if (null !== $return)
		{
			return $return;
		}

		return '';
	}

	function GetContentIdFromPart($arr)
	{
		$return = CBodyStructureParser::_getRootParamFromPart($arr, 3);
		if (null !== $return)
		{
			return $return;
		}

		return '';
	}

	function IsMessageRfc822Part($arr)
	{
		if (isset($arr[0], $arr[1]))
		{
			return (strtolower($arr[0]) == 'message' && strtolower($arr[1]) == 'rfc822');
		}
		return false;
	}

	function GetSizeFromPart($arr)
	{
		$size = CBodyStructureParser::GetEncodedSizeFromPart($arr);
		$encode = CBodyStructureParser::GetEncodeFromPart($arr);
		if ($encode)
		{
			$type = ConvertUtils::GetBodyStructureEncodeType($encode);
			if ($type == IMAP_BS_ENCODETYPE_BASE64)
			{
				$size = $size * 0.75;
			}
			else if ($encode == IMAP_BS_ENCODETYPE_QPRINTABLE)
			{
				$size = $size * 0.44;
			}
		}

		return round($size);
	}

	function GetEncodedSizeFromPart($arr)
	{
		$return = CBodyStructureParser::_getRootParamFromPart($arr, 6);
		if (null !== $return)
		{
			return (int) $return;
		}

		return 0;
	}

	function _getRootParamFromPart($arr, $index)
	{
		if (is_array($arr) && isset($arr[$index]))
		{
			if (is_string($arr[$index]) && 'NIL' !== $arr[$index])
			{
				return $arr[$index];
			}
		}

		return null;
	}

	function _getParamFromPart($arr, $paramName, $paramIndex = 2)
	{
		$return = '';
		if (is_array($arr) && isset($arr[$paramIndex]))
		{
			if (is_array($arr[$paramIndex]))
			{
				CBodyStructureParser::_searchNextParamValue($arr[$paramIndex], $paramName, $return);
			}
		}

		return $return;
	}

	function _searchNextParamValue($array, $paramName, &$return)
	{
		$paramName = strtolower($paramName);
		$returnNext = false;
		foreach ($array as $param)
		{
			if ($returnNext)
			{
				$return = $param;
				break;
			}

			if (is_array($param))
			{
				CBodyStructureParser::_searchNextParamValue($param, $paramName, $return);
			}
			else
			{
				$lparam = strtolower($param);
				if ($lparam == $paramName)
				{
					$returnNext = true;
				}
			}
		}
	}

	function GetNullNameByType($arr)
	{
		if (is_array($arr) && count($arr) > 2)
		{
			$ext = strtolower($arr[1]);
			switch(strtolower($arr[0]))
			{
				case 'image';
					return 'image.'.$ext;
				case 'message';
					return 'message.eml';
			}
		}
		return 'attachment.dat';
	}

	function GetBodyStructurePartType($arr)
	{
		$type = BODYSTRUCTURE_TYPE_NONE;
		if (is_array($arr) && count($arr) > 3)
		{
			$lower_0 = is_string($arr[0]) ? strtolower($arr[0]) : '';
			$lower_1 = is_string($arr[1]) ? strtolower($arr[1]) : '';
			if ($lower_0 == 'text')
			{
				$type = BODYSTRUCTURE_TYPE_TEXT_PLAIN;
				if ($lower_1 == 'html')
				{
					$type = BODYSTRUCTURE_TYPE_TEXT_HTML;
				}
				if (is_array($arr[2]))
				{
					foreach ($arr[2] as $param)
					{
						$lparam = is_string($param) ? strtolower($param) : '';
						if ($lparam == 'name' || $lparam == 'filename')
						{
							$type = BODYSTRUCTURE_TYPE_ATTACHMENT;
						}
					}
				}
			}
			else if (($lower_0 == 'message' && $lower_1 == 'rfc822') || ($lower_0 == 'image' && strlen($arr[3]) > 0))
			{
				$type = BODYSTRUCTURE_TYPE_ATTACHMENT;
			}
			else
			{
				if (is_array($arr[2]))
				{
					foreach ($arr[2] as $param)
					{
						$lparam = is_string($param) ? strtolower($param) : '';
						if ($lparam == 'name' || $lparam == 'filename')
						{
							$type = BODYSTRUCTURE_TYPE_ATTACHMENT;
						}
					}
				}

				if (isset($arr[8]) && is_array($arr[8]))
				{
					foreach ($arr[8] as $param)
					{
						if (is_array($param))
						{
							foreach($param as $value)
							{
								$lparam = is_string($value) ? strtolower($value) : '';
								if ($lparam == 'name' || $lparam == 'filename')
								{
									$type = BODYSTRUCTURE_TYPE_ATTACHMENT;
								}
							}
						}
						else
						{
							$lparam = is_string($param) ? strtolower($param) : '';
							if ($lparam == 'attachment')
							{
								$type = BODYSTRUCTURE_TYPE_ATTACHMENT;
							}
						}
					}
				}
			}
		}
		return $type;
	}

	function ClosingPos($str, $start)
	{
		$level = $isQuote = 0;
		$len = strlen($str);

		for ($i = $start; $i < $len; $i++)
		{
			if ($str{$i} == '"' && $str{$i - 1} != '\\')
			{
				$isQuote = ($isQuote + 1) % 2;
			}

			if (!$isQuote)
			{
				if ($str[$i] == '(')
				{
					$level++;
				}
				else if (($level > 0) && ($str{$i} == ')'))
				{
					$level--;
				}
				else if (($level == 0) && ($str{$i} == ')'))
				{
					return $i;
				}
			}
		}
	}

	function Parse($str)
	{
		$id = $isQuote = 0;
		$a = array();
		$len = strlen($str);

		for ($i = 0; $i < $len; $i++)
		{
			$ch = $str{$i};
			if ($ch == '{')
			{
				$literalStrValue = '';
				$endPos = strpos($str, '}'."\r\n", $i);
				if (false !== $endPos && $endPos - $i > 0 && $endPos - $i < 10)
				{
					$literalStrValue = substr($str, $i + 1, $endPos - $i - 1);
					if (!preg_match('/^[0-9]+$/', $literalStrValue))
					{
						$literalStrValue = '';
					}
				}

				$literalIntValue = (int) $literalStrValue;
				if ($literalIntValue > 0)
				{
					$i = $i + strlen($literalStrValue) + 4;
					$literalLine = substr($str, $i, $literalIntValue);
					$i = $i + $literalIntValue;
					$a[$id] = isset($a[$id]) ? $a[$id].$literalLine : $literalLine;
				}
				else
				{
					$a[$id] = isset($a[$id]) ? $a[$id].$ch : $ch;
				}
			}
			else if ($ch == '"')
			{
				$isQuote = ($isQuote + 1) % 2;
			}
			else if (!$isQuote)
			{
				if ($ch == ' ')
				{
					$id++;
					while ($str{$i + 1} == ' ')
					{
						$i++;
					}
				}
				else if ($ch == '(')
				{
					$i++;
					$endPos = CBodyStructureParser::ClosingPos($str, $i);
					$partLen = $endPos - $i;
					if ($partLen < 0)
					{
						break;
					}
					$a[$id] = CBodyStructureParser::Parse(substr($str, $i, $partLen));
					$i = $endPos;
				}
				else
				{
					$a[$id] = isset($a[$id]) ? $a[$id].$ch : $ch;
				}
			}
			else if ($isQuote)
			{
				if ($ch == '\\')
				{
					$i++;
					if ($ch == '"' || $ch == '\\')
					{
						$a[$id] = isset($a[$id]) ? $a[$id].$ch : $ch;
					}
				}
				else
				{
					$a[$id] = isset($a[$id]) ? $a[$id].$ch : $ch;
				}
			}
		}

		reset($a);
		return $a;
	}

	function GetArray($str)
	{
		$line = trim($str);
		$line = substr($line, 1, strlen($line) - 2);
		$line = str_replace(')(', ') (', $line);

		$struct = CBodyStructureParser::Parse($line);
		if (is_array($struct) && count($struct) > 1 && is_string($struct[0]) && is_string($struct[1]))
		{
			$struct = array($struct);
		}
		return $struct;
	}
}
Return current item: AfterLogic WebMail Lite PHP