Progress bar / animated.gif during phpmailer email send - php

I created a members only based website and when I post new articles, (similar to blog post), I use phpmailer to send an email out to all the members that requested email to be sent to them.
The email contains the new articles content. Title, description etc..
I'm in beta testing stage right now, and with only 3 email accounts it takes about 9 seconds to send out the 3 email when I make a new post. About 3 seconds per email.
I expect to get around 100 users on this site, which would = about 5 minutes to send out all those emails.
Question
Is there a way I can hook up a real time progress bar to show how much time is left when sending the emails?
My setup is like this:
I have my form that is connected to this action script.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/core/init.php");
// new data
$title = $_POST['title'];
$description = $_POST['description'];
// query
$addnotice = DB::getInstance()->insert('table1', array(
'title' => $title,
'description' => $description,
));
$id = isset($_POST['id']);
$users = DB::getInstance()->query("SELECT id, title, description FROM table1");
$users = DB::getInstance()->query("SELECT email FROM table2 WHERE notify= 'Yes'");
foreach($users->results() as $u){
User::sendNotification($u->email, $title, '<strong><h2>'.$title.'</h2></strong><p>'.$description.'</p>');
}
Session::flash('newarticle', '<h3 class="white-tx" align="center">The article has been added!</h3>');
Redirect::to('sitepage.php');
?>
The User::sendNotification comes from my user class file that looks like this.
public function sendNotification($to, $subject, $body) {
require_once 'class.phpmailer.php';
$from = "notifier#*******.com";
$mail = new PHPMailer();
$mail->IsSMTP(true); // use SMTP
$mail->IsHTML(true);
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "host***.*******.com"; // SMTP host
$mail->Port = 465; // set the SMTP port
$mail->Username = "notifier#******.com"; // SMTP username
$mail->Password = "********"; // SMTP password
$mail->SetFrom($from, 'Email Robot');
$mail->AddReplyTo($from,'Do Not Reply');
$mail->Subject = $subject;
$mail->MsgHTML($body);
$address = $to;
$mail->AddAddress($address, $to);
$mail->Send();
}
A real time progress bar would be Ideal, but I would even settle for an animated .gif loading image.
Which I tried by adding this to the action script:
echo '<table align="center" width="100%" height="100%" border="0"><tr align="center" valign="center"><td><img src="images/sending.gif"></td></tr></table>';
But that wasn't even recognized and rolled right past the sending.gif image and posted the article to the website and sent the emails.
I've searched Google for tutorials on the subject, but came up dry.
Any thoughts on this situation would be greatly appreciated.

I'd suggest to use the BCC of only one email if you do not send personalized mails.
If you want to go for the progress bar, here's a sketch of one way you could go:
Add a database table notifications with fields user_id, notice_id
Insert one row for every user WHERE notify= 'Yes' (why not BOOL here?) and new notice
Have a cronjob poll this table every now and then sending the mails (by fetching the appropriate info from the user and notice table) and removing the respective pending rows
Provide a script returning the current number of pending notifications (json) (num rows of the notification table)
Use JS (i.e. jquery) for periodic updates (http query for the aforementioned script)
(You could also have a boolean field sent if you do not want to delete the rows from the notification table but want to track the notifications.)
You could have:
a submit.php where you insert the required notifications into the table
a mail sending cronjob (i.e. php script or whatever) that removes the pending rows after sending
a poll.php where you provide the current number of rows of the notifications table in JSON format.
a status.php where you periodically request the data from poll.php and update the page accordingly

