| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Node Revision Deletion, written by Greg Holsclaw
|
| 7 |
*/
|
| 8 |
|
| 9 |
define('REV_DEL_PERM', 'mass delete revisions');
|
| 10 |
|
| 11 |
/**
|
| 12 |
* Implementation of hook_perm().
|
| 13 |
*/
|
| 14 |
function revision_deletion_perm() {
|
| 15 |
return array(REV_DEL_PERM);
|
| 16 |
}
|
| 17 |
|
| 18 |
/**
|
| 19 |
* Implementation of hook_help().
|
| 20 |
*/
|
| 21 |
function revision_deletion_help($section) {
|
| 22 |
switch ($section) {
|
| 23 |
case 'admin/help#revision_deletion':
|
| 24 |
return t('This module will greatly speed up the task of deleting old revisions of nodes. The database clutter and space can be quickly reclaimed as this module, on cron runs, will delete aged revisions (never the current revision) of nodes older than a set period of time. Options include frequency of the cron deletion job, and the age of revisions before being deleted. Cron.php must be run to execute.');
|
| 25 |
case 'admin/modules#description':
|
| 26 |
return t('Delete old revision of nodes quickly');
|
| 27 |
}
|
| 28 |
}
|
| 29 |
|
| 30 |
|
| 31 |
/**
|
| 32 |
* Implementation of hook_menu().
|
| 33 |
*/
|
| 34 |
function revision_deletion_menu($may_cache) {
|
| 35 |
$items = array();
|
| 36 |
|
| 37 |
if ($may_cache) {
|
| 38 |
$items[] = array(
|
| 39 |
'path' => 'admin/content/revision_deletion',
|
| 40 |
'callback' => 'revision_deletion_page',
|
| 41 |
'title' => t('Revisions to Mass Delete'),
|
| 42 |
'access' => user_access(REV_DEL_PERM),
|
| 43 |
'type' => MENU_NORMAL_ITEM
|
| 44 |
);
|
| 45 |
$items[] = array(
|
| 46 |
'path' => 'admin/content/revision_deletion/settings',
|
| 47 |
'title' => t('Revision deletion'),
|
| 48 |
'callback arguments' => array('revision_deletion_settings'),
|
| 49 |
'callback' => 'drupal_get_form',
|
| 50 |
'access' => user_access('administer site configuration'),
|
| 51 |
'type' => MENU_NORMAL_ITEM,
|
| 52 |
'description' => t('Configure settings for the revision deletion module'),
|
| 53 |
);
|
| 54 |
}
|
| 55 |
return $items;
|
| 56 |
}
|
| 57 |
|
| 58 |
function revision_deletion_settings() {
|
| 59 |
$frequency = drupal_map_assoc(array(86400, 604800, 1209600, 2419200, 4838400), 'format_interval');
|
| 60 |
$age = drupal_map_assoc(array(604800, 2419200, 4838400, 9676800, 15724800, 31449600), 'format_interval');
|
| 61 |
|
| 62 |
$form['rev_del'] = array(
|
| 63 |
'#type' => 'fieldset',
|
| 64 |
'#title' => t('Revision Mass Deletion Settings')
|
| 65 |
);
|
| 66 |
|
| 67 |
//Set revision frequency interval
|
| 68 |
$form['rev_del']['revision_delete_freq'] = array(
|
| 69 |
'#type' => 'select',
|
| 70 |
'#title' => t('Cron Settings'),
|
| 71 |
'#default_value' => variable_get('revision_delete_freq', 604800),
|
| 72 |
'#options' => $frequency,
|
| 73 |
'#description' => t('Frequency of the mass revision delete cron jobs.')
|
| 74 |
);
|
| 75 |
|
| 76 |
//Set revision age for deletion
|
| 77 |
$form['rev_del']['revision_delete_age'] = array(
|
| 78 |
'#type' => 'select',
|
| 79 |
'#title' => t('Revision Age Setting'),
|
| 80 |
'#default_value' => variable_get('revision_delete_age', 2419200),
|
| 81 |
'#options' => $age,
|
| 82 |
'#description' => t('Age in days of revisions that should be deleted.')
|
| 83 |
);
|
| 84 |
|
| 85 |
//Set node types to be deleted
|
| 86 |
$form['rev_del']['revision_delete'] = array(
|
| 87 |
'#type' => 'select',
|
| 88 |
'#title' => t('Select node types for revision deletion. Multiple select enabled.'),
|
| 89 |
'#default_value' => variable_get('revision_delete', array()),
|
| 90 |
'#multiple' => true,
|
| 91 |
'#required' => true,
|
| 92 |
'#options' => node_get_types('names')
|
| 93 |
);
|
| 94 |
|
| 95 |
return system_settings_form($form);
|
| 96 |
}
|
| 97 |
|
| 98 |
|
| 99 |
/**
|
| 100 |
* Implementation of hook_cron().
|
| 101 |
*/
|
| 102 |
function revision_deletion_cron() {
|
| 103 |
$last_update = variable_get('revision_delete_cron', 0);
|
| 104 |
$rev_del_freq = variable_get('revision_delete_freq', 604800);
|
| 105 |
$diff = time() - $rev_del_freq;
|
| 106 |
|
| 107 |
if ($diff > $last_update) {
|
| 108 |
$result = revision_deletion_data();
|
| 109 |
if (db_num_rows($result)) {
|
| 110 |
while ($data = db_fetch_object($result)) {
|
| 111 |
revision_deletion_delete_rev($data);
|
| 112 |
}
|
| 113 |
}
|
| 114 |
variable_set('revision_delete_cron', time());
|
| 115 |
}
|
| 116 |
}
|
| 117 |
|
| 118 |
function revision_deletion_page() {
|
| 119 |
$result = revision_deletion_data();
|
| 120 |
$output = '';
|
| 121 |
|
| 122 |
if (!$result) {
|
| 123 |
$output .= 'Revision Deletion settings has not been configured.<br />';
|
| 124 |
$output .= l(t('> Change Revision Deletion Settings'), 'admin/content/revision_deletion/settings');
|
| 125 |
return $output;
|
| 126 |
}
|
| 127 |
|
| 128 |
$output .= l(t('> Change Revision Deletion Settings'), 'admin/content/revision_deletion/settings') .'<br />';
|
| 129 |
|
| 130 |
if (db_num_rows($result)) {
|
| 131 |
$header = array(t('Title'), t('Node ID'), t('Revision ID'), t('Revision Date'), t('Type'));
|
| 132 |
while ($data = db_fetch_object($result)) {
|
| 133 |
$rows[] = array(
|
| 134 |
array('data' => l($data->title, 'node/'. $data->nid .'/revisions/'. $data->vid .'/view'), 'align' => 'left'),
|
| 135 |
array('data' => $data->nid, 'align' => 'center'),
|
| 136 |
array('data' => $data->vid, 'align' => 'center'),
|
| 137 |
array('data' => format_date($data->timestamp), 'align' => 'left'),
|
| 138 |
array('data' => $data->type, 'align' => 'center')
|
| 139 |
);
|
| 140 |
}
|
| 141 |
$output = l(t('> Change Revision Deletion Settings'), 'admin/content/revision_deletion/settings');
|
| 142 |
$output .= theme('table', $header, $rows);
|
| 143 |
$output .= drupal_get_form('revision_deletion_page_form');
|
| 144 |
}
|
| 145 |
else {
|
| 146 |
$output .= 'No Node Revisions to delete at this time.';
|
| 147 |
}
|
| 148 |
|
| 149 |
return $output;
|
| 150 |
}
|
| 151 |
|
| 152 |
function revision_deletion_page_form() {
|
| 153 |
$form['submit'] = array(
|
| 154 |
'#type' => 'submit',
|
| 155 |
'#value' => t('Run Revision Deletion'),
|
| 156 |
);
|
| 157 |
|
| 158 |
return $form;
|
| 159 |
}
|
| 160 |
|
| 161 |
function revision_deletion_page_form_submit() {
|
| 162 |
$result = revision_deletion_data();
|
| 163 |
|
| 164 |
if (db_num_rows($result)) {
|
| 165 |
while ($data = db_fetch_object($result)) {
|
| 166 |
revision_deletion_delete_rev($data);
|
| 167 |
drupal_set_message(t('Revision Deletion: Aged Node nid=%node, %title, Revision vid=%rev deleted.', array('%node' => $data->nid, '%title' => $data->title, '%rev' => $data->vid)), 'status');
|
| 168 |
}
|
| 169 |
$output = theme('table', $header, $rows);
|
| 170 |
}
|
| 171 |
else {
|
| 172 |
$output = 'No Node Revisions to delete at this time.';
|
| 173 |
}
|
| 174 |
}
|
| 175 |
|
| 176 |
function revision_deletion_data() {
|
| 177 |
$aged = time() - variable_get('revision_delete_age', 2419200);
|
| 178 |
$arguments[] = $aged;
|
| 179 |
|
| 180 |
if (variable_get('revision_delete', NULL)) {
|
| 181 |
$nodes = variable_get('revision_delete', node_get_types('names'));
|
| 182 |
} else {
|
| 183 |
return NULL;
|
| 184 |
}
|
| 185 |
foreach ($nodes as $type => $name) {
|
| 186 |
$cond[] = "'%s'";
|
| 187 |
$arguments[] = $nodes[$type];
|
| 188 |
}
|
| 189 |
|
| 190 |
if (count($nodes) > 1) {
|
| 191 |
$conds = 'n.type IN ('. implode(',', $cond) .')';
|
| 192 |
}
|
| 193 |
else {
|
| 194 |
$conds = "n.type = " . $cond[0];
|
| 195 |
}
|
| 196 |
|
| 197 |
//Build data that does not pick current revision, nr.vid != n.vid.
|
| 198 |
$result = db_query('SELECT nr.nid, nr.vid, nr.timestamp, n.type, n.title FROM {node_revisions} nr INNER JOIN {node} n ON nr.nid = n.nid WHERE nr.timestamp < %d AND nr.vid != n.vid AND '. $conds .' ORDER BY vid', $arguments);
|
| 199 |
|
| 200 |
return $result;
|
| 201 |
}
|
| 202 |
|
| 203 |
/**
|
| 204 |
* Implementation of revision_deletion_delete_rev().
|
| 205 |
* Borrows heavily from the node.module api function to delete revisions, with some of the checks and messages removed.
|
| 206 |
* No check to make sure we are not deleting the current node revision. That is covered in the function that creates the data set.
|
| 207 |
*/
|
| 208 |
|
| 209 |
function revision_deletion_delete_rev($data = NULL) {
|
| 210 |
$node = node_load($data->nid, $data->vid);
|
| 211 |
db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $data->nid, $data->vid);
|
| 212 |
node_invoke_nodeapi($node, 'delete revision');
|
| 213 |
watchdog('content', t('@type: deleted %title revision %revision.', array('@type' => t($data->type), '%title' => $data->title, '%revision' => $data->vid)));
|
| 214 |
}
|