so I have a table in which I have email templates, and these email templates can be later fetched for sending emails.
The structure is :-
for_status subject message
int text text
An example entry is :-
for_status = 1,
subject = Transaction Status Changed,
message = Hi $user->firstname, this is a test message.
Ok, so the problem is, when I send the email with the current message and subject, it displays in the email Hi $user->firstname, this is a test message
Instead of showing, Hi thefirstname here, this is a test message.
I'm fetching user details successfully on the same page in the $user variable.
What's going wrong here?
When you say "table of email templates", is the actual text of the email template in some sort of database?
If this is the case and you have $user->firstname in the database, I'm pretty sure its going to spit that out directly.
You need something whats called placeholders. You need to decide what to have as a place holder, I personally use the following:
{%first_name%}, this is a test message.
Then in your PHP code you just have an array of placeholders & values like this:
$arr = array(
'{%first_name%}' => $user->firstname,
);
//and now replace the body
$body = str_replace(array_keys($arr), $arr, $body);
There is a better way of doing this by using already written libraries or using Regular Expression to correctly parse, but I will leave that up to you to figure it out.
PHP will only perform the substitution for you on strings you have coded into your own PHP files, not those that have come from a database or any other source. If it did, that would be a massive security risk!
You will need to perform substitution on your template yourself.
// $message is: Hi %{userFirstName}, this is a test message.
$message = str_replace('%{userFirstName}', $user->firstname, $message);
So I am sending an email in codeigniter where the message is coming from the database.
What I am wanting to do, is put the posted variables into the html formatted email in the database.
For sending the email I have the following in my controller:
$this->load->library('email');
$this->load->model('cms');
$message = $this->cms->Order_Email();
$this->email->from('info#candykingdom.org', 'Candy Kingdom');
$this->email->to($this->input->post('billingEmail'));
$this->email->subject('Order Confirmation');
$this->email->message($message->content);
$this->email->send();
Now a portion of my email that comes from the database is:
<td>
<p>Hi</p>
<p>Sometimes all you want is to send a simple HTML email with a basic design.</p>
<h1>Really simple HTML email template</h1>
...
I am trying to make the <p>Hi</p> line turn into: <p>Hi John,</p> I have tried changing that line to the following:
<p>Hi <?php echo $this->input->post('billingFname'); ?>,</p>
as well as:
<p>Hi '.$this->input->post('billingFName").',</p>
But in the completed and sent email it displays just like the above in the email. Without replacing the php with the actual variable.
So what I am asking is, what do I type in the stored email message to make the php code replace the php with the actual variable?
For examples, let's use John as $this->input->post('billingFName');
Just a thought
Maybe this would be better achieved with a templating library? like this:
https://github.com/philsturgeon/codeigniter-template
A common approach I've seen is using vars you substitute via str_replace:
The html of your email has some vars you know to substitute, as #USERNAME#. In your db you store
<td>
<p>Hi #USERNAME#</p>
<p>Sometimes all you want is to send a simple HTML email with a basic design.</p>
<h1>Really simple HTML email template</h1>
Then, you change #USERNAME# via a str_replace when you get it from the DB:
$message->content = str_replace( '#USERNAME#', $var_with_username, $message->content );
You may even use arrays in your str_replace, to subsitute as many vars as you want, check http://www.php.net/manual/en/function.str-replace.php#refsect1-function.str-replace-examples for more info.
I want to have the "From" part of a php generated email be just from the company name. Apparently that makes spam filters sad. So, my code is...
$mail->FromName = 'Company Name <some_email#domain.com>';
My issue is that gmail and aol keep returning these emails and the from part looks like this...
From: "Company Name <some_email#domain.com>" <>
Any thoughts about the "<>" at the end?
The <>at the end of "Company Name <some_email#domain.com>" <> indicates that the address is interpreted as containing only the associated name part,with no real email address.
Try generating the From address as 'Company Name' <some_email#domain.com> or as some_email#domain.com (Company Name)
Edit:
Another possible reason for this problem is that your mailer is using separate fields for the name part and the address part of the From header. If so:
$mail->From = "some_email#domain.com";
$mail->FromName = "Company Name";
should solve the problem.
In any decent mail program (MUA) you should be able to see the raw content and headers of emails you've sent and which have been sent to you. If you have a look at some of the latter you'll see that the correct way to do it is:
$from='"Human readable version of address" <mailbox#domain.com>';
BTW: The title of your post says you are using the mail() function but your example code does not call an functions. Your code implies that you are some sort of class to implement your email, but you've provided no details of what that class is - and AFAIK there is no standard class bundled in PHP. Therefore we've no idea what your code is actually doing with the address you feed to it - if it's an off the shelf package it should have come with documentation.
I have a strange problem. I read text from a text file replace all values using str_replace with the relevant values and then send the email via PHPMailer in plain text to the recipient.
Now my problem is whenever the recipient gets my mails he sees characters like '0D'
1. DOMAIN NAME and ACTION=0D
=0D
Give the name of the subdomain. This is the name that will be=0D
used in tables and lists associating the domain with the name=0D
server and IP addresses. The .co.za domain names that are=0D
delegated by UniForum S.A. are at the third level, for example:=0D
thisnetwork.co.za. Domain names in the CO.ZA zone are limited=0D
to 30 characters.=0D
The Action field specifies whether this is a 'N'ew application, an=0D
'U'pdate or a 'D'eletion.=0D
This is my PHPMailer code where I try and set the encoding as well and this does not work either
$mailer->CharSet = 'UTF-8';
This looks like "quoted-printable" content-transfer-encoding.
You can set the transfer-encoding as follows:
$mailer->Encoding = "8bit";
There should be a list of supported encodings in the manual of PHPMailer.
I am sending email to some users and wants to know who had read it, means if some one had read that email then a log file will maintain which contain the email address of that user with date/time/IP.
For this I send a javascript function with the email (html template) which just alert the email address of the user when ever a user opens that email like:
for($n=0; $n<sizeof($checkBox); $n++){
$mail = new PHPMailer();
$mail->IsHTML(true);
$mail->Subject = $subject;
$function = "<script language='javascript'>function stats(emailId){alert(emailId);}</script>";
$bodyOpen = "<body onload='stats(".$checkBox[$n].");'>";
$msg_body .= $body .= "<table><tr><td>Hello Everyone</td></tr></table></body>";
$mail->Body = $function.$bodyOpen.$msg_body;
$mail->WordWrap = 50;
$mail->FromName = 'Muhammad Sajid';
$mail->IsMAIL();
$mail->From = 'webspot49#gmail.com';
$mail->AddAddress($checkBox[$n]);
$sent = $mail->Send();
}
the html template works fine and shows an alert popup on page load but it does not works if I use to send this html template.
And I only want to solve this issue using PHP5.x.x / javascript, no other software or third party tool.
Any help..?
Add Header to email:
Disposition-Notification-To: you#yourdomain.com
As mentioned above it's not reliable and it's better to do something like this:
<img src="http://yourdomain.com/emailreceipt.php?receipt=<email of receiver>" />
And log it in a database, although again this is restricted by the email client's ability to show images and sometimes it may even put the mail into junk because it doesn't detect an image... a workaround that would be to actually outputting an image (say your logo) at the end of that script.
Edit:
A quick lookup at the phpmailer class gave me the following:
$mail->ConfirmReadingTo = 'yourown#emailaddress.com';
but it's the same as the Disposition-Notification-To method above.
Send a beacon image in the emails like so
<img src='http://www.yourserver.com/beacon.php?email_id=$email_id&email_address=$user_address' style='width:1px;height:1px'>
And then use the beacon.php file to log the data. You will then want to output a 1X1 image with appropriate headers.
Important note Many popular email clients (such as Gmail) now block external images, so this is by far, not fool proof.
This is next to impossible to do 100% effectively.
You could control where the content is stored e.g. http://www.example.com/34hg038g85gb8no84g5 and provide a link in the email to that content, you can then detect when that URL was viewed.
Use a method used by MailChimp and other newsletter campaigns, put an invisible image in your email, this image should reside on a server you control, you can then detect when that image is hit when the user opens the email.
It is not possible by definition.
Mailreaders are not browsers, they don't support javascript. They don't even support proper CSS so dont expect too much. So I honestly don't see any way you can do what you're trying to do
I just add a single line:
$dt = date('F \ jS\,\ Y h:i:s a');
for($n=0; $n<sizeof($checkBox); $n++){
$mail = new PHPMailer();
$mail->IsHTML(true);
$mail->Subject = $subject;
$src = "<img src='msajid.isgreat.org/readmail.php?dt=".$dt."&eid=".$checkBox[$n]."' />";
$msg_body .= $src .= "<table><tr><td>Hello Everyone</td></tr></table>";
$mail->Body = $function.$bodyOpen.$msg_body;
$mail->WordWrap = 50;
$mail->FromName = 'Muhammad Sajid';
$mail->IsMAIL();
$mail->From = 'webspot49#gmail.com';
$mail->AddAddress($checkBox[$n]);
$sent = $mail->Send();
}
and in readmail.php file simply insert date/time and userid with a check (if not exist with attached date/time) & fixed it only for Gmail, hotmail but not for Yahoo...
Can some one help to also fix for Yahoo....?
Haaaa.
silly mistake just use complete url like:
$src = "<img src='http://www.msajid.isgreat.org/readmail.php?dt=".$dt."&eid=".$checkBox[$n]."' />";
and it will also work for Yahoo....
While I didn't discover exactly why the simple PHP file wasn't generating the included image (as mentioned in my post 6 hours ago), here is another very complicated way of generating an image file that wasn't rejected by my own PHP 5.4.30 web server.
Here is the code that I put into an index.php file within an /email_image/ subdirectory:
<?php
$message_id = $_REQUEST['message_id'];
$graphic_http = 'http://mywebsite.com/email_image/message_open_tracking.gif';
$filesize = filesize( 'message_open_tracking.gif' );
header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header( 'Cache-Control: private',false );
header( 'Content-Disposition: attachment; filename="a_unique_image_name_' . $message_id . '.gif"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Content-Length: '.$filesize );
readfile( $graphic_http );
exit;
?>
For the image filename, I used the following:
http://mywebsite.com/email_image/?message_id=12345
Within the email_image folder is also a blank 1x1 gif image named "message_open_tracking.gif".
The index.php file can also be revised to make use of the message_id in order to mark that message as having been read. If other variables are included within the querystring, such as the recipient's email address, those values can also be used within that index.php file.
Many thanks to Bennett Stone for the following article:
http://www.phpdevtips.com/2013/06/email-open-tracking-with-php-and-mysql/
I know this is an old thread but I just had to respond... for those of us who must consider this, I suggest we put ourselves in the place of the people who have to write the anti-spam software to thwart our efforts. Detecting a ? or a .php (or other script/binary extension) inside an image tag would be trivial for me as a postulated 'spam assassin' programmer... just as identifying a 1x1 image would be...
I spent 2.5 yrs as National Digital Director for a presidential campaign that raised $20 million before we even had a candidate -- here's what I had developed for that campaign:
At send time (or before), generate a hash on the TO: email address and store that in the db next to the email address.
Use the hash we just generated to modify a small, but plainly visible logo in the email and make a copy of the logo with the hash in the logo file name eg: emxlogox.0FAE7E6.png - refer to that unique image in the email for the logo - make a copy of the logo with the hash name in the filename. This particular logo series only ever appears in targeted mass emails. Warn crew members not to copy it for other purposes (or to rename it extensively if they do). The first part of the filename needs to be something that will not appear in the logs in other contexts to speed your parsing and the code you have to craft to sort out false hits.
Parse the logs for occurrences of the logo being requested, and extract the hash from the filename to match back against the one email address. And your parsing program can also get the IP address and the time delta it took for them to get and open the email so you can identify highly responsive recipients and the ones who took a week to open the email. Do a geo-lookup on the IP and see if you get a match with the location you already have, and/or start recording their travel patterns (or proxy use patterns). Geo deltas could also be identifying email forwards.
Same hash, of course, is used to record clicks, and also the first and second opt-ins. (Now you have a 'dossier' of multiple opt-ins for responses to those abuse reports and you're protecting your email reputation, too).
This method can also be used to identify who forwards emails to their friends and you ask those 'good forwarders' to join some kind of elite digital volunteer crew, offer them discounts or rewards or whatever is appropriate for your business/project... in essence, that same hash also becomes a referrer code.
You can also ask them to right click on the logo in the email and save it without changing the filename, then post it to 'wherever' (the image should have a memorable, readable, meaningful shortlink on it, not an unreadable bit.ly shortlink). You can then use the Google Search API to identify who helped you out in that fashion and thank them or give them rewards... For this purpose, it helps if the first part of your logo filename is really unique like unsportingly.unique.emxlogox.0FAE7E6.png so you don't have to do millions of Google Search API queries - just search on the unique first part of the filename - and look at the hashes after you get the hits.
You store the links where their copy of the logo appeared in your db to add to your dossier of where on the net they are active and have helped you.
Yes, it's slow and burdensome, but in these days when we say we want to develop a 'relationship' with our email list, it's what you have to do to give individual treatment; identify and reward your friends. And yes, you end up with millions of those hashed filename images in one directory, but storage is cheap and it's worth it to really have that relationship with your peeps.
You can't add javascript to your emails.
The only solution would be to have only a link in the email, and the message on the server, Then you'd able to know that the message itself has been viewed.
Embedding a user specific image (1px blank might be good) in the email and record whether it is hot or not is a fair solution. But the problem Gmail like client block external images by default.
Please refer RFC-3798 for more details about MDN.
As the last post was awhile back, I am uncertain as to whether this method still works.
I tested this method on a server running PHP 5.4.30, and it does not seem to output an image.
This is some very simple code:
<img src="http://theservername.com/myaccount_email_read_offline.php">
Note that I removed the querystring and any additional code from this image.
Opening up that separate page, myaccount_email_read_offline.php did display the image.
However, trying to include the image by including a PHP file in its place did not work.
As some of the other answers have mentioned, it is possible to detect when a recipient has opened a message, if the message contains a remotely hosted image (and the recipient's mail client is set to open remotely hosted images).
UltraSMTP is an outgoing SMTP mail server that inserts a remotely hosted image in each outgoing message sent through the server, for this purpose.
See https://www.ultrasmtp.com/kb/developers.php for sample code for sending mail through UltraSMTP from a PHP script (using PHPMailer).