Page 4 of 4
Posted: Wed Jun 06, 2007 9:17 pm
by fishnyc22
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

Posted: Thu Jun 07, 2007 5:07 pm
by fishnyc22
I just noticed that when there is only one record in the database to send out I get this error:
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 169
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
Posted: Thu Jun 07, 2007 8:20 pm
by fishnyc22
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.
Code: Select all
} while ($data_pos < $num_rows && $num_rows > 1); //Only while we're not at the end of the resultset
Thats should do the trick.
Posted: Thu Jun 07, 2007 10:31 pm
by fishnyc22
Dang.. 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.
Code: Select all
} while ($data_pos < $num_rows-1); //Only while we're not at the end of the resultset
Posted: Fri Jun 08, 2007 12:56 am
by Chris Corbyn
fishnyc22 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
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 place

In fact, yes, when you break it down to just one row of input and do the logic using zero to start it works perfectly.
Posted: Fri Jun 08, 2007 1:05 am
by fishnyc22
Right, that would make more sense.... I guess I backwards solved it:)
Thanks
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Posted: Fri May 30, 2008 1:04 am
by fishnyc22
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:
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 5
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.
Code: 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());
}
}
}
Anyway. Any input is appreciated. Hope you're doing well.
dave
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Posted: Fri May 30, 2008 1:17 am
by fishnyc22
Actually, while I hopefully have your attention. I also have seen this error here and there.
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 />
I'm guessing that its the server being overloaded. our usage has gone up a bit. maybe our server is a bit over worked.
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Posted: Fri May 30, 2008 9:43 pm
by Chris Corbyn
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

Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Posted: Mon Jun 02, 2008 8:59 am
by fishnyc22
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:
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());
}
I put in a few print_r() before the query to see what values are getting passed in:
$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
)
$failures has these values:
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'
)
Do you see ANYTHING that would cause the error? Any feedback appreciated.
Fish
><>
Re: [SOLVED] Using Swiftmailer to send bulk messages with CRON
Posted: Mon Jun 02, 2008 9:44 am
by fishnyc22
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!