[KLUG Members] MIME attachments
Adam Tauno Williams
adam at morrison-ind.com
Wed Nov 16 15:08:28 EST 2005
> I add these lines to the header:
> MIME-Version: 1.0
> Content-Type: multipart/mixed; boundary="-d-i-v-i-d-i-n-g--l-i-n-e"
Maybe this will help, the send() method of my PHP MailMessage class:
function send() {
$this->write_debug_log("mail_mesg::send_mesg()");
$boundary = 'PM'.chr(rand(65, 91)).'------'.md5(uniqid(rand()));
if (strlen($this->destination) == 0) {
$this->set_error(0, "Mail Message has no destination");
return 0;
}
if (strlen($this->from) == 0) $this->from = $this->destination;
if (strlen($this->reply_to) == 0) $this->reply_to = $this->from;
$this->write_debug_log(sprintf("mail_mesg::send_mesg() - Message has
%d lines",
$this->get_count()));
while ($counter < $this->get_count()) {
$counter++;
$this->set_position($counter);
$body .= sprintf("%s\n", $this->get());
}
$email = "";
$email = "To: $this->destination".MIMECRLF;
$email .= "From: $this->from".MIMECRLF;
$email .= "Subject: " . $this->get_subject() . MIMECRLF;
$email .= "X-Priority: 3".MIMECRLF;
$email .= "X-Mailer: PHP/Apache/Linux".MIMECRLF;
$email .= "Reply-To: $this->reply_to".MIMECRLF;
$counter = 0;
$body = "";
while ($counter < $this->get_count()) {
$counter++;
$this->set_position($counter);
$body .= sprintf("%s\n", $this->get());
}
if (sizeof($this->mimeparts) > 0) {
$this->write_debug_log("mail_mesg::send_mesg() - This is a MIME
message");
$email .= "MIME-Version: 1.0" . MIMECRLF;
$email .= "Content-Type: multipart/mixed;" . MIMECRLF;
$email .= "\tboundary=\"" . $boundary . "\"" . MIMECRLF;
$email .= "Content-Transfer-Encoding: ".MIMEBIT7.MIMECRLF;
$email .= MIMECRLF.MIMEWARNING.MIMECRLF.MIMECRLF ;
if (!empty($body)) {
$this->attach($body, MIMEBODY, MIMETEXT, MIMEBIT7,
"inline");
}
for ($i=0 ; $i < sizeof($this->mimeparts); $i++) {
if ($this->debug_flag)
$this->write_debug_log(sprintf("mail_mesg:send_mesg() -
Sending attachment %d", $i));
if (!empty($this->mimeparts[$i]))
$email .=
MIMECRLF.'--'.$boundary.MIMECRLF.$this->mimeparts[$i].MIMECRLF;
}
$email .= '--'.$boundary.'--'.MIMECRLF;
} else {
$this->write_debug_log("mail_mesg::send_mesg() - This is a
non-MIME message");
$email .= MIMECRLF;
$email .= "$body";
}
$this->write_debug_log("mail_mesg::send_mesg() - Summoning MDA");
$fp = popen("/usr/sbin/sendmail -t", "w");
if ($fp == 0) {
$this->write_debug_log("mail_mesg::send_mesg() - Summon Failed");
$this->set_error(0, "popen to send mail failed");
$this->write_debug_log("popen to send mail failed");
return 0;
}
$this->write_debug_log($email);
fwrite($fp, $email);
pclose($fp);
return 1;
}
It includes the MIME.def file that looks like -
<?php
define('MIMEBASE64', 'base64');
define('MIMEBIT7', '7bit');
define('MIMEQP', 'quoted_printable');
define('MIMEWARNING', 'This is a MIME encoded message');
define('MIMEOCTET', 'application/octet-stream');
define('MIMETEXT', 'text/plain');
define('MIMEHTML', 'text/html');
define('MIMEJPEG', 'image/jpg');
define('MIMEGIF', 'image/gif');
define('MIMEMSWORD', 'application/msword');
define('MIMEPDF', 'application/pdf');
define('MIMERTF', 'application/rtf');
define('MIMETIFF', 'mage/tiff');
define('MIMESTARWRITER', 'application/vnd.sun.xml.writer');
define('MIMESTARIMPRESS', 'application/vnd.sun.xml.impress');
define('MIMESTARDRAW', 'application/vnd.sun.xml.draw');
define('MIMESTARCALC', 'application/vnd.sun.xml.calc');
define('MIMEICS', 'text/calendar');
define('MIMEVCARD', 'ext/x-vcard');
define('MIMEMSEXCEL', 'application/vnd.ms-excel');
define('MIMETTF', 'application/x-font-ttf');
define('MIMEGNUMERIC', 'application/x-gnumeric');
define('MIMECRLF', "\r\n");
define('MIMECHARSET', 'us-ascii');
define('MIMEINLINE', 'inline');
define('MIMEATTACH', 'attachment');
define('MIMEBODY', MIMECRLF.'BODY'.MIMECRLF);
?>
The attach method looks like -
function attach($data, $description = "", $contenttype = MIMEOCTET,
$encoding = MIMEBASE64, $disp = "attachment") {
if ($this->debug_flag)
$this->write_debug_log("mail_mesg:attach_file");
if (empty($data)) {
$this->write_debug_log("No data to be attached");
return 0;
}
if (trim($contenttype) == '') $contenttype = MIMEOCTET ;
if (trim($encoding) == '') $encoding = MIMEBASE64;
if ($encoding == MIMEBIT7) $emsg = $data;
elseif ($encoding == MIMEQP)
$emsg = $$this->qp_func($data);
elseif ($encoding == MIMEBASE64) {
if (!$this->base64_func) # Check if there is
user-defined function
$emsg = base64_encode($data);
else
$emsg = $$this->base64_func($data);
}
$emsg = chunk_split($emsg);
//Check if content-type is text/plain and if charset is not
specified append default CHARSET
if (preg_match("!^".MIMETEXT."!i", $contenttype) && !
preg_match("!;charset=!i", $contenttype))
$contenttype .= ";\r\n\tcharset=".MIMECHARSET ;
$msg = sprintf("Content-Type: %sContent-Transfer-Encoding: %s%s%s%
s",
$contenttype.MIMECRLF,
$encoding.MIMECRLF,
((($description) && (MIMEBODY != $description))?
"Content-Description: $description".MIMECRLF:""),
($disp?"Content-Disposition: $disp".MIMECRLF:""),
MIMECRLF.$emsg.MIMECRLF);
if (MIMEBODY==$description) {
if ($this->debug_flag)
$this->write_debug_log("mail_mesg:attach_file:attaching body");
$this->mimeparts[0] = $msg;
} else {
if ($this->debug_flag)
$this->write_debug_log("mail_mesg:attach_file:attaching
attachment");
$this->mimeparts[sizeof($this->mimeparts) + 1] = $msg ;
if ($this->debug_flag)
$this->write_debug_log(
sprintf("mail_mesg:attach_file:size of mimeparts %d",
sizeof($this->mimeparts)));
}
return sizeof($this->mimeparts);
}
Maybe that will help?
> And the body of the message looks like...
> --------------------------------------------
> You will only see this if you're using a non-MIME supporting Client!!
> -d-i-v-i-d-i-n-g--l-i-n-e
> Content-Type: text/html;
> <html>
> <head>
> ....
> </html>
> -d-i-v-i-d-i-n-g--l-i-n-e
> ----------------------------------------------
> More attachments work pretty much the same way. I have derived the above by
> inspecting a number of MIMEd mail messages as plain text files, and I'm omitting
> some detail
> Seems simple enough for EVERYONE'S favorite, HTML Mail! :)
> It is a simple example, and the main app generates HTML-based reports
> (PDF, when I get done with it).
> Anyway, I send the message, and it all looks well on recipt... UNTIL
> I try to read the attachment! This is why the above example is not more
> complex; if It doesn't work, then I have missed something that would
> probably be true for a more complex example, but something more complex
> would introduce other factors.... maybe...
> In any case, I get an amusing set of errors, the wording varies with the mail
> application I happen to be using....
>
> Outlook 97:
>
> An error prevented processing the message to completion. The original
> message is contained in the attached file MESSAGE.TXT
>
> Which does NOT display as HTML.
>
> mhstore: bogus multipart content in message xxxx
>
> Really helpful...
>
> I could try more clients, but I suspect I will only increase my collection
> of somewhat useless but mildly amusing error messages.
> I don't want to build something based on a pile of libraries, as I'm trying
> to keep this thing reasonably portable and compact. I am thinking that we
> can build MIME'd messages for special cases rather easily...
> I've also looked for more detailed information about all this, but found very
> little. Perhaps it is swamped by all the references to various MIME-capable
> applications...
> I lok forward to your replies...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://www.kalamazoolinux.org/pipermail/members/attachments/20051116/d69e4d07/attachment-0001.bin
More information about the Members
mailing list