1<?php
2
3/*
4 * This file is part of MailSo.
5 *
6 * (c) 2014 Usenko Timur
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace MailSo\Imap;
13
14/**
15 * @category MailSo
16 * @package Imap
17 */
18class FetchResponse
19{
20	/**
21	 * @var \MailSo\Imap\Response
22	 */
23	private $oImapResponse;
24
25	/**
26	 * @var array|null
27	 */
28	private $aEnvelopeCache;
29
30	/**
31	 * @access private
32	 *
33	 * @param \MailSo\Imap\Response $oImapResponse
34	 */
35	private function __construct($oImapResponse)
36	{
37		$this->oImapResponse = $oImapResponse;
38		$this->aEnvelopeCache = null;
39	}
40
41	/**
42	 * @param \MailSo\Imap\Response $oImapResponse
43	 * @return \MailSo\Imap\FetchResponse
44	 */
45	public static function NewInstance($oImapResponse)
46	{
47		return new self($oImapResponse);
48	}
49
50	/**
51	 * @param bool $bForce = false
52	 *
53	 * @return array|null
54	 */
55	public function GetEnvelope($bForce = false)
56	{
57		if (null === $this->aEnvelopeCache || $bForce)
58		{
59			$this->aEnvelopeCache = $this->GetFetchValue(Enumerations\FetchType::ENVELOPE);
60		}
61		return $this->aEnvelopeCache;
62	}
63
64	/**
65	 * @param int $iIndex
66	 * @param mixed $mNullResult = null
67	 *
68	 * @return mixed
69	 */
70	public function GetFetchEnvelopeValue($iIndex, $mNullResult)
71	{
72		return self::findEnvelopeIndex($this->GetEnvelope(), $iIndex, $mNullResult);
73	}
74
75	/**
76	 * @param int $iIndex
77	 * @param string $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1
78	 *
79	 * @return \MailSo\Mime\EmailCollection|null
80	 */
81	public function GetFetchEnvelopeEmailCollection($iIndex, $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1)
82	{
83		$oResult = null;
84		$aEmails = $this->GetFetchEnvelopeValue($iIndex, null);
85		if (is_array($aEmails) && 0 < count($aEmails))
86		{
87			$oResult = \MailSo\Mime\EmailCollection::NewInstance();
88			foreach ($aEmails as $aEmailItem)
89			{
90				if (is_array($aEmailItem) && 4 === count($aEmailItem))
91				{
92					$sDisplayName = \MailSo\Base\Utils::DecodeHeaderValue(
93						self::findEnvelopeIndex($aEmailItem, 0, ''), $sParentCharset);
94
95//					$sRemark = \MailSo\Base\Utils::DecodeHeaderValue(
96//						self::findEnvelopeIndex($aEmailItem, 1, ''), $sParentCharset);
97
98					$sLocalPart = self::findEnvelopeIndex($aEmailItem, 2, '');
99					$sDomainPart = self::findEnvelopeIndex($aEmailItem, 3, '');
100
101					if (0 < strlen($sLocalPart) && 0 < strlen($sDomainPart))
102					{
103						$oResult->Add(
104							\MailSo\Mime\Email::NewInstance($sLocalPart.'@'.$sDomainPart, $sDisplayName)
105						);
106					}
107				}
108			}
109		}
110
111		return $oResult;
112	}
113
114	/**
115	 * @param string $sRfc822SubMimeIndex = ''
116	 *
117	 * @return \MailSo\Imap\BodyStructure|null
118	 */
119	public function GetFetchBodyStructure($sRfc822SubMimeIndex = '')
120	{
121		$oBodyStructure = null;
122		$aBodyStructureArray = $this->GetFetchValue(Enumerations\FetchType::BODYSTRUCTURE);
123
124		if (is_array($aBodyStructureArray))
125		{
126			if (0 < strlen($sRfc822SubMimeIndex))
127			{
128				$oBodyStructure = BodyStructure::NewInstanceFromRfc822SubPart($aBodyStructureArray, $sRfc822SubMimeIndex);
129			}
130			else
131			{
132				$oBodyStructure = BodyStructure::NewInstance($aBodyStructureArray);
133			}
134		}
135
136		return $oBodyStructure;
137	}
138
139	/**
140	 * @param string $sFetchItemName
141	 *
142	 * @return mixed
143	 */
144	public function GetFetchValue($sFetchItemName)
145	{
146		$mReturn = null;
147		$bNextIsValue = false;
148
149		if (Enumerations\FetchType::INDEX === $sFetchItemName)
150		{
151			$mReturn = $this->oImapResponse->ResponseList[1];
152		}
153		else if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3]))
154		{
155			foreach ($this->oImapResponse->ResponseList[3] as $mItem)
156			{
157				if ($bNextIsValue)
158				{
159					$mReturn = $mItem;
160					break;
161				}
162
163				if ($sFetchItemName === $mItem)
164				{
165					$bNextIsValue = true;
166				}
167			}
168		}
169
170		return $mReturn;
171	}
172
173	/**
174	 * @param string $sRfc822SubMimeIndex = ''
175	 *
176	 * @return string
177	 */
178	public function GetHeaderFieldsValue($sRfc822SubMimeIndex = '')
179	{
180		$sReturn = '';
181		$bNextIsValue = false;
182
183		$sRfc822SubMimeIndex = 0 < \strlen($sRfc822SubMimeIndex) ? ''.$sRfc822SubMimeIndex.'.' : '';
184
185		if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3]))
186		{
187			foreach ($this->oImapResponse->ResponseList[3] as $mItem)
188			{
189				if ($bNextIsValue)
190				{
191					$sReturn = (string) $mItem;
192					break;
193				}
194
195				if (\is_string($mItem) && (
196					$mItem === 'BODY['.$sRfc822SubMimeIndex.'HEADER]' ||
197					0 === \strpos($mItem, 'BODY['.$sRfc822SubMimeIndex.'HEADER.FIELDS') ||
198					$mItem === 'BODY['.$sRfc822SubMimeIndex.'MIME]'))
199				{
200					$bNextIsValue = true;
201				}
202			}
203		}
204
205		return $sReturn;
206	}
207
208	private static function findFetchUidAndSize($aList)
209	{
210		$bUid = false;
211		$bSize = false;
212		if (is_array($aList))
213		{
214			foreach ($aList as $mItem)
215			{
216				if (\MailSo\Imap\Enumerations\FetchType::UID === $mItem)
217				{
218					$bUid = true;
219				}
220				else if (\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE === $mItem)
221				{
222					$bSize = true;
223				}
224			}
225		}
226
227		return $bUid && $bSize;
228	}
229
230	/**
231	 * @param \MailSo\Imap\Response $oImapResponse
232	 *
233	 * @return bool
234	 */
235	public static function IsValidFetchImapResponse($oImapResponse)
236	{
237		return (
238			$oImapResponse
239			&& true !== $oImapResponse->IsStatusResponse
240			&& \MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType
241			&& 3 < count($oImapResponse->ResponseList) && 'FETCH' === $oImapResponse->ResponseList[2]
242			&& is_array($oImapResponse->ResponseList[3])
243		);
244	}
245
246	/**
247	 * @param \MailSo\Imap\Response $oImapResponse
248	 *
249	 * @return bool
250	 */
251	public static function IsNotEmptyFetchImapResponse($oImapResponse)
252	{
253		return (
254			$oImapResponse
255			&& self::IsValidFetchImapResponse($oImapResponse)
256			&& isset($oImapResponse->ResponseList[3])
257			&& self::findFetchUidAndSize($oImapResponse->ResponseList[3])
258		);
259	}
260
261	/**
262	 * @param array $aEnvelope
263	 * @param int $iIndex
264	 * @param mixed $mNullResult = null
265	 *
266	 * @return mixed
267	 */
268	private static function findEnvelopeIndex($aEnvelope, $iIndex, $mNullResult)
269	{
270		return (isset($aEnvelope[$iIndex]) && 'NIL' !== $aEnvelope[$iIndex] && '' !== $aEnvelope[$iIndex])
271			? $aEnvelope[$iIndex] : $mNullResult;
272	}
273}
274