Plaintext/HTML Email doesn't work in mac mail client - php

The code below is the code i am using. It works fine in thunderbird but not in mac mail client (and i assume anything made by microsoft. I currently do not have access to this to test it in). Much as i am aware of the idiosyncrasies of the various mail clients, I am flummoxed by this! It's fairly self explanatory but i am trying to send plain text and html emails to increase the readership. Any help would be much appreciated.
EDIT
I should have clarified that the contents get sent regardless but in thunderbird it displays the message correctly, but in mac mail client you get the entire thing from the first PHP-alt to the last PHP
<?php
//define the receiver of the email
$to = 'youraddress#example.com';
//define the subject of the email
$subject = 'Test HTML email';
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \r\n
$headers = "From: webmaster#example.com\r\nReply-To: webmaster#example.com";
//add boundary string and mime type specification
$headers .= "\r\nContent-Type: multipart/alternative; boundary=\"PHP-alt-".$random_hash."\"";
//define the body of the message.
ob_start(); //Turn on output buffering
?>
--PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hello World!!!
This is simple text email message.
--PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
<h2>Hello World!</h2>
<p>This is something with <b>HTML</b> formatting.</p>
--PHP-alt-<?php echo $random_hash; ?>--
<?
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();
//send the email
$mail_sent = #mail( $to, $subject, $message, $headers );
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed"
echo $mail_sent ? "Mail sent" : "Mail failed";
?>

Rather than try and roll your own mailer, try e.g. PHPMailer. It has very good support for multipart/alternative. It's much easier to integrate this than to roll your own solution. I've been there - after working endlessly around strange MIME problems, I've dropped my hand-made mailer, switched to this, and focused on other things in the time I've spared.
In other words, don't reinvent the wheel. Although doing it yourself can be a good challenge and you'll learn a lot during the process, if you just want it to work, these guys have dealt with the complexity for you.

You're not using output buffering correctly - see man page for ob_end_clean to see that it doesn't return the captured output, you need ob_get_contents for that:
$message =ob_get_contents();
ob_end_clean();

Related

Why is Outlook email changing my email into attachment with .dat extension?

I'm sending a simple email using PHP mail() function in HTML content type. It works fine on every email, except Outlook, where whole content of my mail is transferred into an attachment with .dat extension. Why is it happening? Is there a way to fix it or to workaround?
I haven't found an explanation anywhere, why is it happening in so simple case. (Outlook settings are set to open emails as HTML and HTML emails sent from other websites looks fine too)
mail('myMail#gmail.com', "Testing", "First line<br>Second line <b>bolded text</b>", "From: myWebsite#mail.com\nContent-Type:".' text/html;charset="UTF-8"'."\nContent-Transfer-Encoding: 8bit");
Note that "extra headers should be separated with a CRLF (\r\n)" c.f. https://www.php.net/manual/en/function.mail.php
Try adding the MIME flag and see if it then works for you:
$headers = "From: myWebsite#mail.com \r\n".
"Content-type: text/html; charset=UTF-8 \r\n".
"Content-Transfer-Encoding: 8bit \r\n".
"MIME-Version: 1.0";
mail('myMail#gmail.com', "Testing", "First line<br>Second line <b>bolded text</b>", $headers);

Using mail() to send an attachment AND text/html in an email in PHP4