You can show a progress bar - support for it was introduced in PHP 5.2 - driven by polling it from Javascript. This nice example shows how you can use it with both PHP and jQuery parts. That example is monitoring a file upload, but you can alter it to return anything that changes over time, for example a count while sending your emails in a loop.
As others have mentioned, if you're sending more than a few messages, you need to do it entirely asynchronously as a page load is really not the time to do long operations. For queues, I recommend beanstalkd with Pheanstalk. It doesn't make any difference what email sending class you use as they can all be operated this way (though I'm obviously partial to PHPMailer!).
Your loop is also quite wasteful - there's no need to create, configure and destroy the mailer instance for every message - if your messages have much in common, you can make it much simpler.

Related

Language String Failed to load : Recipients_failed

I have a script that sends a mail to validate a form made by a user. It's a professional application so the mail isn't a spam and the users are members of the company.
Now my PHPmailer() function bug once in two randomly. I would like technical help to see if I did something wrong in my PHP code. So first of all, this is what it should do:
1) the user end his form
2) he has to choose who will receive the email (between 3 choices, and he can cross the 3 checkboxes)
3) One mail will be sent to each person he checked, with a simple link to see the result of the form.
But most of the time, I have this error message:
Language String failed to load:
Recipients_failed [mail]
*[Mail] = the email address*
The PHP script stops there, the page doesn't finish loading and the mail isn't send.
for the exemple, we'll say that in the first page we have [mail1], [mail2] and [mail3] who are 3 checkboxes.
Here is my code:
if(isset['[mail1]']){
$mail = new PHPmailer();
$mail->IsSMTP();
$mail->IsHTML(true);
$mail->Host=*;
$mail->Port=*;
$mail->From='no-reply#*.fr';
$mail->FromName=*;
$mail->SMTPSecure = 'tls';
$mail->SMTPAuth=true;
$mail->Username='no-reply#*.fr';
$mail->Password='*';
$mail->AddAddress([mail1]);
$mail->Subject="*";
$mail->Body = utf8_decode("*");
if(!$mail->Send()){
die($mail->ErrorInfo);
}
$mail->SmtpClose();
unset($mail);
}
I think that the code is ok because this works sometimes, but doesn't work sometimes... What should I do? Speak to OVH or there is something I did wrong?
I think your question has nothing to do with PHP.
The error message simply tells you that one of the recipients does not exist - this message does not come from php but from the SMTP server you are using.
However: I don't know why the server shows you an error message "no translation" - you should contact "OVH" and ask.

How to not make PHPmailer send an email with multiple 'to' addresses?

I have a table in my database which contains emails to be sent. A script runs periodically as a cron job to read the data from table and dispatch the emails via the SMTP server. I am using PHPMailer for the work here. The script runs a loop for sending emails until all the emails in the table have been sent.
The problem is that most consecutive emails being sent have a common subject. So when the loop runs, somehow all the emails that get sent have a long 'to' list. So basically if 5 email entries (with different to addresses) have the same subject and same content, then it ends up sending only 1 email with 5 addresses (one of each email entry) in the 'to' field. This reveals the email address of every person to everyone else on the list. This is undesirable and the emails must be sent to only that one person for whom it is meant.
I don't know what's at play here. Any suggestions?
Are you doing something like this?
$mailer = new PHPMailer();
while($row = fetch_from_db()) {
$mailer->AddAddress($row['email']);
$mailer->send();
}
If so, you need to do a
$mailer->ClearAllRecipients()
after you send each email, so you start out with a "fresh" To: list.
while($row = fetch_from_db()) {
$mailer->AddAddress($row['email']);
$mailer->send();
$mailer->ClearAllRecipients()
}
1st, get the contacts from your db
$contacts = 'GET CONTACTS ARRAY FROM DB'
if(!empty($contacts)){
foreach ($contacts as $crt_contact){
$emails[] = $crt_contact->email ;
}
}
2nd use the following to create the "to" field
$to = implode(',', array_unique($emails));
Use the $to to send in mail() function

PHP bulk mail using "phpmailer" lands in SPAM

I am using the following PHP CODE to send BULK MAIL .But Mails seems to Land in SPAM.I am using "phpmailer" class to send the mail.
require 'mailer/class.phpmailer.php';
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->SMTPSecure = "ssl";
$mail->Host = "smtp.gmail.com";
$mail->Port = 465;
$mail->Username = "info#gmail.com";
$mail->Password = "Bexwa44Puciz"; // GMAIL password
$mail->AddReplyTo('info#gmail.com', 'Info');
$Appname = 'info.com';
$_subject="Newsletter From: ".$Appname;
$ema=",";
$to_bcc=explode(",",$ema);
$mail->AddCustomHeader($headers);
foreach($to_bcc as $tb){
$mail->AddBCC($tb, $dname);
}
$_body ="News content";//$hid;
$mail->FromName = "info.com";
$mail->From="inf#gmail.com";
$mail->Subject = $_subject;
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
$mail->MsgHTML($_body);
if($mail->Send()){
echo "Done";
}else {
echo "Failed";
}
I experienced same. My website sends requests for data confirmation to users a few times each day while I do my daily data maintenance. I sent a test message to my Gmail address and found that if you read your mail through Gmail webmail interface it will sometimes tell you Why the message was spammed. Very useful. It gave the reason "A lot of messages from hp19.hostpapa.com were spam". I am on a budget shared server and I assume a hundred other spammers have bought accounts on the same machine as mine and are using it for evil. My site is non-profit so buying a dedicated box to avoid spam is not an option. So...
My solution was to change my CMS to not use PHP mail() at all. Now my CMS simply displays the message and a mailto: link with Subject parameter set. Now my process is to hit CTRL+C, Click the link, CTRL+V, and hit send. Messages are sent from my computer's IP Address (not on any blacklist) using my mail client, Thunderbird.
This takes me just a couple of seconds longer than it did when my CMS used PHP mail() to send the message for me. However I have found I am receiving a lot more replies so I am happy that the vast majority of messages are not getting spam-binned.
I appreciate this manual solution is not appropriate for automated bulk messaging but for small non-profit sites on shared server who trigger each message with a click, I thought it was worth sharing.
There are a number of reasons you could be going into someones spam box. Your email server could be blacklisted due to either you, or another user on your server. You can check it at http://mxtoolbox.com/blacklists.aspx
Also check your SPF records in your DNS

