[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Mime/ -> Decode.php (source)

   1  <?php
   2  /**
   3   * Zend Framework
   4   *
   5   * LICENSE
   6   *
   7   * This source file is subject to the new BSD license that is bundled
   8   * with this package in the file LICENSE.txt.
   9   * It is also available through the world-wide-web at this URL:
  10   * http://framework.zend.com/license/new-bsd
  11   * If you did not receive a copy of the license and are unable to
  12   * obtain it through the world-wide-web, please send an email
  13   * to [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_Mime
  17   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  19   * @version    $Id$
  20   */
  21  
  22  /**
  23   * @see Zend_Mime
  24   */
  25  require_once 'Zend/Mime.php';
  26  
  27  /**
  28   * @category   Zend
  29   * @package    Zend_Mime
  30   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  31   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  32   */
  33  class Zend_Mime_Decode
  34  {
  35      /**
  36       * Explode MIME multipart string into seperate parts
  37       *
  38       * Parts consist of the header and the body of each MIME part.
  39       *
  40       * @param  string $body     raw body of message
  41       * @param  string $boundary boundary as found in content-type
  42       * @return array parts with content of each part, empty if no parts found
  43       * @throws Zend_Exception
  44       */
  45      public static function splitMime($body, $boundary)
  46      {
  47          // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
  48          $body = str_replace("\r", '', $body);
  49  
  50          $start = 0;
  51          $res = array();
  52          // find every mime part limiter and cut out the
  53          // string before it.
  54          // the part before the first boundary string is discarded:
  55          $p = strpos($body, '--' . $boundary . "\n", $start);
  56          if ($p === false) {
  57              // no parts found!
  58              return array();
  59          }
  60  
  61          // position after first boundary line
  62          $start = $p + 3 + strlen($boundary);
  63  
  64          while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
  65              $res[] = substr($body, $start, $p-$start);
  66              $start = $p + 3 + strlen($boundary);
  67          }
  68  
  69          // no more parts, find end boundary
  70          $p = strpos($body, '--' . $boundary . '--', $start);
  71          if ($p===false) {
  72              throw new Zend_Exception('Not a valid Mime Message: End Missing');
  73          }
  74  
  75          // the remaining part also needs to be parsed:
  76          $res[] = substr($body, $start, $p-$start);
  77          return $res;
  78      }
  79  
  80      /**
  81       * decodes a mime encoded String and returns a
  82       * struct of parts with header and body
  83       *
  84       * @param  string $message  raw message content
  85       * @param  string $boundary boundary as found in content-type
  86       * @param  string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
  87       * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found
  88       * @throws Zend_Exception
  89       */
  90      public static function splitMessageStruct($message, $boundary, $EOL = Zend_Mime::LINEEND)
  91      {
  92          $parts = self::splitMime($message, $boundary);
  93          if (count($parts) <= 0) {
  94              return null;
  95          }
  96          $result = array();
  97          foreach ($parts as $part) {
  98              self::splitMessage($part, $headers, $body, $EOL);
  99              $result[] = array('header' => $headers,
 100                                'body'   => $body    );
 101          }
 102          return $result;
 103      }
 104  
 105      /**
 106       * split a message in header and body part, if no header or an
 107       * invalid header is found $headers is empty
 108       *
 109       * The charset of the returned headers depend on your iconv settings.
 110       *
 111       * @param  string $message raw message with header and optional content
 112       * @param  array  $headers output param, array with headers as array(name => value)
 113       * @param  string $body    output param, content of message
 114       * @param  string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
 115       * @return null
 116       */
 117      public static function splitMessage($message, &$headers, &$body, $EOL = Zend_Mime::LINEEND)
 118      {
 119          // check for valid header at first line
 120          $firstline = strtok($message, "\n");
 121          if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) {
 122              $headers = array();
 123              // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
 124              $body = str_replace(array("\r", "\n"), array('', $EOL), $message);
 125              return;
 126          }
 127  
 128          // find an empty line between headers and body
 129          // default is set new line
 130          if (strpos($message, $EOL . $EOL)) {
 131              list($headers, $body) = explode($EOL . $EOL, $message, 2);
 132          // next is the standard new line
 133          } else if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) {
 134              list($headers, $body) = explode("\r\n\r\n", $message, 2);
 135          // next is the other "standard" new line
 136          } else if ($EOL != "\n" && strpos($message, "\n\n")) {
 137              list($headers, $body) = explode("\n\n", $message, 2);
 138          // at last resort find anything that looks like a new line
 139          } else {
 140              @list($headers, $body) = @preg_split("%([\r\n]+)\\1%U", $message, 2);
 141          }
 142  
 143          $headers = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
 144  
 145          if ($headers === false ) {
 146              // an error occurs during the decoding
 147              return;
 148          }
 149  
 150          // normalize header names
 151          foreach ($headers as $name => $header) {
 152              $lower = strtolower($name);
 153              if ($lower == $name) {
 154                  continue;
 155              }
 156              unset($headers[$name]);
 157              if (!isset($headers[$lower])) {
 158                  $headers[$lower] = $header;
 159                  continue;
 160              }
 161              if (is_array($headers[$lower])) {
 162                  $headers[$lower][] = $header;
 163                  continue;
 164              }
 165              $headers[$lower] = array($headers[$lower], $header);
 166          }
 167      }
 168  
 169      /**
 170       * split a content type in its different parts
 171       *
 172       * @param  string $type       content-type
 173       * @param  string $wantedPart the wanted part, else an array with all parts is returned
 174       * @return string|array wanted part or all parts as array('type' => content-type, partname => value)
 175       */
 176      public static function splitContentType($type, $wantedPart = null)
 177      {
 178          return self::splitHeaderField($type, $wantedPart, 'type');
 179      }
 180  
 181      /**
 182       * split a header field like content type in its different parts
 183       *
 184       * @param  string $type       header field
 185       * @param  string $wantedPart the wanted part, else an array with all parts is returned
 186       * @param  string $firstName  key name for the first part
 187       * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
 188       * @throws Zend_Exception
 189       */
 190      public static function splitHeaderField($field, $wantedPart = null, $firstName = 0)
 191      {
 192          $wantedPart = strtolower($wantedPart);
 193          $firstName = strtolower($firstName);
 194  
 195          // special case - a bit optimized
 196          if ($firstName === $wantedPart) {
 197              $field = strtok($field, ';');
 198              return $field[0] == '"' ? substr($field, 1, -1) : $field;
 199          }
 200  
 201          $field = $firstName . '=' . $field;
 202          if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) {
 203              throw new Zend_Exception('not a valid header field');
 204          }
 205  
 206          if ($wantedPart) {
 207              foreach ($matches[1] as $key => $name) {
 208                  if (strcasecmp($name, $wantedPart)) {
 209                      continue;
 210                  }
 211                  if ($matches[2][$key][0] != '"') {
 212                      return $matches[2][$key];
 213                  }
 214                  return substr($matches[2][$key], 1, -1);
 215              }
 216              return null;
 217          }
 218  
 219          $split = array();
 220          foreach ($matches[1] as $key => $name) {
 221              $name = strtolower($name);
 222              if ($matches[2][$key][0] == '"') {
 223                  $split[$name] = substr($matches[2][$key], 1, -1);
 224              } else {
 225                  $split[$name] = $matches[2][$key];
 226              }
 227          }
 228  
 229          return $split;
 230      }
 231  
 232      /**
 233       * decode a quoted printable encoded string
 234       *
 235       * The charset of the returned string depends on your iconv settings.
 236       *
 237       * @param  string encoded string
 238       * @return string decoded string
 239       */
 240      public static function decodeQuotedPrintable($string)
 241      {
 242          return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
 243      }
 244  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1