To make life difficult, the client I'm working for is using a really large yet old system which runs on PHP4.0 and they're not wanting any additional libraries added.
I'm trying to send out an email through PHP with both an attachment and accompanying text/html content but I'm unable to send both in one email.
This sends the attachment:
$headers = "Content-Type: text/csv;\r\n name=\"result.csv\"\r\n Content-Transfer-Encoding: base64\r\n Content-Disposition: attachment\r\n boundary=\"PHP-mixed-".$random_hash."\"";
$output = $attachment;
mail($emailTo, $emailSubject, $output, $headers);
This sends text/html:
$headers = "Content-Type: text/html; charset='iso-8859-1'\r\n";
$output = $emailBody; // $emailBody contains the HTML code.
This sends an attachment containing the text/html along with the attachment contents:
$headers = "Content-Type: text/html; charset='iso-8859-1'\r\n".$emailBody."\r\n";
$headers = "Content-Type: text/csv;\r\n name=\"result.csv\"\r\n Content-Transfer-Encoding: base64\r\n Content-Disposition: attachment\r\n boundary=\"PHP-mixed-".$random_hash."\"";
$output = $attachment;
What I need to know is how can I send an email with text/html in the email body and also add an attachment to it. I'm sure I'm missing something really simple here!
Thanks in advance.
Okay, I've finally cracked it! For reference:
$emailBody .= "<html><body>Blah</body></html>";
$emailSubject = "Subject";
$emailCSV = "\"Col1\", \"Col2\"\r\n"; // etc.
$attachment = $emailCSV;
$boundary = md5(time());
$header = "From: Name <address#address.com>\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed;boundary=\"" . $boundary . "\"\r\n";
$output = "--".$boundary."\r\n";
$output .= "Content-Type: text/csv; name=\"result.csv\";\r\n";
$output .= "Content-Disposition: attachment;\r\n\r\n";
$output .= $attachment."\r\n\r\n";
$output .= "--".$boundary."\r\n";
$output .= "Content-type: text/html; charset=\"utf-8\"\r\n";
$output .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$output .= $emailBody."\r\n\r\n";
$output .= "--".$boundary."--\r\n\r\n";
mail($emailTo, $emailSubject, $output, $header);
Trying to send attachments using the PHP mail() function is an exercise in frustration; put simply, it's just not worth the effort. I would never ever suggest even attempting it, even in current PHP versions. I would always use a library like phpMailer.
I know you said you aren't allowed to use a third party library, but in this case, you would be crazy not to use one. We're talking about the difference between one day of work and a year; it's that big a deal. The PHP mail() function is incredibly difficult to work with, and trying to write code with it to send attachments from scratch will leave you with brittle, bug-ridden code that takes forever to get working reliably in all cases. This is why libraries like phpMailer exist.
So I suggest that regardless of what they want you to do, you should download phpMailer -- the PHP4 version is still available -- and see if it works for you. (The download page even still has the really old versions, so you should be able to go far enough back in time to find one that works with PHP 4.0. It shouldn't take you any time at all to get a simple demo up and running with it. Demonstrate that it works; that may well soften their stance against third party libraries.
(If it doesn't soften their stance, then there's not much hope of this project ever being completed in a sane amount of time. In that case, the best you can do is add a few extra zeros to your quote for the project price and grit your teeth)

Iphone web app download attachment function in php

I have a iphone app which use uiwebview to include a mobile site, the mobile site is developed in PHP, some of the page is allow people to download some attachments by using header force download, since the file will be convert to some binary and finally output as a download file by made use of php header function, im wondering will it be work in iphone app uiwebview too?
This site provides a script that they say works.
Here's my code sending vcard as attachement with no message:
//create a boundary string. It must be unique
$random_hash = md5(date('r', time())); $alt_random_hash = md5(date('r', time()+1));
//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = (chunk_split(base64_encode(file_get_contents($url)));
$filename = "Alain_Leblanc.vcf";
// Write the email message (which will become an attachement)
$headers .= "
MIME-Version: 1.0
From: info#AlainLeblancAssurances.ca
Reply-To: info#AlainLeblancAssurances.ca
Content-Type: text/x-vcard; charset=utf-8; name=$filename; boundary=$random_hash
Content-Disposition: attachment; filename=$filename
Content-Transfer-Encoding: base64
--$random_hash
$attachment
--$random_hash--
";
//send the email
$mail_sent = #mail($_POST['userEmail'], "Fiche contacts d'Alain Leblanc", "", $headers);
// display email result in browser
echo $mail_sent ? "rand: ".$random_hash ."<br/>Alt: ".$alt_random_hash."<br/>".$headers : "Mail failed";

Generate csv file from form data on fly then email to address

I have a form that users are able to fill in and want to be able to generate an Excel file and populate it with the data from the form. I then want it to email me the file with the completed data. How can this be done?
This is currently generating the email:
$body = "You have a new member account application from the website, please see the details below:
\n
Membership Type: $group1_field\n\n
Contact Details\n
Organisation: $member_organ_field\n
Address: $member_address_field\n
Postcode: $member_post_field\n
Tel: $member_tel_field\n
Fax: $member_fax_field\n
Email address: $member_email_field\n
Website: $member_website_field\n\n
Contacts \n
Member 1 \n
Name: $member1_name1_field\n
Position: $member1_position1_field\n
Direct Email: $member1_email1_field\n
Direct Tel: $member1_tel1_field\n\n
Member 2 \n
Name: $member1_name2_field\n
Position: $member1_position2_field\n
Direct Email: $member1_email2_field\n\n
Member 3 \n
Name: $member1_name3_field\n
Position: $member1_position3_field\n
Direct Email: $member1_email3_field\n\n
Type Of Organisation: ".$checkbox1results."\n
Type Of Activity: ".$checkbox2results."$member3_other_field\n\n
Summary Description \n
$member_summary_field \n\n
Company Information \n
Total no. of employees (Welsh site): $member4_total_field\n
Turnover (from Welsh site): $member4_turnover_field\n
Date of company formation: $member4__formation\n
Do you export aborad? Where? $member4_export_field\n\n
Member consent: ".$checkbox3results."\n\n
Completed by: $member4_com_field\n
Company position: $member4_com_pos_field\n
Invoice required: $CheckboxGroup4_field\n\n
Please follow up this request asap.\n\n
";
mail($to, $subject, $body);
echo "Thank you for your account application, we will contact you shortly.";
} ?>
The easiest way would be can create a csv, which is readable by Excel.
It's essentially a comma seperated list of values. Each line representing a row.
The first line can optionally be the column headings, eg:
$string = '"Organisation","Address","Postcode"' . PHP_EOL;
$string .= "\"$member_organ_field\",\"$member_address_field\",\"$member_post_field\"" . PHP_EOL;
file_put_contents('myfile.csv', $string); // write file
Be sure to quote field names and values as a stray unquoted , (comma) would mess up your columns.
Other wise there is an PEAR library for write excel files.
You can them email the file as an attachment using the built-in mail function, see example here
Or using Swift Mailer, see example here
UPDATE
This is the general gist of what you need, the code may not be perfect to please read over it and don't copy and paste.
<?php
$random_hash = md5(date('r', time()));
$csvString = "..."; // your entire csv as a string
$attachment = chunk_split(base64_encode($csvString));
$to = "to#me.com";
$from = "from#you.com";
$subject = "my subject";
$body = "... what ever you want to appear in the body";
$headers = "From: $from\r\nReply-To: $from";
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
$output = "
--PHP-mixed-$random_hash;
Content-Type: multipart/alternative; boundary='PHP-alt-$random_hash'
--PHP-alt-$random_hash
Content-Type: text/plain; charset='iso-8859-1'
Content-Transfer-Encoding: 7bit
$body
--PHP-mixed-$random_hash
Content-Type: text/csv; name=mycsv.csv
Content-Transfer-Encoding: base64
Content-Disposition: attachment
$attachment
--PHP-mixed-$random_hash--";
mail($to, $subject, $output, $headers);
echo "Thank you for your account application, we will contact you shortly.";
?>
There are two options:
Create a CSV file from the data above
Create an Excel spreadsheet from the data above
By default, windows will associate CSV files with Excel (if it's installed) so most people will open a CSV in Excel (if they have it installed).
For each case, read here:
http://www.dreamincode.net/forums/topic/10131-working-with-excel-files-comma-delimited-or-csv/
http://phpexcel.codeplex.com/
It's also worth noting that if you're generating a .xls file then your PHP will need to run on windows with a copy of Excel installed (I wouldn't advise this, and if you want to go with the Excel option then you might want to consider creating .xlsx files with the PHPExcel tool I linked you to, this does not require an installed copy of Excel and so it can be deployed on Linux)
EDIT: To email the files as attachments you can user PHPMailer (an example of how easy this is can be found here, and you can download the class here)
Pear could be useful here. I found: Spreadsheet_Excel_Writer. Basic documentation and usage for it is here.

Read MIME data using PHP

I have a third party program which basically allows users to send email and then it displays it in the system. But the problem is that it is generating an output like this: I want to just take this data and format it to something presentable. I would like to avoid REGEX. Are there any options or standard ways of displaying the content below in a more presentable fashion. Basically I will associate everything below as $text and then call a function clean($text) of sorts.
> This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
--B_3331365494_4098727
Content-type: text/plain;
charset="US-ASCII"
Content-transfer-encoding: 7bit
test
--B_3331365494_4098727
Content-type: text/html;
charset="US-ASCII"
Content-transfer-encoding: quoted-printable
<HTML>
<HEAD>
<TITLE>Test</TITLE>
</HEAD>
<BODY>
<FONT FACE="Calibri, Verdana, Helvetica, Arial"><SPAN STYLE='font-size:11pt'>test</SPAN></FONT>
</BODY>
</HTML>
--B_3331365494_4098727--
PEAR::Mail_mimeDecode is a great class to decode MIME messages. Once installed, you can use it as such:
$message = new Mail_mimeDecode($text);
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$messageStruct = $message->decode($params);
//messageStruct is now an array representing the message
// with all the parts properly included.

Categories