* 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' => array(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 = array_reverse(node_revision_list($node)); foreach ($revisions as $key => $revision){ $vid = $revision->vid; $current = l(t('current'), "node/$node->nid/diff/$vid"); $next = l(t('next'), "node/$node->nid/diff/$vid/".( $revisions[$key+1]->vid )); $prev = l(t('prev'), "node/$node->nid/diff/$vid/".( $revisions[$key-1]->vid)); if ($vid < $node->vid) { $rows[] = array(t('Archive: %u on %d ',array('%u' => theme('username', user_load(array('uid' => $revision->uid))),'%d' => format_date($revision->timestamp, 'small'))). ($revision->history ? '
'. $revision->history .'' : ''),$prev, $current, $next); } else { if ($vid > $node->vid){ $rows[] = array(t('Drafted: %u on %d ',array('%u' => theme('username', user_load(array('uid' => $revision->uid))),'%d' => format_date($revision->timestamp, 'small'))). ($revision->history ? '
'. $revision->history .'' : ''),$prev, $current, $next); } else { $current = ''; $rows[] = array(t('Published by %u on %d',array('%u' => theme('username', user_load(array('uid' => $revision->uid))),'%d' => format_date($revision->timestamp, 'small'))). ($revision->history ? '
'. $revision->history .'' : ''),$prev, $current, $next); } } } $output .= theme('table', $header, $rows); return $output; } // 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; } ?>