* This module is distributed under the GPL.
*/
include_once 'Text/Diff.php';
include_once 'Text/Diff/Renderer.php';
include_once 'Text/Diff/Renderer/inline.php';
function diff_help($section) {
switch ($section) {
case 'admin/help#diff':
case 'admin/modules#description':
case 'admin/diff':
return "Show difference between node revisions.";
}
}
/**
* Implementation of hook_perm().
*/
function diff_perm() {
return array('access diff');
}
/**
* Implementation of hook_menu().
*/
function diff_menu($may_cache)
{
$items = array();
//if (!$may_cache) {
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
if ($node->nid) {
if ( count(node_revision_list($node)) > 1 ) {
$items[] = array('path' => 'node/'. arg(1) .'/diff', 'title' => t('diff'),
'callback' => 'diff_page',
'callback arguments' => arg(1),
'access' => user_access('access diff'),
'weight' => 6,
'type' => MENU_LOCAL_TASK);
}
}
}
$path = drupal_get_path('module', 'diff');
$style = "";
drupal_set_html_head($style);
//}
return $items;
}
/**
* Show a difference between revisions.
*/
function diff_page($nid, $rid1 = NULL, $rid2 = NULL) {
if (!is_null($rid1)) {
return _diff_show_revision($nid, $rid1, $rid2);
}
else {
return _diff_show_page($nid);
}
}
function _diff_show_revision($nid, $rid1, $rid2 = NULL) {
$r1 = node_load($nid, $rid1);
$r2 = node_load($nid, $rid2);
$source = explode("\n", diff_node_render($r2));
$target = explode("\n", diff_node_render($r1));
$diff = &new Text_Diff($source, $target);
$renderer = &new Text_Diff_Renderer_inline();
$node = $r1;
$node->body = $renderer->render($diff);
return theme('node', $node);
}
function _diff_show_page($nid) {
$node = node_load($nid);
drupal_set_title($node->title);
$header = array(t('Older revisions'), array('data' => t('Operations'), 'colspan' => 3));
// $last_key = count($node->revisions) - 1;
$revisions = node_revision_list($node);
foreach ($revisions as $key => $revision) {
$vid = $revision->vid;
if ($key != 0) {
$prev = l(t('previous'), "node/$node->nid/diff/$vid/".( $revisions[$key-1]->vid ));
$first = l(t('first'), "node/$node->nid/diff/$vid/" .($revisions[0]->vid));
}
$current = l(t('current'), "node/$node->nid/diff/$vid");
$rows[] = array(
t('revision %r (%v) revised by %u on %d',
array(
'%r' => 1 + $key,
'%v' => $vid,
'%u' => theme('username', user_load(array('uid' => $revision->uid))),
'%d' => format_date($revision->timestamp, 'small')
)
)
. ($revision->history ? '
'. $revision->history .'' : ''),
$prev, $first, $current);
}
return theme('table', $header, $rows);
}
// Get node *body* output (filtered and with module-specific fields). Modified from node_update_index()
// return HTML
function diff_node_render($node) {
if (node_hook($node, 'view')) {
node_invoke($node, 'view', false, false);
}
else {
$node = node_prepare($node, false);
}
// Allow modules to change $node->body before viewing.
node_invoke_nodeapi($node, 'view', false, false);
return $node->body;
}
?>