public function parse($raw) { $this->raw = $raw; // http://pear.php.net/manual/en/package.mail.mail-mimedecode.decode.php $decoder = new Mail_mimeDecode($this->raw); $this->decoded = $decoder->decode(['decode_headers' => true, 'include_bodies' => true, 'decode_bodies' => true]); $this->from = mb_convert_encoding($this->decoded->headers['from'], $this->charset, $this->charset); $this->to = mb_convert_encoding($this->decoded->headers['to'], $this->charset, $this->charset); $this->subject = mb_convert_encoding($this->decoded->headers['subject'], $this->charset, $this->charset); $this->date = mb_convert_encoding($this->decoded->headers['date'], $this->charset, $this->charset); $this->from_email = preg_replace('/.*<(.*)>.*/', "\$1", $this->from); if (isset($this->decoded->parts) && is_array($this->decoded->parts)) { foreach ($this->decoded->parts as $idx => $body_part) { $this->decode_part($body_part); } } if (isset($this->decoded->disposition) && $this->decoded->disposition == 'inline') { $mime_type = "{$this->decoded->ctype_primary}/{$this->decoded->ctype_secondary}"; if (isset($this->decoded->d_parameters) && array_key_exists('filename', $this->decoded->d_parameters)) { $filename = $this->decoded->d_parameters['filename']; } else { $filename = 'file'; } if ($this->is_valid_attachment($mime_type)) { $this->save_attachment($filename, $this->decoded->body, $mime_type); } $this->body = ""; } // We might also have uuencoded files. Check for those. if (empty($this->body)) { $this->body = isset($this->decoded->body) ? $this->decoded->body : ""; } if (preg_match("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $this->body) > 0) { foreach ($decoder->uudecode($this->body) as $file) { // $file = [ 'filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $filedata ] $this->save_attachment($file['filename'], $file['filedata']); } // Strip out all the uuencoded attachments from the body while (preg_match("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $this->body) > 0) { $this->body = preg_replace("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", "\n", $this->body); } } $this->body = mb_convert_encoding($this->body, $this->charset, $this->charset); return $this; }
/** * @brief Read an email message * * @param $src (optional) Which file to read the email from. Default is php://stdin for use as a pipe email handler * * @return An associative array of files saved. The key is the file name, the value is an associative array with size and mime type as keys. */ public function readEmail($src = 'php://stdin') { // Process the e-mail from stdin $fd = fopen($src, 'r'); while (!feof($fd)) { $this->raw .= fread($fd, 1024); } // Now decode it! // http://pear.php.net/manual/en/package.mail.mail-mimedecode.decode.php $decoder = new Mail_mimeDecode($this->raw); $this->decoded = $decoder->decode(array('decode_headers' => TRUE, 'include_bodies' => TRUE, 'decode_bodies' => TRUE)); // Set $this->from_email and check if it's allowed $this->from = $this->decoded->headers['from']; $this->from_email = preg_replace('/.*<(.*)>.*/', "\$1", $this->from); if (!(in_array('all', $this->allowed_senders) || in_array($this->from_email, $this->allowed_senders))) { die("{$this->from_email} not an allowed sender"); } // Set the $this->subject $this->subject = $this->decoded->headers['subject']; $subjectParts = explode(' ', $this->subject); if (is_array($subjectParts) && count($subjectParts) == 3) { if (strpos($subjectParts[0], 'uid:') !== false) { $this->newFileName = str_replace('uid:', '', $subjectParts[0]); } if (strpos($subjectParts[1], 'dir:') !== false) { $this->newFileName .= '_' . str_replace('dir:', '', $subjectParts[1]); } if (strpos($subjectParts[2], 'maxSize:') !== false) { $this->newFileName .= '_' . str_replace('maxSize:', '', $subjectParts[2]); } } // Find the email body, and any attachments // $body_part->ctype_primary and $body_part->ctype_secondary make up the mime type eg. text/plain or text/html if (isset($this->decoded->parts) && is_array($this->decoded->parts)) { foreach ($this->decoded->parts as $idx => $body_part) { $this->decodePart($body_part); } } if (isset($this->decoded->disposition) && $this->decoded->disposition == 'inline') { $mimeType = "{$this->decoded->ctype_primary}/{$this->decoded->ctype_secondary}"; if (isset($this->decoded->d_parameters) && array_key_exists('filename', $this->decoded->d_parameters)) { $filename = $this->decoded->d_parameters['filename']; } else { $filename = 'file'; } $this->saveFile($filename, $this->decoded->body, $mimeType); $this->body = "Body was a binary"; } // We might also have uuencoded files. Check for those. if (!isset($this->body)) { if (isset($this->decoded->body)) { $this->body = $this->decoded->body; } else { $this->body = "No plain text body found"; } } if (preg_match("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $this->body) > 0) { foreach ($decoder->uudecode($this->body) as $file) { // file = Array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $filedata) $this->saveFile($file['filename'], $file['filedata']); } // Strip out all the uuencoded attachments from the body while (preg_match("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $this->body) > 0) { $this->body = preg_replace("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", "\n", $this->body); } } // Put the results in the database if needed if ($this->save_msg_to_db && !is_null($this->pdo)) { $this->saveToDb(); } // Send response e-mail if needed if ($this->send_email && $this->from_email != "") { $this->sendEmail(); } // Print messages if ($this->debug) { $this->debugMsg(); } return $this->saved_files; }
/** * Decodes the contents of the part to either a 7bit or 8bit encoding. * * @return string The decoded text. * Returns the empty string if there is no text to decode. */ public function transferDecode() { $encoding = $this->getCurrentEncoding(); /* If the contents are empty, return now. */ if (!strlen($this->_contents)) { $this->_flags['lastTransferDecode'] = $encoding; return $this->_contents; } switch ($encoding) { case 'base64': $message = base64_decode($this->_contents); $this->_flags['lastTransferDecode'] = '8bit'; break; case 'quoted-printable': $message = preg_replace("/=\r?\n/", '', $this->_contents); $message = $this->replaceEOL($message); $message = quoted_printable_decode($message); $this->_flags['lastTransferDecode'] = Horde_MIME::is8bit($message) ? '8bit' : '7bit'; break; /* Support for uuencoded encoding - although not required by RFCs, some mailers may still encode this way. */ /* Support for uuencoded encoding - although not required by RFCs, some mailers may still encode this way. */ case 'uuencode': case 'x-uuencode': case 'x-uue': if (function_exists('convert_uudecode')) { $message = convert_uuencode($this->_contents); } else { $files =& Mail_mimeDecode::uudecode($this->_contents); $message = $files[0]['filedata']; } $this->_flags['lastTransferDecode'] = '8bit'; break; default: if (isset($this->_flags['lastTransferDecode']) && $this->_flags['lastTransferDecode'] != $encoding) { $message = $this->replaceEOL($this->_contents); } else { $message = $this->_contents; } $this->_flags['lastTransferDecode'] = $encoding; break; } return $message; }