I'm having a problem using a mailing function in a php ecomm app I purchased from envato. The developer has a mailer function which is used to send emails from the website.
Function :
/* Send mail with custom templates:$template : E-mail template.$array : Variables for email template. $subject : E-mail Subject.$to : E-mail receiver.*/
function mailing($template,$array,$subject,$to) {
$cfg = DB::select('SELECT * FROM config WHERE id = 1')[0];
$array['url'] = url('');
$array['name'] = $cfg->name;
$array['address'] = nl2br($cfg->address);
$array['phone'] = $cfg->phone;
$array['email'] = $cfg->email;
// Get the template from the database
$message = DB::select("SELECT template FROM templates WHERE code = '".$template."'")[0]->template;
foreach ($array as $ind => $val) {
$message = str_replace("{{$ind}}",$val,$message);
}
$message = preg_replace('/\{\{(.*?)\}\}/is','',$message);
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= 'From: '.$cfg->name.' <'.$cfg->email.'>'."\r\n";
mail($to,$subject,$message,$headers);
return true;
}
The email template is pulled from the db.
As part of the checkout process in the API.php file, the mailer function is used to email the order to the user with the follwing code:
// Send an email to customer
mailing(
'order',
array( 'buyer_name'=>$data['name'],
'buyer_email'=>$data['email'],
'buyer_fields'=>$email_fields,
'name'=>$this->cfg->name,
'address'=>$this->cfg->address,
'phone'=>$this->cfg->phone,
'products'=>$email_products,
'total'=>$total
),
'Order Confirmation #'.$order,
$data['email']
);
This is fine, however, I'm trying to get that to also send myself the email of the order as opposed to having to check the admin ux as is currently the way it works. Could anyone point me in the right direction ?
Many Thanks in advance.
The simple answer is to add another call to mail() an replace $to with your email address in the mailing() function.
But as this is probably used in more than one place in the app, it might be nice to add a parameter to this function that tells it to email to you as well as the intended recipient
function mailing($template,$array,$subject,$to, $toMe=false) {
// new parameter ^^^^^^^^^^^
$cfg = DB::select('SELECT * FROM config WHERE id = 1')[0];
$array['url'] = url('');
$array['name'] = $cfg->name;
$array['address'] = nl2br($cfg->address);
$array['phone'] = $cfg->phone;
$array['email'] = $cfg->email;
// Get the template from the database
$message = DB::select("SELECT template FROM templates WHERE code = '".$template."'")[0]->template;
foreach ($array as $ind => $val) {
$message = str_replace("{{$ind}}",$val,$message);
}
$message = preg_replace('/\{\{(.*?)\}\}/is','',$message);
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= 'From: '.$cfg->name.' <'.$cfg->email.'>'."\r\n";
mail($to,$subject,$message,$headers);
// now mail yourself if $toMe is true
if ( $toMe !== false ) {
mail($toMe,$subject,$message,$headers);
}
return true;
}
Then anywhere in the app where it sends mail yo can add a request to get a copy of the email. BUT, if you dont add the new parameter, the mailing() function will act just as it did before.
// Send an email to customer
mailing(
'order',
array( 'buyer_name'=>$data['name'],
'buyer_email'=>$data['email'],
'buyer_fields'=>$email_fields,
'name'=>$this->cfg->name,
'address'=>$this->cfg->address,
'phone'=>$this->cfg->phone,
'products'=>$email_products,
'total'=>$total
),
'Order Confirmation #'.$order,
$data['email'],
'me#mymail.com' // new parameter added
);
Now none of the existing calls to mailing will be effected, because you used a default value in the function prototype, unless you add the extra parameter to the call to mailing but any of them you want to alter can be done easily, and as you specify the address when you want to get a copy, you can use any of your email addresses.
Just add another
mail($to,$subject,$message,$headers);
line and replace $to with your email. That's it.
Related
I am trying to send all of my users an email for a custom event. For this, I have written the following code but it is not working. What am I doing wrong?
//send mail to all users
$result= $wpdb->get_var( $wpdb->prepare("SELECT user_email FROM $table_users"));
foreach($result as $email) {
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers.= "From:mysite<info#mysite.com>\r\n";
$message = "<b>Dear! user</b>,<br/><br/> A new share is available to purchase
for amount $".$sellamt."<br>this is an automated mail.pls don't reply to this mail. ";
$send=mail($email,"mysite:New share Available to Purchase!",$message,$headers);
}
header('Location: /offer_csuccess');
exit();
Use get_users function to get all users depending on roles or any parameter you pass.
$users = get_users();
foreach( $users as $user ) {
wp_mail( $user->user_email, "New Share Available to Purchase!", $message );
}
Also using WordPress you have advantage not to mention the headers every time. You just need to use wp_mail. It really does sending email simpler.
Hope it help :)
get all user function get_users();
$all_users = get_users();
foreach ($all_users as $user) {
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers.= "From:mysite<info#mysite.com>\r\n";
$message = "<b>Dear! user</b>,<br/><br/> A new share is available to purchase
for amount $".$sellamt."<br>this is an automated mail.pls don't reply to this mail. ";
$send=mail($user->user_email,"mysite:New share Available to Purchase!",$message,$headers);
}
exit();
I'm attempting to BCC to a list of subscribers from a database, using PHP mail(). Everything works, but I'm running into a problem that has troubled me all morning. I'm able to send the list with BCC, but are unable to append the receiving end email address to the deader "To:".
For example, I send the list to the following email addresses (test1#example.com, test2#example.com, and test3#example.com). Each email address receives an email and the other email addresses are hidden because of BCC.
My problem is that in the header, "To:" is displayed blank on all of the receiving ends of the list. That I understand and know that header won't display because I have only the BCC header within the outgoing message. I've attemted to for loop the process but I receive all of the emails, plus one for that address in one loop.
Here is my working code: The working code includes the loop that I attempted for solving the To: header. I'm able to send the email, though I receive all of the emails that were sent.
<?php
/*
Gathers the number of rows within the database. Used for the loop that displays the entire list in the BCC.
*/
session_start();
include_once '../dbconnect.php';
$result = mysql_query("SELECT * FROM news");
$num_rows = mysql_num_rows($result);
$rows = $num_rows;
/*
Requests the list from the database, please the list in a loop, displays the list only once, and places list in an operator.
*/
$result = mysql_query("SELECT * FROM `news`");
while($row = mysql_fetch_array( $result )) {
for ($x = 1; $x <= 1; $x++) {
$contacts.= "".$row['email'].",";
}
}
/*
ATTEMPT (It works... sort of): Sends mail to the list using BCC, displays the ONLY receivers email address in the To: header
*/
$result = mysql_query("SELECT * FROM `news`");
while($row = mysql_fetch_array( $result )) {
for ($x = 1; $x <= 1; $x++) {
$receiver= "".$row['email']."";
$to = "$receiver";
$subject = 'Test Email';
$headers = "From: example#example.com\r\n";
$headers .= "BCC: $contacts";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$message = '<html><body>';
$message .= '<h1 style="">Test Message</h1>';
$message .= '</body></html>';
mail($to,$subject, $message, $headers);
}
}
?>
My general thought was to loop, but I can't find a solution that actually solves this completely, by BBC to the list and displaying only the receiving ends email address in the To: header. Any thoughts or ideas?
Update with SMTP Server
I've been attempting to use the solution found in this thread and apply it to an SMTP server. Send the message using SendGrid was the ideal choice. I've come up with the below option, but the script only seems to send one message to one of the addresses in the database and not all the address.
<?php
require_once "Mail.php";
$sub = $_POST['subject'];
$ttl = $_POST['title'];
$img = $_POST['image'];
$bdy = $_POST['body'];
$lk = $_POST['link'];
mysql_connect("", "", "") or die(mysql_error()) ;
mysql_select_db("") or die(mysql_error()) ;
$result = mysql_query("SELECT `email` FROM news");
$num_rows = mysql_num_rows($result);
$receivers = array();
while ($row = mysql_fetch_array($result)) {
$receivers[] = $row['email'];
}
foreach ($receivers as $receiver) { }
$from = "test#example.com";
$to = $receiver;
$subject = $sub;
$mime = "1.0";
$ctype = "text/html; charset=ISO-8859-1";
$body = '
<html><body>
<p>Test Message!</p>
</body></html>
';
$host = "";
$port = "";
$username = "";
$password = "";
$headers = array ('From' => $from,
'To' => $to,
'Subject' => $subject,
'MIME-Version' => $mime ,
'Content-Type:' => $ctype);
$smtp = Mail::factory('smtp',
array ('host' => $host,
'port' => $port,
'auth' => true,
'username' => $username,
'password' => $password));
$mail = $smtp->send($to, $headers, $body);
if (PEAR::isError($mail)) {
echo("<p>" . $mail->getMessage() . "</p>");
} else {
echo("<p>Message successfully sent!</p>");
}
?>
The code includes some general improvements to your code. I have added inline comments to explain what I have done.
<?php
// General thing: If you do not need a session, do not start one ;)
session_start();
include_once '../dbconnect.php';
// Select only what you really need from the table. This saves you memory
// and it speeds up the query.
$result = mysql_query("SELECT `email` FROM news");
// You are not using these numbers in the script you showed us. I am just
// leaving them in here to show you, how you can reuse the "$result"
// variable without querying the database again.
$num_rows = mysql_num_rows($result);
// We are reusing the "$result" here without re-querying the database, which
// speeds the whole process up and takes load away from the database. We are
// storing all receivers in a dedicated variable, to reuse them later on.
$receivers = array();
while ($row = mysql_fetch_array($result)) {
$receivers[] = $row['email'];
}
// Now, instead of querying the database again, we are using our stored mail
// addresses in "$receivers" to send the emails one by one. We could have
// done this part in the "while" loop before, but I wanted to stay close to
// your code, so you would recognize it ;)
foreach ($receivers as $receiver) {
// I have removed the "for" loop here, because it runs only once. If a loop
// only runs once and you control all its input, you really do not need a
// loop at all (except some exceptions, just in case someone knows one^^).
// You can actually just put the value of $receiver in $to. PHP is pretty
// good at typecasting of scalar types (integers, strings etc.), so you do
// not need to worry about that.
$to = $receiver;
$subject = 'Test Email';
// I am putting the headers into an array and implode them later on. This
// way we can make sure that we are not forgetting the new line characters
// somewhere.
$headers = array(
"From: example#example.com",
"MIME-Version: 1.0",
"Content-Type: text/html; charset=ISO-8859-1",
// I have removed the "BCC" header here, because this loops send out an
// email to each user seperately. It is basically me sending an email to
// you. Afterwards I copy&paste all the content to another new mail and
// send it to another fella. You would never know that you both got the
// same mail ;)
);
$message = '<html><body>';
$message .= '<h1 style="">Test Message</h1>';
$message .= '</body></html>';
// Imploding the headers.
$imploded_headers = implode("\r\n", $headers);
mail($to, $subject, $message, $imploded_headers);
}
This code basically send out one email at a time. No one who receives such an email knows which email addresses the email went to.
As mentioned in the code, this snippet can be further optimized. Since email sending itself is a pretty difficult area, I would really suggest that you find some PHP library that bundles that whole thing and work with it. You can make so many mistakes with the whole email sending thing, that I would not run a script like that in production if you do not want to get marked as spam soon after.
Add \r\n to:
$headers .= "BCC: $contacts\r\n";
Each header must be on new line.
I have the following function for sending an email:
function send_email($email){
$subject = "TITLE";
$message = "HERE IS THE MESSAGE";
// Always set content-type when sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
// More headers
$headers .= 'From: <emaily>' . "\r\n";
mail($email,$subject,$message,$headers);
}
Instead of $message being a string, I want to call in the file email.html which holds my template.
I have added this:
require 'email.html';
But how can I call in the file?
$message = [call in email.html here]
Require is used when you want to call functions within another php file, or when you want to include some data to an HTTP response.
For this problem, file_get_contents('email.html') is the preferred option. This would be the method I would use:
function send_email($email){
$subject = "Subject of your email";
$message = "";
if(file_exists("email_template.html")){
$message = file_get_contents('email_template.html');
$parts_to_mod = array("part1", "part2");
$replace_with = array($value1, $value2);
for($i=0; $i<count($parts_to_mod); $i++){
$message = str_replace($parts_to_mod[$i], $replace_with[$i], $message);
}
}else{
$message = "Some Default Message";
/* this likely won't ever be called, but it's good to have error handling */
}
// Always set content-type when sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
// More headers
$headers .= 'From: <doNotReply#myDomain.com>' . "\r\n";
$headers .= "To: <$email>\r\n";
$header .= "Reply-To: doNotReply#myDomain.com\r\n";
mail($email,$subject,$message,$headers);
}
I modified your code a little bit and added in both the file_get_contents and file_exists. file_exists confirms that the file is there. If it's not, it avoids the potential error from trying to read it in and can be changed to use some default. My next addition was a for loop. In the $parts_to_mod array, enter in the default values from the template that need to be replaced. In the $replace_with array, put in the unique values that you want to replace parts of the template with.
As an example where I use this, I have a template URL for one of my programs that says id=IDENTIFIER&hash=THEHASH so in my program, my parts_to_mod says $parts_to_mod = array("IDENTIFIER", "THEHASH"); and my replace_with says $replace_with = array($theUsersIdentifier, $theUsersHash);. It then enters the for-loop and replaces the those values in parts_to_modify with the values in replace_with.
Simple concepts and they make your code much shorter and easier to maintain.
Edit:
Here is some sample code:
Let's the say the template is:
<span>Dear PUTNAMEHERE,</span><br>
<div>PUTMESSAGEHERE</div>
<div>Sincerely,<br>PUTSENDERHERE</div>
So, in your php code you'd say:
$parts_to_mod = array("PUTNAMEHERE", "PUTMESSAGEHERE", "PUTSENDERHERE");
$replace_with = array($name, $theBodyOfYourEmail, $whoYouAre);
just use file_get_contents('email.html') This method returns a string with the file contents
You can use this function to call custom email template.
function email($fields = array(),$name_file, $from, $to) {
if(!empty($name_file)) {
$mail_tem_path = 'templates/mails/mail--'.$name_file.'.php'; //change path of files and type file.
if(file_exists($mail_tem_path)) {
$headers = "MIME-Version: 1.0". "\r\n";
$headers .= "Content-Type: text/html;charset=UTF-8". "\r\n";
// Additional headers
$headers .= "From:".$fields["subject_from"]." <$from>". "\r\n";
$headers .= "Content-Transfer-Encoding: 8Bit". "\r\n";
$message = file_get_contents($mail_tem_path);
$message = preg_replace("/\"/", "'", $message);
foreach ($fields as $field) {
// Replace the % with the actual information
$message = str_replace('%'.$field["name"].'%', $field["value"], $message);
}
$send = mail($to, $fields["subject"], $message, $headers);
} else {
$send = mail($to, "Error read mail template", "Contact with admin to repair this action.");
}
} else {
$send = mail($to, "Error no exist mail template", "Contact with admin to repair this action.");
}
return $send;
}
Template html
<html>
<body>
TODO write content %value_on_array%
</body>
</html>
Array and execute function.
$fields = array(
"subject" => "tienda_seller_subject",
"subject_from" => "tienda_email_subject_from",
0 => array(
"name" => "value_on_array",
"value" => "result before change"
),
);
//email($fields = array(),$name_file, $from, $to);
email($fields, 'admin', 'owner#email.com', 'client#email.com');
Result
I'm creating a simple mail form with checkboxes, a couple of input tabs, and a text input section. It uses PHP to retrieve the information then email it to a specific email. Right now I have it emailing to my own yahoo email just for testing. When I test the site on my hosting account jacobbuller.com/testsites/peacock/contact.php the form works perfectly and forwards the email from my generic "theski" server email. But when I upload the site to the actually live hosting account for peacockautoservice.com the contact form works - it executes and sends a ?msg=1 variable in the url - but I never receive the email in my Yahoo account...
Here's the PHP I am using to send the email.
<?php ob_start();
<?php
$required_field = array('name', 'email', 'message');
foreach($required_field as $fieldname) {
if (!isset($_POST[$fieldname])) {
$errors[] = $fieldname;
}}
if (empty($errors)) {
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$contact = $_POST['contact'];
$phone = $_POST['phone'];
$services = IsChecked('checkboxes', 'factory');
$services .= IsChecked('checkboxes', 'timing belt');
$services .= IsChecked('checkboxes', 'brakes');
$services .= IsChecked('checkboxes', 'computerized');
$services .= IsChecked('checkboxes', 'steering and suspension');
$services .= IsChecked('checkboxes', 'heating and air');
$services .= IsChecked('checkboxes', 'electrical');
$services .= IsChecked('checkboxes', 'other');
$body = "Customer:" . $name;
$body.= "Phone Number:" . $phone;
$body.= "Contact:" . $contact;
$body.= "Services:" . $services;
$body.= "Message:" . $message;
$to = "jcbbuller#yahoo.com";
$subject = "Peacock Auto Services Inquirey";
$from = $email;
$mailed = mail($to, $subject, $body, $from) or die("Error!");
}
if($mailed) {
redirect_to("../contact.php?msg=1");
}
?>
<?php
// IsChecked FUNCTION - Detemines what checkbox are/aren't checked on form.
function IsChecked($postname, $value){
if(!empty($_POST[$postname])) {
foreach($_POST[$postname] as $job) {
if ($job == $value) {
$project = " ". $value . " ";
return $project;
}
}
}
} //END IsChecked FUNCTION
function redirect_to( $location = NULL ) {
if ($location != NULL) {
header("Location: {$location}");
exit;
}
}
?>
<?php ob_end_flush(); ?>
Please let me know if you see something wrong with the PHP above or if you know why their GoDaddy hosting account is not executing the email. I tried using their customer service network but they said that they can't help me with my code...
Your issue is mainly at server end. Mail function is working because of your check on it, if it had failed, it would have given you notification. So, mails are going definitely. If mail server is working properly at your production server, then check for SPAM folder at yahoo mail server. I would suggest you to ask your hosting provider to enable SPF and DKIM records because most of email providers requires sender authentication (if it is not a spam) and these records are helpful in it.
I can also see that your not using any headers, so I would suggest you to use extended headers to avoid providers identifying you as a spammer. I use below mentioned headers and my emails never go in spam on anyprovider, but again it depends on IP reputation of the server as well.
$headers .= "Reply-To: Awaraleo <email#domain.org>\r\n";
$headers .= "Return-Path: Awaraleo <email#domain.org>\r\n";
$headers .= "From: Awaraleo <email#domain.org>\r\n";
$headers .= "Organization: Awaraleo\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "X-Priority: 3\r\n";
$headers .= "X-Mailer: PHP". phpversion() ."\r\n";
and then use it like
mail($to,$subject,$message,$headers);
Here email#domain.org should be a valid email address created on the domain where this form is implemented.
Another authentic way is to use SMTP Authentication in coding.
I want to send the user an activation link after they registered an account. when I put this http://www.homeloan.com.sg in the $message I didn't receive the email, but when I remove the .sg and put http://www.homeloan.com it works. There's no error message, so I really don't know what's my mistake. Please help
here are my codes:
$id = mysql_insert_id();
$to = 'myemail#gmail.com';
$subject = "E-mail Verification";
$message = 'Click on the link to verify your account-> http://www.homeloan.com.sg/rates/activate?id='.$id.'';
$headers = "From: Homeloan Singapore" . "\r\n" . "Reply-To: enquiry#homeloan.com.sg";
mail($to,$subject,$message,$headers, '-f enquiry#homeloan.com.sg');
Make sure if your site have a form to fill, then fill the form correctly by assembling the input tag in the corresponded variable.
Try concatenating 'the email' to the variables ($...) with (.) or "...".
I really don't know what's my mistake
There is no mistake. I tried this code:
<?php
$id = 1;
$to = 'my_email#gmail.com';
$subject = "E-mail Verification";
$message = 'Click on the link to verify your account-> http://www.homeloan.com.sg/rates/activate?id='.$id;
$headers = "From: Homeloan Singapore" . "\r\n" . "Reply-To: enquiry#homeloan.com.sg";
mail($to,$subject,$message,$headers, '-f enquiry#homeloan.com.sg');
It arrived in the mailbox. Maybe, for your account it was put into spam folder?