| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: diff.pages.inc,v 1.1.2.9 2010/08/12 16:34:08 yhahn Exp $ 3 4 /** 5 * @file 6 * Menu callbacks for hook_menu(). 7 */ 8 9 /** 10 * Menu callback - show latest diff for a given node. 11 */ 12 function diff_latest($node) { 13 $revisions = node_revision_list($node); 14 $new = array_shift($revisions); 15 $old = array_shift($revisions); 16 drupal_goto("node/{$node->nid}/revisions/view/{$old->vid}/{$new->vid}"); 17 } 18 19 /** 20 * Generate an overview table of older revisions of a node and provide 21 * an input form to select two revisions for a comparison. 22 */ 23 function diff_diffs_overview($node) { 24 drupal_set_title(t('Revisions for %title', array('%title' => $node->title))); 25 return drupal_get_form('diff_node_revisions', $node); 26 } 27 28 /** 29 * Input form to select two revisions. 30 * 31 * @param $node 32 * Node whose revisions are displayed for selection. 33 */ 34 function diff_node_revisions($form_state, $node) { 35 global $form_values; 36 $form = array(); 37 38 $form['nid'] = array( 39 '#type' => 'hidden', 40 '#value' => $node->nid, 41 ); 42 43 $revision_list = node_revision_list($node); 44 45 if (count($revision_list) > REVISION_LIST_SIZE) { 46 // If the list of revisions is longer than the number shown on one page split the array. 47 $page = isset($_GET['page']) ? $_GET['page'] : '0'; 48 $revision_chunks = array_chunk(node_revision_list($node), REVISION_LIST_SIZE); 49 $revisions = $revision_chunks[$page]; 50 // Set up global pager variables as would 'pager_query' do. 51 // These variables are then used in the theme('pager') call later. 52 global $pager_page_array, $pager_total, $pager_total_items; 53 $pager_total_items[0] = count($revision_list); 54 $pager_total[0] = ceil(count($revision_list) / REVISION_LIST_SIZE); 55 $pager_page_array[0] = max(0, min($page, ((int)$pager_total[0]) - 1)); 56 } 57 else { 58 $revisions = $revision_list; 59 } 60 61 $revert_permission = FALSE; 62 if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) { 63 $revert_permission = TRUE; 64 } 65 $delete_permission = FALSE; 66 if ((user_access('delete revisions') || user_access('administer nodes')) && node_access('delete', $node)) { 67 $delete_permission = TRUE; 68 } 69 70 foreach ($revisions as $revision) { 71 $operations = array(); 72 $revision_ids[$revision->vid] = ''; 73 74 if ($revision->current_vid > 0) { 75 $form['info'][$revision->vid] = array( 76 '#value' => t('!date by !username', array( 77 '!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid"), 78 '!username' => theme('username', $revision))) 79 . (($revision->log != '') ? '<p class="revision-log">'. filter_xss($revision->log) .'</p>' : ''), 80 ); 81 } 82 else { 83 $form['info'][$revision->vid] = array( 84 '#value' => t('!date by !username', array( 85 '!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid/revisions/$revision->vid/view"), 86 '!username' => theme('username', $revision))) 87 . (($revision->log != '') ? '<p class="revision-log">'. filter_xss($revision->log) .'</p>' : '') 88 ); 89 if ($revert_permission) { 90 $operations[] = array('#value' => l(t('revert'), "node/$node->nid/revisions/$revision->vid/revert")); 91 } 92 if ($delete_permission) { 93 $operations[] = array('#value' => l(t('delete'), "node/$node->nid/revisions/$revision->vid/delete")); 94 } 95 // Set a dummy, even if the user has no permission for the other 96 // operations, so that we can check if the operations array is 97 // empty to know if the row denotes the current revision. 98 $operations[] = array(); 99 } 100 $form['operations'][$revision->vid] = $operations; 101 102 } 103 $new_vid = key($revision_ids); 104 next($revision_ids); 105 $old_vid = key($revision_ids); 106 $form['diff']['old'] = array( 107 '#type' => 'radios', 108 '#options' => $revision_ids, 109 '#default_value' => $old_vid 110 ); 111 $form['diff']['new'] = array( 112 '#type' => 'radios', 113 '#options' => $revision_ids, 114 '#default_value' => $new_vid 115 ); 116 $form['submit'] = array('#type' => 'submit', '#value' => t('Show diff')); 117 118 if (count($revision_list) > REVISION_LIST_SIZE) { 119 $form['#suffix'] = theme('pager', NULL, REVISION_LIST_SIZE, 0); 120 } 121 122 return $form; 123 } 124 125 /** 126 * Submit code for input form to select two revisions. 127 */ 128 function diff_node_revisions_submit($form, &$form_state) { 129 // the ids are ordered so the old revision is always on the left 130 $old_vid = min($form_state['values']['old'], $form_state['values']['new']); 131 $new_vid = max($form_state['values']['old'], $form_state['values']['new']); 132 $form_state['redirect'] = 'node/'. $form_state['values']['nid'] .'/revisions/view/'. $old_vid .'/'. $new_vid; 133 } 134 135 /** 136 * Validation for input form to select two revisions. 137 */ 138 function diff_node_revisions_validate($form, &$form_state) { 139 $old_vid = $form_state['values']['old']; 140 $new_vid = $form_state['values']['new']; 141 if ($old_vid==$new_vid || !$old_vid || !$new_vid) { 142 form_set_error('diff', t('Select different revisions to compare.')); 143 } 144 } 145 146 /** 147 * Create output string for a comparison of 'node' between 148 * versions 'old_vid' and 'new_vid'. 149 * 150 * @param $node 151 * Node on which to perform comparison 152 * @param $old_vid 153 * Version ID of the old revision. 154 * @param $new_vid 155 * Version ID of the new revision. 156 */ 157 function diff_diffs_show($node, $old_vid, $new_vid) { 158 159 // Set same title as on the 'Revisions' tab for consistency 160 drupal_set_title(t('Revisions for %title', array('%title' => $node->title))); 161 162 $node_revisions = node_revision_list($node); 163 164 $old_node = node_load($node->nid, $old_vid); 165 $new_node = node_load($node->nid, $new_vid); 166 167 // Generate table header (date, username, logmessage). 168 $old_header = t('!date by !username', array( 169 '!date' => l(format_date($old_node->revision_timestamp), "node/$node->nid/revisions/$old_node->vid/view"), 170 '!username' => theme('username', $node_revisions[$old_vid]), 171 )); 172 $new_header = t('!date by !username', array( 173 '!date' => l(format_date($new_node->revision_timestamp), "node/$node->nid/revisions/$new_node->vid/view"), 174 '!username' => theme('username', $node_revisions[$new_vid]), 175 )); 176 177 $old_log = $old_node->log != '' ? '<p class="revision-log">'. filter_xss($old_node->log) .'</p>' : ''; 178 $new_log = $new_node->log != '' ? '<p class="revision-log">'. filter_xss($new_node->log) .'</p>' : ''; 179 180 // Generate previous diff/next diff links. 181 $next_vid = _diff_get_next_vid($node_revisions, $new_vid); 182 if ($next_vid) { 183 $next_link = l(t('next diff >'), 'node/'. $node->nid .'/revisions/view/'. $new_vid .'/'. $next_vid); 184 } 185 else { 186 $next_link = ''; 187 } 188 $prev_vid = _diff_get_previous_vid($node_revisions, $old_vid); 189 if ($prev_vid) { 190 $prev_link = l(t('< previous diff'), 'node/'. $node->nid .'/revisions/view/'. $prev_vid .'/'. $old_vid); 191 } 192 else { 193 $prev_link = ''; 194 } 195 196 $cols = _diff_default_cols(); 197 $header = _diff_default_header($old_header, $new_header); 198 $rows = array(); 199 if ($old_log || $new_log) { 200 $rows[] = array( 201 array( 202 'data' => $old_log, 203 'colspan' => 2 204 ), 205 array( 206 'data' => $new_log, 207 'colspan' => 2 208 ) 209 ); 210 } 211 $rows[] = array( 212 array( 213 'data' => $prev_link, 214 'class' => 'diff-prevlink', 215 'colspan' => 2 216 ), 217 array( 218 'data' => $next_link, 219 'class' => 'diff-nextlink', 220 'colspan' => 2 221 ) 222 ); 223 $rows = array_merge($rows, _diff_body_rows($old_node, $new_node)); 224 $output = theme('diff_table', $header, $rows, array('class' => 'diff'), NULL, $cols); 225 226 if ($node->vid == $new_vid) { 227 $output .= '<div class="diff-section-title">'. t('Current revision:') .'</div>'; 228 } 229 else { 230 $output .= '<div class="diff-section-title">'. t('Revision of !new_date:', array('!new_date' => format_date($new_node->revision_timestamp))) .'</div>'; 231 } 232 // Don't include node links (final argument) when viewing the diff. 233 $output .= node_view($new_node, FALSE, FALSE, FALSE); 234 return $output; 235 } 236 237 /** 238 * Creates an array of rows which represent a diff between $old_node and $new_node. 239 * The rows can be used via theme('diff_table') to be displayed. 240 * 241 * @param $old_node 242 * Node for comparison which will be displayed on the left side. 243 * @param $new_node 244 * Node for comparison which will be displayed on the right side. 245 */ 246 function _diff_body_rows($old_node, $new_node) { 247 drupal_add_css(drupal_get_path('module', 'diff') .'/diff.css', 'module', 'all', FALSE); 248 module_load_include('inc', 'diff', 'includes/node'); 249 if (module_exists('taxonomy')) { 250 module_load_include('inc', 'diff', 'includes/taxonomy'); 251 } 252 if (module_exists('upload')) { 253 module_load_include('inc', 'diff', 'includes/upload'); 254 } 255 256 $rows = array(); 257 $any_visible_change = FALSE; 258 // @todo quick workaround for PHP >= 5.3.0 date_diff() conflict. 259 $node_diffs = _diff_module_invoke_all($old_node, $new_node); 260 261 // We start off assuming all form elements are in the correct order. 262 $node_diffs['#sorted'] = TRUE; 263 264 // Recurse through all child elements. 265 $count = 0; 266 foreach (element_children($node_diffs) as $key) { 267 // Assign a decimal placeholder weight to preserve original array order. 268 if (!isset($node_diffs[$key]['#weight'])) { 269 $node_diffs[$key]['#weight'] = $count/1000; 270 } 271 else { 272 // If one of the child elements has a weight then we will need to sort 273 // later. 274 unset($node_diffs['#sorted']); 275 } 276 $count++; 277 } 278 279 // One of the children has a #weight. 280 if (!isset($node_diffs['#sorted'])) { 281 uasort($node_diffs, "element_sort"); 282 } 283 284 // Render diffs for each. 285 foreach ($node_diffs as $node_diff) { 286 $show_header = isset($node_diff['#format']['show_header']) ? $node_diff['#format']['show_header'] : FALSE; 287 if ($node_diff_rows = diff_get_rows($node_diff['#old'], $node_diff['#new'], $show_header)) { 288 $rows[] = array(array( 289 'data' => t('Changes to %name', array('%name' => $node_diff['#name'])), 290 'class' => 'diff-section-title', 291 'colspan' => 4 292 )); 293 $rows = array_merge($rows, $node_diff_rows); 294 $any_visible_change = TRUE; 295 } 296 } 297 if (!$any_visible_change) { 298 $rows[] = array(array( 299 'data' => t('No visible changes'), 300 'class' => 'diff-section-title', 301 'colspan' => 4 302 )); 303 // Needed to keep safari happy 304 $rows[] = array( 305 array('data' => ''), 306 array('data' => ''), 307 array('data' => ''), 308 array('data' => ''), 309 ); 310 } 311 return $rows; 312 } 313 314 /** 315 * Helper function to invoke hook_diff in all enabled modules that implement it. 316 * 317 * Don't use module_invoke_all() since if date.module is enabled will clash with 318 * PHP 5.3's date_diff() function. 319 * 320 * @todo figure out any else possible solution but not workaround. 321 * @link http://drupal.org/node/639320 322 * @see module_invoke_all() 323 */ 324 function _diff_module_invoke_all($old_node, $new_node) { 325 $return = array(); 326 foreach (module_implements('diff') as $module) { 327 if ($module == 'date') { 328 continue; // Avoid function name collision with date_diff(). 329 } 330 $result = module_invoke($module, 'diff', $old_node, $new_node); 331 if (isset($result) && is_array($result)) { 332 $return = array_merge_recursive($return, $result); 333 } 334 elseif (isset($result)) { 335 $return[] = $result; 336 } 337 } 338 return $return; 339 } 340 341 /** 342 * Get the entry in the revisions list after $vid. 343 * Returns FALSE if $vid is the last entry. 344 * 345 * @param $node_revisions 346 * Array of node revision IDs in descending order. 347 * @param $vid 348 * Version ID to look for. 349 */ 350 function _diff_get_next_vid($node_revisions, $vid) { 351 $previous = NULL; 352 foreach ($node_revisions as $revision) { 353 if ($revision->vid == $vid) { 354 return ($previous ? $previous->vid : FALSE); 355 } 356 $previous = $revision; 357 } 358 return FALSE; 359 } 360 361 /** 362 * Get the entry in the revision list before $vid. 363 * Returns FALSE if $vid is the first entry. 364 * 365 * @param $node_revisions 366 * Array of node revision IDs in descending order. 367 * @param $vid 368 * Version ID to look for. 369 */ 370 function _diff_get_previous_vid($node_revisions, $vid) { 371 $previous = NULL; 372 foreach ($node_revisions as $revision) { 373 if ($previous && $previous->vid == $vid) { 374 return $revision->vid; 375 } 376 $previous = $revision; 377 } 378 return FALSE; 379 } 380 381 /** 382 * Helper function to create default 'cols' array for diff table. 383 */ 384 function _diff_default_cols() { 385 return array( 386 array( 387 array( 388 'class' => 'diff-marker', 389 ), 390 array( 391 'class' => 'diff-content', 392 ), 393 array( 394 'class' => 'diff-marker', 395 ), 396 array( 397 'class' => 'diff-content', 398 ), 399 ), 400 ); 401 } 402 403 /** 404 * Helper function to create default 'header' array for diff table. 405 */ 406 function _diff_default_header($old_header = '', $new_header = '') { 407 return array( 408 array( 409 'data' => $old_header, 410 'colspan' => 2 411 ), 412 array( 413 'data' => $new_header, 414 'colspan' => 2 415 ) 416 ); 417 } 418 419 /** 420 * AHAH callback for rendering the inline diff of a node. 421 */ 422 function diff_inline_ahah($node) { 423 $form_state = array('values' => $_POST); 424 if ($form = form_get_cache($form_state['values']['form_build_id'], $form_state)) { 425 if (!empty($form_state['values']['revision']) && is_numeric($form_state['values']['revision'])) { 426 $vid = $form_state['values']['revision']; 427 } 428 else { 429 $vid = 0; 430 } 431 drupal_json(array('status' => TRUE, 'data' => diff_inline_show($node, $vid))); 432 exit; 433 } 434 drupal_json(array('status' => FALSE, 'data' => '')); 435 exit; 436 } 437 438 /** 439 * Show the inline diff for a given node, vid. If vid = 0 or no previous vid 440 * exists for the given revision returns the normally rendered content of the 441 * specified revision. 442 */ 443 function diff_inline_show($node, $vid = 0, $metadata = TRUE) { 444 $new_node = $vid ? node_load($node->nid, $vid, TRUE) : drupal_clone($node); 445 $new = node_build_content($new_node); 446 $new = drupal_render($new->content); 447 448 $old = $vid ? _diff_get_previous_vid(node_revision_list($node), $vid) : 0; 449 if ($old) { 450 $old = node_build_content(node_load($node->nid, $old, TRUE)); 451 $old = drupal_render($old->content); 452 $output = $metadata ? theme('diff_inline_metadata', $new_node) : ''; 453 $output .= diff_get_inline($old, $new); 454 return $output; 455 } 456 return $new; 457 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |