/** * Split binary string to chunks * * @param string $binaryString The string to be chunked. * @param int $bits The chunk length. * @return array */ private static function chunk($binaryString, $bits) { $binaryString = chunk_split($binaryString, $bits, ' '); if (\CUtil::binSubstr($binaryString, -1) == ' ') { $binaryString = \CUtil::binSubstr($binaryString, 0, -1); } return explode(' ', $binaryString); }
/** * Unpack values from string (something like rsplit). * Simple example for separator ".": * <code> * // Unpack all values: * unpack('test.all.values', 0) -> ['test', 'all', 'values'] * * // Unpack 2 values (by default). First element containing the rest of string. * unpack('test.all.values') -> ['test.all', 'values'] * * // Exception if separator is missing * unpack('test.all values', 3) -> throws BadSignatureException * </code> * * @param string $value String for unpacking. * @param int $limit If $limit === 0 - unpack all values, default - 2. * @return array * @throws BadSignatureException */ protected function unpack($value, $limit = 2) { // Some kind of optimization if ($limit === 0) { if (strpos($value, $this->separator) === false) { throw new BadSignatureException('Separator not found in value'); } return explode($this->separator, $value); } $result = array(); while (--$limit > 0) { $pos = bxstrrpos($value, $this->separator); if ($pos === false) { throw new BadSignatureException('Separator not found in value'); } $result[] = \CUtil::binSubstr($value, $pos + 1); $value = \CUtil::binSubstr($value, 0, $pos); } $result[] = $value; return array_reverse($result); }
private static function parseMessage($message, $charset) { $headerP = CUtil::binStrpos($message, "\r\n\r\n"); $rawHeader = CUtil::binSubstr($message, 0, $headerP); $body = CUtil::binSubstr($message, $headerP + 4); $header = CMailMessage::ParseHeader($rawHeader, $charset); $htmlBody = ''; $textBody = ''; $parts = array(); if ($header->IsMultipart()) { $startB = "\r\n--" . $header->GetBoundary() . "\r\n"; $endB = "\r\n--" . $header->GetBoundary() . "--\r\n"; $startP = CUtil::binStrpos($message, $startB) + CUtil::binStrlen($startB); $endP = CUtil::binStrpos($message, $endB); $data = CUtil::binSubstr($message, $startP, $endP - $startP); $isHtml = false; $rawParts = preg_split("/\r\n--" . preg_quote($header->GetBoundary(), '/') . "\r\n/s", $data); $tmpParts = array(); foreach ($rawParts as $part) { if (CUtil::binSubstr($part, 0, 2) == "\r\n") { $part = "\r\n" . $part; } list(, $subHtml, $subText, $subParts) = CMailMessage::parseMessage($part, $charset); if ($subHtml) { $isHtml = true; } if ($subText) { $tmpParts[] = array($subHtml, $subText); } $parts = array_merge($parts, $subParts); } if (strtolower($header->MultipartType()) == 'alternative') { foreach ($tmpParts as $part) { if ($part[0]) { if (!$textBody || $htmlBody && strlen($htmlBody) < strlen($part[0])) { $htmlBody = $part[0]; $textBody = $part[1]; } } else { if (!$textBody || strlen($textBody) < strlen($part[1])) { $htmlBody = ''; $textBody = $part[1]; } } } } else { foreach ($tmpParts as $part) { if ($textBody) { $textBody .= "\r\n\r\n"; } $textBody .= $part[1]; if ($isHtml) { if ($htmlBody) { $htmlBody .= "\r\n\r\n"; } $htmlBody .= $part[0] ?: $part[1]; } } } } else { $bodyPart = CMailMessage::decodeMessageBody($header, $body, $charset); if (!$bodyPart['FILENAME'] && strpos(strtolower($bodyPart['CONTENT-TYPE']), 'text/') === 0) { if (strtolower($bodyPart['CONTENT-TYPE']) == 'text/html') { $htmlBody = $bodyPart['BODY']; $textBody = htmlToTxt($bodyPart['BODY']); } else { $textBody = $bodyPart['BODY']; } } else { $parts[] = $bodyPart; } } return array($header, $htmlBody, $textBody, $parts); }