I implemented a html email inside a html file. And i have a php file which uses the PHPMailer class to send emails.
What i want to achieve is, i have some text inside the html that should change depends who i send the email.
This is the php file that sends the emails
<?php
// get variables
$contact_name = addslashes($_GET['contact_name']);
$contact_phone = addslashes($_GET['contact_phone']);
$contact_email = addslashes($_GET['contact_email']);
$contact_message = addslashes($_GET['contact_message']);
// send mail
require("class.phpmailer.php");
$mailer = new PHPMailer();
$mailer->IsSMTP();
$mailer->Host = 'ssl://smtp.gmail.com:465';
$mailer->SMTPAuth = TRUE;
$mailer->Username = 'danyel.p#gmail.com';
$mailer->Password = 'mypass';
$mailer->From = 'contact_email';
$mailer->FromName = 'PS Contact';
$mailer->Subject = $contact_name;
$mailer->AddAddress('pdaniel#gmail.com');
$mailer->Body = $contact_message;
if($mailer->Send())
echo 'ok';
?>
And the html file containing a simple html mail implemented with tables and all that standard it need.
I want to ask braver minds than mine which is the best approach to accomplish this. :)
Thank you in advance,
Daniel!
EDIT: right now, in the $mailer->Body i have the $contact_message variable as a text email.. but i want in that body to load an html file containing an html email and i want to somehow change the body of the html email with the text inside this $contact_message variable.
One simple way to go is to have special tokens in your html files that will be replaced by the caller. For example assuming that you have two variables that might dynamically change content, name, surname then put something like this in your html: %%NAME%%, %%SURNAME%% and then in the calling script simply:
$html = str_replace("%%NAME%%", $name, $html);
$html = str_replace("%%SURNAME%%", $surname, $html);
or by nesting the two above:
$html = str_replace("%%NAME%%", $name, str_replace("%%SURNAME%%", $surname, $html));
EDIT
A more elegant solution in case you have many variables: Define an associative array that will hold your needles and replacements for them:
$myReplacements = array ( "%%NAME%%" => $name,
"%%SURNAME%%" => $surname
);
and use a loop to make it happen:
foreach ($myReplacements as $needle => $replacement)
$html = str_replace($needle, $replacement, $html);
Create conditional statements based on the email you want to see to.
Then include that in the tempalted php html email text.
You can also pass the changing values to a function which will implement the above.
If I build a website I usually use a templating engine, something like Smarty... You could write your html mail in a smarty template file. Then you could add the wanted texts based on criteria automatically. Just assign the correct values to the templating engine.
To answer your edit:
function renderHtmlEmail($body) {
ob_start();
include ('my_html_email.php');
return ob_get_clean();
}
In your my_html_email.php file you would have something like so:
<html>
<body>
<p>....<p>
<!-- the body -->
<?php echo $body; ?>
</body>
</html>
And
$mailer->Body = renderHtmlEmail($contact_message);
If you need other variables to pass to the layout/template file, add params to that method, or pass an associative array like so function renderHtmlEmail($viewVars) and inside the function extract($viewVars);
You will then be able to use those vars inside the template, for ex. Dear <?php echo $to; ?>,
You will probably have to change your html file from .html to .php if it isn't already.
That is, if I understood the issue correctly.
Related
In the context of processing html form input and responding by sending email via php, rather than having a lengthy heredoc assignment statement in the middle of my code, I'd like to have the email text in a file and read it in when needed, expanding the embedded variables as required.
Using appropriately prepared HTML form data input, I previously had…
$message = <<<TEXT
NAME: {$_POST["fname"]} {$_POST["lname"]}
POSTAL ADDRESS: {$_POST["postal"]}
EMAIL ADDRESS: {$_POST["email"]}
[... message body etc.]
TEXT;
Moving the text to a file I then tried…
$message = file_get_contents('filename.txt');
…but found that variables in the text are not expanded, resulting in output including the variable identifiers as literals.
Is there a way to expand the variables when reading the file into a string ?
There's probably a duplicate, if found I'll delete. But there are two ways that come to mind:
If you construct your file like this:
NAME: {fname} {lname}
Then loop the $_POST variables:
$message = file_get_contents('filename.txt');
foreach($_POST as $key => $val) {
$message = str_replace('{'.$key.'}', $val, $message);
}
If you construct your file like this:
NAME: <?= $_POST["fname"] ?> <?= $_POST["lname"] ?>
If HTML .txt or other (not .php) then:
ob_start();
$file = file_get_contents('filename.txt');
eval($file);
$message = ob_get_clean();
If it's a .php file then buffer the output and include:
ob_start();
include('filename.php');
$message = ob_get_clean();
Thanks to the help from AbraCadaver I put everything into a function which will handle the file and array, returning the composed message. I constructed the file to use [key] marking the places where data is to be inserted. Works like a charm. Thank you.
function compose_message($file, $array) {
// reads content of $file
// interpolates values from $array into text of file
// returns composed message
$message = file_get_contents($file);
$keys = array_keys($array);
foreach ($keys as $key) {
$message = str_replace("[$key]", $array[$key], $message);
}
return $message;
}
I am trying to use swiftmailer in my project so that I can send html newsletter to multiple users. I have searched thoroughly but all i got never worked for me. I want to paste more than one recipient in the form input field seperated by comma and send the html email to them.
I set the recipients to a variable($recipients_emails) and pass it to setTo() method in the sending code, same with the html_email.
Questions are:
Q1 How do i send to more than one recipient from the recipient input field.
I tried this:
if (isset($_POST['recipients_emails'])) {
$recipients_emails = array($_POST['recipients_emails'] );
$recipients_emails= implode(',',$recipients_emails);
}
Q2 How do I make the Html within heredoc tag. when i tried concatenating like this ->setBody('<<<EOT'.$html_email.'EOT;', 'text/html'); , my message would appears with the heredoc tag.
if (isset($_POST['html_email'])) {
$html_email = $_POST['html_email'];
}
How do I have input from $_POST['html_email']; to be within EOT tag;
this in part of swiftmailer sending script ;
$message = Swift_Message::newInstance()
->setSubject($subject)
->setFrom($from)
->setTo($recipients_emails)
->setBody($html_email, 'text/html');
Nota bene : Am still learning these things.
According to this document
// Using setTo() to set all recipients in one go
$message->setTo([
'person1#example.org',
'person2#otherdomain.org' => 'Person 2 Name',
'person3#example.org',
'person4#example.org',
'person5#example.org' => 'Person 5 Name'
]);
You can input array directly into setTo, setCc or setBcc function, do not need to convert it into string
You should validate the input-data by first exploding them into single E-Mail-Adresses and push the valid Data into an Array. After this you can suppy the generated Array to setTo().
<input type="text" name="recipients" value="email1#host.com;email2#host.com;...">
On Submit
$recipients = array();
$emails = preg_split('/[;,]/', $_POST['recipients']);
foreach($emails as $email){
//check and trim the Data
if($valid){
$recipients[] = trim($email);
// do something else if valid
}else{
// Error-Handling goes here
}
}
Ok so first of all you need to create a variable that form your heredoc contents. The end tag of heredoc has to have no whitespace before it and then use that variable. (to output variables inside heredoc you need to wrap them with curly braces) see example..
$body = <<<EOT
Here is the email {$html_email}
EOT;
$message = Swift_Message::newInstance()
->setSubject($subject)
->setFrom($from)
->setTo($recipients_emails)
->setBody($body, 'text/html');
I have an automated email system set up to send an html file as an email. I bring that file into my email with PHPMailer, using
$mail->msgHTML(file_get_contents('mailContent.html'), dirname(__FILE__));
In the PHP source, before I add the mailContent.html, I have a variable $name='John Appleseed' (it is dynamic, this is just an example)
In the HTML file, I'm wondering if there is a way that I can use this $name variable in a <p> tag.
You can add a special string like %name% in your mailContent.html file, then you can replace this string with the value your want:
In mailContent.html:
Hello %name%,
…
In your PHP code:
$name='John Appleseed';
$content = str_replace('%name%', $name, file_get_contents('mailContent.html'));
$content will have the value Hello %name%, …, you can send it:
$mail->msgHTML($content, dirname(__FILE__));
You can also replace several strings in one call to str_replace() by using two arrays:
$content = str_replace(
array('%name%', '%foo%'),
array($name, $foo),
file_get_contents('mailContent.html')
);
And you can also replace several strings in one call to strtr() by using one array:
$content = strtr(
file_get_contents('mailContent.html'),
array(
'%name%' => $name,
'%foo%' => $foo,
)
);
You need to use a templating system for this. Templating can be done with PHP itself by writing your HTML in a .php file like this:
template.php:
<html>
<body>
<p>
Hi <?= $name ?>,
</p>
<p>
This is an email message. <?= $someVariable ?>
</p>
</body>
</html>
Variables are added using <?= $variable ?> or <?php echo $variable ?>. Make sure your variables are properly escaped HTML using htmlspecialchars() if they come from user input.
And then to the template in your program, do something like this:
$name = 'John Appleseed';
$someVariable = 'Foo Bar';
ob_start();
include('template.php');
$message = ob_get_contents();
ob_end_clean();
$mail->msgHTML($message, dirname(__FILE__));
As well as using PHP for simple templating, you can use templating languages for PHP such as Twig.
Here is a function to do it using extract, and ob_*
extract will turn keys into variables with their value of key in the array. Hope that makes sense. It will turn array keys into variables.
function getHTMLWithDynamicVars(array $arr, $file)
{
ob_start();
extract($arr);
include($file);
$realData = ob_get_contents();
ob_end_clean();
return $realData;
}
Caller example:
$htmlFile = getHTMLWithDynamicVars(['name' => $name], 'mailContent.html');
In one of my older scripts I have a function which parses a file for variables that look like {{ variableName }} and have them replaced from an array lookup.
function parseVars($emailFile, $vars) {
$vSearch = preg_match_all('/{{.*?}}/', $emailFile, $vVariables);
for ($i=0; $i < $vSearch; $i++) {
$vVariables[0][$i] = str_replace(array('{{', '}}'), NULL, $vVariables[0][$i]);
}
if(count($vVariables[0]) == 0) {
throw new TemplateException("There are no variables to replace.");
}
$formattedFile = '';
foreach ($vVariables[0] as $value) {
$formattedFile = str_replace('{{'.$value.'}}', $vars[$value], $formattedFile);
}
return $formattedFile;
}
Do you have the $name variable in the same file where you send the mail? Then you can just replace it with a placeholder;
Place __NAME__ in the HTML file where you want the name to show up, then use str_ireplace('__NAME__', $name, file_get_contents('mailContent.html')) to replace the placeholder with the $name variable.
I am a new questioner but a long time reader and I can't seem to find a solution to my PHP code.
I am trying to send and email after a form contact has been submitted. Piece of cake until I decided I wanted my html email saved in a different file rather than having it defined as a string within my form process php file. I have to say I find it much more easier to edit the layout of the message this way.
It turns out it is no easy task, though.
I have "contact-form-process.php"
parsing the information submitted through the form;
adding that information to an array,
i.e.
$formdata = array(
'first-name' => $_POST['first-name'],
'last-name' => $_POST['last-name'],
'email' => $_POST['email'],
'message-subject' => filter_var($_POST['message-subject'], FILTER_SANITIZE_STRING),
'message-body' => filter_var($_POST['message-body'], FILTER_SANITIZE_STRING),
);
and "sender-copy.php" which
is the actual html email that I am sending out;
performs some simple operations with variables defined in "contact-form-process.php",
i.e.
<p>
Dear <?php $value = (isset($formdata['first-name']) ? $formdata['first-name'] : 'NOT-SET'),
</p>
Now back to "contact-form-process.php", in it I include the html email body as a string ($message = file_get_contents('sender-copy.php', TRUE);) and treat it to evaluate PHP code snippets it contains:
$message = preg_replace_callback (
'/<\?php(.+)\?>/',
function ($match) {
eval($match[1]);
return $value;
},
$message
);
So now I have difficulty in retrieving $formdata array values from the evaluated PHP snippets in the "sender-copy.php" string.
Here is a copy of my output:
<p>
Dear NOT-SET,
</p>
Anyone? Thank you.
Unlike JavaScript, PHP does not inherit variables from the parent scope. This means that inside your preg_replace_callback callback, $formdata does not exist.
Fortunately, there is an easy way to inherit it:
function($match) use ($formdata) { ... }
That said, I would strongly recommend changing your approach. You could do something like this:
ob_start();
require("sender-copy.php");
$message = ob_get_contents();
ob_end_clean();
Alternatively, and much more safely, you can change your "sender-copy" to this:
<p>Dear {first-name},</p>
And use this replacement method:
$message = preg_replace_callback("/\{([^}]+)\}/",function($m) use ($formdata) {
if( isset($formdata[$m[1]])) return $formdata[$m[1]];
return "NOT-SET";
},$message);
I am piping email that get's sent to my server to a PHP script. The script parses the email so I can assign variables.
My problem is once in awhile somebody will include my email address to an email that's getting sent to multiple recipients and my script will only get the first one. I need it to find my email address then assign it to a variable.
Here is what the email array looks like: http://pastebin.com/0gdQsBYd
Using the example above I would need to get the 4th recipient: my_user_email#mydomain.com
Here is the code I am using to get the "To -> name" and "To -> address"
# Get the name and email of the recipient
$toName = $results['To'][0]['name'];
$toEmail = $results['To'][0]['address'];
I assume I need to do a foreach($results['To'] as $to) then a preg_match but I am not good with regular expressions to find the email I want.
Some help is appreciated. Thank you.
Instead of usin preg_match inside foreach loop you can use strstr like below
Supposing you are looking for my_user_email#mydomain.com use following code
foreach($results['To'] as $to)
{
// gets value occuring before the #, if you change the 3 rd parameter to false returns domain name
$user = strstr($to, '#', true) ;
if($user == 'my_user_email')
{
//your action code goes here
}
}
example:
<?php
$email = 'name#example.com';
$domain = strstr($email, '#');
echo $domain; // prints #example.com
$user = strstr($email, '#', true); // As of PHP 5.3.0
echo $user; // prints name
?>
Actually, you do not need to use a regexp at all. Instead you can use a PHP for statement that loops through your array of To addresses.
$count = count($root['To']);
for ($i=0; $i < $count; $i++) {
//Do something with your To array here using $root['To'][$i]['address']
}