Page 1 of 1
email is not sent when using a loop
Posted: Fri Nov 16, 2007 5:10 pm
by choubix
hello,
i am trying to send an email to many recipients.
it returns a blank page...
I guess it comes from the decorator or from the email field...
can someone tell me what's wrong there please?
is there any possibility to better the code so it doesnt load the server too much please?
thanks!
Code: Select all
//sends an email to clients having won points (uses tables: winners && clients)
$query = (" SELECT winners.id_winner, SUM(winning_numbers), clients.fname, clients.lname, clients.email
FROM winners, clients
WHERE winners.id_winner = clients.id_clients
AND mailsent = 0
GROUP BY id_winner ");
$result = mysql_query($query) or die('Query failed. ' . mysql_error());
while($row = mysql_fetch_array($result))
{
//Start Swift
$smtp =& new Swift_Connection_SMTP("smtp.xxxxx.com");
$smtp->attachAuthenticator(new Swift_Authenticator_LOGIN());
$smtp->setUsername("xxxxxx");
$smtp->setPassword("xxxxxxx");
$swift =& new Swift($smtp);
//Create the message
$message =& new Swift_Message("Dear {fname} {lname} you have won!", "Congratulations, you have played on http://www.xxxxxxx.com and won {points} points! Please log on xxxxxx.com and check if you can redeem your points for exclusive gifts. You can also convert your points into more chances to win excluse prizes offered by our partners! Have a great day!");
$message->setTo("undisclosed-recipients:;");
$replacements = array(
"$row['email']" => array("{fname}" => "$row['fname']", "{lname}" => "$row['lname']", "{points}" => "$row['SUM(winning_numbers)']*200")
);
//Load the plugin with these replacements
$swift->attachPlugin(new Swift_Plugin_Decorator($replacements), "decorator");
//Now check if Swift actually sends it
$swift->send($message, "$row['email']", "admin@xxxxx.com");
print "ok";
}
$swift->disconnect();
Posted: Fri Nov 16, 2007 6:20 pm
by Chris Corbyn
Move all the connection stuff outside the loop.You're opening a crap load of connections then only closing the last one.

Posted: Fri Nov 16, 2007 6:33 pm
by choubix
hi Chris,
I have tried that. indeed i would make the connection faster but still: it doesnt send anything.
I remember managing to get swift to send emails by removing all decorator stuff earlier today.
but of course none of the tags {fname}, {lname} and {points} worked at that time (the $query is ok though)
by the way:
- will {points} be correctly interpreted or will it show a*200 (where a is a number) ??
- is it correct to use the batchsend in that case? (this will be a cron job, sent to quite a few persons so I quite dont want to disclose other users emails

)
here is the current code:
Code: Select all
$query = (" SELECT winners.id_winner, SUM(winning_numbers), clients.fname, clients.lname, clients.email
FROM winners, clients
WHERE winners.id_winner = clients.id_clients
AND mailsent = 0
GROUP BY id_winner ");
$result = mysql_query($query) or die('Query failed. ' . mysql_error());
//Start Swift
$smtp =& new Swift_Connection_SMTP("smtp.xxxxx.com");
$smtp->attachAuthenticator(new Swift_Authenticator_LOGIN());
$smtp->setUsername("xxxxxx");
$smtp->setPassword("xxxxxx");
while($row = mysql_fetch_array($result))
{
$swift =& new Swift($smtp);
//Create the message
$message =& new Swift_Message("Dear {fname} {lname} you have won!", "Congratulations, you have played on http://www.xxxxxx.com and won {points} points! Please log on xxxxx.com and check if you can redeem your points for exclusive gifts. You can also convert your points into more chances to win excluse prizes offered by our partners! Have a great day!");
$replacements = array(
"$row['email']" => array("{fname}" => "$row['fname']", "{lname}" => "$row['lname']", "{points}" => "$row['SUM(winning_numbers)']*200")
);
//Load the plugin with these replacements
$swift->attachPlugin(new Swift_Plugin_Decorator($replacements), "decorator");
//Now check if Swift actually sends it
$swift->batchSend($message, "$row['email']", "admin@xxxxxxx.com");
print "ok";
}
$swift->disconnect();
Posted: Sat Nov 17, 2007 8:23 am
by Chris Corbyn
Lose all the double quotes -- they're not needed and indeed will make "$a*200" appear as a string rather than a computed number.
You're still doing way too much inside the loop (overwriting $swift, overwriting $replacements etc).
Try this.
Code: Select all
$query = (" SELECT winners.id_winner, SUM(winning_numbers), clients.fname, clients.lname, clients.email
FROM winners, clients
WHERE winners.id_winner = clients.id_clients
AND mailsent = 0
GROUP BY id_winner ");
$result = mysql_query($query) or die('Query failed. ' . mysql_error());
//Start Swift
$smtp =& new Swift_Connection_SMTP("smtp.xxxxx.com");
$smtp->attachAuthenticator(new Swift_Authenticator_LOGIN());
$smtp->setUsername("xxxxxx");
$smtp->setPassword("xxxxxx");
$swift =& new Swift($smtp);
//Create the message
$message =& new Swift_Message("Dear {fname} {lname} you have won!", "Congratulations, you have played on http://www.xxxxxx.com and won {points} points! Please log on xxxxx.com and check if you can redeem your points for exclusive gifts. You can also convert your points into more chances to win excluse prizes offered by our partners! Have a great day!");
$recipients =& new Swift_RecipientList();
$replacements = array();
while($row = mysql_fetch_array($result))
{
$replacements[$row['email']] = array("{fname}" => $row['fname'], "{lname}" => $row['lname'], "{points}" => $row['SUM(winning_numbers)']*200);
$recipients->addTo($row['email']);
}
//Load the plugin with these replacements
$swift->attachPlugin(new Swift_Plugin_Decorator($replacements), "decorator");
//Now check if Swift actually sends it
if ($swift->batchSend($message, $recipients, "admin@xxxxxxx.com"))
{
echo "OK";
}
$swift->disconnect();
Posted: Sat Nov 17, 2007 9:44 pm
by choubix
hi chris,
thanks for your message.
i managed to make it work yesterday (i noticed that my quotes were not placed correctly... shame on me...)
thanks for helping me making the script run faster!!
seems to be better that way.
I will read more thoroughly the wiki to make sure my emails are not sent directly into the trash box of the recipients now
Thanks!

Posted: Sat Nov 17, 2007 11:12 pm
by choubix
it's a bit "off topic" but"
as we are using smtp.domain.com with swiftmailer:
do we need a MX record for smtp.domain.com along with the SPF record?
Posted: Sun Nov 18, 2007 2:12 am
by chuckl
Your domain setup is probably as, if not more, important than correct mail formatting in ensuring that your emails are actually delivered. Remember that all Swiftmailer does in effect is ensure that the mail is handed to the email system.
Since the mail server is sending mail for your domain it must be referenced in the SPF record. Also make sure it has a valid DNS entry and reverse DNS.
Posted: Sun Nov 18, 2007 8:47 am
by choubix
hi chuckl,
what i read was that i had to setup a SPF record myself.
when you are talking about DNS and reverse DNS can you please be a bit more precise ?
I already have set up the website using A records mainly and 1 MX record.
they are like this:
A records:
webmail.mydomain.com
mx1.mydomain.com
pop3.mydomain.com
webmail.mydomain,com
smtp.mydomain.com
mydomain.com
MX record:
mail.mydomain.com
Is this domain configuration ok since
- I am using
admin@mydomain.com (this address exists) in swift mailer.
- I am using smtp.mydomain.com to send the emails (using my login credentials)
I know that from here
http://old.openspf.org/wizard.html I can generate a SPF record for the domain.
thanks!

Posted: Sun Nov 18, 2007 10:12 am
by chuckl
I'm not quite sure how to be more precise, but I'll try.
If the server that sends the mail identifies itself as smtp.mydomain.com when sending mail, then there must be a DNS entry for machine/subdomain 'smtp' in the DNS record for mydomain.com pointing to the IP address of that server.
There should also be a reverse DNS entry containing that IP address (reversed obviously) referring to machine/subdomain 'smtp'.
Your domain SPF record should cover ALL servers that originate or send mail for your domain. It's almost impossible to give advice on how to do this, since there are so many ways of setting up an SPF record.
The other common trap often mentioned here is that when sending from a website, the mail is sent as originating from Apache user 'nobody' or 'www-data', rather than the domain of the website.
Hope that helps,
Posted: Sun Nov 18, 2007 10:55 am
by choubix
hi chuckl,
just wanted to make myself more explicit:
with swift mailer:
- I am sending my emails using smtp.mydomain.com
- I also use an existing email address with login// password in my php script.
- all the records in my previous post are redirected to the ip address of my server (both A and MX records)
BUT: when I try a reverse lookup here:
http://remote.12dt.com/lookup.php
my IP address redirects to my server in this way:
IP address resolves to wpccXXXX.myhost.com, top level domain myhost.com
according to the common trap you mentionned:
doesnt swift prevent us from this as we need to use a smtp + login/password? (i use an existing email address)
could you advise me on what to do in order to configure my DNS correctly please?
thanks

Posted: Mon Nov 19, 2007 2:41 am
by Chris Corbyn
Yep, most likely you're on a shared server and there's not really a lot you can do about reverse mappings when you're not authoritative for the IP address.
The SMTP server DOES NOT need to have a MX record held against it no. The SMTP server DOES need to have a reverse DNS entry configured however -- ideally one that responds to pings.
The domain of the sender (i.e. the From: address or the Return-Path: address) DOES need to have a MX record. Well, technically many server wall fallback to trying an A record but a large portion of servers will actually try a lookup of your MX record before accepting mail.
SPF is very important too. The SMTP server you're sending from must be in the SPF record list for the domain of your sender (i.e. the SMTP server must be allowed to send mail From: your domain).
To summarise:
SMTP does not need MX.
SMTP does need reverse DNS.
Sender address needs a MX record.
SMTP server needs to be in SPF record for sender.
Posted: Mon Nov 19, 2007 8:56 am
by choubix
thanks Chris.
I get what you are saying and I believe this explanation find it's place in a Sticky
Just want to make sure it is crystal clear on my side:
when you say: Sender address needs a MX record
does it mean:
- mydomain.com must have a MX record pointing to my IP address OR
-
email_used_to_send_emails@mydomain.com must have a MX record pointing to my IP address?
funny that you mention this: I actually am on a dedicated server (well: it is what I pay for...)
I have a Plesk dashboard + access to apache etcetc
I have to check with the guys how I can get the REVERSE DNS to point to my SMTP server.