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);
Related
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 have a question and try searching on Google and Stakoverflow and could't find any perfect solution. I am using phpmailer and want to let the user to customize it's body message. So I have given and option to edit the email body text by providing a texarea input box in back end where user will input the email text with some my own provided php variable.
For example body text is "Dear {$username}, thank you for signup.". Once I store this input into database and want to retrieve this in php:
$username = "ABC"; //username variable
$message = $row["message"]; //stored email body message
echo $message;
OUTPUT DATA: "Dear {$username}, thank you for signup."
I want to get it like this "Dear ABC, thank you for signup.". How is it possible or is there any other option I can use it with php varialbe or defined type?
You're not getting an answer you're expecting because contents of $row["message"] don't get evaluated again. And that's actually a good thing because users could use any variable name they want, which would create a security threat.
There is a quality solution, though. You should check out template engines for PHP, e.g. Smarty and Twig. They allow you to create templates with placeholders, for example something like:
Dear {{username}}, thank you for sign-up!
which you could store in a file or let your users define their own templates. Template engine will then read the template and, using the values you send it, replace those placeholders with actual values.
To see how this is done in practice, choose a template engine and check its documentation.
I have found a solution in PHP with str_replace function. This function is really very helpful. I have tried with modified input message "Dear user_name, thank you for signup.":
$username = "ABC"; //username variable
$message = $row["message"]; //stored email body message
$message_new = str_replace("user_name", $username, $message);
echo $message_new;
OUTPUT DATA: "Dear ABC, thank you for signup."
You can use PHP eval() function.
$msg = "$cust_dt->cus_name, Your order placed successfully. ID: $sms_oid Total: $sms_ord_tot";
echo $msg;//output1
eval("\$msg= \"$msg\";");
echo $msg;//output2
Output 1: $cust_dt->cus_name, Your order placed successfully. ID:
$sms_oid Total: $sms_ord_tot
Output 2: John Doe, Your order placed successfully. ID: 454554545
Total: 1600
You can store a strings like $msg in a database and use eval() function to evaluate string into php code.
For More:
https://www.w3schools.com/php/func_misc_eval.asp
https://www.php.net/manual/en/function.eval.php
Just wanted to say THANK YOU!!!!
This also works by putting ((name)), and using that inside str_replace - instead of just using "user_name"
Which is a little more user-friendly - and keeps from accidentally replacing things if someone were to type "user_name", for instance lol
Plus it'll make it look cool when having your "insert" legend at the top saying:
Choose one of the following:
((name)) = Clients Name
You saved me so much time!
I'm using the Zend_Mail_Message class to display emails inside of my PHP app, and am able to output the subject, content, date and even the NAME of the sender (using $message->from) but I can't figure out how to get the email address of the person who sent the message. The documentation is no help and googling finds a million results for how to send messages with Zend, but nothing about getting the address that sent the message.
EDIT:
This is how I ended up doing it. After some more digging, I found the sender's email in a field called 'return-path'. Unfortunately, this field has a dash in the name (WTF??) so to access it, I had to do this:
$return_path = 'return-path';
$message->reply_to = $zendMessage->$return_path;
Using the return-path caused some problems with some emails, specifically messages from no-reply accounts (mail-noreply#gmail.com, member#linkedin.com etc). These addresses would end up looking something like this:
m-9xpfkzulthmad8z9lls0s6ehupvordjdcor30geppm12kbvyropj1zs5#bounce.linkedin.com
...which obviously doesn't work for display in a 'from' field on the front-end. Email clients like Apple Mail and Gmail show mail-noreply#gmail.com or member#linkedin.com, so that's what I was going for too.
Anyways, after some more research, I discovered that the 'from' field in a Zend Mail Message object always looks something like this:
"user account name" <user#email.com>
The part in < > is what I was after, but simply doing $from = $zend_message->from only gave me the user's account name (hence my original question). After some more playing around, this is how I finally got it working:
$from = $zendMessage->from;
$start = strpos($from, '<');
$email = substr($from, $start, -1);
$result = str_replace('<', '', $email);
Hopefully this will save someone some frustration. If anyone knows of a simpler way of doing this, please let me know.
This works well..
$senderMailAddress = null;
foreach ( $message->getHeader('from')->getAddressList() as $address ) {
if ( $senderMailAddress === null) {
$senderMailAddress = $address->getEmail();
}
}
The main problem here is that many email programs, relay agents and virus scanner along the way do funny stuff to an actually simple and well defined email standard.
Zend_Mail_Message extends to Zend_Mail_Part which has a method called getHeaders(). This will have all the data from an email stored in the head versus the body which is accessed with getContent() and the actual email message.
With this method you'll get an array of all the key/value pairs in the header and while developing you should be able to determine which header field you will actually want. Once you know that you can then get the actual field with getHeader('field_name') or with its actual name directly.
However, if you have to many different email senders you may want to stick with the complete header array though and evaluate multiple fields for the best result like if there's an "reply-to" address. Again there are many uncertainties because the standard isn't always obeyed.
This is my current code:
and I want to add a number of tables to change the design of the email, I am very new to PHP and ZEND any help would be great thanks.
As Mike Brant said, you can create your HTML then copy in inline. However you will then need to ensure that the email is sent with the proper mime-type so that the user's email reader knows to render as HTML and not as plain text. It isn't that hard, but I found that the PEAR mail and mail_mime libraries really make it even easier and more obvious what's being done. There are also some 3rd party email apis, for example I've had good success on one project using http://swiftmailer.org/
The best way to start is to just layout your email in HTML the way you want it and then just copy into your HEREDOC section and replace the content with the variables.
Create one (zend)layout for your e-mails like you do it for your website. Best with html 4.0 doctype. Avoid CSS. Most E-Mail Clients cannot render it correctly. If you have to use CSS, embed it into style-tags (no external content) and embed the style-Tag into the body. (most web-mailers are dropping the head-section).
Now create views for every mail-type you want to send (e.g.: registration, pw-lost,...)
assign the variables to the view and render it into the layout. Render the Layout into Zend-Email Object.
If you want to manage the content, subject, sender,... over an administration-area, just create a table with the following colums:
type (can be registration, pw-Lost...)
Subject
From
To (for mails which are adressed to the admin e.g.: when users post comments)
CC
Bcc
Html-Text (the Text of the e-Mail with Place-Holders for personalzation)
Text (optional plain text containing Place-Holders) you can pack this text additionaly to you html-Mail or just send html or Text Depending on the user settings.
Some extra-colums for attachments (optional)
Now you can adminster the different Mails and drop your views (not the layout).
At least create a mail-class which you can access in that way:
$mail = new My_Mail(My_Mail::PW_LOST);
$mail->bind($userData); // will replace the placeholders in the text
$mail->addTo(...);
$mail->send(); // will replace the placeholders in the text, renders the layout, Sends the mail.
Code-Sample:
I can provide code samples on saturday if you are interested
You can use the Zend_Mail class (Zend/Mail.php) to send emails. The details are in the code sample below:
$mail = new Zend_Mail();
$mail->setBodyText($bodyText);
$mail->setBodyHtml($bodyHtml);
$mail->setFrom($senderAddress, $senderLabel);
$mail->addTo($recipientAddress, $recipientLabel);
$mail->setSubject($subject);
$mail->send();
A question you might have is how the email (text and html) contents are assigned to $bodyText and $bodyHtml. You can create a couple of phtml files one for html content and the other for text. See the code below on how to achieve this:
$this->view->fullname = "John Abc";
$this->view->emaildata = $data //Possibly an array of data from the db
$bodyText = $this->view->render('emails/htmlemail.phtml')
$bodyHtml = $this->view->render('emails/textemail.phtml')
Note: This snippet should be above the previous one.
Hope this answers your questions. Happy coding :)
I am using zend. I have the following piece of code,
....
$cust = 'test#test.com';
$list.='Also Sent Mail to following members';
foreach($m_list as $value)
{
$mail_to_manu = new Zend_Mail('utf-8');
$mail_to_manu->clearFrom();
$mail_to_manu->setBodyHtml('Text')
->setFrom('noreply#test.com', 'test admin')
->addTo($value['email'])
->setSubject('Test');
$mail_to_manu->send();
$list.=$value['manufacturers_email'].'<br/>';
}
$this->_helper->flashMessenger->addMessage('Mail send to '. $cust. ' Successfully'.$list);
$this->_redirector->gotoUrl('/index');
.....
I got message with out any break.my message looks like,
Mail send to test#test.com Successfully Also Sent Mail to following members some1#example.com some2#example.com...
I need to my message will be like,
Mail send to test#test.com Successfully
Also Sent Mail to following members,
some1#example.com
some2#example.com
...
So i need some break one after another.Is it possible to do that in Flash messenger. If yes,Kindly Advice.
Are you using strip_tags or something similar in the view script? It could cause the <br /> tags to get stripped out.
It's also possible to add multiple messages by calling flashMessenger->addMessage() once for every address:
$cust = 'test#test.com';
$this->_helper->flashMessenger->addMessage('Mail send to '. $cust. ' Successfully');
if(count($m_list)>0 )
$this->_helper->flashMessenger->addMessage('Also Sent Mail to following members');
foreach($m_list as $value)
{
$mail_to_manu = new Zend_Mail('utf-8');
$mail_to_manu->clearFrom();
$mail_to_manu->setBodyHtml('Text')
->setFrom('noreply#test.com', 'test admin')
->addTo($value['email'])
->setSubject('Test');
$mail_to_manu->send();
$this->_helper->flashMessenger->addMessage($value['manufacturers_email']);
}
$this->_redirector->gotoUrl('/index');
Your question
The reason why it's all bunched up together is that you're echoing it all out in a loop without additional markup.
What about something like:
foreach ($this->messages as $message)
{
echo '<p class="message">' . $this->escape($message) . '</p>';
}
But, in fact, there is a much better way of handling the flashMessenger in views. As you know the Zend FlashMessenger is an action helper. But there is also a great view helper avaiable which helps you output your messages nicely. The best thing about it is, that you can pass an array('warning' => 'This is a warning') and the array key (warning) will be used as class for the <p> tag. You can find information about this helper on Carlton Gibson's blog and additional explanations in this SO question.
Your variable naming needs improvement
Write readable variable names like $customer instead of just $cust. Nobody ever said shortening variable names is a means of writing lean code ;). Shortening variable names is bad (code smell) because it make code less readable for others and for yourself in the future.
Use casing like this $mailToManufacturer instead of using underscores. It's a general agreement (standard) and therefore good for readability and understanding of code too.