summaryrefslogtreecommitdiff
path: root/program/include/rcube_mime_struct.php
diff options
context:
space:
mode:
Diffstat (limited to 'program/include/rcube_mime_struct.php')
-rw-r--r--program/include/rcube_mime_struct.php209
1 files changed, 209 insertions, 0 deletions
diff --git a/program/include/rcube_mime_struct.php b/program/include/rcube_mime_struct.php
new file mode 100644
index 000000000..bc00da50a
--- /dev/null
+++ b/program/include/rcube_mime_struct.php
@@ -0,0 +1,209 @@
+<?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)
+ {
+ 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);
+ 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)
+ {
+ $part_a = $this->getPartArray($this->structure, $part);
+ if ($part_a) {
+ if (!is_array($part_a[0]))
+ return $part_a[5];
+ }
+
+ return '';
+ }
+
+ function getPartCharset($part)
+ {
+ $part_a = $this->getPartArray($this->structure, $part);
+ if ($part_a) {
+ if (is_array($part_a[0]))
+ return '';
+ else {
+ if (is_array($part_a[2])) {
+ $name = '';
+ while (list($key, $val) = each($part_a[2]))
+ if (strcasecmp($val, 'charset') == 0)
+ return $part_a[2][$key+1];
+ }
+ }
+ }
+
+ return '';
+ }
+
+ function getPartArray($a, $part)
+ {
+ if (!is_array($a)) {
+ return false;
+ }
+ if (strpos($part, '.') > 0) {
+ $original_part = $part;
+ $pos = strpos($part, '.');
+ $rest = substr($original_part, $pos+1);
+ $part = substr($original_part, 0, $pos);
+ if ((strcasecmp($a[0], 'message') == 0) && (strcasecmp($a[1], 'rfc822') == 0)) {
+ $a = $a[8];
+ }
+ return self::getPartArray($a[$part-1], $rest);
+ }
+ else if ($part>0) {
+ if (!is_array($a[0]) && (strcasecmp($a[0], 'message') == 0)
+ && (strcasecmp($a[1], 'rfc822') == 0)) {
+ $a = $a[8];
+ }
+ if (is_array($a[$part-1]))
+ return $a[$part-1];
+ else
+ return $a;
+ }
+ 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;
+ }
+
+
+}