The following program is intended to match incoming email aliases with those in the database, and forward the email to the right address, like Craigslist does.
I am now getting this error:
Error: [1] You must provide at least one recipient email address.
in anon-email.php at line number: sending the email
Here is the code:
$mailboxinfo = imap_mailboxmsginfo($connection);
$messageCount = $mailboxinfo->Nmsgs; //Number of emails in the inbox
for ($MID = 1; $MID <= $messageCount; $MID++)
{
$EmailHeaders = imap_headerinfo($connection, $MID); //Save all of the header information
$Body = imap_qprint(imap_fetchbody($connection, $MID, 1)); //The body of the email to be forwarded
$MessageSentToAllArray = $EmailHeaders->to; //Grab the “TO” header
$MessageSentToAllObject = $MessageSentToAllArray[0];
$MessageSentToMailbox = $MessageSentToAllObject->mailbox ."#". $MessageSentToAllObject->host; //Everything before and after the “#” of the recipient
$MessageSentFromAllArray = $EmailHeaders->from; //Grab the “FROM” header
$MessageSentFromAllObject = $MessageSentFromAllArray[0];
$MessageSentFromMailbox = $MessageSentFromAllObject->mailbox ."#". $MessageSentFromAllObject->host; //Everything before and after the “#” of the sender
$MessageSentFromName = $MessageSentFromAllObject->personal; //The name of the person who sent the email
$toArray = searchRecipient($MessageSentToMailbox); //Find the correct person to send the email to
if($toArray == FALSE) //If the alias they entered doesn’t exist…
{
$bounceback = 'Sorry the email in your message does not appear to be correct';
/* Send a bounceback email */
$mail = new PHPMailer(); // defaults to using php “mail()”
$mail -> ContentType = 'text/plain'; //Plain email
$mail -> IsHTML(false); //No HTML
$the_body = wordWrap($bounceback, 70); //Word wrap to 70 characters for formatting
$from_email_address = 'name#domain.com';
$mail->AddReplyTo($from_email_address, "domain.Com");
$mail->SetFrom($from_email_address, "domain.Com");
$address = $MessageSentFromMailbox; //Who we’re sending the email to
$mail->AddAddress($address, $MessageSentFromName);
$mail->Subject = 'Request'; //Subject of the email
$mail->Body = $the_body;
if(!$mail->Send()) //If the mail fails, send to customError
{
customError(1, $mail->ErrorInfo, "anon-email.php", "sending the email");
}
}
else //If the candidate address exists, forward on the email
{
$mail = new PHPMailer(); // defaults to using php “mail()”
$mail -> ContentType = 'text/plain'; //Plain E-mail
$mail -> IsHTML(FALSE); //No HTML
$the_body = wordwrap($Body, 70); //Wordwrap for proper email formatting
$from_email_address = "$MessageSentFromMailbox";
$mail->AddReplyTo($from_email_address);
$mail->SetFrom($from_email_address);
$address = $toArray[1]; //Who we’re sending the email to
$mail->AddAddress($address, $toArray[0]); //The name of the person we’re sending to
$mail->Subject = $EmailHeaders->subject; //Subject of the email
$mail->Body = ($the_body);
if(!$mail->Send()) //If mail fails, go to the custom error
{
customError(1, $mail->ErrorInfo, "anon-email.php", "sending the email");
}
}
/* Mark the email for deletion after processing */
imap_delete($connection, $MID);
}
imap_expunge($connection); // Expunge processes all of the emails marked to be deleted
imap_close($connection);
function searchRecipient() // function to search the database for the real email
{
global $MessageSentToMailbox; // bring in the alias email
$email_addr = mysql_query("SELECT email FROM tbl WHERE source='$MessageSentToMailbox'"); // temp store of the real email
$row = mysql_fetch_array($email_addr); //making temp store of data for use in program
if(empty($row['email']))
{
return FALSE;
}
else /* Else, return find the person's name and return both in an array */
{
$results = mysql_query("SELECT * FROM tbl WHERE email = '$email_addr'"); // temp store of both queries from this function
$row = mysql_fetch_array($results, $email_addr); //making temp store of data for use in program
$name = $row['author']; // taking the author data and naming its variable
return array($name, $email_addr); // this is the name and the real email address to be used in function call
}
}
function customError($errno, $errstr, $file, $line)
{
error_log("Error: [$errno] $errstr in $file at line number: $line",1, "name#domain.com","From: name#domain.com.com");
die();
}
Here is the first thing I would try:
It would appear that your function searchRecipient isn't being passed a parameter. Rather than use the global keyword, I would define it in your function call. Also, mysql_fetch_array does not pass back an associative array, which is what you are using in your next step. I would change that to mysql_fetch_assoc (it's the same thing essentially). There are also a few other minor syntax corrections in this function. Here are my proposed changes to that function. I think this should fix your problem. Or at least get you moving forward.
function searchRecipient($MessageSentToMailbox) // function to search the database for the real email
{
$email_addr = mysql_query("SELECT email FROM tbl WHERE source='$MessageSentToMailbox'"); // temp store of the real email
$row = mysql_fetch_assoc($email_addr); //making temp store of data for use in program
if(empty($row['email']))
{
return FALSE;
}
else /* Else, return find the person's name and return both in an array */
{
$email_addr = $row['email'];
$results = mysql_query("SELECT * FROM tbl WHERE email = '$email_addr'"); // temp store of both queries from this function
$row = mysql_fetch_assoc($results); //making temp store of data for use in program
$name = $row['author']; // taking the author data and naming its variable
return array($name, $email_addr); // this is the name and the real email address to be used in function call
}
}
You could also combine this into one query and make it a little easier. Here is that solution.
function searchRecipient($MessageSentToMailbox)
{
$results = mysql_query("SELECT email, author FROM tbl WHERE source='$MessageSentToMailbox'");
$row = mysql_fetch_assoc($results);
if(empty($row['email']) || empty($row['author'])) return false;
return array($row['email'], $row['author']);
}
Related
I have a google apps scripts app that gets Gmail message attachments, posts it to DB using JDBC. then on the server, a PHP script gets the data and puts in into a file and attaches it to an email.
the problem is that the files are corrupt when email arrives
here is the google apps script function that gets the attachment content
function getMessageAttachmentsArray(msg){
var GmailAttachments = msg.GmailMessage.getAttachments();
var validAttachments = [];
var attachmentNames = [];
if(GmailAttachments)
{
for(i in GmailAttachments)
{
var gName = GmailAttachments[i].getName();
attachmentNames.push(gName);
var mimeType = GmailAttachments[i].getContentType();
var size = GmailAttachments[i].getSize();
var content = Utilities.base64Encode(GmailAttachments[i].getDataAsString(), Utilities.Charset.UTF_8);
var push = {"content":content,"mimeType":mimeType,"fileName":gName,"size":size,"id":""};
validAttachments.push(push);
}
}
return [validAttachments, attachmentNames];
}
here is the PHP code that generated the email from the file data:
require_once 'smtpmail/classes/class.phpmailer.php';
$mail = new PHPmailer(true);
$email = $argv[1];
$messageid = $argv[2];
$fax_number = $argv[3];
$attachments = array();
//get the attachments for this email
$Sql = "select * from user_attachments where email = '$email' and messageid like '$messageid%'";
$res = mysql_query($Sql);
while($row = mysql_fetch_array($res)){
$return['filename'] = $row['name'];
$return['mime'] = $row['mime_type'];
$content = base64_decode(str_pad(strtr($row['raw_data'], '-_', '+/'), strlen($row['raw_data']) % 4, '=', STR_PAD_RIGHT));
$temp_file = tempnam(sys_get_temp_dir(), 'Fax');
file_put_contents($temp_file, $content);
$return['file'] = $temp_file;
array_push($attachments, $return);
}
try{
$mail->IsSMTP();
$mail->SMTPDebug = 1;
$mail->SetFrom("example#example.com", "example email");
$mail->Subject = '';
$mail->Body = ' '; //put in a blank body to avoid smtp error
$mail->AddAddress($email);
foreach($attachments as $file){
$mail->AddAttachment($file['file'], $file['filename'], 'base64' ,mime_content_type($file['file']));
}
if($mail->send()){
echo "email to $email sent successfully\n";
}else{
echo "error sending email to $email\n";
}
}catch(phpmailerException $e){
echo $e->errorMessage();
}catch(Exception $e){
echo $e->getMessage();
}
When the message is received it shows the attachments but when downloaded I can not open them and there is a message that the file is corrupt or the file extension does not match the file format
what am I doing wrong?
Thanks in advance.
EDIT:
I tried emailing the attachment without posting to the DB, by posting to the server with UrlFetchApp() and the results are the same. clearly, I am doing something wrong with Base64_encode / decode...
maybe the google apps scripts :
Utilities.base64Encode(GmailAttachments[i].getDataAsString(), Utilities.Charset.UTF_8);
creates a different base64 format than PHP base64_decode expects?
p.s.
I tried also with and without 'str_pad' and I still got the same results.
I changed:
Utilities.base64Encode(GmailAttachments[i].getDataAsString(), Utilities.Charset.UTF_8);
to:
Utilities.base64Encode(GmailAttachments[i].getBytes());
and it works
This is my code to send emails in SugarCRM CE 6.5.x version,
<?php
if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid EntryPoint');
require_once('include/SugarPHPMailer.php');
$msg = new SugarPHPMailer();
$emailObj = new Email();
$defaults = $emailObj->getSystemDefaultEmail();
//Setup template
require_once('XTemplate/xtpl.php');
$xtpl = new XTemplate('custom/modules/Users/ChangePassword.html');
//assign recipients email and name
$rcpt_email = 'sohan.tirpude#mphasis.com';
$rcpt_name = 'Sohan';
//Set RECIPIENT's address
$email = $msg->AddAddress($rcpt_email, $rcpt_name);
//Send msg to users
$template_name = 'User';
//Assign values to variables in template
$xtpl->assign('EMAIL_NAME', $rcpt_name);
$xtpl->parse();
//$body = "Hello Sohan, It's been 80 days that you haven't changed your password. Please take some time out to change password first before it expires.";
$msg->From = $defaults['email'];
$msg->FromName = $defaults['name'];
$msg->Body = from_html(trim($xtpl->text($template_name)));
//$msg->Body = $body;
$msg->Subject = 'Change Password Request';
$msg->prepForOutbound();
$msg->AddAddress($email);
$msg->setMailerForSystem();
//Send the message, log if error occurs
if (!$msg->Send()){
$GLOBALS['log']->fatal('Error sending e-mail: ' . $msg->ErrorInfo);
}
?>
Now this script send blanks emails, and when I hardcoded body part then it is takes those message written in body, and sends an email. So, please help me here.
I am sending emails using PHPmailer. As of now, I am successful in sending email to one address. Now, I want to send multiple emails in just one click.
PROBLEM: I have tried to use some loops below to send multiple email but I get wrong outpout. Yes, it sends email but to only one address, and the email address is getting all of the emails that are supposed to be emailed to other emails.
For example, when I send 17 emails, those 17 emails are sent to only one address. The emails should be sent according to the addresses in the database, with corresponding unique attachments. Example: abc#gmail.com should have abc.pdf attached, and 123#gmail.com should have 123.pdf attached.
I think it's in the loop. Please help me figure it out. Thanks.
require_once('phpmailer/class.phpmailer.php');
include("phpmailer/class.smtp.php");
$mail = new PHPMailer();
$body = file_get_contents('phpmailer/body.html');
$body = preg_replace('/\/b]/','',$body);
$file ='phpmailer/mailpass.txt';
if($handle = fopen($file,"r")){
$contentpass = fread($handle,'15');
fclose($handle);
}
$mail->IsSMTP();
$mail->Host = "smtp.gmail.com";
$mail->SMTPDebug = 1;
$mail->SMTPAuth = true;
$mail->SMTPSecure = "tls";
$mail->Host = "smtp.gmail.com";
$mail->Port = 587;
$mail->Username = "email#gmail.com";
$mail->Password = $contentpass;
$mail->SetFrom("email#gmail.com", "Subject");
$mail->AddReplyTo("email#gmail.com","Subject");
$mail->Subject = "Subjects";
$mail->AltBody = "Subject";
$mail->MsgHTML($body);
$file='current_schoolyear.txt';
if($handle = fopen($file,"r"))
{
$content = fread($handle,'9');
fclose($handle);
}
$input = addslashes($_POST['depchair']);
$email = "select email_address from sa_student where schoolyear = '$input'";
if ($p_address=mysql_query($email))
{
while($row = mysql_fetch_assoc($p_address))
{
$mail->AddAddress($row['email_address']);
$input = addslashes($_POST['depchair']);
$control = "select control_no from sa_student where schoolyear = '$input'";
if($ctrl=mysql_query($control)){
$ctrl_no = mysql_result($ctrl, 0);
$mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
}
else
{
echo "No attached document.";
}
if(!$mail->Send()) {
$message = "<div class=\"nNote nFailure\" >
<p>Error sending email. " . $mail->ErrorInfo ."</p>
</div>";
} else {
$message = "<div class=\"nNote nSuccess\" >
<p> Email have been sent to the examinees in ".$input_depchair. "! </p>
</div>";
}
}
}
else
{
echo (mysql_error ());
}
UPDATED CODE: After running the code below, I was able to send an email and with the correct attachment. However, there was only ONE email sent (the last email address in the database), and the rest of the emails were not sent.
$input = addslashes($_POST['depchair']);
$email = "select email_address, control_no from sa_student where schoolyear = '$input'";
if ($p_address=mysql_query($email))
{
while($row = mysql_fetch_assoc($p_address))
{
$cloned = clone $mail;
$cloned->AddAddress($row['email_address']);
$cloned->AddAttachment("fpdf/pdf_reports/document/".$row['control_no'].".pdf");
if(!$cloned->Send()) {
$message = "<div class=\"nNote nFailure\" >
<p>Error sending email. " . $mail->ErrorInfo ."</p>
</div>";
} else {
$message = "<div class=\"nNote nSuccess\" >
<p> Email have been sent to the examinees in ".$input_depchair. "! </p>
</div>";
}
unset( $cloned );
}
}
else
{
echo (mysql_error ());
}
After you send an email $mail->Send(), execute this:
$mail->ClearAllRecipients();
in your while loop.
So your basic while loop structure looks like this:
while($row = mysql_fetch_assoc($p_address)){
$mail->AddAddress($row['email_address']);
$mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
$mail->send();
$mail->ClearAllRecipients();
$mail->ClearAttachments(); //Remove all attachements
}
Within your loop, create a clone of the $mail object - before you add the recipient and attachment - then use the clone to send the email. The next loop iteration will create a new clone free of the previous address and attachment:
while($row = mysql_fetch_assoc($p_address)) {
$cloned = clone $mail;
$cloned->AddAddress($row['email_address']);
// add attchment to $cloned, etc.
if ( $cloned->send() ) { /* etc */ }
unset( $cloned );
}
This will "clear" your per-iteration changes (like address, attachment, etc) without you having to reenter config properties (like, from, host, etc.)
Addendum:
Your attachments will likely be all the same because you're not fetching new results for these lines (within your loop):
$input=addslashes($_POST['depchair']);
$control = "select control_no from sa_student where schoolyear = '$input'";
if ($ctrl=mysql_query($control)) {
$ctrl_no = mysql_result($ctrl, 0);
$mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
}
$ctrl_no will always return the same result because (I'm assuming) $_POST['depchair'] does not change - thus $input, $control, $ctrl, and $ctrl_no all remain (effectively) the same for each loop. You need to find whatever it is your actually intend to be the $ctrl_no for each loop - right now you're using the same one over and over.
The following query could probably help:
// replace
// $email = "select email_address from sa_student where schoolyear = '$input'";
// with:
$students_query = "select email_address, control_no from sa_student where schoolyear = '$input'";
// then
// if ($p_address=mysql_query($email)) {
// while($row = mysql_fetch_assoc($p_address)) {
// becomes
if ( $students=mysql_query($students_query) ) {
while ( $row = mysql_fetch_assoc( $students ) ) {
// so that finally, etc
$cloned->AddAddress($row['email_address']);
$ctrl_no = $row['control_no'];
This pulls both the student email address and their control_no in the same query, making sure they stay associated with each other through the loop. You can then get rid of the second mid-loop query, since all the results you need were pulled in the first out-of-loop query. The above isn't all the code you need to change, just the critical parts.
A little background,
I'm creating a simple function that emails all users whenever the admin of a blog creates a new announcement. I want to gather all emails using an sql query and inputting them all inside the message body or perhaps looping sending the emails one at a time (though that may seem like it would take longer).
So far this is my code:
public function emailAll()
{
$this->set_mail_settings();
$message = new YiiMailMessage;
$request = Yii::app()->db->createCommand("
SELECT email FROM persons WHERE party_id
")->queryRow();
$message->subject = 'Star Cruises - Login Information';
$message->addTo('sendTo#someone.com');
$message->from = Yii::app()->params['adminEmail'];
Yii::app()->mail->send($message);
exit();
}
private function set_mail_settings()
{
$sysParam = SystemParameters::model()->getSystemParameters(
array("smtp_host", "smtp_port", 'smtp_user','smtp_password')
);
Yii::app()->mail->transportOptions['username'] = $sysParam['smtp_user'];
Yii::app()->mail->transportOptions['password'] = $sysParam['smtp_password'];
Yii::app()->mail->transportOptions['host'] = $sysParam['smtp_host'];
Yii::app()->mail->transportOptions['port'] = $sysParam['smtp_port'];
}
The emailAll() function is called whenever an email is used.
My problem is the $request. I don't know how I would gather all the emails and putting them into the $message->addTo();
UPDATE: I was doing it fine until I reached this point:
public function emailAll()
{
$this->set_mail_settings();
$message = new YiiMailMessage;
$emails = Yii::app()->db->createCommand("SELECT group_concat(email) as em FROM persons")->queryRow();
$email_ids = explode(",",$emails["em"]);
$message->setBcc($email_ids);
$message->setBody('Sample');
$message->subject = 'New Announcement!';
//$message->addTo('blah#blah.com');
$message->from = Yii::app()->params['adminEmail'];
Yii::app()->mail->send($message);
}
private function set_mail_settings()
{
$sysParam = SystemParameters::model()->getSystemParameters(
array("smtp_host", "smtp_port", 'smtp_user','smtp_password')
);
Yii::app()->mail->transportOptions['username'] = $sysParam['smtp_user'];
Yii::app()->mail->transportOptions['password'] = $sysParam['smtp_password'];
Yii::app()->mail->transportOptions['host'] = $sysParam['smtp_host'];
Yii::app()->mail->transportOptions['port'] = $sysParam['smtp_port'];
}
Then I got an error on this line from YiiMail.php:
189 $msg = 'Sending email to '.implode(', ', array_keys($message->to))."\n".
And it stated that : array_keys() expects parameter 1 to be array, null given.
I understand what it wants, but I don't understand WHY this error occurred?
You can get all email ids with use of below query and use BCC instead of To for security reason.
$emails = Yii::app()->db->createCommand("SELECT group_concat(email) as em FROM persons WHERE party_id = $party_id")->queryRow();
$email_ids = explode(",",$emails["em"]);
$message->setBcc($email_ids); // use bcc to hide email ids from other users
$message->addTo("noreply#yourdomain.com"); //as To is required, set some dummy id or your own id.
I think I am doing everything right but I keep getting a t_string error in the code. I will show what line. If anyone can figure this out, I would be very greatful. I did do research on quotes, and am thinking maybe the data in the database has something to do with the error since it includes the # symbol and period.
The error is at line 76 which is if(empty($row['email']))
The entire code is
ini_set("include_path", ".:/public_html/phpmailer"); //Used for simplicity
include("mysql_connect.php"); //The database name, login, etc..
set_error_handler("customError"); //I created a custom error
$login = 'username#domain.com';
$password = 'password';
$server = '{imap.gmail.com:993/ssl/novalidate-cert}';
$connection = imap_open($server, $login, $password);
$mailboxinfo = imap_mailboxmsginfo($connection);
$messageCount = $mailboxinfo->Nmsgs; //Number of emails in the inbox
for ($MID = 1; $MID <= $messageCount; $MID++)
{
$EmailHeaders = imap_headerinfo($connection, $MID); //Save all of the header information
$Body = imap_qprint(imap_fetchbody($connection, $MID, 1)); //The body of the email to be forwarded
$MessageSentToAllArray = $EmailHeaders->to; //Grab the “TO” header
$MessageSentToAllObject = $MessageSentToAllArray[0];
$MessageSentToMailbox = $MessageSentToAllObject->mailbox; //Everything before the “#” of the recipient
$MessageSentToHost = $MessageSentToAllObject->host; //Everything after the “#” of the recipient
$MessageSentFromAllArray = $EmailHeaders->from; //Grab the “FROM” header
$MessageSentFromAllObject = $MessageSentFromAllArray[0];
$MessageSentFromMailbox = $MessageSentFromAllObject->mailbox; //Everything before the “#” of the sender
$MessageSentFromHost = $MessageSentFromAllObject->host; //Everything after the “#” of the sender
$MessageSentFromName = $MessageSentFromAllObject->personal; //The name of the person who sent the email
$toArray = searchRecipient($MessageSentToMailbox); //Find the correct person to send the email to
if($toArray == FALSE) //If the alias they entered doesn’t exist…
{
$bounceback = 'Sorry the email in your message does not appear to be correct';
/* Send a bounceback email */
$mail = new PHPMailer(); // defaults to using php “mail()”
$mail -> ContentType = ‘text/plain’; //Plain email
$mail -> IsHTML(false); //No HTML
$the_body = wordWrap($bounceback, 70); //Word wrap to 70 characters for formatting
$from_email_address = 'Support#domain.com';
$mail->AddReplyTo($from_email_address, "Domain.Com");
$mail->SetFrom($from_email_address, "Domain.Com");
$address = "$MessageSentFromMailbox#$MessageSentFromHost"; //Who we’re sending the email to
$mail->AddAddress($address, $MessageSentFromName);
$mail->Subject = 'WAHM Link Request'; //Subject of the email
$mail->Body = $the_body;
if(!$mail->Send()) //If the mail fails, send to customError
{
customError(1, $mail->ErrorInfo, "anon-email.php", "sending the email");
}
}
else //If the candidate address exists, forward on the email
{
$mail = new PHPMailer(); // defaults to using php “mail()”
$mail -> ContentType = ‘text/plain’; //Plain E-mail
$mail -> IsHTML(FALSE); //No HTML
$the_body = wordwrap($Body, 70); //Wordwrap for proper email formatting
$from_email_address = "$MessageSentFromMailbox#$MessageSentFromHost";
$mail->AddReplyTo($from_email_address, $MessageSentFromName);
$mail->SetFrom($from_email_address, $MessageSentFromName);
$address = $toArray[1]; //Who we’re sending the email to
$mail->AddAddress($address, $toArray[0]); //The name of the person we’re sending to
$mail->Subject = $EmailHeaders->subject; //Subject of the email
$mail->Body = ($the_body);
if(!$mail->Send()) //If mail fails, go to the custom error
{
customError(1, $mail->ErrorInfo, "anon-email.php", "sending the email");
}
}
/* Mark the email for deletion after processing */
imap_delete($connection, $MID);
}
imap_expunge($connection); // Expunge processes all of the emails marked to be deleted
imap_close($connection);
function searchRecipient() // function to search the database for the real email
{
global $MessageSentToMailbox; // bring in the alias email
$email_addr = mysql_query("SELECT email FROM tbl WHERE source='$MessageSentToMailbox'"); // temp store of the real email
$row = mysql_fetch_assoc($email_addr); //making temp store of data for use in program
if(empty($row['email']))
{
return FALSE;
}
else /* Else, return find the person's name and return both in an array */
{
$query = "SELECT * FROM tbl WHERE email = '$email_addr'"; // pulling in the row where the emails match
$results = mysql_query($query, $email_addr); // temp store of both queries from this function
$row = mysql_fetch_assoc($results); //making temp store of data for use in program
$name = $row['author']; // taking the author data and naming its variable
return array($name, $email_addr); // this is the name and the real email address to be used in function call
}
}
function customError($errno, $errstr, $file, $line)
{
error_log("Error: [$errno] $errstr in $file at line number: $line",1, "name#domain.com","From: name#domain.com");
die();
}
It has taken me quite a long time to figure this out, not least because it seems that stackoverflow has corrected the problem for you. There are a number of 0xA0 characters littered randomly through your source code (my editor counts 33) in the middle of white-space blocks. The PHP parser is obviously not liking these very much and throwing an error.
I have just done a find/replace in my editor to convert them all to spaces (0x20) and it now parses.
It seems that I spoiled it for everybody with my first edit of your question, as SO corrected the problem then and I now can't repeat it by copying the code as it is currently displayed, despite rolling back to the original version - sorry everyone.
If you copy and paste the above code back into your editor, the problem disappeared. StackOverflow has actively fixed the problem.
I'm not sure if this is the error, but you have fancy single quotes here:
$mail -> ContentType = ‘text/plain’; //Plain email
It actually appears since twice in your code.