=== modified file 'includes/common.inc'
--- includes/common.inc 2007-06-04 14:15:51 +0000
+++ includes/common.inc 2007-06-04 14:20:50 +0000
@@ -2832,6 +2832,325 @@ function drupal_common_themes() {
}
/**
+ * Create/build/execute deletion packages.
+ *
+ * @param $id
+ * A unique string identifier for the deletion being performed.
+ *
+ * @param $op
+ * An operation to be performed -- one of the following values:
+ *
+ * 'query' -- Pass a deletion query to the API.
+ *
+ * 'new package' -- Used to begin a new deletion package. A package is set of deletion
+ * queries associated with a particular kind of deletion -- for example,
+ * all the queries associated with a node deletion. Most often it will
+ * not be necessary to start a new package, as most non-core deletions will
+ * already be part of a package initiated by core. Once a package has
+ * been started, all calls to drupal_delete() containing the 'query',
+ * 'metadata', and 'callback' operations are added to the package. A
+ * package is complete when either a new package is started, or
+ * when drupal_delete() is called with the 'confirm' or 'execute'
+ * operations.
+ *
+ * 'confirm' -- Initiates the confirmation cycle. This command fully builds all packages
+ * for deletion, and returns a confirm form array containing any injected messages
+ * which can be used to print a confirmation screen.
+ *
+ * 'form' -- Pass in a package-specific set of form elements, to be displayed in the
+ * confirm form. Use this in multiple deletion scenarios where the confirm
+ * information shouldn't be displayed if the package is aborted.
+ *
+ * 'execute' -- Initiates the deletion of all constructed packages. Confirmation messages
+ * are bypassed, but abort messages are respected.
+ *
+ * 'callback' -- Register a callback function. The function is called after the package
+ * has been deleted. Useful for miscellaneous cleanup, user messages, etc.
+ *
+ * 'metadata' -- Pass metadata related to the deletion or package to the API. This is made
+ * available to all hooks called during the deletion cycle.
+ *
+ * Additional arguments are passed to the function, depending on the operation to be
+ * performed:
+ *
+ * 'query' -- The query to be passed, followed by any additional arguments for escaped
+ * values.
+ * ex. drupal_delete('comment', 'query', 'DELETE FROM {comments} WHERE nid = %d', array('nid' => $node->nid));
+ * The additional arguments can be passed in any fashion that db_query() accepts.
+ *
+ * 'new package' -- No arguments required.
+ *
+ * 'confirm' -- An associative array with the following key/value pairs:
+ * 'form' => Optional. An array representing the form elements to pass to the confirm form.
+ * 'question' => Optional. The question for the confirm form.
+ * 'path' => Optional. The cancellation path for the confirm form.
+ *
+ * Also, any valid options from the $options argument of confirm_form() may be passed,
+ * and they will be passed through to the confirm form.
+ * ex. drupal_delete('admin_node', 'confirm',
+ * array(
+ * 'form' => $form,
+ * 'question' => t('Are you sure you want to delete these items?'),
+ * 'path' => 'admin/content/node',
+ * 'yes' => t('Delete all'),
+ * 'destination' => 'admin/content/node',
+ * )
+ * );
+ *
+ *
+ * 'form' -- An array representing the package-specific form elements to pass to the confirm form.
+ * ex. drupal_delete('admin_node', 'form',
+ * array(
+ * "node_$node->nid" => array(
+ * '#value' => check_plain($node->title),
+ * '#prefix' => '
',
+ * '#suffix' => "\n",
+ * ),
+ * )
+ * );
+ *
+ * 'execute' -- No arguments required.
+ *
+ * 'callback' -- An associative array of callback functions, key = name of function,
+ * value = an array of arguments to pass to the function.
+ * ex. drupal_delete('node', 'callback',
+ * array(
+ * 'node_delete_post' => array($node->nid, $node->title, $node->type),
+ * )
+ * );
+ *
+ * 'metadata' -- An associative array of metadata.
+ * ex. drupal_delete('comment', 'metadata',
+ * array(
+ * 'comment_messages' => $messages
+ * )
+ * );
+ */
+function drupal_delete($id, $op) {
+ static $delete_id = 0,
+ $is_package = NULL,
+ $deletion_data = array(),
+ $built = NULL,
+ $form = array();
+
+ $confirm = NULL;
+ $execute = NULL;
+ $destination = FALSE;
+
+ // Process additional arguments.
+ $all_args = func_get_args();
+ if (count($all_args) > 2) {
+ // Get any additional arguments after required ones.
+ $args = array_slice($all_args, 2);
+ // Shift off query string if present.
+ if ($op == 'query' || $op == 'delete') {
+ $query = array_shift($args);
+ }
+ // Clean up args passed as an array.
+ if (is_array($args[0])) {
+ $args = $args[0];
+ }
+ }
+ else {
+ $args = array();
+ }
+
+ switch ($op) {
+ // Query to add to a package
+ case 'query':
+ // Add the information for this deletion into the package array.
+ $deletion_data[$delete_id][$id][] = array('query' => $query, 'args' => $args);
+ break;
+ // New package -- mark it as such and get the next deletion ID.
+ case 'new package':
+ $delete_id++;
+ $is_package = TRUE;
+ $deletion_data[$delete_id] = array(
+ 'metadata' => array(),
+ 'callback' => array(),
+ 'form' => array(),
+ );
+ break;
+ // Confirm all packages.
+ case 'confirm':
+ // Set execute switch and destination if bypass is enabled.
+ if (variable_get('bypass_delete_confirmation', 0)) {
+ $execute = TRUE;
+ $destination = isset($args['destination']) ? $args['destination'] : NULL;
+ }
+ else {
+ $confirm = TRUE;
+ }
+ break;
+ // Add package-specific form array pieces, callbacks, metadata.
+ case 'form':
+ case 'callback':
+ case 'metadata':
+ $deletion_data[$delete_id][$op] += $args;
+ break;
+ // Execute all packages.
+ case 'execute':
+ $execute = TRUE;
+ break;
+ }
+
+ // Allow modules to inject confirm/abort data.
+ if (isset($confirm) || isset($execute)) {
+ // $built is kept as a static and checked to avoid calling this code twice
+ // when the package is executed.
+ if (!isset($built)) {
+ $built = TRUE;
+
+ // Main confirm form.
+ if (isset($args['form'])) {
+ $form = $args['form'];
+ }
+
+ foreach ($deletion_data as $package_id => $package_info) {
+ $package_confirm_data = array();
+ // Reset $delete_id to the package to be passed.
+ $delete_id = $package_id;
+ // Call hook_delete_pre() once for each package.
+ foreach (module_implements('delete_pre') as $module) {
+ $function = $module .'_delete_pre';
+ $confirm_data = $function($package_info);
+ // Check for an aborted package.
+ if (isset($confirm_data['abort'])) {
+ // Set abort message.
+ if (isset($confirm_data['abort']['message'])) {
+ drupal_set_message($confirm_data['abort']['message'], 'error');
+ }
+ // Set abort destination.
+ if (isset($confirm_data['abort']['destination'])) {
+ $abort_destination = $confirm_data['abort']['destination'];
+ }
+ // Remove the package.
+ unset($deletion_data[$package_id]);
+ }
+ else {
+ // Add elements to confirm form data for the package.
+ $package_confirm_data = array_merge_recursive($package_confirm_data, $confirm_data);
+ }
+ }
+ // Add in package-specific confirm form elements if the package still exists.
+ if (isset($deletion_data[$package_id])) {
+ $form = array_merge_recursive($form, $package_confirm_data);
+ if (!empty($package_info['form'])) {
+ $form = array_merge_recursive($form, $package_info['form']);
+ }
+ }
+ }
+ if (isset($confirm)) {
+ // Check to make sure there's at least one valid package left.
+ $count = FALSE;
+ foreach ($deletion_data as $package_id => $package_info) {
+ // Package should contain more than just 'form', 'callback', and 'metadata'
+ // keys if it contains any actual deletion data -- otherwise it was just a
+ // metadata-only package.
+ if (count($package_info) > 3) {
+ $count = TRUE;
+ break;
+ }
+ }
+ // Generate the confirm form.
+ if ($count) {
+ $question = isset($args['question']) ? $args['question'] : t('Delete the item?');
+ $path = isset($args['path']) ? $args['path'] : 'node';
+ unset($args['question'], $args['path']);
+ $args['name'] = 'delete';
+ // Submit handler - triggers execute operation for the API.
+ $form['#submit'] = array('delete_confirm_submit');
+ return confirm_form($form, $question, $path, $args);
+ }
+ // No packages left after aborts -- go to an abort destination if it exists.
+ elseif (isset($abort_destination)) {
+ drupal_goto($abort_destination);
+ }
+ // Fallback to cancel path.
+ elseif (isset($args['path'])) {
+ drupal_goto($args['path']);
+ }
+ // Last fallback, front page.
+ else {
+ drupal_goto('');
+ }
+ }
+ }
+ }
+
+ // Execute all constructed packages.
+ if (isset($execute)) {
+
+ // Explicitly reset the package information.
+ $delete_id = 0;
+ $is_package = NULL;
+ $package_data = $deletion_data;
+ $deletion_data = array();
+ $built = NULL;
+
+ // Execute the deletion of all packages.
+ drupal_delete_execute($package_data, $destination);
+ }
+}
+
+/**
+ * Executes all database deletions in all packages of a single page call.
+ *
+ * @param $package_data
+ * The complete array of deletion data for all packages.
+ * @param $destination
+ * A destination for operations that bypass the confirm step.
+ */
+function drupal_delete_execute($package_data, $destination = NULL) {
+ foreach ($package_data as $package_id => $package_info) {
+ // Allow modules to perform any operations just prior to the deletion of the packages.
+ drupal_alter('delete', $package_info);
+ // Extract callbacks and metadata.
+ $callbacks = $package_info['callback'];
+ unset($package_info['callback'], $package_info['metadata'], $package_info['form']);
+ // Perform the deletions.
+ foreach ($package_info as $deletions) {
+ foreach ($deletions as $deletion) {
+ db_query($deletion['query'], $deletion['args']);
+ }
+ }
+ // Execute post-deletion callbacks.
+ foreach ($callbacks as $function => $args) {
+ if (function_exists($function)) {
+ call_user_func_array($function, $args);
+ }
+ }
+ }
+
+ // Redirect for confirmation bypass.
+ drupal_redirect($destination);
+}
+
+/**
+ * Generates a drupal_goto() based on the value of $goto.
+ *
+ * @param $goto
+ * Can be any of the following values:
+ * -- A string representing a valid Drupal path.
+ * -- An array containing arguments to pass to drupal_goto().
+ * -- NULL to redirect to $_GET['q'].
+ * -- FALSE to bypass the redirection.
+ */
+function drupal_redirect($goto) {
+ if ($goto !== FALSE) {
+ if (isset($goto)) {
+ if (is_array($goto)) {
+ call_user_func_array('drupal_goto', $goto);
+ }
+ else {
+ drupal_goto($goto);
+ }
+ }
+ drupal_goto($_GET['q']);
+ }
+}
+
+/**
* @ingroup schemaapi
* @{
*/
=== modified file 'includes/form.inc'
--- includes/form.inc 2007-06-04 14:15:51 +0000
+++ includes/form.inc 2007-06-04 14:20:51 +0000
@@ -492,17 +492,7 @@ function drupal_redirect_form($form, $re
if ($goto !== FALSE && isset($form['#redirect'])) {
$goto = $form['#redirect'];
}
- if (!isset($goto) || ($goto !== FALSE)) {
- if (isset($goto)) {
- if (is_array($goto)) {
- call_user_func_array('drupal_goto', $goto);
- }
- else {
- drupal_goto($goto);
- }
- }
- drupal_goto($_GET['q']);
- }
+ drupal_redirect(isset($goto) ? $goto : NULL);
}
/**
=== modified file 'modules/book/book.module'
--- modules/book/book.module 2007-06-04 14:15:52 +0000
+++ modules/book/book.module 2007-06-04 14:20:52 +0000
@@ -466,10 +466,10 @@ function book_nodeapi(&$node, $op, $teas
}
break;
case 'delete revision':
- db_query('DELETE FROM {book} WHERE vid = %d', $node->vid);
+ drupal_delete('book', 'query', 'DELETE FROM {book} WHERE vid = %d', array('vid' => $node->vid));
break;
case 'delete':
- db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
+ drupal_delete('book', 'query', 'DELETE FROM {book} WHERE nid = %d', array('nid' => $node->nid));
break;
}
}
=== modified file 'modules/comment/comment.module'
--- modules/comment/comment.module 2007-06-04 16:34:10 +0000
+++ modules/comment/comment.module 2007-06-04 16:44:36 +0000
@@ -232,7 +232,8 @@ function comment_menu() {
$items['comment/delete'] = array(
'title' => 'Delete comment',
- 'page callback' => 'comment_delete',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('comment_delete', 2),
'access arguments' => array('administer comments'),
'type' => MENU_CALLBACK,
);
@@ -474,8 +475,9 @@ function comment_nodeapi(&$node, $op, $a
break;
case 'delete':
- db_query('DELETE FROM {comments} WHERE nid = %d', $node->nid);
- db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $node->nid);
+ $args = array('nid' => $node->nid);
+ drupal_delete('comment', 'query', 'DELETE FROM {comments} WHERE nid = %d', $args);
+ drupal_delete('node_comment_statistics', 'query', 'DELETE FROM {node_comment_statistics} WHERE nid = %d', $args);
break;
case 'update index':
@@ -1100,50 +1102,44 @@ function comment_render($node, $cid = 0)
/**
* Menu callback; delete a comment.
*/
-function comment_delete($cid = NULL) {
+function comment_delete(&$form_state, $cid = NULL) {
$comment = db_fetch_object(db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.cid = %d', $cid));
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
- $output = '';
-
if (is_object($comment) && is_numeric($comment->cid)) {
- $output = drupal_get_form('comment_confirm_delete', $comment);
+ drupal_delete('comment', 'new package');
+ drupal_delete('comment', 'callback',
+ array(
+ 'comment_delete_post' => array($comment),
+ // Clear the cache so an anonymous poster can see the node being deleted.
+ 'cache_clear_all' => array(),
+ )
+ );
+
+ // Delete comment and its replies.
+ _comment_delete_thread($comment);
+
+ return drupal_delete('comment', 'confirm',
+ array(
+ 'question' => t('Are you sure you want to delete the comment %title?', array('%title' => $comment->subject)),
+ 'path' => 'node/'. $comment->nid,
+ 'description' => t('Any replies to this comment will be lost. This action cannot be undone.'),
+ 'destination' => 'node/'. $comment->nid,
+ )
+ );
}
else {
- drupal_set_message(t('The comment no longer exists.'));
+ drupal_set_message(t('The comment no longer exists.'), 'error');
+ drupal_goto('');
}
-
- return $output;
-}
-
-function comment_confirm_delete(&$form_state, $comment) {
- $form = array();
- $form['#comment'] = $comment;
- return confirm_form(
- $form,
- t('Are you sure you want to delete the comment %title?', array('%title' => $comment->subject)),
- 'node/'. $comment->nid,
- t('Any replies to this comment will be lost. This action cannot be undone.'),
- t('Delete'),
- t('Cancel'),
- 'comment_confirm_delete');
}
-function comment_confirm_delete_submit($form, &$form_state) {
- drupal_set_message(t('The comment and all its replies have been deleted.'));
+function comment_delete_post($comment) {
- $comment = $form['#comment'];
-
- // Delete comment and its replies.
- _comment_delete_thread($comment);
+ drupal_set_message(t('The comment %subject and all its replies have been deleted.', array('%subject' => $comment->subject)));
+ watchdog('content', 'Comment: deleted %subject and all its replies.', array('%subject' => $comment->subject));
_comment_update_node_statistics($comment->nid);
-
- // Clear the cache so an anonymous user sees that his comment was deleted.
- cache_clear_all();
-
- $form_state['redirect'] = "node/$comment->nid";
- return;
}
/**
@@ -1298,45 +1294,82 @@ function theme_comment_admin_overview($f
function comment_multiple_delete_confirm(&$form_state) {
$edit = $form_state['post'];
- $form['comments'] = array('#prefix' => '', '#tree' => TRUE);
+ $form['comments']['#tree'] = TRUE;
+ $form['prefix'] = array('#value' => '');
// array_filter() returns only elements with actual values
$comment_counter = 0;
- foreach (array_filter($edit['comments']) as $cid => $value) {
+ foreach (array_filter($edit['comments']) as $cid) {
$comment = _comment_load($cid);
if (is_object($comment) && is_numeric($comment->cid)) {
$subject = db_result(db_query('SELECT subject FROM {comments} WHERE cid = %d', $cid));
- $form['comments'][$cid] = array('#type' => 'hidden', '#value' => $cid, '#prefix' => '- ', '#suffix' => check_plain($subject) .'
');
+ // This is a placeholder -- preserves proper ordering in the confirm form.
+ $form["comment_$cid"] = array();
+
+ // Start a new package for each comment.
+ drupal_delete('comment', 'new package');
+ drupal_delete('comment', 'callback', array('comment_delete_post' => array($comment)));
+
+ _comment_delete_thread($comment);
+
+ // Add the confirm form piece for this node.
+ drupal_delete('admin_comment', 'form',
+ array(
+ "comment_$cid" => array(
+ '#value' => check_plain($subject),
+ '#prefix' => '- ',
+ '#suffix' => "
\n",
+ ),
+ 'comments' => array(
+ "comment_$cid" => array(
+ '#type' => 'hidden',
+ '#value' => $cid,
+ )
+ )
+ )
+ );
+
$comment_counter++;
}
}
- $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
+ $form['suffix'] = array('#value' => '
');
+ $form['operation'] = array(
+ '#type' => 'hidden',
+ '#value' => 'delete'
+ );
+
+ // New package for the main admin callback.
+ drupal_delete('admin_comment', 'new package');
+
+ // Add the main callback for the mass deletion last.
+ drupal_delete('admin_comment', 'callback',
+ array(
+ 'comment_multiple_delete_confirm_post' => array(),
+ )
+ );
if (!$comment_counter) {
drupal_set_message(t('There do not appear to be any comments to delete or your selected comment was deleted by another administrator.'));
drupal_goto('admin/content/comment');
}
else {
- return confirm_form($form,
- t('Are you sure you want to delete these comments and all their children?'),
- 'admin/content/comment', t('This action cannot be undone.'),
- t('Delete comments'), t('Cancel'));
+ return drupal_delete('admin_comment', 'confirm',
+ array(
+ 'form' => $form,
+ 'question' => t('Are you sure you want to delete these comments and all their children?'),
+ 'path' => 'admin/content/comment',
+ 'yes' => t('Delete all'),
+ 'destination' => 'admin/content/comment',
+ )
+ );
}
}
/**
- * Perform the actual comment deletion.
+ * Post deletion callback for multiple comment deletion.
*/
-function comment_multiple_delete_confirm_submit($form, &$form_state) {
- if ($form_state['values']['confirm']) {
- foreach ($form_state['values']['comments'] as $cid => $value) {
- $comment = _comment_load($cid);
- _comment_delete_thread($comment);
- _comment_update_node_statistics($comment->nid);
- }
+function comment_multiple_delete_confirm_post() {
cache_clear_all();
drupal_set_message(t('The comments have been deleted.'));
- }
- drupal_goto('admin/content/comment');
}
/**
@@ -1910,8 +1943,7 @@ function _comment_delete_thread($comment
}
// Delete the comment:
- db_query('DELETE FROM {comments} WHERE cid = %d', $comment->cid);
- watchdog('content', 'Comment: deleted %subject.', array('%subject' => $comment->subject));
+ drupal_delete('comment', 'query', 'DELETE FROM {comments} WHERE cid = %d', array('cid' => $comment->cid));
comment_invoke_comment($comment, 'delete');
=== modified file 'modules/forum/forum.module'
--- modules/forum/forum.module 2007-06-04 16:34:10 +0000
+++ modules/forum/forum.module 2007-06-04 16:39:31 +0000
@@ -169,7 +169,7 @@ function forum_perm() {
function forum_nodeapi(&$node, $op, $teaser, $page) {
switch ($op) {
case 'delete revision':
- db_query('DELETE FROM {forum} WHERE vid = %d', $node->vid);
+ drupal_delete('forum', 'query', 'DELETE FROM {forum} WHERE vid = %d', array('vid' => $node->vid));
break;
}
}
@@ -453,7 +453,7 @@ function forum_insert($node) {
* Implementation of hook_delete().
*/
function forum_delete(&$node) {
- db_query('DELETE FROM {forum} WHERE nid = %d', $node->nid);
+ drupal_delete('forum', 'query', 'DELETE FROM {forum} WHERE nid = %d', array('nid' => $node->nid));
}
/**
=== modified file 'modules/node/node.module'
--- modules/node/node.module 2007-06-04 16:34:10 +0000
+++ modules/node/node.module 2007-06-04 16:40:58 +0000
@@ -1676,29 +1676,75 @@ function theme_node_admin_nodes($form) {
function node_multiple_delete_confirm(&$form_state) {
$edit = $form_state['post'];
- $form['nodes'] = array('#prefix' => '', '#tree' => TRUE);
- // array_filter returns only elements with TRUE values
- foreach (array_filter($edit['nodes']) as $nid => $value) {
- $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid));
- $form['nodes'][$nid] = array('#type' => 'hidden', '#value' => $nid, '#prefix' => '', '#suffix' => check_plain($title) ."\n");
+ $form['nodes']['#tree'] = TRUE;
+ $form['prefix'] = array('#value' => '');
+
+ // array_filter() returns only elements with TRUE values.
+ $nids = array_filter($edit['nodes']);
+ $nodes = db_query('SELECT nid, title, type FROM {node} WHERE nid IN(%s)', implode(', ', $nids));
+ while ($node = db_fetch_object($nodes)) {
+
+ // This is a placeholder -- preserves proper ordering in the confirm form.
+ $form["node_$node->nid"] = array();
+
+ // Start a new package for each node.
+ drupal_delete('node', 'new package');
+
+ // Add the confirm form piece for this node.
+ drupal_delete('admin_node', 'form',
+ array(
+ "node_$node->nid" => array(
+ '#value' => check_plain($node->title),
+ '#prefix' => '- ',
+ '#suffix' => "
\n",
+ ),
+ 'nodes' => array(
+ "node_$node->nid" => array(
+ '#type' => 'hidden',
+ '#value' => $node->nid,
+ )
+ )
+ )
+ );
+ drupal_delete('node', 'callback',
+ array(
+ 'node_delete_post' => array($node->nid, $node->title, $node->type),
+ )
+ );
+ node_delete($node->nid);
}
- $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
+ $form['suffix'] = array('#value' => '
');
+
+ $form['operation'] = array(
+ '#type' => 'hidden',
+ '#value' => 'delete',
+ );
+
+ // New package for the main admin callback.
+ drupal_delete('admin_node', 'new package');
+
+ // Add the main callback for the mass deletion last.
+ drupal_delete('admin_node', 'callback',
+ array(
+ 'node_multiple_delete_confirm_post' => array(),
+ )
+ );
- return confirm_form($form,
- t('Are you sure you want to delete these items?'),
- 'admin/content/node', t('This action cannot be undone.'),
- t('Delete all'), t('Cancel'));
+ return drupal_delete('admin_node', 'confirm',
+ array(
+ 'form' => $form,
+ 'question' => t('Are you sure you want to delete these items?'),
+ 'path' => 'admin/content/node',
+ 'yes' => t('Delete all'),
+ 'destination' => 'admin/content/node',
+ )
+ );
}
-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);
- }
- drupal_set_message(t('The items have been deleted.'));
- }
- $form_state['redirect'] = 'admin/content/node';
- return;
+function node_multiple_delete_confirm_post() {
+ // Clear the cache so an anonymous poster can see the nodes being deleted.
+ cache_clear_all();
+ drupal_set_message(t('The items have been deleted.'));
}
/**
@@ -1780,32 +1826,44 @@ function node_revision_revert($nid, $rev
* revision is deleted.
*/
function node_revision_delete($nid, $revision) {
- if (user_access('administer nodes')) {
- $node = node_load($nid);
- if (node_access('delete', $node)) {
- // Don't delete the current revision
- if ($revision != $node->vid) {
- $node = node_load($nid, $revision);
-
- db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $nid, $revision);
- node_invoke_nodeapi($node, 'delete revision');
- drupal_set_message(t('Deleted %title revision %revision.', array('%title' => $node->title, '%revision' => $revision)));
- watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node->type, '%title' => $node->title, '%revision' => $revision));
- }
+ $node = node_load($nid);
- else {
- drupal_set_message(t('Deletion failed. You tried to delete the current revision.'));
- }
- if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $nid)) > 1) {
- drupal_goto("node/$nid/revisions");
- }
- else {
- drupal_goto("node/$nid");
- }
+ if (user_access('administer nodes') && node_access('delete', $node)) {
+
+ // Don't delete the current revision
+ if ($revision != $node->vid) {
+ $node = node_load($nid, $revision);
+
+ drupal_delete('node_revisions', 'new package');
+ drupal_delete('node_revisions', 'callback', array('node_revision_delete_post' => array($node, $revision)));
+ drupal_delete('node_revisions', 'query', 'DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d', array('nid' => $nid, 'vid' => $revision));
+ node_invoke_nodeapi($node, 'delete revision');
+ drupal_delete('node_revisions', 'execute');
}
+ else {
+ drupal_set_message(t('Deletion failed. You tried to delete the current revision.'));
+ }
+ }
+ else {
+ drupal_access_denied();
}
+}
- drupal_access_denied();
+/**
+ * Post revision deletion opertations.
+ */
+function node_revision_delete_post($node, $revision) {
+
+ drupal_set_message(t('Deleted %title revision %revision.', array('%title' => $node->title, '%revision' => $revision)));
+ watchdog('content', '@type: deleted %title revision %revision.', array('@type' => t($node->type), '%title' => $node->title, '%revision' => $revision));
+
+
+ if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) > 1) {
+ drupal_goto("node/$node->nid/revisions");
+ }
+ else {
+ drupal_goto("node/$node->nid");
+ }
}
/**
@@ -2360,25 +2418,25 @@ function node_form_submit($form, &$form_
* Menu callback -- ask for confirmation of node deletion
*/
function node_delete_confirm(&$form_state, $node) {
- $form['nid'] = array('#type' => 'value', '#value' => $node->nid);
- return confirm_form($form,
- t('Are you sure you want to delete %title?', array('%title' => $node->title)),
- isset($_GET['destination']) ? $_GET['destination'] : 'node/'. $node->nid,
- t('This action cannot be undone.'),
- t('Delete'), t('Cancel'));
-}
+ drupal_delete('node', 'new package');
+ drupal_delete('node', 'callback',
+ array(
+ 'node_delete_post' => array($node->nid, $node->title, $node->type),
+ // Clear the cache so an anonymous poster can see the node being deleted.
+ 'cache_clear_all' => array(),
+ )
+ );
-/**
- * Execute node deletion
- */
-function node_delete_confirm_submit($form, &$form_state) {
- if ($form_state['values']['confirm']) {
- node_delete($form_state['values']['nid']);
- }
+ node_delete($node->nid, FALSE);
- $form_state['redirect'] = '';
- return;
+ return drupal_delete('node', 'confirm',
+ array(
+ 'question' => t('Are you sure you want to delete %title?', array('%title' => $node->title)),
+ 'path' => isset($_GET['destination']) ? $_GET['destination'] : 'node/'. $node->nid,
+ 'destination' => isset($_GET['destination']) ? $_GET['destination'] : '',
+ )
+ );
}
/**
@@ -2389,23 +2447,24 @@ function node_delete($nid) {
$node = node_load($nid);
if (node_access('delete', $node)) {
- db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
- db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);
+ $args = array('nid' => $node->nid);
+ drupal_delete('node', 'query', 'DELETE FROM {node} WHERE nid = %d', $args);
+ drupal_delete('node_revision', 'query', 'DELETE FROM {node_revisions} WHERE nid = %d', $args);
// Call the node-specific callback (if any):
node_invoke($node, 'delete');
node_invoke_nodeapi($node, 'delete');
+ }
+}
- // Clear the cache so an anonymous poster can see the node being deleted.
- cache_clear_all();
+function node_delete_post($nid, $title, $type) {
- // Remove this node from the search index if needed.
- if (function_exists('search_wipe')) {
- search_wipe($node->nid, 'node');
- }
- drupal_set_message(t('%title has been deleted.', array('%title' => $node->title)));
- watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title));
+ // Remove this node from the search index if needed.
+ if (function_exists('search_wipe')) {
+ search_wipe($nid, 'node');
}
+ drupal_set_message(t('%title has been deleted.', array('%title' => $title)));
+ watchdog('content', '@type: deleted %title.', array('@type' => t($type), '%title' => $title));
}
/**
=== modified file 'modules/path/path.module'
--- modules/path/path.module 2007-06-04 14:15:53 +0000
+++ modules/path/path.module 2007-06-04 14:20:53 +0000
@@ -127,12 +127,12 @@ function path_admin_delete($pid = 0) {
function path_set_alias($path = NULL, $alias = NULL, $pid = NULL, $language = '') {
if ($path && !$alias) {
// Delete based on path
- db_query("DELETE FROM {url_alias} WHERE src = '%s' AND language = '%s'", $path, $language);
+ drupal_delete('url_alias', 'query', "DELETE FROM {url_alias} WHERE src = '%s' AND language = '%s'", array('src' => $path, 'language' => $language));
drupal_clear_path_cache();
}
else if (!$path && $alias) {
// Delete based on alias
- db_query("DELETE FROM {url_alias} WHERE dst = '%s' AND language = '%s'", $alias, $language);
+ drupal_delete('url_alias', 'query', "DELETE FROM {url_alias} WHERE dst = '%s' AND language = '%s'", array('dst' => $alias, 'language' => $language));
drupal_clear_path_cache();
}
else if ($path && $alias) {
=== modified file 'modules/poll/poll.module'
--- modules/poll/poll.module 2007-06-04 14:15:51 +0000
+++ modules/poll/poll.module 2007-06-04 14:20:50 +0000
@@ -91,9 +91,9 @@ function poll_cron() {
* Implementation of hook_delete().
*/
function poll_delete($node) {
- db_query("DELETE FROM {poll} WHERE nid = %d", $node->nid);
- db_query("DELETE FROM {poll_choices} WHERE nid = %d", $node->nid);
- db_query("DELETE FROM {poll_votes} WHERE nid = %d", $node->nid);
+ drupal_delete('poll', 'query', 'DELETE FROM {poll} WHERE nid = %d', array('nid' => $node->nid));
+ drupal_delete('poll_choices', 'query', 'DELETE FROM {poll_choices} WHERE nid = %d', array('nid' => $node->nid));
+ drupal_delete('poll_votes', 'query', 'DELETE FROM {poll_votes} WHERE nid = %d', array('nid' => $node->nid));
}
/**
=== modified file 'modules/statistics/statistics.module'
--- modules/statistics/statistics.module 2007-05-26 05:23:49 +0000
+++ modules/statistics/statistics.module 2007-05-26 05:24:48 +0000
@@ -553,7 +553,7 @@ function statistics_nodeapi(&$node, $op,
switch ($op) {
case 'delete':
// clean up statistics table when node is deleted
- db_query('DELETE FROM {node_counter} WHERE nid = %d', $node->nid);
+ drupal_delete('node_counter', 'query', 'DELETE FROM {node_counter} WHERE nid = %d', array('nid' => $node->nid));
}
}
=== modified file 'modules/system/system.module'
--- modules/system/system.module 2007-06-04 14:15:50 +0000
+++ modules/system/system.module 2007-06-04 16:54:39 +0000
@@ -2398,21 +2398,26 @@ function system_node_type($op, $info) {
* block foo?").
* @param $path
* The page to go to if the user denies the action.
- * Can be either a drupal path, or an array with the keys 'path', 'query', 'fragment'.
- * @param $description
- * Additional text to display (defaults to "This action cannot be undone.").
- * @param $yes
- * A caption for the button which confirms the action (e.g. "Delete",
- * "Replace", ...).
- * @param $no
- * A caption for the link which denies the action (e.g. "Cancel").
- * @param $name
- * The internal name used to refer to the confirmation item.
+ * Can be either a Drupal path, or an array with the keys 'path', 'query', 'fragment'.
+ * @param $options
+ * An associative array of options, with the following key/value pairs:
+ * 'description' => Additional text to display.
+ * Default is "This action cannot be undone".
+ * 'yes' => A caption for the button which confirms the action (e.g. "Confirm",
+ * "Replace", ...). Default is "Delete".
+ * 'no' => A caption for the link which denies the action (e.g. "Cancel").
+ * Default is "Cancel".
+ * 'name' => The internal name used to refer to the confirmation item.
+ * Default is "confirm".
+ * 'destination' => A destination page to go to after form submission -- the value can
+ * be of any form of the $goto argument accepted by drupal_redirect().
+ *
* @return
* The form.
*/
-function confirm_form($form, $question, $path, $description = NULL, $yes = NULL, $no = NULL, $name = 'confirm') {
- $description = isset($description) ? $description : t('This action cannot be undone.');
+function confirm_form($form, $question, $path, $options = array()) {
+ $description = isset($options['description']) ? $options['description'] : t('This action cannot be undone.');
+ $name = isset($options['name']) ? $options['name'] : 'confirm';
// Prepare cancel link
$query = $fragment = NULL;
@@ -2421,25 +2426,38 @@ function confirm_form($form, $question,
$fragment = isset($path['fragment']) ? $path['fragment'] : NULL;
$path = isset($path['path']) ? $path['path'] : NULL;
}
- $cancel = l($no ? $no : t('Cancel'), $path, array('query' => $query, 'fragment' => $fragment));
+ $cancel = l(isset($options['no']) ? $options['no'] : t('Cancel'), $path, array('query' => $query, 'fragment' => $fragment));
drupal_set_title($question);
- // Confirm form fails duplication check, as the form values rarely change -- so skip it.
- $form['#skip_duplicate_check'] = TRUE;
-
$form['#attributes'] = array('class' => 'confirmation');
$form['description'] = array('#value' => $description);
$form[$name] = array('#type' => 'hidden', '#value' => 1);
+ if (isset($options['destination'])) {
+ $form['destination'] = array('#type' => 'value', '#value' => $options['destination']);
+ }
$form['actions'] = array('#prefix' => '', '#suffix' => '
');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => $yes ? $yes : t('Confirm'));
+ $form['actions']['submit'] = array('#type' => 'submit', '#value' => isset($options['yes']) ? $options['yes'] : t('Delete'));
$form['actions']['cancel'] = array('#value' => $cancel);
+
$form['#theme'] = 'confirm_form';
return $form;
}
/**
+ * Executes confirmation pages for the Deletion API.
+ */
+function delete_confirm_submit($form, &$form_state) {
+ if ($form_state['values']['delete']) {
+ drupal_delete('', 'execute');
+ }
+ if (isset($form_state['values']['destination'])) {
+ $form_state['redirect'] = $form_state['values']['destination'];
+ }
+}
+
+/**
* Determine if a user is in compact mode.
*/
function system_admin_compact_mode() {
=== modified file 'modules/taxonomy/taxonomy.module'
--- modules/taxonomy/taxonomy.module 2007-06-04 16:34:10 +0000
+++ modules/taxonomy/taxonomy.module 2007-06-04 16:39:32 +0000
@@ -876,14 +876,14 @@ function taxonomy_node_save($node, $term
* Remove associations of a node to its terms.
*/
function taxonomy_node_delete($node) {
- db_query('DELETE FROM {term_node} WHERE nid = %d', $node->nid);
+ drupal_delete('term_node', 'query', 'DELETE FROM {term_node} WHERE nid = %d', array('nid' => $node->nid));
}
/**
* Remove associations of a node to its terms.
*/
function taxonomy_node_delete_revision($node) {
- db_query('DELETE FROM {term_node} WHERE vid = %d', $node->vid);
+ drupal_delete('term_node', 'query', 'DELETE FROM {term_node} WHERE vid = %d', array('vid' => $node->vid));
}
/**
=== modified file 'modules/upload/upload.module'
--- modules/upload/upload.module 2007-06-04 14:15:51 +0000
+++ modules/upload/upload.module 2007-06-04 14:20:52 +0000
@@ -574,31 +574,44 @@ function upload_delete($node) {
}
foreach ($files as $fid => $file) {
- // Delete all files associated with the node
- db_query('DELETE FROM {files} WHERE fid = %d', $fid);
- file_delete($file->filepath);
+ // Delete all file revision information associated with the node
+ drupal_delete('files', 'query', 'DELETE FROM {files} WHERE fid = %d', array('fid' => $fid));
}
- // Delete all file revision information associated with the node
- db_query('DELETE FROM {upload} WHERE nid = %d', $node->nid);
+ // Delete all files associated with the node
+ drupal_delete('upload', 'query', 'DELETE FROM {upload} WHERE nid = %d', array('nid' => $node->nid));
+
+ // Register a callback to delete the files.
+ drupal_delete('files', 'callback', array('upload_delete_post' => array($files)));
}
function upload_delete_revision($node) {
if (is_array($node->files)) {
+ $files = array();
foreach ($node->files as $file) {
// Check if the file will be used after this revision is deleted
$count = db_result(db_query('SELECT COUNT(fid) FROM {upload} WHERE fid = %d', $file->fid));
// if the file won't be used, delete it
if ($count < 2) {
- db_query('DELETE FROM {files} WHERE fid = %d', $file->fid);
- file_delete($file->filepath);
+ drupal_delete('files', 'query', 'DELETE FROM {files} WHERE fid = %d', array('fid' => $file->fid));
+ $files[$file->fid] = $file;
}
}
}
- // delete the revision
- db_query('DELETE FROM {upload} WHERE vid = %d', $node->vid);
+ // Delete the revision.
+ drupal_delete('upload', 'query', 'DELETE FROM {upload} WHERE vid = %d', array('vid' => $node->vid));
+
+ // Register a callback to delete the files.
+ drupal_delete('files', 'callback', array('upload_delete_post' => array($files)));
+}
+
+function upload_delete_post($files) {
+ foreach ($files as $file) {
+ // Delete all files associated with the node or revision.
+ file_delete($file->filepath);
+ }
}
function _upload_form($node) {