0

I rarely ask questions on SE but now the teacher has become the student because this is driving me mad. I am doing a simple batch through an update hook and publishing some unpublished nodes. I am aware I could do this with a flat query, but I am preferring to use the batch system.

For whatever reason it arbitrarily stops at 50% no matter what I do. I have tried modifying the nodes per pass, etc. No errors. It just stop at the halfway point. When I debug the hook, I can see the counter variable increments right up to halfway and then stops. This is the hook. Am I crazy?

function mymodule_update_7200(&$sandbox) {
// Initialize the batch
  if (!isset($sandbox['total'])) {
    $result = db_query('SELECT nid FROM {node} n WHERE n.type = :type AND n.status = 0', array(':type' => 'event'));
    $sandbox['total'] = $result->rowCount();
    $sandbox['current'] = 0;

    // Disable Scheduler
    module_disable(array('scheduler'));
    drupal_set_message(t('The scheduler module was disabled'));
  }

  $nodes_per_pass = 20;

  // Get the nodes to process during this pass.
  $result = db_query_range('SELECT nid FROM {node} n WHERE n.type = :type AND n.status = 0', $sandbox['current'], $nodes_per_pass, array(':type' => 'event'));
  foreach($result as $row){

    $node = node_load($row->nid);

    // Run a database update directly so we don't trigger any API calls through node_save
    db_query("UPDATE {node} n SET n.status = 1 WHERE n.nid = :nid", array(':nid' => $row->nid));

    // Log the event being published
    watchdog(
      'events',
      'Event was published: %title',
      array('%title' => $node->title),
      WATCHDOG_NOTICE,
      l('View', "node/$node->nid")
    );

    // Increment "current" by 1.
    $sandbox['current']++;
  }

  // Set the value for finished. If current == total then finished will be 1, signifying we are done.
  $sandbox['#finished'] = ($sandbox['current'] / $sandbox['total']);

  if ($sandbox['#finished'] === 1) {
    drupal_set_message(t('@nodes events were published. View the log for details.', array('@nodes' => $sandbox['total'])));
  }
}
  • "No errors." ... does that include in your web server error log? I don't see anything obviously wrong with your script. – user5482 Feb 5 '15 at 18:26
  • I know. It's crazy, right? Yes, no errors in PHP, MYSQL, or Apache logs. None on the watchdog either. – webkenny Feb 5 '15 at 18:30
  • Also, FWIW - I am running this locally on a MAMP Pro server. APC enabled along with XDebug. (I doubt that matters but worth mentioning) – webkenny Feb 5 '15 at 18:32
  • In every example I can find, they use $sandbox['progress'] instead of $sandbox['current']. Could that make a difference? – RoloDMonkey Feb 6 '15 at 1:19
1

The problem in this case is caused because results query differs between iterations.

You should replace:

$result = db_query_range('SELECT nid FROM {node} n WHERE n.type = :type AND n.status = 0', $sandbox['current'], $nodes_per_pass, array(':type' => 'event'));

with

$result = db_query_range('SELECT nid FROM {node} n WHERE n.type = :type AND n.status = 0 ORDER BY n.nid ASC', 0, $nodes_per_pass, array(':type' => 'event'));

| improve this answer | |
  • Of course. You sir, are excellent. I can't believe it's always the basic SQL that hangs us in the end. Thank you! – webkenny Feb 14 '15 at 21:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.