Though I have thanked you alot over the past few days.... It can't nearly be enough. All your help is greatly appreciated
[SOLVED] Using Swiftmailer to send bulk messages with CRON
Moderators: Chris Corbyn, General Moderators
Whoops... I got it. I had the SEND outside the DoWhile Loop. Works PERFECTLY!. This is awesome. I love how it runs the batchs in one query and still uses one set of IDs to update the database...
Though I have thanked you alot over the past few days.... It can't nearly be enough. All your help is greatly appreciated
Though I have thanked you alot over the past few days.... It can't nearly be enough. All your help is greatly appreciated
I just noticed that when there is only one record in the database to send out I get this error:
It doesn not happen when there is more than one. Line 169 of BatchMailer.php is
EDIT:
However the message does go out. But it does not update the value in the DB to 'S'. So something is killing before that
Code: Select all
Fatal error: Call to a member function on a non-object in /var/www/vhosts/domain.com/httpdocs/util/lib/swift/Swift/BatchMailer.php on line 169Code: Select all
$message->headers->set("To", "");However the message does go out. But it does not update the value in the DB to 'S'. So something is killing before that
OK, I figured it out.
Where there was only one record in the recordset, the doWhile loop was reseting the batch because at first pass $data_pos = 0 and $num_rows = 1.... so $message, $sender were set to null so it ran another cycle and failed the inner while loop, but tried to send the batch after the while loop.
I fixed it by changing this line and adding "&& $num_rows > 1" so it stops there when the record set is only one row.
Thats should do the trick.
Where there was only one record in the recordset, the doWhile loop was reseting the batch because at first pass $data_pos = 0 and $num_rows = 1.... so $message, $sender were set to null so it ran another cycle and failed the inner while loop, but tried to send the batch after the while loop.
I fixed it by changing this line and adding "&& $num_rows > 1" so it stops there when the record set is only one row.
Code: Select all
} while ($data_pos < $num_rows && $num_rows > 1); //Only while we're not at the end of the resultsetDang.. I take that back. Still getting that bug.
EDIT: I think I resolved it however. Does this make sense??? Seems that when I set the doWhile loop to be the following, It solved the problem.
EDIT: I think I resolved it however. Does this make sense??? Seems that when I set the doWhile loop to be the following, It solved the problem.
Code: Select all
} while ($data_pos < $num_rows-1); //Only while we're not at the end of the resultset- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
I think that makes sense. Where I first declare "$data_pos = -1;" I initially had it to 0 but started to think it probably needed to be -1 due to the way I increment it in the loop. I guess 0 was correct in the first placefishnyc22 wrote:EDIT: I think I resolved it however. Does this make sense??? Seems that when I set the doWhile loop to be the following, It solved the problem.
Code: Select all
} while ($data_pos < $num_rows-1); //Only while we're not at the end of the resultset
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Hey Chris, A while back you helped me out A LOT with this. Just thought I would check in with a bit of advise. First off. Last I spoke to you, you were raising money for a trip Down Under. Now I see your location is DOWN UNDER... did you move. Good stuff man. I guess you had a good walk about 
Anyway. This is my problem. I've been randomly getting these errors when running my script:
This is my script. Not sure if you can see anything here thats causing it but its driving me crazy. The error doesnt give me much info, but I thought maybe you may have an idea. I'm wondering if maybe its happening on and off when they failure array is hit. I've never actually gotten a -1 in my db's status column.
Anyway. Any input is appreciated. Hope you're doing well.
dave
Anyway. This is my problem. I've been randomly getting these errors when running my script:
Code: Select all
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5Code: Select all
$max_size = 100;
$sql = "
SELECT
Q.id,
Q.msg_id,
M.m_subject,
M.m_message,
A.ag_shortname,
A.ag_nickname,
Q.to_id,
Q.to_email,
Q.to_name
FROM
`bt_sms_queue` AS Q,
`bt_messages` AS M,
`members` AS A
WHERE
A.member_id = M.m_agid
AND Q.msg_id = M.mid
AND M.mailserver = 2
AND Q.status = 0
ORDER BY
Q.msg_id
LIMIT " . $max_size;
$result = mysql_query($sql, $connection) or die(mysql_error());
$num_rows = mysql_num_rows($result);
$data_pos = 1; //Current position in the resultset
$ids = array();
//Nothing to do if no data
if ($num_rows > 0)
{
$swift =& new Swift(new Swift_Connection_SMTP("localhost"));
$batch =& new Swift_BatchMailer($swift);
do
{
//Build up a list of recipients
$list =& new Swift_RecipientList();
$message = NULL;
$sender = NULL;
$message_id = -1; //For tracking in the loop
while ($row = mysql_fetch_assoc($result))
{
$data_pos++;
//Not the same message anymore -- different batch
if ($message_id > -1 && $row["msg_id"] != $message_id)
{
mysql_data_seek($result, --$data_pos); //Backtrack ready for next batch
break; //Just this loop
}
$message_id = $row["msg_id"]; //Keep watching!
//No need to repeatedly create $message or $sender in the loop
if ($message === NULL) $message =& new Swift_Message($row["m_subject"], $row["m_message"]);
if ($sender === NULL) $sender =& new Swift_Address($row["ag_shortname"]."@domain.com",$row["ag_nickname"] );
$list->addTo($row["to_email"], $row["to_name"]);
//Collect recipient IDs for use later
$ids[] = $row["id"];
}
//Send this batch
$batch->send($message, $list, $sender);
} while ($data_pos < $num_rows); //Only while we're not at the end of the resultset
//If we have any records to update
if (!empty($ids))
{
//Some may have failed, some may not
$failures = $batch->getFailedRecipients();
foreach ($failures as $key => $value)
{
//Filter for use in SQL (and add single quotes)
$failures[$key] = "'" . mysql_real_escape_string($value) . "'";
}
//Update all that have NOT failed to 'S'
$sql2 = "
UPDATE bt_sms_queue
SET status = 1
WHERE
id IN (" . @implode(",", $ids) . ")";
if (!empty($failures))
{
$sql2 .= " AND to_email NOT IN (" . implode(",", $failures) . ")";
}
mysql_query($sql2, $connection) or die(mysql_error());
//Update all that have failed to 'F'
if (!empty($failures))
{
$sql3 = "
UPDATE bt_sms_queue
SET status = -1
WHERE
id IN (" . implode(",", $ids) . " AND to_email IN (" . implode(",", $failures) . ")";
mysql_query($sql3, $connection) or die(mysql_error());
}
}
}dave
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Actually, while I hopefully have your attention. I also have seen this error here and there.
I'm guessing that its the server being overloaded. our usage has gone up a bit. maybe our server is a bit over worked.
Code: Select all
<br />
<b>Warning</b>: mysql_data_seek(): Offset 2 is invalid for MySQL result index 57 (or the query data is unbuffered) in <b>/var/www/vhosts/domain.com/httpdocs/sender.php</b> on line <b>75</b><br />- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
I can't see which query that error is coming from at a glance. Maybe add some text to the die() statements to identify each on separately, or perhaps use trigger_error() so you get the line number? 
The mysql_data_seek() error looks valid. I don't think an overworked server would affect it... it's suggesting that the resultset you're trying to seek on doesn't have 3 rows of data in it
The mysql_data_seek() error looks valid. I don't think an overworked server would affect it... it's suggesting that the resultset you're trying to seek on doesn't have 3 rows of data in it
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Yeah I probably should have thought to do that. Thanks for the tip.
From that. I found that its the 3rd query that is causing the error:
I put in a few print_r() before the query to see what values are getting passed in:
$ids had these values:
$failures has these values:
Do you see ANYTHING that would cause the error? Any feedback appreciated.
Fish
><>
From that. I found that its the 3rd query that is causing the error:
Code: Select all
if (!empty($failures))
{
$sql3 = "
UPDATE bt_sms_queue
SET status = -1
WHERE
id IN (" . implode(",", $ids) . " AND to_email IN (" . implode(",", $failures) . ")";
mysql_query($sql3, $connection) or die("Query3: " . mysql_error());
}$ids had these values:
Code: Select all
Array
(
[0] => 688519
[1] => 688518
[2] => 688514
[3] => 688482
[4] => 688481
[5] => 688477
[6] => 688475
[7] => 688474
[8] => 688470
[9] => 688469
[10] => 688468
[11] => 688467
[12] => 688466
[13] => 688465
[14] => 688464
[15] => 688463
[16] => 688462
[17] => 688461
[18] => 688460
[19] => 688459
[20] => 688458
[21] => 688457
[22] => 688456
[23] => 688455
[24] => 688454
[25] => 688453
[26] => 688452
[27] => 688451
[28] => 688450
[29] => 688449
[30] => 688448
[31] => 688447
[32] => 688446
[33] => 688445
[34] => 688444
[35] => 688443
[36] => 688442
[37] => 688441
[38] => 688440
[39] => 688439
[40] => 688438
[41] => 688437
[42] => 688436
[43] => 688435
[44] => 688434
[45] => 688433
)
Code: Select all
Array
(
[0] => 'NUMBER@messaging.sprintpcs.com'
[1] => 'NUMBER@messaging.sprintpcs.com'
[2] => 'NUMBER@messaging.sprintpcs.com'
[3] => 'NUMBER@messaging.sprintpcs.com'
[4] => 'NUMBER@messaging.sprintpcs.com'
[5] => 'NUMBER@messaging.sprintpcs.com'
[6] => 'NUMBER@mobile.mycingular.com'
[7] => 'NUMBER@messaging.sprintpcs.com'
[8] => 'NUMBER@messaging.sprintpcs.com'
[9] => 'NUMBER@messaging.sprintpcs.com'
[10] => 'NUMBER@mobile.mycingular.com'
[11] => 'NUMBER@mobile.mycingular.com'
[12] => 'NUMBER@mobile.mycingular.com'
[13] => 'NUMBER@messaging.sprintpcs.com'
[14] => 'NUMBER@messaging.sprintpcs.com'
[15] => 'NUMBER@mobile.mycingular.com'
[16] => 'NUMBER@messaging.nextel.com'
[17] => 'NUMBER@tmomail.net'
[18] => 'NUMBER@messaging.sprintpcs.com'
)
Fish
><>
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
I outputted the query to see what it looks like and found I was missing a closing ")" in the first IN statement.
Thanks for the suggestion and the help!
Thanks for the suggestion and the help!