| | |
| | | <?php |
| | | |
| | | |
| | | /* |
| | | +-----------------------------------------------------------------------+ |
| | | | program/include/rcube_mime_struct.php | |
| | | | | |
| | | | This file is part of the RoundCube Webmail client | |
| | | | Copyright (C) 2005-2010, RoundCube Dev. - Switzerland | |
| | | | Licensed under the GNU GPL | |
| | | | | |
| | | | PURPOSE: | |
| | | | Provide functions for handling mime messages structure | |
| | | | | |
| | | | Based on Iloha MIME Library. See http://ilohamail.org/ for details | |
| | | | | |
| | | +-----------------------------------------------------------------------+ |
| | | | Author: Aleksander Machniak <alec@alec.pl> | |
| | | | Author: Ryo Chijiiwa <Ryo@IlohaMail.org> | |
| | | +-----------------------------------------------------------------------+ |
| | | |
| | | $Id$ |
| | | |
| | | */ |
| | | |
| | | |
| | | class rcube_mime_struct |
| | | { |
| | | private $structure; |
| | | |
| | | |
| | | function __construct($str=null) |
| | | function getStructurePartType($structure, $part) |
| | | { |
| | | if ($str) |
| | | $this->structure = $this->parseStructure($str); |
| | | } |
| | | |
| | | /* |
| | | * Parses IMAP's BODYSTRUCTURE string into array |
| | | */ |
| | | function parseStructure($str) |
| | | { |
| | | $line = substr($str, 1, strlen($str) - 2); |
| | | $line = str_replace(')(', ') (', $line); |
| | | |
| | | $struct = self::parseBSString($line); |
| | | if (!is_array($struct[0]) && (strcasecmp($struct[0], 'message') == 0) |
| | | && (strcasecmp($struct[1], 'rfc822') == 0)) { |
| | | $struct = array($struct); |
| | | } |
| | | |
| | | return $struct; |
| | | } |
| | | |
| | | /* |
| | | * Parses IMAP's BODYSTRUCTURE string into array and loads it into class internal variable |
| | | */ |
| | | function loadStructure($str) |
| | | { |
| | | if (empty($str)) |
| | | return true; |
| | | |
| | | $this->structure = $this->parseStructure($str); |
| | | return (!empty($this->structure)); |
| | | } |
| | | |
| | | function getPartType($part) |
| | | { |
| | | $part_a = $this->getPartArray($this->structure, $part); |
| | | $part_a = self::getPartArray($structure, $part); |
| | | if (!empty($part_a)) { |
| | | if (is_array($part_a[0])) |
| | | return 'multipart'; |
| | | else if ($part_a[0]) |
| | | return $part_a[0]; |
| | | } |
| | | |
| | | |
| | | return 'other'; |
| | | } |
| | | |
| | | function getPartEncoding($part) |
| | | function getStructurePartEncoding($structure, $part) |
| | | { |
| | | $part_a = $this->getPartArray($this->structure, $part); |
| | | $part_a = self::getPartArray($structure, $part); |
| | | if ($part_a) { |
| | | if (!is_array($part_a[0])) |
| | | return $part_a[5]; |
| | | } |
| | | |
| | | |
| | | return ''; |
| | | } |
| | | |
| | | function getPartCharset($part) |
| | | function getStructurePartCharset($structure, $part) |
| | | { |
| | | $part_a = $this->getPartArray($this->structure, $part); |
| | | $part_a = self::getPartArray($structure, $part); |
| | | if ($part_a) { |
| | | if (is_array($part_a[0])) |
| | | return ''; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | return ''; |
| | | } |
| | | |
| | | function getPartArray($a, $part) |
| | | function getStructurePartArray($a, $part) |
| | | { |
| | | if (!is_array($a)) { |
| | | return false; |
| | |
| | | else |
| | | return $a; |
| | | } |
| | | else if (($part==0) || (empty($part))) { |
| | | else if (($part == 0) || (empty($part))) { |
| | | return $a; |
| | | } |
| | | } |
| | | |
| | | private function closingParenPos($str, $start) |
| | | { |
| | | $level = 0; |
| | | $len = strlen($str); |
| | | $in_quote = 0; |
| | | |
| | | for ($i=$start; $i<$len; $i++) { |
| | | if ($str[$i] == '"' && $str[$i-1] != "\\") { |
| | | $in_quote = ($in_quote + 1) % 2; |
| | | } |
| | | if (!$in_quote) { |
| | | if ($str[$i] == '(') |
| | | $level++; |
| | | else if (($level > 0) && ($str[$i] == ')')) |
| | | $level--; |
| | | else if (($level == 0) && ($str[$i] == ')')) |
| | | return $i; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Parses IMAP's BODYSTRUCTURE string into array |
| | | */ |
| | | private function parseBSString($str) |
| | | { |
| | | $id = 0; |
| | | $a = array(); |
| | | $len = strlen($str); |
| | | $in_quote = 0; |
| | | |
| | | for ($i=0; $i<$len; $i++) { |
| | | if ($str[$i] == '"') { |
| | | $in_quote = ($in_quote + 1) % 2; |
| | | } else if (!$in_quote) { |
| | | // space means new element |
| | | if ($str[$i] == ' ') { |
| | | $id++; |
| | | // skip additional spaces |
| | | while ($str[$i+1] == ' ') |
| | | $i++; |
| | | // new part |
| | | } else if ($str[$i] == '(') { |
| | | $i++; |
| | | $endPos = self::closingParenPos($str, $i); |
| | | $partLen = $endPos - $i; |
| | | if ($partLen < 0) |
| | | break; |
| | | $part = substr($str, $i, $partLen); |
| | | $a[$id] = self::parseBSString($part); // send part string |
| | | $i = $endPos; |
| | | } else |
| | | $a[$id] .= $str[$i]; //add to current element in array |
| | | } else if ($in_quote) { |
| | | if ($str[$i] == "\\") { |
| | | $i++; // escape backslashes |
| | | if ($str[$i] == '"' || $str[$i] == "\\") |
| | | $a[$id] .= $str[$i]; |
| | | } |
| | | else |
| | | $a[$id] .= $str[$i]; //add to current element in array |
| | | } |
| | | } |
| | | |
| | | reset($a); |
| | | return $a; |
| | | } |
| | | |
| | | |
| | | } |