I am trying to send emails using the PHP mail function, but I am running into issues when it actually sends the email.
For some reason, the $to variable has a space between each character. So when it's emailed, the spaces are filled with dots. The $to email is being grabbed from a TSV file generated from a remote system that I do not control.
I have seen where people have a line where it searches for white space and deletes it but i do not want to go that route.
The CC function works perfectly.
Does anyone know what may be happening? I have seen a couple of threads and bugs but they do not match it exactly.
<?php
$Name= $_POST["Name"];
//File Upload Script
if ($_FILES["file"]["error"] > 0)
{
}
else
{
echo "File name: " . $_FILES["file"]["name"] . "<br>";
echo "Type: " . $_FILES["file"]["type"] . "<br>";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";
move_uploaded_file($_FILES["file"]["tmp_name"], "C:/xampp/htdocs/Uploads/" . $_FILES["file"]["name"]);
echo "http://php/Uploads/" . $_FILES["file"]["name"];
}
$URLLink = "C:/xampp/htdocs/Uploads/" . $_FILES["file"]["name"];
//End File Upload Script
//Reading TSV File
$filename = $URLLink;
//Deleting first line and last 5 lines
$alines=file($filename);
$dlines=array_slice($alines,1, -5);
$fileContents=implode($dlines);
$fp=fopen($filename,'w+');
fwrite($fp,$fileContents);
fclose($fp);
//END of Deleting first line and last 5 lines
$filename = $URLLink;
$file = file($filename);
foreach($file as $line)
{
list($start_time, $end_time, $instance, $status, $coordinator) = explode(" ", $line);
$from = $SentFrom;
$to = $coordinator;
$to = str_replace(' ', '', $coordinator);
//$to = str_replace('.', '', $coordinator);
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= "From:" . $from . "\r\n" . "CC:" . $mailer . "," . $emailone. "," . $emailtwo;
$subject = "Test";
include_once("EmailBody.php");
mail($to, $subject, $message, $headers);
}
?>
Page before is a form.
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Impact Notification</title>
<link rel="stylesheet" href="../style/style.css" type="text/css" media="screen" />
<link rel="stylesheet" href="../style/menustyle.css" type="text/css" media="screen" />
<style type="text/css">
.auto-style1 {
font-family: "Lucida Calligraphy";
}
</style>
</head>
<body style="color: #black; background-color: #0000FF;">
<div align="center"id="MainWrapper" style="width: 70%">
<div id="container" style="width:100%">
<div id="PageHeader">
<?php include_once("../template/template_header.php");?>
</div>
<div id="leftcolumn" style="height:auto;width:11%;float:left;padding:15px 15px 15px 15px;">
<?php include_once("../template/menu.php"); ?>
</div>
<div id="content" style="background-color:#EEEEEE;height:auto;width:80%;float:left;">
<h2 class="auto-style1">Email Notification</h2>
<form action="sendemail.php" method="post" name="emails" enctype="multipart/form-data">
<table style="width: 100%">
<tr>
<td>Enter Your Name</td>
<td><input name="Name" type="text" style="width: 300px; height: 24px;" /></td>
<tr>
<td style="width: 180px"><strong>File Upload:</strong></td>
<td><input type="file" name="file" id="file" /></td>
</tr>
</table>
<br />
<input name="Submit" type="submit" value="Submit" /><input name="Clear" type="reset" value="Reset" /><br />
<br />
</form>
</div>
</div>
</div>
Revised Answer: BAD DATA HANDLING!
Whilst it may still be a UTF / Charset issue, according to the code you have provided and sample data, your data handling is incorrect. Here are some tips for you (which have been incorporated into my suggested foreach loops below).
Your text file header contains a number of fields that you would like to retrieve. These are represented as the following fields sequentially in a row, separated by tabs:
Start Time End Time Instance Type Status Endpoint Organizer ....etc
You seem to be wanting a number of these fields to be captured, and amongst them, the $coordinator value needs to contain the data within the organiser field as listed within the text file (which appears to always be an email address):
Looking at your raw tsv file, your "list" processor is processing the wrong variables as you have missed the endpoint field!! Even if you're not going to use it, you'd need to put something in there for it to work the way you have set things up. At the very best, you would be storing the value for endpoint as $coordinator, but I suspect you wouldn't be getting that far because of the way you are exploding (see point 2 below).
The file you submitted seems to be separated by tabs, yet you're exploding using spaces. Change the " " in your explode to "\t". Currently, you're probably getting junk in your variable data (as it is splitting after every space in each line) - the organiser email address is not going to ever make it into $coordinator - perhaps you could echo your variables as a test to see what I mean (and comment out your mail function while you're testing).
I have revised your foreach loop:
foreach($file as $line)
{
list($start_time, $end_time, $instance, $status, $endpoint, $coordinator) = explode("\t", $line);
$from = $SentFrom;
$to = $coordinator;
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= "From:" . $from . "\r\n" . "CC:" . $mailer . "," . $emailone. "," .$emailtwo;
$subject = "Test";
include_once("EmailBody.php"); // Can' really comment on what's going on here - as I don't know what is in this file ! :)
mail($to, $subject, $message, $headers);
}
You are stripping 5 lines from the bottom of the file and one from the top, but I see 6 lines that need to be removed from the bottom and one from the top in your sample file. Perhaps change the -5 to -6. Or alternatively, you could do something like this in your foreach loop to instruct the routine not to send an email if the $coordinator variable is "blank" so it doesn't fail if it reads a blank line, etc:
Alternative ForEach Loop - to stop blank lines within your file causing failures:
foreach($file as $line)
{
list($start_time, $end_time, $instance, $status, $endpoint, $coordinator) = explode("\t", $line);
if (trim($coordinator) !== '')
{
$from = $SentFrom;
$to = $coordinator;
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= "From:" . $from . "\r\n" . "CC:" . $mailer . "," . $emailone. "," .$emailtwo;
$subject = "Test";
include_once("EmailBody.php"); // Can' really comment on what's going on here - as I don't know what is in this file ! :)
mail($to, $subject, $message, $headers);
}
}
You seem to be using a Windows implementation of PHP Mail. You may not have any issues with your current message content - just be aware that any lines starting with a period/fullstop will be removed. If you have any of your message lines starting with a '.', you might need something like this:
$vardata = str_replace("\n.", "\n..", $vardata);
Looking at a hex dump of the file, your data is encoded as UTF-16, which for ASCII data includes a nul character between each character of data. You can convert with iconv()
Note: you need to run this on the original file before you try extracting the data.
$str = file_get_contents('2.tsv');
$result = iconv($in_charset = 'UTF-16LE' , $out_charset = 'UTF-8' , $str);
if (false === $result)
{
throw new Exception('Input string could not be converted.');
}
$result = substr($result, 3); // Strip BOM
file_put_contents('3.tsv',$result);
echo $result;
Alternatively you can use
$str = file_get_contents('2.tsv');
$result = mb_convert_encoding($str, 'ASCII', 'UTF-16LE'); //instead of iconv()
file_put_contents('3.tsv',$result);
I have run both successfully on my development server.
You could use trim(), to strip all sorts of whitespace characters only at the beginning and end of the string. I don't think I've seen it suggested yet.
http://nl1.php.net/trim
This function returns a string with whitespace stripped from the beginning and end of str. Without the second parameter, trim() will strip these characters:
" " (ASCII 32 (0x20)), an ordinary space.
"\t" (ASCII 9 (0x09)), a tab.
"\n" (ASCII 10 (0x0A)), a new line (line feed).
"\r" (ASCII 13 (0x0D)), a carriage return.
"\0" (ASCII 0 (0x00)), the NUL-byte.
"\x0B" (ASCII 11 (0x0B)), a vertical tab.
Related
I use jQuery to serve a link where users can download a .txt file. jQuery just gets the content of a textarea and sets it as the href attribute. This is necessary because the content of the textarea is set with the response of an ajax call.
The download of the file works like this:
$(document).on('click', '#download', function(){
$(this).attr('href','data:text/plain;charset=utf-8,' + encodeURIComponent( $('#kundendaten').val() ) );
});
One part of the Ajax call response is the textarea:
$kundendaten = '<textarea id="kundendaten">';
$kundendaten .= 'Name: '. $_POST['nachname'] .' '. $_POST['vorname'] . PHP_EOL;
$kundendaten .= 'Email: '. $_POST['email'] . PHP_EOL;
$kundendaten .= '</textarea>';
On Mac OS I get a .txt file with line breaks and everything is fine. On Windows though the line breaks are missing in the .txt file. I also tried \n instead of PHP_EOL but there was no difference.
Any idea how I can solve this?
PHP_EOL only works to the system it is running on, so if your website is hosted on a linux box, it will do the EOL to a linux standard.
The following would be your best bet.
$kundendaten = '<textarea id="kundendaten">' . "\r\n";
$kundendaten .= 'Name: '. $_POST['nachname'] .' '. $_POST['vorname'] . "\r\n";
$kundendaten .= 'Email: '. $_POST['email'] . "\r\n";
$kundendaten .= '</textarea>' . "\r\n";
Also if you are using this a lot throughout a file I would create a constant referencing "\r\n" and use that. (If I remember the syntax correctly, as follows;
DEFINE("_EOL", "\r\n");
Hope to get some help with a piece of code, I am using a theme for wordpress which sets the mail headers to text/html, this causes some problems with plain text mail ex. linebreaks don't show anymore.
I tried setting :
} else {
return 'text/plain';
}
but I don't know php very well so I don't know where to place it to make it work. I would like to set the text/plain for mails not defined.
this is the code for the wp header :
/**
* filter mail headers
*/
function wp_mail($compact) {
if (isset($_GET['action']) && $_GET['action'] == 'lostpassword') return $compact;
if ($compact['headers'] == '') {
//$compact['headers'] = 'MIME-Version: 1.0' . "\r\n";
$compact['headers'] = 'Content-type: text/html; charset=utf-8' . "\r\n";
$compact['headers'].= "From: " . get_option('blogname') . " < " . get_option('admin_email') . "> \r\n";
}
$compact['message'] = str_ireplace('[site_url]', home_url() , $compact['message']);
$compact['message'] = str_ireplace('[blogname]', get_bloginfo('name') , $compact['message']);
$compact['message'] = str_ireplace('[admin_email]', get_option('admin_email') , $compact['message']);
$compact['message'] = html_entity_decode($compact['message'], ENT_QUOTES, 'UTF-8');
$compact['subject'] = html_entity_decode($compact['subject'], ENT_QUOTES, 'UTF-8');
//$compact['message'] = et_get_mail_header().$compact['message'].et_get_mail_footer();
return $compact;
}
Instead of changing that, change your plain line breaks to html.
$message=nl2br($message); // of course use your var name.
That way you get to keep a standard format for email as well. plain text has nothing so special to need a separate header in this case. This function will convert all line breaks to html version.
Other than new lines most of your plain text will hold its formatting even in html because it has no special tags.
Here is how you will place it
function wp_mail($compact) {
// leave your existing code intact here, don't remove it.
$compact["message"]=nl2br($compact["message"]);
return $compact;
}
1st, I know mysql_ is outdated and I should use mysqli (unfortunatly, I inherited this system and its way too much work to change it over at the present time)
The problem I have is when I execute the code, I am getting random blank emails. This system loops through a list of stores in a database and lists the information in a table for the store managers. It doesnt really matter what information is being presented. Does anyone see anything right off hand that micht cause this problem?
while($store = mysql_fetch_array($result_store)){
#Updates the Report Date for each store in the Loop
$report_date = "UPDATE ActiveStores SET Report_Date = '$Today' WHERE StoreNumber = $store[StoreNumber]";
if (!mysql_query($report_date, $con)){
die('Error: ' . mysql_error());
}
#Selects data from ActiveStores for the current store in the loop
$result2 = mysql_query("SELECT * FROM ActiveStores WHERE StoreNumber = '$store[StoreNumber]' ORDER BY StoreNumber");
#Loops through the currently selected store and Creates an Array of the data
while ($row = mysql_fetch_array($result2)) {
#Sets Store Variable
$Store = $row['StoreNumber'];
echo '<table width="1110"><table width="1102"><tr>';
# To Email Address
#$emailaddress = '******#*****.com';
# Message Subject
$emailsubject= 'Testing Report - Store: ' . $Store;
#Turn on Output buffer for email
ob_start();
#Heading for Report
echo '<h2 class="blktext">Walgreens Weekly Report - ' . $Today . '<br /></h2>';
echo '<h2>Insurance Orders:</h2>';
#Cancelled Orders for the store this week
$result_cash_canceled = mysql_query("SELECT * FROM Orders WHERE StoreNumber = '$Store' AND Cancel = 'checked' AND Order_Type = 'Cash' AND Cancel_Date > '$Sevendaysback'");
$tot_ord_ins_prt = mysql_num_rows($result_cash_canceled);
if ($tot_ord_ins_prt !== 0){
echo '<h4 class="blktext">Cancelled Orders for the store this week</h4><span class="blktext">';
echo '<p><i>Fitter Action: Fitter to contact client to notify of cancelled order, if not initialed by client.</i></p>';
echo "<table border='4' class='rpttbl' frame='hsides' rules='rows' width='1400'>";
echo '<tr><th>Store #</th><th>Order #</th><th>Customer</th><th>Phone #</th><th>Cancel Date</th width="150"><th>Reason for Cancellation</th><th width = "150">Patient Notified<th></tr>';
while($row_cash_canceled = mysql_fetch_array($result_cash_canceled)){
echo "<tr>";
echo "<td align='center'>" . $row_cash_canceled['StoreNumber'] . "</td>";
echo "<td align='center'>" . $row_cash_canceled['Order_ID'] . "</td>";
echo "<td align='center'>" . $row_cash_canceled['Cust_First_Name'] . " " . $row_bo['Cust_Last_Name'] . "</td>";
echo "<td align='center'>" . $row_cash_canceled['Cust_Phone'] . "</td>";
echo "<td align='center'>" . $row_cash_canceled['Cancel_Date'] . "</td>";
echo "<td align='center'> </td>";
echo "<td align='left'>( ) Called: Patient Cancelled notified<br />( ) Called: LVM for Patient</td>";
echo "</tr>";
}
echo "</table>";
echo "Total: " . $tot_ord_ins_prt;
echo'</span>';
}
#Message at bottom of email
echo '<br /><br /><br /><br /><p>Thank you for your prompt attention to this report.</p>';
echo '<p>If this report is blank in all the above sections, this means, at this point, we are not showing any active orders within our system.<br />';
echo 'If you feel this is in error, please contact our Customer Care team at: <strong>(***) ***-8125</strong></p>';
echo '<p>Please update this form with the appropriate action taken by patient, and fax back to: (866) 8**-**** OR email to: ******#*****.com</p>';
echo '<p>Fitter Name: ________________________________________</p>';
echo '<p>Comments: _______________________________________________________________<br />';
echo '_________________________________________________________________________</p>';
echo '<p>The information contained in this email, together with any attachments, is intended only for the use of the individual or entity<br /> to which it is addressed. It may contain information that is confidential and prohibited from disclosure. If you are not the intended <br />';
echo 'recipient, you are hereby notified that any dissemination, or copying, of this message or any attachment is strictly prohibited.</br> If you have received this message<br /> in error, please notify the original sender immediately by phone or by return email, </br>';
echo 'and delete this email, along with any attachments. <br />Receipt by anyone other than the intended recipient is not</br> a waiver of any privileged information. </p>';
}
$body=ob_get_contents();
ob_end_clean();
#$body = "** It is Imperative that you respond to this email. When you receive this please print it out, sign your name and store number and fax the form to ***-***-1161**<br /><br /><br />";
#$body .= "Name: <br /><br />Store #:";
$headers = 'From: Visual Footcare Technologies *****#****.com'.$eol;
$headers .= 'Reply-To: Visual Footcare Technologies *****#*****.com'.$eol;
$headers .= 'Return-Path: Visual Footcare Technologies <mcooper#visualfootcare.com>'.$eol; // these two to set reply address
#$headers .= 'Cc: ******#*****.com'.$eol;
$headers .= "Message-ID:<".$now." TheSystem#".$_SERVER['SERVER_NAME'].">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol; // These two to help avoid spam-filters
$mime_boundary=md5(time());
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/related; boundary=\"".$mime_boundary."\"".$eol;
$msg = "";
$msg .= "Content-Type: multipart/alternative".$eol;
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= $body.$eol.$eol;
$msg .= "--".$mime_boundary."--".$eol.$eol; // finish with two eol's for better security. see Injection.
then a standard mail(......) code to send the email and then ending the loop.
hope that makes sense.
try changing this
if ($tot_ord_ins_prt !== 0)
to
if ($tot_ord_ins_prt !== false)
MIME header blocks must be terminated by a blank line, even when used in a multi-part section. I don't know what you mean by "random", but I suspect that "blank emails" could be the result of your message body being interpreted as invalid MIME headers.
Insert a blank line between the last MIME header and your message body:
$msg .= $eol.$body.$eol.$eol;
If this doesn't help, you should probably show that "standard" mail line you mentioned. Since it's the one that actually sends the email, I'm surprised you didn't include it. You included a whole lot of other code. It would be good to see what you do with the two strings, $headers and $msg.
My page has the following structure:
<?php
session_start();
ob_start();
?>
HTML HEADER
links to stylesheets global.css and mail.css
<?php
function email(){
/* using the stylesheets global.css and mail.css */
$text = '<div class="test">
<p id="par">...
<span id="write" class="text">...</span>
</p>
</div>';
return $text;
}
?>
/* some text and html stuff */
<?php
if(isset(...)){
/* php form validation */
/* after validating I send an email to the user where I call
the function email() which use the stylesheets. */
$mail_text = 'Dear .....';
$mail_text .= email();
$mail_headers = "From: test#test.com\r\n".
'X-Mailer: PHP/' . phpversion().
'MIME-Version: 1.0' . "\r\n".
'Content-type: text/html; charset=utf-8' . "\r\n";
if(mail(..., ..., $mail_text, $mail_headers)){
header('location: newlocation.php');
}
?>
/* HTML FORMS and text and .... */
<?php
ob_end_flush();
?>
The email is sent with the text coming from the email() function, but without formatting cause the CSS are "printed out" only after ob_end_flush() at the bottom of the page.
How could I solve that? There are many classes and styles inside email(), so writing every times <div style="..."> and so on is not a good solution.
You are confused about output buffering. The html/css you print out at the start of the page isn't being captured anywhere, and will NOT be part of $mail_text. Just because you're usign output buffering doesn't make that buffer magically appear in a variable. You'd need at least $mail_text .= ob_get_clean() or something to extract the buffer's contents and put it into your variable.
Im trying to embed an image within my message body but it ends up as an attachment
$mailer->Subject = APP_NAME . " - " . $name . " send you and Ad : " . $row['name'];
$mailer->IsHTML(true);
$mailer->AddEmbeddedImage('../images/namDiams.png', 'logoimg', 'namDimes.png');
//footer
$footer = "Regards<br/><br/>";
$footer .= '<table style="width: 95%">';
$footer .= '<tr>';
$footer .= '<td>';
$footer .= "<strong><span style='font-size: 15px'>NamDimes Team</span></strong><br/>
NamDimes<br/>
Contact Number: " . APP_CONTACT . "<br/>
Email: " . APP_EMAIL . "<br/>
Website: " . APP_WEBSITE . "<br/>";
$footer .= '</td>';
$footer .= '<td style="text-align:right">';
$footer .= '<img src=\"cid:logoimg\" />';
$footer .= '</td>';
$footer .= '</tr>';
$footer .= '</table>';
$mailer->Body = $body . $footer;
$mailer->AltBody="This is text only alternative body.";
$mailer->AddAttachment('../' . $row['image_path'], $row['name'] . ".jpg");
i have set everything else, including the addresses, the mail gets send out, logo image that I want embed in the body gets attached as an attachment, anyone know why?
Don't use $mailer->AddEmbeddedImage, but directly add
<img src="http://.../images/namDiams.png" /> instead.
The mail length should be lighter... And it works.
EDIT
I don't know if it will help you but there is a little mistake here :
$mailer->AddEmbeddedImage('../images/namDiams.png', 'logoimg', 'namDimes.png');
Should be
$mailer->AddEmbeddedImage('../images/namDiams.png', 'logoimg', 'namDiames.png');//the last param the second 'a' was missing...
Another topic here
I can confirm that user2189925's answer does work. However, I use the absolute path since the location of the calling script is more likely to change than the location of the image.
e.g.
<img src="C:\folder\images\namDiames.png" />
Faced the same problem, then I decided to replace the following
<img src="img/example.jpg"
with
<img src= "https://mysitename.com/img/example.jpg">
and it worked.
just give path of your image to the mail body eg: (img src="../images/cat.jpeg) it will definately work