Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Wednesday, October 14, 2026

Diff for Metafox/lib/Mail/mimeDecode.php between version 1.1 and 1.2

version 1.1, 2005/06/05 12:14:29 version 1.2, 2005/11/07 20:37:49
Line 1 
Line 1 
 <?Php  <?php
 // +-----------------------------------------------------------------------+  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 // | Copyright (c) 2002  Richard Heyes                                     |  // +-----------------------------------------------------------------------+
 // | All rights reserved.                                                  |  // | Copyright (c) 2002-2003  Richard Heyes                                |
 // |                                                                       |  // | Copyright (c) 2003-2005  The PHP Group                                |
 // | Redistribution and use in source and binary forms, with or without    |  // | All rights reserved.                                                  |
 // | modification, are permitted provided that the following conditions    |  // |                                                                       |
 // | are met:                                                              |  // | Redistribution and use in source and binary forms, with or without    |
 // |                                                                       |  // | modification, are permitted provided that the following conditions    |
 // | o Redistributions of source code must retain the above copyright      |  // | are met:                                                              |
 // |   notice, this list of conditions and the following disclaimer.       |  // |                                                                       |
 // | o Redistributions in binary form must reproduce the above copyright   |  // | o Redistributions of source code must retain the above copyright      |
 // |   notice, this list of conditions and the following disclaimer in the |  // |   notice, this list of conditions and the following disclaimer.       |
 // |   documentation and/or other materials provided with the distribution.|  // | o Redistributions in binary form must reproduce the above copyright   |
 // | o The names of the authors may not be used to endorse or promote      |  // |   notice, this list of conditions and the following disclaimer in the |
 // |   products derived from this software without specific prior written  |  // |   documentation and/or other materials provided with the distribution.|
 // |   permission.                                                         |  // | o The names of the authors may not be used to endorse or promote      |
 // |                                                                       |  // |   products derived from this software without specific prior written  |
 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |  // |   permission.                                                         |
 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |  // |                                                                       |
 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |  // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |  // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |  // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |  // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
 // |                                                                       |  // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
 // +-----------------------------------------------------------------------+  // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
 // | Author: Richard Heyes <richard@phpguru.org>                           |  // |                                                                       |
 // +-----------------------------------------------------------------------+  // +-----------------------------------------------------------------------+
   // | Author: Richard Heyes <richard@phpguru.org>                           |
 require_once 'PEAR.php';  // +-----------------------------------------------------------------------+
   
 /**  require_once 'PEAR.php';
 *  +----------------------------- IMPORTANT ------------------------------+  
 *  | Usage of this class compared to native php extensions such as        |  /**
 *  | mailparse or imap, is slow and may be feature deficient. If available|  *  +----------------------------- IMPORTANT ------------------------------+
 *  | you are STRONGLY recommended to use the php extensions.              |  *  | Usage of this class compared to native php extensions such as        |
 *  +----------------------------------------------------------------------+  *  | mailparse or imap, is slow and may be feature deficient. If available|
 *  *  | you are STRONGLY recommended to use the php extensions.              |
 * Mime Decoding class  *  +----------------------------------------------------------------------+
 *  *
 * This class will parse a raw mime email and return  * Mime Decoding class
 * the structure. Returned structure is similar to  *
 * that returned by imap_fetchstructure().  * This class will parse a raw mime email and return
 *  * the structure. Returned structure is similar to
 * USAGE: (assume $input is your raw email)  * that returned by imap_fetchstructure().
 *  *
 * $decode = new Mail_mimeDecode($input, "\r\n");  * USAGE: (assume $input is your raw email)
 * $structure = $decode->decode();  *
 * print_r($structure);  * $decode = new Mail_mimeDecode($input, "\r\n");
 *  * $structure = $decode->decode();
 * Or statically:  * print_r($structure);
 *  *
 * $params['input'] = $input;  * Or statically:
 * $structure = Mail_mimeDecode::decode($params);  *
 * print_r($structure);  * $params['input'] = $input;
 *  * $structure = Mail_mimeDecode::decode($params);
 * TODO:  * print_r($structure);
 *  - Implement further content types, eg. multipart/parallel,  *
 *    perhaps even message/partial.  * TODO:
 *  *  o Implement multipart/appledouble
 * @author  Richard Heyes <richard@phpguru.org>  *  o UTF8: ???
 * @version $Revision$  
 * @package Mail                  > 4. We have also found a solution for decoding the UTF-8
 */                  > headers. Therefore I made the following function:
                   >
 class Mail_mimeDecode extends PEAR                  > function decode_utf8($txt) {
 {                  > $trans=array("Å&#8216;"=>"õ","ű"=>"û","Å�"=>"Ã&#8226;","Ű"
                   =>"Ã&#8250;");
     /**                  > $txt=strtr($txt,$trans);
      * The raw email to decode                  > return(utf8_decode($txt));
      * @var    string                  > }
      */                  >
     var $_input;                  > And I have inserted the following line to the class:
                   >
     /**                  > if (strtolower($charset)=="utf-8") $text=decode_utf8($text);
      * The header part of the input                  >
      * @var    string                  > ... before the following one in the "_decodeHeader" function:
      */                  >
     var $_header;                  > $input = str_replace($encoded, $text, $input);
                   >
     /**                  > This way from now on it can easily decode the UTF-8 headers too.
      * The body part of the input  
      * @var    string  *
      */  * @author  Richard Heyes <richard@phpguru.org>
     var $_body;  * @version $Revision$
   * @package Mail
     /**  */
      * If an error occurs, this is used to store the message  class Mail_mimeDecode extends PEAR
      * @var    string  {
      */      /**
     var $_error;       * The raw email to decode
        * @var    string
     /**       */
      * Flag to determine whether to include bodies in the      var $_input;
      * returned object.  
      * @var    boolean      /**
      */       * The header part of the input
     var $_include_bodies;       * @var    string
        */
     /**      var $_header;
      * Flag to determine whether to decode bodies  
      * @var    boolean      /**
      */       * The body part of the input
     var $_decode_bodies;       * @var    string
        */
     /**      var $_body;
      * Flag to determine whether to decode headers  
      * @var    boolean      /**
      */       * If an error occurs, this is used to store the message
     var $_decode_headers;       * @var    string
        */
     /**      var $_error;
     * If invoked from a class, $this will be set. This has problematic  
     * connotations for calling decode() statically. Hence this variable      /**
     * is used to determine if we are indeed being called statically or       * Flag to determine whether to include bodies in the
     * via an object.       * returned object.
     */       * @var    boolean
     var $mailMimeDecode;       */
       var $_include_bodies;
     /**  
      * Constructor.      /**
      *       * Flag to determine whether to decode bodies
      * Sets up the object, initialise the variables, and splits and       * @var    boolean
      * stores the header and body of the input.       */
      *      var $_decode_bodies;
      * @param string The input to decode  
      * @access public      /**
      */       * Flag to determine whether to decode headers
     function Mail_mimeDecode($input)       * @var    boolean
     {       */
         list($header, $body)   = $this->_splitBodyHeader($input);      var $_decode_headers;
   
         $this->_input          = $input;      /**
         $this->_header         = $header;       * Constructor.
         $this->_body           = $body;       *
         $this->_decode_bodies  = false;       * Sets up the object, initialise the variables, and splits and
         $this->_include_bodies = true;       * stores the header and body of the input.
                *
         $this->mailMimeDecode  = true;       * @param string The input to decode
     }       * @access public
        */
     /**      function Mail_mimeDecode($input)
      * Begins the decoding process. If called statically      {
      * it will create an object and call the decode() method          list($header, $body)   = $this->_splitBodyHeader($input);
      * of it.  
      *          $this->_input          = $input;
      * @param array An array of various parameters that determine          $this->_header         = $header;
      *              various things:          $this->_body           = $body;
      *              include_bodies - Whether to include the body in the returned          $this->_decode_bodies  = false;
      *                               object.          $this->_include_bodies = true;
      *              decode_bodies  - Whether to decode the bodies      }
      *                               of the parts. (Transfer encoding)  
      *              decode_headers - Whether to decode headers      /**
      *              input          - If called statically, this will be treated       * Begins the decoding process. If called statically
      *                               as the input       * it will create an object and call the decode() method
      * @return object Decoded results       * of it.
      * @access public       *
      */       * @param array An array of various parameters that determine
     function decode($params = null)       *              various things:
     {       *              include_bodies - Whether to include the body in the returned
        *                               object.
         // Have we been called statically? If so, create an object and pass details to that.       *              decode_bodies  - Whether to decode the bodies
         if (!isset($this->mailMimeDecode) AND isset($params['input'])) {       *                               of the parts. (Transfer encoding)
        *              decode_headers - Whether to decode headers
             $obj = new Mail_mimeDecode($params['input']);       *              input          - If called statically, this will be treated
             $structure = $obj->decode($params);       *                               as the input
        * @return object Decoded results
         // Called statically but no input       * @access public
         } elseif (!isset($this->mailMimeDecode)) {       */
             return PEAR::raiseError('Called statically and no input given');      function decode($params = null)
       {
         // Called via an object          // determine if this method has been called statically
         } else {          $isStatic = !(isset($this) && get_class($this) == __CLASS__);
             $this->_include_bodies = isset($params['include_bodies'])  ? $params['include_bodies']  : false;  
             $this->_decode_bodies  = isset($params['decode_bodies'])   ? $params['decode_bodies']   : false;          // Have we been called statically?
             $this->_decode_headers = isset($params['decode_headers'])  ? $params['decode_headers']  : false;          // If so, create an object and pass details to that.
           if ($isStatic AND isset($params['input'])) {
             $structure = $this->_decode($this->_header, $this->_body);  
             if ($structure === false) {              $obj = new Mail_mimeDecode($params['input']);
                 $structure = $this->raiseError($this->_error);              $structure = $obj->decode($params);
             }  
         }          // Called statically but no input
           } elseif ($isStatic) {
         return $structure;              return PEAR::raiseError('Called statically and no input given');
     }  
           // Called via an object
     /**          } else {
      * Performs the decoding. Decodes the body string passed to it              $this->_include_bodies = isset($params['include_bodies']) ?
      * If it finds certain content-types it will call itself in a                                       $params['include_bodies'] : false;
      * recursive fashion              $this->_decode_bodies  = isset($params['decode_bodies']) ?
      *                                       $params['decode_bodies']  : false;
      * @param string Header section              $this->_decode_headers = isset($params['decode_headers']) ?
      * @param string Body section                                       $params['decode_headers'] : false;
      * @return object Results of decoding process  
      * @access private              $structure = $this->_decode($this->_header, $this->_body);
      */              if ($structure === false) {
     function _decode($headers, $body, $default_ctype = 'text/plain')                  $structure = $this->raiseError($this->_error);
     {              }
         $return = new stdClass;          }
         $headers = $this->_parseHeaders($headers);  
           return $structure;
         foreach ($headers as $value) {      }
             if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {  
                 $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]);      /**
                 $return->headers[strtolower($value['name'])][] = $value['value'];       * Performs the decoding. Decodes the body string passed to it
        * If it finds certain content-types it will call itself in a
             } elseif (isset($return->headers[strtolower($value['name'])])) {       * recursive fashion
                 $return->headers[strtolower($value['name'])][] = $value['value'];       *
        * @param string Header section
             } else {       * @param string Body section
                 $return->headers[strtolower($value['name'])] = $value['value'];       * @return object Results of decoding process
             }       * @access private
         }       */
       function _decode($headers, $body, $default_ctype = 'text/plain')
         reset($headers);      {
         while (list($key, $value) = each($headers)) {          $return = new stdClass;
             $headers[$key]['name'] = strtolower($headers[$key]['name']);          $return->headers = array();
             switch ($headers[$key]['name']) {          $headers = $this->_parseHeaders($headers);
   
                 case 'content-type':          foreach ($headers as $value) {
                     $content_type = $this->_parseHeaderValue($headers[$key]['value']);              if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
                   $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]);
                     if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) {                  $return->headers[strtolower($value['name'])][] = $value['value'];
                         $return->ctype_primary   = $regs[1];  
                         $return->ctype_secondary = $regs[2];              } elseif (isset($return->headers[strtolower($value['name'])])) {
                     }                  $return->headers[strtolower($value['name'])][] = $value['value'];
   
                     if (isset($content_type['other'])) {              } else {
                         while (list($p_name, $p_value) = each($content_type['other'])) {                  $return->headers[strtolower($value['name'])] = $value['value'];
                             $return->ctype_parameters[$p_name] = $p_value;              }
                         }          }
                     }  
                     break;          reset($headers);
           while (list($key, $value) = each($headers)) {
                 case 'content-disposition';              $headers[$key]['name'] = strtolower($headers[$key]['name']);
                     $content_disposition = $this->_parseHeaderValue($headers[$key]['value']);              switch ($headers[$key]['name']) {
                     $return->disposition   = $content_disposition['value'];  
                     if (isset($content_disposition['other'])) {                  case 'content-type':
                         while (list($p_name, $p_value) = each($content_disposition['other'])) {                      $content_type = $this->_parseHeaderValue($headers[$key]['value']);
                             $return->d_parameters[$p_name] = $p_value;  
                         }                      if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) {
                     }                          $return->ctype_primary   = $regs[1];
                     break;                          $return->ctype_secondary = $regs[2];
                       }
                 case 'content-transfer-encoding':  
                     $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']);                      if (isset($content_type['other'])) {
                     break;                          while (list($p_name, $p_value) = each($content_type['other'])) {
             }                              $return->ctype_parameters[$p_name] = $p_value;
         }                          }
                       }
         if (isset($content_type)) {                      break;
             switch (strtolower($content_type['value'])) {  
                 case 'text/plain':                  case 'content-disposition':
                     $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';                      $content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;                      $return->disposition   = $content_disposition['value'];
                     break;                      if (isset($content_disposition['other'])) {
                           while (list($p_name, $p_value) = each($content_disposition['other'])) {
                 case 'text/html':                              $return->d_parameters[$p_name] = $p_value;
                     $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';                          }
                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;                      }
                     break;                      break;
   
                 case 'multipart/parallel':                  case 'content-transfer-encoding':
                 case 'multipart/report': // RFC1892                      $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']);
                 case 'multipart/signed': // PGP                      break;
                 case 'multipart/digest':              }
                 case 'multipart/alternative':          }
                 case 'multipart/related':  
                 case 'multipart/mixed':          if (isset($content_type)) {
                     if(!isset($content_type['other']['boundary'])){              switch (strtolower($content_type['value'])) {
                         $this->_error = 'No boundary found for ' . $content_type['value'] . ' part';                  case 'text/plain':
                         return false;                      $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
                     }                      $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
                       break;
                     $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain';  
                   case 'text/html':
                     $parts = $this->_boundarySplit($body, $content_type['other']['boundary']);                      $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
                     for ($i = 0; $i < count($parts); $i++) {                      $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
                         list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]);                      break;
                         $part = $this->_decode($part_header, $part_body, $default_ctype);  
                         if($part === false)                  case 'multipart/parallel':
                             $part = $this->raiseError($this->_error);                  case 'multipart/report': // RFC1892
                         $return->parts[] = $part;                  case 'multipart/signed': // PGP
                     }                  case 'multipart/digest':
                     break;                  case 'multipart/alternative':
                   case 'multipart/related':
                 case 'message/rfc822':                  case 'multipart/mixed':
                     $obj = &new Mail_mimeDecode($body);                      if(!isset($content_type['other']['boundary'])){
                     $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies));                          $this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
                     unset($obj);                          return false;
                     break;                      }
   
                 default:                      $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain';
                     if(!isset($content_transfer_encoding['value']))  
                         $content_transfer_encoding['value'] = '7bit';                      $parts = $this->_boundarySplit($body, $content_type['other']['boundary']);
                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null;                      for ($i = 0; $i < count($parts); $i++) {
                     break;                          list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]);
             }                          $part = $this->_decode($part_header, $part_body, $default_ctype);
                           if($part === false)
         } else {                              $part = $this->raiseError($this->_error);
             $ctype = explode('/', $default_ctype);                          $return->parts[] = $part;
             $return->ctype_primary   = $ctype[0];                      }
             $return->ctype_secondary = $ctype[1];                      break;
             $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null;  
         }                  case 'message/rfc822':
                       $obj = &new Mail_mimeDecode($body);
         return $return;                      $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies,
     }                                                                                'decode_bodies'  => $this->_decode_bodies,
                                                                                                                     'decode_headers' => $this->_decode_headers));
     /**                      unset($obj);
      * Given the output of the above function, this will return an                      break;
      * array of references to the parts, indexed by mime number.  
      *                  default:
      * @param  object $structure   The structure to go through                      if(!isset($content_transfer_encoding['value']))
      * @param  string $mime_number Internal use only.                          $content_transfer_encoding['value'] = '7bit';
      * @return array               Mime numbers                      $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null;
      */                      break;
     function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '')              }
     {  
         $return = array();          } else {
         if (!empty($structure->parts)) {              $ctype = explode('/', $default_ctype);
             if ($mime_number != '') {              $return->ctype_primary   = $ctype[0];
                 $structure->mime_id = $prepend . $mime_number;              $return->ctype_secondary = $ctype[1];
                 $return[$prepend . $mime_number] = &$structure;              $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null;
             }          }
             for ($i = 0; $i < count($structure->parts); $i++) {  
           return $return;
                   }
                 if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') {  
                     $prepend      = $prepend . $mime_number . '.';      /**
                     $_mime_number = '';       * Given the output of the above function, this will return an
                 } else {       * array of references to the parts, indexed by mime number.
                     $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1));       *
                 }       * @param  object $structure   The structure to go through
        * @param  string $mime_number Internal use only.
                 $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend);       * @return array               Mime numbers
                 foreach ($arr as $key => $val) {       */
                     $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key];      function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '')
                 }      {
             }          $return = array();
         } else {          if (!empty($structure->parts)) {
             if ($mime_number == '') {              if ($mime_number != '') {
                 $mime_number = '1';                  $structure->mime_id = $prepend . $mime_number;
             }                  $return[$prepend . $mime_number] = &$structure;
             $structure->mime_id = $prepend . $mime_number;              }
             $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure;              for ($i = 0; $i < count($structure->parts); $i++) {
         }  
           
         return $return;                  if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') {
     }                      $prepend      = $prepend . $mime_number . '.';
                       $_mime_number = '';
     /**                  } else {
      * Given a string containing a header and body                      $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1));
      * section, this function will split them (at the first                  }
      * blank line) and return them.  
      *                  $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend);
      * @param string Input to split apart                  foreach ($arr as $key => $val) {
      * @return array Contains header and body section                      $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key];
      * @access private                  }
      */              }
     function _splitBodyHeader($input)          } else {
     {              if ($mime_number == '') {
         if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {                  $mime_number = '1';
             return array($match[1], $match[2]);              }
         }              $structure->mime_id = $prepend . $mime_number;
         $this->_error = 'Could not split header and body';              $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure;
         return false;          }
     }  
           return $return;
     /**      }
      * Parse headers given in $input and return  
      * as assoc array.      /**
      *       * Given a string containing a header and body
      * @param string Headers to parse       * section, this function will split them (at the first
      * @return array Contains parsed headers       * blank line) and return them.
      * @access private       *
      */       * @param string Input to split apart
     function _parseHeaders($input)       * @return array Contains header and body section
     {       * @access private
        */
         if ($input !== '') {      function _splitBodyHeader($input)
             // Unfold the input      {
             $input   = preg_replace("/\r?\n/", "\r\n", $input);          if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
             $input   = preg_replace("/\r\n(\t| )+/", ' ', $input);              return array($match[1], $match[2]);
             $headers = explode("\r\n", trim($input));          }
           $this->_error = 'Could not split header and body';
             foreach ($headers as $value) {          return false;
                 $hdr_name = substr($value, 0, $pos = strpos($value, ':'));      }
                 $hdr_value = substr($value, $pos+1);  
                 if($hdr_value[0] == ' ')      /**
                     $hdr_value = substr($hdr_value, 1);       * Parse headers given in $input and return
        * as assoc array.
                 $return[] = array(       *
                                   'name'  => $hdr_name,       * @param string Headers to parse
                                   'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value       * @return array Contains parsed headers
                                  );       * @access private
             }       */
         } else {      function _parseHeaders($input)
             $return = array();      {
         }  
           if ($input !== '') {
         return $return;              // Unfold the input
     }              $input   = preg_replace("/\r?\n/", "\r\n", $input);
               $input   = preg_replace("/\r\n(\t| )+/", ' ', $input);
     /**              $headers = explode("\r\n", trim($input));
      * Function to parse a header value,  
      * extract first part, and any secondary              foreach ($headers as $value) {
      * parts (after ;) This function is not as                  $hdr_name = substr($value, 0, $pos = strpos($value, ':'));
      * robust as it could be. Eg. header comments                  $hdr_value = substr($value, $pos+1);
      * in the wrong place will probably break it.                  if($hdr_value[0] == ' ')
      *                      $hdr_value = substr($hdr_value, 1);
      * @param string Header value to parse  
      * @return array Contains parsed result                  $return[] = array(
      * @access private                                    'name'  => $hdr_name,
      */                                    'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value
     function _parseHeaderValue($input)                                   );
     {              }
           } else {
         if (($pos = strpos($input, ';')) !== false) {              $return = array();
           }
             $return['value'] = trim(substr($input, 0, $pos));  
             $input = trim(substr($input, $pos+1));          return $return;
       }
             if (strlen($input) > 0) {  
       /**
                 // This splits on a semi-colon, if there's no preceeding backslash       * Function to parse a header value,
                 // Can't handle if it's in double quotes however. (Of course anyone       * extract first part, and any secondary
                 // sending that needs a good slap).       * parts (after ;) This function is not as
                 $parameters = preg_split('/\s*(?<!\\\\);\s*/i', $input);       * robust as it could be. Eg. header comments
        * in the wrong place will probably break it.
                 for ($i = 0; $i < count($parameters); $i++) {       *
                     $param_name  = substr($parameters[$i], 0, $pos = strpos($parameters[$i], '='));       * @param string Header value to parse
                     $param_value = substr($parameters[$i], $pos + 1);       * @return array Contains parsed result
                     if ($param_value[0] == '"') {       * @access private
                         $param_value = substr($param_value, 1, -1);       */
                     }      function _parseHeaderValue($input)
                     $return['other'][$param_name] = $param_value;      {
                     $return['other'][strtolower($param_name)] = $param_value;  
                 }          if (($pos = strpos($input, ';')) !== false) {
             }  
         } else {              $return['value'] = trim(substr($input, 0, $pos));
             $return['value'] = trim($input);              $input = trim(substr($input, $pos+1));
         }  
               if (strlen($input) > 0) {
         return $return;  
     }                  // This splits on a semi-colon, if there's no preceeding backslash
                   // Now works with quoted values; had to glue the \; breaks in PHP
     /**                  // the regex is already bordering on incomprehensible
      * This function splits the input based                  $splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/';
      * on the given boundary                  preg_match_all($splitRegex, $input, $matches);
      *                  $parameters = array();
      * @param string Input to parse                  for ($i=0; $i<count($matches[0]); $i++) {
      * @return array Contains array of resulting mime parts                      $param = $matches[0][$i];
      * @access private                      while (substr($param, -2) == '\;') {
      */                          $param .= $matches[0][++$i];
     function _boundarySplit($input, $boundary)                      }
     {                      $parameters[] = $param;
         $tmp = explode('--'.$boundary, $input);                  }
   
         for ($i=1; $i<count($tmp)-1; $i++) {                  for ($i = 0; $i < count($parameters); $i++) {
             $parts[] = $tmp[$i];                      $param_name  = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ ");
         }                      $param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ ");
                       if ($param_value[0] == '"') {
         return $parts;                          $param_value = substr($param_value, 1, -1);
     }                      }
                       $return['other'][$param_name] = $param_value;
     /**                      $return['other'][strtolower($param_name)] = $param_value;
      * Given a header, this function will decode it                  }
      * according to RFC2047. Probably not *exactly*              }
      * conformant, but it does pass all the given          } else {
      * examples (in RFC2047).              $return['value'] = trim($input);
      *          }
      * @param string Input header value to decode  
      * @return string Decoded header value          return $return;
      * @access private      }
      */  
     function _decodeHeader($input)      /**
     {       * This function splits the input based
         // Remove white space between encoded-words       * on the given boundary
         $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);       *
        * @param string Input to parse
         // For each encoded-word...       * @return array Contains array of resulting mime parts
         while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {       * @access private
        */
             $encoded  = $matches[1];      function _boundarySplit($input, $boundary)
             $charset  = $matches[2];      {
             $encoding = $matches[3];          $parts = array();
             $text     = $matches[4];  
           $bs_possible = substr($boundary, 2, -2);
             switch (strtolower($encoding)) {          $bs_check = '\"' . $bs_possible . '\"';
                 case 'b':  
                     $text = base64_decode($text);          if ($boundary == $bs_check) {
                     break;              $boundary = $bs_possible;
           }
                 case 'q':  
                     $text = str_replace('_', ' ', $text);          $tmp = explode('--' . $boundary, $input);
                     preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);  
                     foreach($matches[1] as $value)          for ($i = 1; $i < count($tmp) - 1; $i++) {
                         $text = str_replace('='.$value, chr(hexdec($value)), $text);              $parts[] = $tmp[$i];
                     break;          }
             }  
           return $parts;
             $input = str_replace($encoded, $text, $input);      }
         }  
       /**
         return $input;       * Given a header, this function will decode it
     }       * according to RFC2047. Probably not *exactly*
        * conformant, but it does pass all the given
     /**       * examples (in RFC2047).
      * Given a body string and an encoding type,       *
      * this function will decode and return it.       * @param string Input header value to decode
      *       * @return string Decoded header value
      * @param  string Input body to decode       * @access private
      * @param  string Encoding type to use.       */
      * @return string Decoded body      function _decodeHeader($input)
      * @access private      {
      */          // Remove white space between encoded-words
     function _decodeBody($input, $encoding = '7bit')          $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
     {  
         switch ($encoding) {          // For each encoded-word...
             case '7bit':          while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
                 return $input;  
                 break;              $encoded  = $matches[1];
               $charset  = $matches[2];
             case 'quoted-printable':              $encoding = $matches[3];
                 return $this->_quotedPrintableDecode($input);              $text     = $matches[4];
                 break;  
               switch (strtolower($encoding)) {
             case 'base64':                  case 'b':
                 return base64_decode($input);                      $text = base64_decode($text);
                 break;                      break;
   
             default:                  case 'q':
                 return $input;                      $text = str_replace('_', ' ', $text);
         }                      preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
     }                      foreach($matches[1] as $value)
                           $text = str_replace('='.$value, chr(hexdec($value)), $text);
     /**                      break;
      * Given a quoted-printable string, this              }
      * function will decode and return it.  
      *              $input = str_replace($encoded, $text, $input);
      * @param  string Input body to decode          }
      * @return string Decoded body  
      * @access private          return $input;
      */      }
     function _quotedPrintableDecode($input)  
     {      /**
         // Remove soft line breaks       * Given a body string and an encoding type,
         $input = preg_replace("/=\r?\n/", '', $input);       * this function will decode and return it.
        *
         // Replace encoded characters       * @param  string Input body to decode
                 $input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input);       * @param  string Encoding type to use.
        * @return string Decoded body
         return $input;       * @access private
     }       */
       function _decodeBody($input, $encoding = '7bit')
     /**      {
      * Checks the input for uuencoded files and returns          switch (strtolower($encoding)) {
      * an array of them. Can be called statically, eg:              case '7bit':
      *                  return $input;
      * $files =& Mail_mimeDecode::uudecode($some_text);                  break;
      *  
      * It will check for the begin 666 ... end syntax              case 'quoted-printable':
      * however and won't just blindly decode whatever you                  return $this->_quotedPrintableDecode($input);
      * pass it.                  break;
      *  
      * @param  string Input body to look for attahcments in              case 'base64':
      * @return array  Decoded bodies, filenames and permissions                  return base64_decode($input);
      * @access public                  break;
      * @author Unknown  
      */              default:
     function &uudecode($input)                  return $input;
     {          }
         // Find all uuencoded sections      }
         preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches);  
       /**
         for ($j = 0; $j < count($matches[3]); $j++) {       * Given a quoted-printable string, this
        * function will decode and return it.
             $str      = $matches[3][$j];       *
             $filename = $matches[2][$j];       * @param  string Input body to decode
             $fileperm = $matches[1][$j];       * @return string Decoded body
        * @access private
             $file = '';       */
             $str = preg_split("/\r?\n/", trim($str));      function _quotedPrintableDecode($input)
             $strlen = count($str);      {
           // Remove soft line breaks
             for ($i = 0; $i < $strlen; $i++) {          $input = preg_replace("/=\r?\n/", '', $input);
                 $pos = 1;  
                 $d = 0;          // Replace encoded characters
                 $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077);                  $input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input);
   
                 while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) {          return $input;
                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);      }
                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);  
                     $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);      /**
                     $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20);       * Checks the input for uuencoded files and returns
                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));       * an array of them. Can be called statically, eg:
        *
                     $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));       * $files =& Mail_mimeDecode::uudecode($some_text);
        *
                     $file .= chr(((($c2 - ' ') & 077) << 6) |  (($c3 - ' ') & 077));       * It will check for the begin 666 ... end syntax
        * however and won't just blindly decode whatever you
                     $pos += 4;       * pass it.
                     $d += 3;       *
                 }       * @param  string Input body to look for attahcments in
        * @return array  Decoded bodies, filenames and permissions
                 if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) {       * @access public
                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);       * @author Unknown
                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);       */
                     $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);      function &uudecode($input)
                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));      {
           // Find all uuencoded sections
                     $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));          preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches);
   
                     $pos += 3;          for ($j = 0; $j < count($matches[3]); $j++) {
                     $d += 2;  
                 }              $str      = $matches[3][$j];
               $filename = $matches[2][$j];
                 if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) {              $fileperm = $matches[1][$j];
                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);  
                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);              $file = '';
                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));              $str = preg_split("/\r?\n/", trim($str));
               $strlen = count($str);
                 }  
             }              for ($i = 0; $i < $strlen; $i++) {
             $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file);                  $pos = 1;
         }                  $d = 0;
                   $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077);
         return $files;  
     }                  while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) {
                       $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
     /**                      $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
      * getSendArray() returns the arguments required for Mail::send()                      $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
      * used to build the arguments for a mail::send() call                      $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20);
      *                      $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
      * Usage:  
      * $mailtext = Full email (for example generated by a template)                      $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
      * $decoder = new Mail_mimeDecode($mailtext);  
      * $parts =  $decoder->getSendArray();                      $file .= chr(((($c2 - ' ') & 077) << 6) |  (($c3 - ' ') & 077));
      * if (!PEAR::isError($parts) {  
      *     list($recipents,$headers,$body) = $parts;                      $pos += 4;
      *     $mail = Mail::factory('smtp');                      $d += 3;
      *     $mail->send($recipents,$headers,$body);                  }
      * } else {  
      *     echo $parts->message;                  if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) {
      * }                      $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
      * @return mixed   array of recipeint, headers,body or Pear_Error                      $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
      * @access public                      $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
      * @author Alan Knowles <alan@akbkhome.com>                      $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
      */  
     function getSendArray()                      $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
     {  
         // prevent warning if this is not set                      $pos += 3;
         $this->_decode_headers = FALSE;                      $d += 2;
         $headerlist =$this->_parseHeaders($this->_header);                  }
         $to = "";  
         if (!$headerlist) {                  if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) {
             return $this->raiseError("Message did not contain headers");                      $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
         }                      $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
         foreach($headerlist as $item) {                      $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
             $header[$item['name']] = $item['value'];  
             switch (strtolower($item['name'])) {                  }
                 case "to":              }
                 case "cc":              $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file);
                 case "bcc":          }
                     $to = ",".$item['value'];  
                 default:          return $files;
                    break;      }
             }  
         }      /**
         if ($to == "") {       * getSendArray() returns the arguments required for Mail::send()
             return $this->raiseError("Message did not contain any recipents");       * used to build the arguments for a mail::send() call
         }       *
         $to = substr($to,1);       * Usage:
         return array($to,$header,$this->_body);       * $mailtext = Full email (for example generated by a template)
     }       * $decoder = new Mail_mimeDecode($mailtext);
        * $parts =  $decoder->getSendArray();
        * if (!PEAR::isError($parts) {
        *     list($recipents,$headers,$body) = $parts;
        *     $mail = Mail::factory('smtp');
        *     $mail->send($recipents,$headers,$body);
        * } else {
        *     echo $parts->message;
        * }
        * @return mixed   array of recipeint, headers,body or Pear_Error
     /**       * @access public
      * Returns a xml copy of the output of       * @author Alan Knowles <alan@akbkhome.com>
      * Mail_mimeDecode::decode. Pass the output in as the       */
      * argument. This function can be called statically. Eg:      function getSendArray()
      *      {
      * $output = $obj->decode();          // prevent warning if this is not set
      * $xml    = Mail_mimeDecode::getXML($output);          $this->_decode_headers = FALSE;
      *          $headerlist =$this->_parseHeaders($this->_header);
      * The DTD used for this should have been in the package. Or          $to = "";
      * alternatively you can get it from cvs, or here:          if (!$headerlist) {
      * http://www.phpguru.org/xmail/xmail.dtd.              return $this->raiseError("Message did not contain headers");
      *          }
      * @param  object Input to convert to xml. This should be the          foreach($headerlist as $item) {
      *                output of the Mail_mimeDecode::decode function              $header[$item['name']] = $item['value'];
      * @return string XML version of input              switch (strtolower($item['name'])) {
      * @access public                  case "to":
      */                  case "cc":
     function getXML($input)                  case "bcc":
     {                      $to = ",".$item['value'];
         $crlf    =  "\r\n";                  default:
         $output  = '<?xml version=\'1.0\'?>' . $crlf .                     break;
                    '<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf .              }
                    '<email>' . $crlf .          }
                    Mail_mimeDecode::_getXML($input) .          if ($to == "") {
                    '</email>';              return $this->raiseError("Message did not contain any recipents");
           }
         return $output;          $to = substr($to,1);
     }          return array($to,$header,$this->_body);
       }
     /**  
      * Function that does the actual conversion to xml. Does a single      /**
      * mimepart at a time.       * Returns a xml copy of the output of
      *       * Mail_mimeDecode::decode. Pass the output in as the
      * @param  object  Input to convert to xml. This is a mimepart object.       * argument. This function can be called statically. Eg:
      *                 It may or may not contain subparts.       *
      * @param  integer Number of tabs to indent       * $output = $obj->decode();
      * @return string  XML version of input       * $xml    = Mail_mimeDecode::getXML($output);
      * @access private       *
      */       * The DTD used for this should have been in the package. Or
     function _getXML($input, $indent = 1)       * alternatively you can get it from cvs, or here:
     {       * http://www.phpguru.org/xmail/xmail.dtd.
         $htab    =  "\t";       *
         $crlf    =  "\r\n";       * @param  object Input to convert to xml. This should be the
         $output  =  '';       *                output of the Mail_mimeDecode::decode function
         $headers = @(array)$input->headers;       * @return string XML version of input
        * @access public
         foreach ($headers as $hdr_name => $hdr_value) {       */
       function getXML($input)
             // Multiple headers with this name      {
             if (is_array($headers[$hdr_name])) {          $crlf    =  "\r\n";
                 for ($i = 0; $i < count($hdr_value); $i++) {          $output  = '<?xml version=\'1.0\'?>' . $crlf .
                     $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent);                     '<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf .
                 }                     '<email>' . $crlf .
                      Mail_mimeDecode::_getXML($input) .
             // Only one header of this sort                     '</email>';
             } else {  
                 $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent);          return $output;
             }      }
         }  
       /**
         if (!empty($input->parts)) {       * Function that does the actual conversion to xml. Does a single
             for ($i = 0; $i < count($input->parts); $i++) {       * mimepart at a time.
                 $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf .       *
                            Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) .       * @param  object  Input to convert to xml. This is a mimepart object.
                            str_repeat($htab, $indent) . '</mimepart>' . $crlf;       *                 It may or may not contain subparts.
             }       * @param  integer Number of tabs to indent
         } elseif (isset($input->body)) {       * @return string  XML version of input
             $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' .       * @access private
                        $input->body . ']]></body>' . $crlf;       */
         }      function _getXML($input, $indent = 1)
       {
         return $output;          $htab    =  "\t";
     }          $crlf    =  "\r\n";
           $output  =  '';
     /**          $headers = @(array)$input->headers;
      * Helper function to _getXML(). Returns xml of a header.  
      *          foreach ($headers as $hdr_name => $hdr_value) {
      * @param  string  Name of header  
      * @param  string  Value of header              // Multiple headers with this name
      * @param  integer Number of tabs to indent              if (is_array($headers[$hdr_name])) {
      * @return string  XML version of input                  for ($i = 0; $i < count($hdr_value); $i++) {
      * @access private                      $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent);
      */                  }
     function _getXML_helper($hdr_name, $hdr_value, $indent)  
     {              // Only one header of this sort
         $htab   = "\t";              } else {
         $crlf   = "\r\n";                  $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent);
         $return = '';              }
           }
         $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value);  
         $new_hdr_name  = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name)));          if (!empty($input->parts)) {
               for ($i = 0; $i < count($input->parts); $i++) {
         // Sort out any parameters                  $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf .
         if (!empty($new_hdr_value['other'])) {                             Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) .
             foreach ($new_hdr_value['other'] as $paramname => $paramvalue) {                             str_repeat($htab, $indent) . '</mimepart>' . $crlf;
                 $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf .              }
                             str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf .          } elseif (isset($input->body)) {
                             str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf .              $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' .
                             str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf;                         $input->body . ']]></body>' . $crlf;
             }          }
   
             $params = implode('', $params);          return $output;
         } else {      }
             $params = '';  
         }      /**
        * Helper function to _getXML(). Returns xml of a header.
         $return = str_repeat($htab, $indent) . '<header>' . $crlf .       *
                   str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf .       * @param  string  Name of header
                   str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf .       * @param  string  Value of header
                   $params .       * @param  integer Number of tabs to indent
                   str_repeat($htab, $indent) . '</header>' . $crlf;       * @return string  XML version of input
        * @access private
         return $return;       */
     }      function _getXML_helper($hdr_name, $hdr_value, $indent)
       {
 } // End of class          $htab   = "\t";
 ?>          $crlf   = "\r\n";
           $return = '';
   
           $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value);
           $new_hdr_name  = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name)));
   
           // Sort out any parameters
           if (!empty($new_hdr_value['other'])) {
               foreach ($new_hdr_value['other'] as $paramname => $paramvalue) {
                   $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf .
                               str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf .
                               str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf .
                               str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf;
               }
   
               $params = implode('', $params);
           } else {
               $params = '';
           }
   
           $return = str_repeat($htab, $indent) . '<header>' . $crlf .
                     str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf .
                     str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf .
                     $params .
                     str_repeat($htab, $indent) . '</header>' . $crlf;
   
           return $return;
       }
   
   } // End of class
   ?>

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top