|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00025 require_once 'Zend/Mime.php'; 00026 00033 class Zend_Mime_Decode 00034 { 00045 public static function splitMime($body, $boundary) 00046 { 00047 // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r? 00048 $body = str_replace("\r", '', $body); 00049 00050 $start = 0; 00051 $res = array(); 00052 // find every mime part limiter and cut out the 00053 // string before it. 00054 // the part before the first boundary string is discarded: 00055 $p = strpos($body, '--' . $boundary . "\n", $start); 00056 if ($p === false) { 00057 // no parts found! 00058 return array(); 00059 } 00060 00061 // position after first boundary line 00062 $start = $p + 3 + strlen($boundary); 00063 00064 while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) { 00065 $res[] = substr($body, $start, $p-$start); 00066 $start = $p + 3 + strlen($boundary); 00067 } 00068 00069 // no more parts, find end boundary 00070 $p = strpos($body, '--' . $boundary . '--', $start); 00071 if ($p===false) { 00072 throw new Zend_Exception('Not a valid Mime Message: End Missing'); 00073 } 00074 00075 // the remaining part also needs to be parsed: 00076 $res[] = substr($body, $start, $p-$start); 00077 return $res; 00078 } 00079 00090 public static function splitMessageStruct($message, $boundary, $EOL = Zend_Mime::LINEEND) 00091 { 00092 $parts = self::splitMime($message, $boundary); 00093 if (count($parts) <= 0) { 00094 return null; 00095 } 00096 $result = array(); 00097 foreach ($parts as $part) { 00098 self::splitMessage($part, $headers, $body, $EOL); 00099 $result[] = array('header' => $headers, 00100 'body' => $body ); 00101 } 00102 return $result; 00103 } 00104 00117 public static function splitMessage($message, &$headers, &$body, $EOL = Zend_Mime::LINEEND) 00118 { 00119 // check for valid header at first line 00120 $firstline = strtok($message, "\n"); 00121 if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) { 00122 $headers = array(); 00123 // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r? 00124 $body = str_replace(array("\r", "\n"), array('', $EOL), $message); 00125 return; 00126 } 00127 00128 // find an empty line between headers and body 00129 // default is set new line 00130 if (strpos($message, $EOL . $EOL)) { 00131 list($headers, $body) = explode($EOL . $EOL, $message, 2); 00132 // next is the standard new line 00133 } else if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) { 00134 list($headers, $body) = explode("\r\n\r\n", $message, 2); 00135 // next is the other "standard" new line 00136 } else if ($EOL != "\n" && strpos($message, "\n\n")) { 00137 list($headers, $body) = explode("\n\n", $message, 2); 00138 // at last resort find anything that looks like a new line 00139 } else { 00140 @list($headers, $body) = @preg_split("%([\r\n]+)\\1%U", $message, 2); 00141 } 00142 00143 $headers = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR); 00144 00145 if ($headers === false ) { 00146 // an error occurs during the decoding 00147 return; 00148 } 00149 00150 // normalize header names 00151 foreach ($headers as $name => $header) { 00152 $lower = strtolower($name); 00153 if ($lower == $name) { 00154 continue; 00155 } 00156 unset($headers[$name]); 00157 if (!isset($headers[$lower])) { 00158 $headers[$lower] = $header; 00159 continue; 00160 } 00161 if (is_array($headers[$lower])) { 00162 $headers[$lower][] = $header; 00163 continue; 00164 } 00165 $headers[$lower] = array($headers[$lower], $header); 00166 } 00167 } 00168 00176 public static function splitContentType($type, $wantedPart = null) 00177 { 00178 return self::splitHeaderField($type, $wantedPart, 'type'); 00179 } 00180 00190 public static function splitHeaderField($field, $wantedPart = null, $firstName = 0) 00191 { 00192 $wantedPart = strtolower($wantedPart); 00193 $firstName = strtolower($firstName); 00194 00195 // special case - a bit optimized 00196 if ($firstName === $wantedPart) { 00197 $field = strtok($field, ';'); 00198 return $field[0] == '"' ? substr($field, 1, -1) : $field; 00199 } 00200 00201 $field = $firstName . '=' . $field; 00202 if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { 00203 throw new Zend_Exception('not a valid header field'); 00204 } 00205 00206 if ($wantedPart) { 00207 foreach ($matches[1] as $key => $name) { 00208 if (strcasecmp($name, $wantedPart)) { 00209 continue; 00210 } 00211 if ($matches[2][$key][0] != '"') { 00212 return $matches[2][$key]; 00213 } 00214 return substr($matches[2][$key], 1, -1); 00215 } 00216 return null; 00217 } 00218 00219 $split = array(); 00220 foreach ($matches[1] as $key => $name) { 00221 $name = strtolower($name); 00222 if ($matches[2][$key][0] == '"') { 00223 $split[$name] = substr($matches[2][$key], 1, -1); 00224 } else { 00225 $split[$name] = $matches[2][$key]; 00226 } 00227 } 00228 00229 return $split; 00230 } 00231 00240 public static function decodeQuotedPrintable($string) 00241 { 00242 return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR); 00243 } 00244 }