From 5686eea147e4e67cd627bc06a0d2785e0ac58f7e Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Wed, 3 Oct 2007 17:35:22 +0000 Subject: - Patch #164510 by yched et al: node.changed not updated on mass operations. --- modules/node/node.admin.inc | 61 ++++++----------------------- modules/node/node.module | 95 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 49 deletions(-) (limited to 'modules') diff --git a/modules/node/node.admin.inc b/modules/node/node.admin.inc index 115bb486e..a533ee0e8 100644 --- a/modules/node/node.admin.inc +++ b/modules/node/node.admin.inc @@ -82,27 +82,33 @@ function node_node_operations() { $operations = array( 'publish' => array( 'label' => t('Publish'), - 'callback' => 'node_operations_publish', + 'callback' => 'node_mass_update', + 'callback arguments' => array('updates' => array('status' => 1)), ), 'unpublish' => array( 'label' => t('Unpublish'), - 'callback' => 'node_operations_unpublish', + 'callback' => 'node_mass_update', + 'callback arguments' => array('updates' => array('status' => 0)), ), 'promote' => array( 'label' => t('Promote to front page'), - 'callback' => 'node_operations_promote', + 'callback' => 'node_mass_update', + 'callback arguments' => array('updates' => array('status' => 1, 'promote' => 1)), ), 'demote' => array( 'label' => t('Demote from front page'), - 'callback' => 'node_operations_demote', + 'callback' => 'node_mass_update', + 'callback arguments' => array('updates' => array('promote' => 0)), ), 'sticky' => array( 'label' => t('Make sticky'), - 'callback' => 'node_operations_sticky', + 'callback' => 'node_mass_update', + 'callback arguments' => array('updates' => array('status' => 1, 'sticky' => 1)), ), 'unsticky' => array( 'label' => t('Remove stickiness'), - 'callback' => 'node_operations_unsticky', + 'callback' => 'node_mass_update', + 'callback arguments' => array('updates' => array('sticky' => 0)), ), 'delete' => array( 'label' => t('Delete'), @@ -112,48 +118,6 @@ function node_node_operations() { return $operations; } -/** - * Callback function for admin mass publishing nodes. - */ -function node_operations_publish($nodes) { - db_query('UPDATE {node} SET status = 1 WHERE nid IN('. db_placeholders($nodes) .')', $nodes); -} - -/** - * Callback function for admin mass unpublishing nodes. - */ -function node_operations_unpublish($nodes) { - db_query('UPDATE {node} SET status = 0 WHERE nid IN('. db_placeholders($nodes) .')', $nodes); -} - -/** - * Callback function for admin mass promoting nodes. - */ -function node_operations_promote($nodes) { - db_query('UPDATE {node} SET status = 1, promote = 1 WHERE nid IN('. db_placeholders($nodes) .')', $nodes); -} - -/** - * Callback function for admin mass demoting nodes. - */ -function node_operations_demote($nodes) { - db_query('UPDATE {node} SET promote = 0 WHERE nid IN('. db_placeholders($nodes) .')', $nodes); -} - -/** - * Callback function for admin mass editing nodes to be sticky. - */ -function node_operations_sticky($nodes) { - db_query('UPDATE {node} SET status = 1, sticky = 1 WHERE nid IN('. db_placeholders($nodes) .')', $nodes); -} - -/** - * Callback function for admin mass editing nodes to remove stickiness. - */ -function node_operations_unsticky($nodes) { - db_query('UPDATE {node} SET sticky = 0 WHERE nid IN('. db_placeholders($nodes) .')', $nodes); -} - /** * List node administration filters that can be applied. */ @@ -364,7 +328,6 @@ function node_admin_nodes_submit($form, &$form_state) { call_user_func_array($function, $args); cache_clear_all(); - drupal_set_message(t('The update has been performed.')); } else { // We need to rebuild the form to go to a second step. For example, to diff --git a/modules/node/node.module b/modules/node/node.module index 7e1865565..56de974d5 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -2533,3 +2533,98 @@ function node_unpublish_by_keyword_action($node, $context) { } } } + +/** + * Make mass update of nodes, changing all nodes in the $nodes array + * to update them with the field values in $updates. + * + * IMPORTANT NOTE: This function is intended to work when called + * from a form submit handler. Calling it outside of the form submission + * process may not work correctly. + * + * @param array $nodes + * Array of node nids to update. + * @param array $updates + * Array of key/value pairs with node field names and the + * value to update that field to. + */ +function node_mass_update($nodes, $updates) { + // We use batch processing to prevent timeout when updating a large number + // of nodes. + if (count($nodes) > 10) { + $batch = array( + 'operations' => array( + array('_node_mass_update_batch_process', array($nodes, $updates)) + ), + 'finished' => '_node_mass_update_batch_finished', + 'title' => t('Processing'), + 'error_message' => t('The update has encountered an error.'), + ); + batch_set($batch); + } + else { + foreach($nodes as $nid) { + _node_mass_update_helper($nid, $updates); + } + drupal_set_message(t('The update has been performed.')); + } +} + +/** + * Node Mass Update - helper function. + */ +function _node_mass_update_helper($nid, $updates) { + $node = node_load($nid, NULL, TRUE); + foreach ($updates as $name => $value) { + $node->$name = $value; + } + node_save($node); + return $node; +} + +/** + * Node Mass Update Batch operation + */ +function _node_mass_update_batch_process($nodes, $updates, &$context) { + if (!isset($context['sandbox']['progress'])) { + $context['sandbox']['progress'] = 0; + $context['sandbox']['max'] = count($nodes); + $context['sandbox']['nodes'] = $nodes; + } + + // Process nodes by groups of 5. + $count = min(5, count($context['sandbox']['nodes'])); + for ($i = 1; $i <= $count; $i++) { + // For each nid, load the node, reset the values, and save it. + $nid = array_shift($context['sandbox']['nodes']); + $node = _node_mass_update_helper($nid, $updates); + + // Store result for post-processing in the finished callback. + $context['results'][] = l($node->title, 'node/'. $node->nid); + + // Update our progress information. + $context['sandbox']['progress']++; + $context['message'] = t('Processing %title', array('%title' => $node->title)); + } + + // Inform the batch engine that we are not finished, + // and provide an estimation of the completion level we reached. + if ($context['sandbox']['progress'] != $context['sandbox']['max']) { + $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max']; + } +} + +/** + * Node Mass Update Batch 'finished' callback. + */ +function _node_mass_update_batch_finished($success, $results, $operations) { + if ($success) { + drupal_set_message(t('The update has been performed.')); + } + else { + drupal_set_message(t('An error occurred and processing did not complete.'), 'error'); + $message = format_plural(count($results), '1 item successfully processed:', '@count items successfully processed:'); + $message .= theme('item_list', $results); + drupal_set_message($message); + } +} \ No newline at end of file -- cgit v1.2.3