/** * Begins the decoding process. If called statically * it will create an object and call the decode() method * of it. * * @param array $ An array of various parameters that determine * various things: * include_bodies - Whether to include the body in the returned * object. * 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 * as the input * @return object Decoded results * @access public */ function decode($params = null) { // Have we been called statically? If so, create an object and pass details to that. if (!isset($this->mailMimeDecode) and isset($params['input'])) { $obj = new MIMEDECODE($params['input']); $structure = $obj->decode($params); // Called statically but no input } elseif (!isset($this->mailMimeDecode)) { return $this->_error = 'Called statically and no input given'; // Called via an object } else { // $this->_include_bodies = isset($params['include_bodies']) ? $params['include_bodies'] : false; // $this->_decode_bodies = isset($params['decode_bodies']) ? $params['decode_bodies'] : false; // $this->_decode_headers = isset($params['decode_headers']) ? $params['decode_headers'] : false; //Trace $this->_decode_headers = true; $structure = $this->_decode($this->_header, $this->_body); if ($structure === false) { $structure = $this->_error; } } return $structure; }
/** * Performs the decoding. Decodes the body string passed to it * If it finds certain content-types it will call itself in a * recursive fashion * * @param string $ Header section * @param string $ Body section * @return object Results of decoding process * @access private */ function _decode($headers, $body, $default_ctype = 'text/plain') { $return = new stdClass(); $headers = $this->_parseHeaders($headers); 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']; } elseif (isset($return->headers[strtolower($value['name'])])) { $return->headers[strtolower($value['name'])][] = $value['value']; } else { $return->headers[strtolower($value['name'])] = $value['value']; } } reset($headers); while (list($key, $value) = each($headers)) { $headers[$key]['name'] = strtolower($headers[$key]['name']); switch ($headers[$key]['name']) { case 'content-type': $content_type = $this->_parseHeaderValue($headers[$key]['value']); if (preg_match('/([0-9a-z+.-]+)\\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { $return->ctype_primary = $regs[1]; $return->ctype_secondary = $regs[2]; } if (isset($content_type['other'])) { while (list($p_name, $p_value) = each($content_type['other'])) { $return->ctype_parameters[$p_name] = $p_value; } } break; case 'content-disposition': $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); $return->disposition = $content_disposition['value']; if (isset($content_disposition['other'])) { while (list($p_name, $p_value) = each($content_disposition['other'])) { $return->d_parameters[$p_name] = $p_value; } } break; case 'content-transfer-encoding': $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); break; } } if (isset($content_type)) { switch (trim(strtolower($content_type['value']))) { case 'text/plain': $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; case 'text/html': $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; case 'multipart/parallel': case 'multipart/report': // RFC1892 // RFC1892 case 'multipart/signed': // PGP // PGP case 'multipart/digest': case 'multipart/alternative': case 'multipart/related': case 'multipart/mixed': if (!isset($content_type['other']['boundary'])) { $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; return false; } $default_ctype = strtolower($content_type['value']) === 'multipart/digest' ? 'message/rfc822' : 'text/plain'; $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); for ($i = 0; $i < count($parts); $i++) { list($part_header, $part_body) = $this->_split_body_header($parts[$i]); $part = $this->_decode($part_header, $part_body, $default_ctype); if ($part === false) { $part = $this->raiseError($this->_error); } $return->parts[] = $part; } break; case 'message/rfc822': // $obj = &new MIMEDECODE($body);// See below by Anoop $obj = new MIMEDECODE($body); // Php 5.4 fix by Anoop $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies)); unset($obj); break; default: if (!isset($content_transfer_encoding['value'])) { $content_transfer_encoding['value'] = '7bit'; } $this->_include_bodies ? $return->body = $this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body : null; break; } } else { $ctype = explode('/', $default_ctype); $return->ctype_primary = $ctype[0]; $return->ctype_secondary = $ctype[1]; $this->_include_bodies ? $return->body = $this->_decode_bodies ? $this->_decodeBody($body) : $body : null; } return $return; }