Swiftmailer BCCing 500 users

There are 500 unique users in our system and we have created a notification system that will send all the users a plain-text email when there is an update to one of the sections. The system uses swiftmailer and creates an email object and then BCCs the 500 users before sending it.
I just want some reassurance that BCCing 500 users means the server will consider this as sending out 1 email but to a lot of users. I don't want to run into any email limit restrictions set by my server host.
It will not count as one email. The fact that the content of the message is the same is irrelevant, as you still have 500 recipients. In addition, your host's email server probably caps the number of BCC recipients per message at a more reasonable value, so I'd be surprised if you could even do this at all. This sort of blast should be sent via individual messages. If your host balks at the volume, you'll likely have to go to a delivery service like Constant Contact et al.
I also tried to send 1000 emails using this method of BCC and it seemed that the limit for me was around 100 emails. So don't use this. Instead try to use the plugin that SwiftMailer provides.
Here is some sample code:
$mailer = Swift_Mailer::newInstance(
Swift_SmtpTransport::newInstance('smtp.example.org', 25)
);
// Use AntiFlood to re-connect after 100 emails
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100));
// And specify a time in seconds to pause for (30 secs)
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30));
$content = 'email body'
$message = Swift_Message::newInstance('Email subject')
->setFrom(array('no-reply#email.com'=> 'From me'))
->setBody($content,'text/html');
$emails = array('email1#email.com','email2#email.com','email3#email.com');
foreach($emails as $recipient){
$message->setTo($recipient);
$mailer->send($message);
}
I hope this helps with your problem as a simpler solution.

Sending Email with content from PHP/Mysql

I want to send emails where the data is from a php/mySQL query.
I know that html will render in the email but i don't think the php codes will.
So is there any way where i can send emails with content queried from a mySQL DB ?
I already search here, there is one topic that covers it but the person who advised suggested a pdf export or to use a 3rd party tool which in my case are not applicable.
Thank you for the help guys :)
Use PHPMailer to generate the email on the server. It makes it very easy to generate multi-part messages (plaintext + html, with attachments and embedded/inline images). Basically:
// set up PHPMailer
$mail = new PHPMailer();
$mail->SetFrom('you#yourserver.com');
$mail->AddReplyTo('you#somewhereelse.com');
$mail->Subject('Your profile');
$mail->IsHTML(TRUE);
// do your database query
$con = connect_to_database();
$stmt = run_database_query($con, "SELECT ... FROM ...");
$data = fetch_from_database($stmt);
// set the email address
$mail->AddAddress($data['email'], $data['fullname']);
// html content for smart email clients
$html = <<<EOL
<h1>Welcome</h1>
<p>Your username is {$data['username']}.</p>
EOL;
// plain text alternate content
$text = <<<EOL
Welcome
Your username is {$data['username']}.
EOL;
// add the content to the mail
$mail->MsgHTML($html);
// add alternate content
$mail->AltBody($text);
// send the mail
if ($mail->Send()) {
// mail sent correctly
} else {
die("Uhoh, could not send to {$mail['email']}:" . $mail->ErrorInfo);
}
To avoid spam issues you can wrap the PHPMailer in a class and instantiate that at every e-mail address read from the database table.
For each email address you can create a new instance and do kind of a ->setMailAddr($mail,$fullName) and after send the e-mail destroy this instance.
The ideal is to place a new instance at every POST. In this case, you can put a FORM into the page.

Categories