? .DS_Store ? node-355905-3.patch ? sites/all/.DS_Store ? sites/all/modules/devel ? sites/default/files ? sites/default/settings.php Index: modules/node/node.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v retrieving revision 1.43 diff -u -p -r1.43 node.admin.inc --- modules/node/node.admin.inc 20 Mar 2009 08:14:34 -0000 1.43 +++ modules/node/node.admin.inc 17 Apr 2009 06:03:36 -0000 @@ -90,33 +90,33 @@ function node_node_operations() { $operations = array( 'publish' => array( 'label' => t('Publish'), - 'callback' => 'node_mass_update', - 'callback arguments' => array('updates' => array('status' => 1)), + 'callback' => 'node_mass_operation', + 'callback arguments' => array('op' => 'update', 'updates' => array('status' => 1)), ), 'unpublish' => array( 'label' => t('Unpublish'), - 'callback' => 'node_mass_update', - 'callback arguments' => array('updates' => array('status' => 0)), + 'callback' => 'node_mass_operation', + 'callback arguments' => array('op' => 'update', 'updates' => array('status' => 0)), ), 'promote' => array( 'label' => t('Promote to front page'), - 'callback' => 'node_mass_update', - 'callback arguments' => array('updates' => array('status' => 1, 'promote' => 1)), + 'callback' => 'node_mass_operation', + 'callback arguments' => array('op' => 'update', 'updates' => array('status' => 1, 'promote' => 1)), ), 'demote' => array( 'label' => t('Demote from front page'), - 'callback' => 'node_mass_update', - 'callback arguments' => array('updates' => array('promote' => 0)), + 'callback' => 'node_mass_operation', + 'callback arguments' => array('op' => 'update', 'updates' => array('promote' => 0)), ), 'sticky' => array( 'label' => t('Make sticky'), - 'callback' => 'node_mass_update', - 'callback arguments' => array('updates' => array('status' => 1, 'sticky' => 1)), + 'callback' => 'node_mass_operation', + 'callback arguments' => array('op' => 'update', 'updates' => array('status' => 1, 'sticky' => 1)), ), 'unsticky' => array( 'label' => t('Remove stickiness'), - 'callback' => 'node_mass_update', - 'callback arguments' => array('updates' => array('sticky' => 0)), + 'callback' => 'node_mass_operation', + 'callback arguments' => array('op' => 'update', 'updates' => array('sticky' => 0)), ), 'delete' => array( 'label' => t('Delete'), @@ -337,106 +337,6 @@ function node_filter_form_submit($form, } /** - * 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'), - // We use a single multi-pass operation, so the default - // 'Remaining x of y operations' message will be confusing here. - 'progress_message' => '', - 'error_message' => t('The update has encountered an error.'), - // The operations do not live in the .module file, so we need to - // tell the batch engine which file to load before calling them. - 'file' => drupal_get_path('module', 'node') . '/node.admin.inc', - ); - 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']++; - } - - // 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); - } -} - -/** * Menu callback: content administration. */ function node_admin_content($form_state) { @@ -642,9 +542,8 @@ function node_multiple_delete_confirm(&$ function node_multiple_delete_confirm_submit($form, &$form_state) { if ($form_state['values']['confirm']) { - foreach ($form_state['values']['nodes'] as $nid => $value) { - node_delete($nid); - } + $nodes = array_keys($form_state['values']['nodes']); + node_mass_operation($nodes, 'delete'); drupal_set_message(t('The items have been deleted.')); } $form_state['redirect'] = 'admin/content/node'; Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1033 diff -u -p -r1.1033 node.module --- modules/node/node.module 26 Mar 2009 13:31:25 -0000 1.1033 +++ modules/node/node.module 17 Apr 2009 06:03:37 -0000 @@ -1560,16 +1560,14 @@ function node_user_cancel($edit, $accoun switch ($method) { case 'user_cancel_block_unpublish': // Unpublish nodes (current revisions). - module_load_include('inc', 'node', 'node.admin'); $nodes = db_select('node', 'n')->fields('n', array('nid'))->condition('uid', $account->uid)->execute()->fetchCol(); - node_mass_update($nodes, array('status' => 0)); + node_mass_operation($nodes, 'update', array('status' => 0)); break; case 'user_cancel_reassign': // Anonymize nodes (current revisions). - module_load_include('inc', 'node', 'node.admin'); $nodes = db_select('node', 'n')->fields('n', array('nid'))->condition('uid', $account->uid)->execute()->fetchCol(); - node_mass_update($nodes, array('uid' => 0)); + node_mass_operation($nodes, 'update', array('uid' => 0)); // Anonymize old revisions. db_update('node_revision')->fields(array('uid' => 0))->condition('uid', $account->uid)->execute(); // Clean history. @@ -1578,11 +1576,8 @@ function node_user_cancel($edit, $accoun case 'user_cancel_delete': // Delete nodes (current revisions). - // @todo Introduce node_mass_delete() or make node_mass_update() more flexible. $nodes = db_select('node', 'n')->fields('n', array('nid'))->condition('uid', $account->uid)->execute()->fetchCol(); - foreach ($nodes as $nid) { - node_delete($nid); - } + node_mass_operation($nodes, 'delete'); // Delete old revisions. db_delete('node_revision')->condition('uid', $account->uid)->execute(); // Clean history. @@ -3166,3 +3161,126 @@ function node_elements() { function theme_node_links($element) { return theme('links', $element['#value'], array('class' => 'links inline')); } + +/** + * Perform a mass operation on nodes, switching based on the specified + * operation. Currently supports updating and deleting, utilizing the batch + * API for large numbers of 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 string $op + * The operation to be performed (Currently either 'delete' or 'update') + * @param array $updates + * Array of key/value pairs with node field names and the + * value to update that field to. + */ +function node_mass_operation($nodes, $op, $updates = array()) { + // 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_operation_batch_process', array($nodes, $op, $updates)) + ), + 'finished' => '_node_mass_operation_batch_finished', + 'title' => t('Processing'), + // We use a single multi-pass operation, so the default + // 'Remaining x of y operations' message will be confusing here. + 'progress_message' => '', + 'error_message' => t('The %op has encountered an error.', array('%op' => $op)), + ); + batch_set($batch); + } + else { + foreach ($nodes as $nid) { + _node_mass_operation_helper($nid, $op, $updates); + } + drupal_set_message(t('The %op has been performed.', array('%op' => $op))); + } +} + +/** + * Node Mass Operation - helper function. + */ +function _node_mass_operation_helper($nid, $op, $updates) { + $node = node_load($nid, NULL, TRUE); + + switch ($op) { + case 'update': + foreach ($updates as $name => $value) { + $node->$name = $value; + } + node_save($node); + break; + + case 'delete': + node_delete($nid); + $node->nid = NULL; + break; + } + + return $node; + +} + +/** + * Node Mass Operation Batch operation + */ +function _node_mass_operation_batch_process($nodes, $op, $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, call the opertion helper + $nid = array_shift($context['sandbox']['nodes']); + + $node = _node_mass_operation_helper($nid, $op, $updates); + + switch ($op) { + case 'update': + // Store result for post-processing in the finished callback. + $context['results'][] = l($node->title, 'node/' . $node->nid); + break; + + case 'delete': + // Store result for post-processing in the finished callback. + $context['results'][] = t('Deleted '. $node->title); + break; + } + + + // Update our progress information. + $context['sandbox']['progress']++; + } + + // 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_operation_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 Index: modules/user/user.api.php =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.api.php,v retrieving revision 1.4 diff -u -p -r1.4 user.api.php --- modules/user/user.api.php 14 Mar 2009 23:01:38 -0000 1.4 +++ modules/user/user.api.php 17 Apr 2009 06:03:38 -0000 @@ -128,16 +128,14 @@ function hook_user_cancel($edit, $accoun switch ($method) { case 'user_cancel_block_unpublish': // Unpublish nodes (current revisions). - module_load_include('inc', 'node', 'node.admin'); $nodes = db_select('node', 'n')->fields('n', array('nid'))->condition('uid', $account->uid)->execute()->fetchCol(); - node_mass_update($nodes, array('status' => 0)); + node_mass_operation($nodes, 'update', array('status' => 0)); break; case 'user_cancel_reassign': // Anonymize nodes (current revisions). - module_load_include('inc', 'node', 'node.admin'); $nodes = db_select('node', 'n')->fields('n', array('nid'))->condition('uid', $account->uid)->execute()->fetchCol(); - node_mass_update($nodes, array('uid' => 0)); + node_mass_operation($nodes, 'update', array('uid' => 0)); // Anonymize old revisions. db_update('node_revision')->fields(array('uid' => 0))->condition('uid', $account->uid)->execute(); // Clean history. @@ -147,9 +145,7 @@ function hook_user_cancel($edit, $accoun case 'user_cancel_delete': // Delete nodes (current revisions). $nodes = db_select('node', 'n')->fields('n', array('nid'))->condition('uid', $account->uid)->execute()->fetchCol(); - foreach ($nodes as $nid) { - node_delete($nid); - } + node_mass_operation($node, 'delete'); // Delete old revisions. db_delete('node_revision')->condition('uid', $account->uid)->execute(); // Clean history.