I'm trying to generate EML files from PHP. Is there any library that will allow me to easily create them? I could find some ActiveX component on the internet but would rather use something more portable.
I ended up building the MIME message myself using this kind of template, where each field is replaced by a TEMPLATE_<name> variable:
From: TEMPLATE_FROM_ADDRESS
MIME-Version: 1.0
To: TEMPLATE_TO_ADDRESS
Subject: TEMPLATE_SUBJECT
Content-Type: multipart/mixed; boundary="080107000800000609090108"
This is a message with multiple parts in MIME format.
--080107000800000609090108
Content-Type: text/plain
TEMPLATE_BODY
--080107000800000609090108
Content-Type: application/octet-stream;name="TEMPLATE_ATTACH_FILENAME"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="TEMPLATE_ATTACH_FILENAME"
TEMPLATE_ATTACH_CONTENT
--080107000800000609090108
Then creating the final message is quite simple using str_replace:
$content = file_get_contents("Template.eml");
$content = str_replace("TEMPLATE_FROM_ADDRESS", $fromEmail, $content);
$content = str_replace("TEMPLATE_TO_ADDRESS", $toEmail, $content);
// etc. for each template parameter
// Also don't forget to base64_encode the attachment content;
$content = str_replace("TEMPLATE_ATTACH_CONTENT", base64_encode($attachContent), $content);
Additional info about file attachment in this post: Attachment name and file extension not working in email *.eml
Edit (2018): Since this answer was written it seems it's been copied and pasted a bit everywhere, the template in particular. To avoid any conflict with other MIME data, you should make sure that the boundary "080107000800000609090108" is unique - it's a string of random characters no longer than 70 characters.
I think you don't need a library. It's just plain text (e.g. http://bitdaddys.com/example1.eml)
Date: Sat, 12 Aug 2006 14:25:25 -0400
From: John Doe <jdoes#someserver.com>
Subject: BitDaddys Software
To: sales#bitdaddys.com
Dear BitDaddys Corp.,
We have added your software to our approved list.
Thank you for your efforts.
Sincerely,
John Doe
Some Server Company
You can just output text with headers and save it using fwrite. For attachments use base64_encode() as stated here
Use imap_savebody (part of the imap library http://us1.php.net/manual/en/function.imap-savebody.php) with a null $part_number. It creates a beautiful .eml file with one line of code with the entire message (null $part_number = all parts... not documented but works).
the other two solutions depend on the format of the email (only one attachment and no html section in the first solution, and only text email in the second).
imap_savebody creates a perfect .eml file no matter what the format of the incoming email is (as long as it's RFC-complaint of course).
Related
I'm using TCPDF using
$base64String = $pdf->Output('file.pdf', 'E');
So I can send the data via AJAX
The only problem is that it comes with header information in addition to the Base64 string
Content-Type: application/pdf;
name="FILE-31154d59f28c63efae86e4f3d6a00e13.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="FILE-31154d59f28c63efae86e4f3d6a00e13.pdf"
So if I take the string that is created to base64_decode() or use with phpMailer in my case it errors. Is it possible to remove the headers so I only have the base64 string?
(The error is that the pdf can't be read by any PDF reader when opened)
I thought I'd be able to find something that solves this but I haven't found anything!!
UPDATE
This is what I've put in place to solve the issue
$base64String = preg_replace('/Content-[\s\S]+?;/', '', $base64String);
$base64String = preg_replace('/name=[\s\S]+?pdf"/', '', $base64String);
$base64String = preg_replace('/filename=[\s\S]+?"/', '', $base64String);
However it's not very elegant! So if anyone has a better solution please post it below :)
TCPDF docs are huge but unusable – it's easier to read the source code directly. It has those extra headers because you're asking for them by using the E output mode, which is intended for generating email messages.
For sending the PDF data as a PHPMailer attachment, you want the straight binary PDF data as a string, as provided by the S output mode, which you can pass straight into addStringAttachment(), and PHPMailer will handle all the encoding for you. All you have to do is this:
$mail->addStringAttachment($pdf->Output('file.pdf', 'S'), 'file.pdf');
To convert the PDF binary into base64, for example to us it in a JSON string, simply pass it through base64_encode:
$base64String = base64_encode($pdf->Output('file.pdf', 'S'));
I have written php code for reading email. I am using
imap_fetchbody($this->conn, $i, 1.2);
for displaying email message. When mail is with attachment it is display in well mannered but if email is without attachment it displays nothing. When I am using
$body = imap_fetchbody($this->conn, $i, 1);
message is displaying in text/plain format. like this
this is system generated mail -- Regards! Md Belal
When I am using
$body = imap_body($this->conn, $i);
it is displaying like this
--047d7b5d2f88ddb36c050069a175 Content-Type: text/plain; charset=UTF-8 this is system generated mail -- Regards! Md Belal 8287326270 --047d7b5d2f88ddb36c050069a175 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
this is system generated mail
--
Regards!
Md Belal
--047d7b5d2f88ddb36c050069a175--
I need to display it in well mannered. Like this.
this is system generated mail
--
Regards!
Md Belal
What to do please help. Thanks!
Try this
https://stackoverflow.com/a/14936048/2289510
btw i haven't tried but nl2br (http://hu1.php.net/nl2br) may can help you too, its adding line breaks when your result is in text/plain format and its contains \n \r characters.
PHP -IMAP
I have saved all imap mail to database and displaying them from database. My problem is that one mail is showing "Content-Transfer-Encoding: base64". If i base64 decode it then other mails also get affected. I haven't been able to change it to human readable format till yet. Any help will be highly appreciated.
I have tried many solution but The code currently I am using is,
mb_convert_encoding($body, "ISO-8859-1", "UTF-8");
The output of this mail is
------=_NextPart_001_0606_012497BF.12408D60
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: base64
OTA5MTU5Mzg3DQoNCuS7juaKgOacr+i1sOWQkeeuoeeQhueahOWbm+S4quaguOW/gw0KMjAxMi05
LTE1ICAxNjowMjoxNw==
------=_NextPart_001_0606_012497BF.12408D60
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0
Zi04IiBodHRwLWVxdWl2PUNvbnRlbnQtVHlwZT4NCjxNRVRBIG5hbWU9R0VORVJBVE9SIGNvbnRl
bnQ9Ik1TSFRNTCA4LjAwLjYwMDEuMTg5OTkiPjwvSEVBRD4NCjxCT0RZPg0KPFA+PEZPTlQgc2l6
ZT0yPjkwOTE1OTM4NzxCUj48QlI+5LuO5oqA5pyv6LWw5ZCR566h55CG55qE5Zub5Liq5qC45b+D
PC9GT05UPjwvUD4NCjxQPjxGT05UIHNpemU9Mj4yMDEyLTktMTUmbmJzcDsgMTY6MDI6MTc8L0ZP
TlQ+PC9QPjwvQk9EWT48L0hUTUw+DQo=
------=_NextPart_001_0606_012497BF.12408D60--
It's base64, you have to use base64_decode on body part like this:
base64_decode('OTA5MTU5Mzg3DQoNCuS7juaKgOacr+i1sOWQkeeuoeeQhueahOWbm+S4quaguOW/gw0KMjAxMi05LTE1ICAxNjowMjoxNw==');
just to manually check there are several online services like
http://www.motobit.com/util/base64-decoder-encoder.asp
just copy and paste the base64 source and choose "decode". You will get a "human readyble format".
I just got PHP's mail function to work properly in my test environment.
I have a PHP app that outputs a number of strings. It would be really nice to convert these strings to attachments (*.TXT -files) in an email, without first storing them on disk and having to read them back. Would this be possible in PHP?
Yes, this is possible. You just need to make your email message a multipart message with the following syntax:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=random-boundary
This is the optional preamble of a multipart/mixed message.
--random-boundary
Content-Type: text/plain
This is the main message body.
--random-boundary
Content-Type: text/plain
Content-Disposition: attachment; filename=file.txt
This is the content of the attached file.
--random-boundary--
This is the optional epilogue of a multipart/mixed message.
Each part can then be described like any other message. But you should probably use a library that does this for you.
Now if you’re using PHP’s mail function, the first two line would be the header and the rest would be the contents of that mail message. The boundary should be a random boundary so that the possibility of having that string with -- in front of it being in the contents of one part is very unlikely.
Yes, you can use e.g. PEAR's Mail_Mine class for it.
bool addAttachment ( string $file , string $c_type = 'application/octet-stream' , string $name = '' , boolean $isfile = true , string $encoding = 'base64' ) is the method you want to use, with $file containing your strings and $isfile being false.
And you can Use Zend_Mail Classes for much easier code
the file name would be "smapleFilename" and its the last parameter in createAttachment function
but don't foget to setup your transport before that
sample :
$mail = new Zend_Mail();
$mail->setBodyText("body")
->createAttachment("your wanted text " , Zend_Mime::TYPE_TEXT,
Zend_Mime::DISPOSITION_ATTACHMENT , Zend_Mime::ENCODING_BASE64, "smapleFilename.txt");
$mail->setFrom('test#222222.com', 'Server');
$mail->addTo('test#hotmail.com');
$mail->setSubject("subject");
$mail->send();
in Zend framework project you would do like this :
resources.mail.transport.type = smtp
resources.mail.transport.host = "mail.111111.com"
resources.mail.transport.auth = login
resources.mail.transport.username = test#111111.com
resources.mail.transport.password = test
;resources.mail.transport.ssl = tls
resources.mail.transport.port = 2525
resources.mail.transport.register = true ; True by default
I have a custom web based contact management system that we built in PHP to track contacts and recently starting checking our Google e-mail box using IMAP and then, if that contact is in our contact management system:
Copying the message into a MySQL database table that's associated with that contact
Marking that contact to follow up with that day
Archiving the message in Gmail
Everything seems to be working great, EXCEPT... every so many emails we get a really garbled message that looks like this:
FABRRRQAUUUUAJXDjxZrUtzNFa2UMwjYj5YnYgZ74Ndwa4bwfzqmpH3/wDZjTcl
CnKdr2Fa7SJP+Ek8S/8AQJX/AMB5P8aZN4s162j33GmxxrnG54XUfqa6ysHxp/yA/wDtqv8AWuej
jFUqKDgtSpQsr3L13r4tPDcOoShBcTxgog6FiP5CsrwtpjuzavekvcTZKFuwPf8AH+VZOlwS+Iby
1jlBFnZRKhGeDjt9Sf0Fd0qhVCqAABgA
I go back and check the message and it appears to be only text, so I don't think it is an image. Any idea how to prevent that?
Thanks in advance.
Sincerely,
James
The example you provided looks like it is base64 encoded. The headers of the email message will tell you how to handle the content of the email message.
For example, the following defines an email message where the body is plain text, but it is stored as being base64 encoded. I have "x"ed out the privacy sensitive information.
Received: from xxxxxxxxx ([xxx.xx.xx.xxx]) by xxxxxxxxxx.xxx.xxxxxxxxxxxxxxx.xxx with Microsoft SMTPSVC(6.0.3790.3959);
Wed, 29 Apr 2009 21:29:16 +0000
Received: from xxxx-xxx-xxxxxx ([xxx.xx.xxx.xxxx]) by xxxxxxxx ; Wed, 29 Apr 2009 15:29:16
-0600
Message-ID: <AADB29A7-AAED-4068-B4A8-300E3B0D93AB#localhost>
MIME-Version: 1.0
From: xxxxxxxxxx#xxxxxxxxxxxxxxx.com
To: xxxxxxxxxx#xxxxxxxxxxxxxxx.com
Date: 29 Apr 2009 15:29:16 -0600
Subject: xxxx Account Update
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
Return-Path: xxxxxx#xxxxxxxx.com
X-OriginalArrivalTime: 29 Apr 2009 21:29:16.0374 (UTC) FILETIME=[8C63AF60:01C9C911]
Pay close attention to the Content-Type and Content-Transfer-Encoding headers.
I believe the IMAP is over SSL, so it might be the connection to IMAP that gets out of sync. The best solution I have for that is just check to see if the body contains a really long word. Since that garble has no spaces:
<?php
function wordlength($txt, $limit)
{
$words = explode(' ', $txt);
foreach($words as $v)
{
if(strlen($v) > $limit)
{
return false;
}
}
return true;
}
?>
Usage:
<?php
$txt = "Message Body would be here";
if(!wordlength($txt, 45))
{
//maybe try to pull the message again or
//send an email to you telling you there is a problem
}
?>
I picked 45 just in case some uses the word Pneumonoultramicroscopicsilicovolcanoconiosis in an email. :D
Jordan might be right though. It may just be base64 encoded. I would just explode() the headers then and search for that and if it's there, a simple base64_decode() will do the trick.
This helped me with a garbled e-mail subject.
http://php.net/manual/en/function.imap-header.php