1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8$section = 'wiki page'; 9$section_class = "tiki_wiki_page manage"; // This will be body class instead of $section 10require_once('tiki-setup.php'); 11$histlib = TikiLib::lib('hist'); 12require_once('lib/wiki/renderlib.php'); 13 14$access->check_feature('feature_wiki'); 15 16if (! isset($_REQUEST["source"])) { 17 $access->check_feature('feature_history'); 18} else { 19 $access->check_feature('feature_source'); 20} 21// Get the page from the request var or default it to HomePage 22if (! isset($_REQUEST["page"])) { 23 $smarty->assign('msg', tra("No page indicated")); 24 $smarty->display("error.tpl"); 25 die; 26} else { 27 $page = $_REQUEST["page"]; 28 $smarty->assign_by_ref('page', $_REQUEST["page"]); 29} 30 31$auto_query_args = ['page', 'oldver', 'newver', 'diff_style', 'paginate', 'history_offset']; 32 33// Now check permissions to access this page 34if (! isset($_REQUEST["source"])) { 35 $access->check_permission('tiki_p_wiki_view_history', '', 'wiki page', $_REQUEST['page']); 36} else { 37 $access->check_permission('tiki_p_wiki_view_source', '', 'wiki page', $_REQUEST['page']); 38} 39$info = $tikilib->get_page_info($page); 40if (empty($info)) { 41 $smarty->assign('msg', tra('No page indicated')); 42 $smarty->display('error.tpl'); 43 die; 44} 45 46$tikilib->get_perm_object($_REQUEST['page'], 'wiki page', $info); 47 48if (isset($_REQUEST['preview'], $_REQUEST['flaggedrev'], $_REQUEST['page']) && $prefs['flaggedrev_approval'] == 'y' && $tiki_p_wiki_approve == 'y') { 49 $targetFlag = null; 50 51 if (isset($_REQUEST['approve'])) { 52 $targetFlag = 'OK'; 53 $targetVersion = (int) $_REQUEST['approve']; 54 } elseif (isset($_REQUEST['unapprove'])) { 55 $targetFlag = 'REJECT'; 56 $targetVersion = (int) $_REQUEST['unapprove']; 57 } 58 59 if ($targetFlag) { 60 $flaggedrevisionlib = TikiLib::lib('flaggedrevision'); 61 62 $flaggedrevisionlib->flag_revision($info['pageName'], $targetVersion, 'moderation', $targetFlag); 63 } 64} 65 66$smarty->assign_by_ref('info', $info); 67 68if ($prefs['feature_contribution'] == 'y') { 69 $contributionlib = TikiLib::lib('contribution'); 70 $contributions = $contributionlib->get_assigned_contributions($page, 'wiki page'); 71 $smarty->assign_by_ref('contributions', $contributions); 72 if ($prefs['feature_contributor_wiki'] == 'y') { 73 $contributors = $logslib->get_wiki_contributors($info); 74 $smarty->assign_by_ref('contributors', $contributors); 75 } 76} 77 78$paginate = (isset($_REQUEST['paginate']) && $_REQUEST['paginate'] == 'on') || ! isset($_REQUEST['diff_style']); 79$smarty->assign('paginate', $paginate); 80 81if (isset($_REQUEST['history_offset']) && $paginate) { 82 $history_offset = (int) $_REQUEST['history_offset']; 83} else { 84 $history_offset = 0; 85} 86$smarty->assign('history_offset', $history_offset); 87 88if (isset($_REQUEST['history_pagesize']) && $paginate) { 89 $history_pagesize = (int) $_REQUEST['history_pagesize']; 90} elseif (isset($_SESSION['history_pagesize'])) { 91 $history_pagesize = (int) $_SESSION['history_pagesize']; 92} else { 93 $history_pagesize = (int) $prefs['maxRecords']; 94} 95$_SESSION['history_pagesize'] = $history_pagesize; 96$smarty->assign('history_pagesize', $history_pagesize); 97 98// fetch page history, but omit the actual page content (to save memory) 99$history = $histlib->get_page_history($page, false, $history_offset, $paginate ? $history_pagesize : -1); 100$smarty->assign('history_cant', $histlib->get_nb_history($page) - 1); 101 102if ($prefs['flaggedrev_approval'] == 'y') { 103 $flaggedrevisionlib = TikiLib::lib('flaggedrevision'); 104 105 if ($flaggedrevisionlib->page_requires_approval($page)) { 106 $approved_versions = $flaggedrevisionlib->get_versions_with($page, 'moderation', 'OK'); 107 $rejected_versions = $flaggedrevisionlib->get_versions_with($page, 'moderation', 'REJECT'); 108 109 $smarty->assign('flaggedrev_approval', true); 110 111 $info['approved'] = in_array($info['version'], $approved_versions); 112 $info['rejected'] = in_array($info['version'], $rejected_versions); 113 114 $new_history = []; 115 116 foreach ($history as $version) { 117 $version['approved'] = in_array($version['version'], $approved_versions); 118 $version['rejected'] = in_array($version['version'], $rejected_versions); 119 if ($version['rejected']) { 120 $version['rejection_reason'] = $flaggedrevisionlib->get_flag_comment($page, $version['version'], 'moderation', 'REJECT'); 121 } 122 if ($tiki_p_wiki_view_latest == 'y' || $version['approved'] || $version['rejected']) { 123 $new_history[] = $version; 124 } 125 } 126 127 while ($tiki_p_wiki_approve != 'y' && sizeof($new_history) > 0 && ! $new_history[0]['approved'] && ! $new_history[0]['rejected']) { 128 array_shift($new_history); 129 } 130 131 $history = $new_history; 132 } 133} 134 135if (! isset($_REQUEST['show_all_versions'])) { 136 $_SESSION['show_all_versions'] = isset($_SESSION['show_all_versions']) ? $_SESSION['show_all_versions'] : 'y'; 137} else { 138 $_SESSION['show_all_versions'] = $_REQUEST['show_all_versions'] === 'n' ? 'n' : 'y'; 139} 140 141$sessions = []; 142if (count($history) > 0) { 143 $lastuser = ''; // calculate edit session info 144 $lasttime = 0; // secs 145 $idletime = 1800; // max gap between edits in sessions 30 mins? Maybe should use a pref? 146 for ($i = 0, $cnt = count($history); $i < $cnt; $i++) { 147 if ((isset($history[$i]['user']) && $history[$i]['user'] != $lastuser) || (isset($history[$i]['lastModif']) && $lasttime - $history[$i]['lastModif'] > $idletime)) { 148 $sessions[] = $history[$i]; 149 //$history[$i]['session'] = $history[$i]['version']; 150 } elseif (count($sessions) > 0) { 151 $history[$i]['session'] = $sessions[count($sessions) - 1]['version']; 152 } 153 if (isset($history[$i]['user'])) { 154 $lastuser = $history[$i]['user']; 155 } else { 156 $lastuser = ''; 157 } 158 if (isset($history[$i]['lastModif'])) { 159 $lasttime = $history[$i]['lastModif']; 160 } else { 161 $lasttime = 0; 162 } 163 } 164 $csesh = count($sessions) + 1; 165 foreach ($history as &$h) { // move ending 'version' into starting 'session' 166 if (! empty($h['session'])) { 167 foreach ($history as &$h2) { 168 if ($h2['version'] == $h['session']) { 169 $h2['session'] = $h['version']; 170 } 171 } 172 $h['session'] = ''; 173 } 174 } 175 if ($_SESSION['show_all_versions'] == "n") { 176 for ($i = 0, $cnt = count($history); $i < $cnt; $i++) { // remove versions inside sessions 177 if (! empty($history[$i]['session']) && $i < $cnt - 1) { 178 $seshend = $history[$i]['session']; 179 $i++; 180 for ($i; $i < $cnt; $i++) { 181 if ($history[$i]['version'] >= $seshend) { 182 unset($history[$i]); 183 } else { 184 $i--; 185 break; 186 } 187 } 188 } 189 } 190 } 191} 192$smarty->assign('show_all_versions', $_SESSION['show_all_versions']); 193$history_versions = []; 194$history_sessions = []; 195reset($history); 196foreach ($history as &$h) { // as $h has been used by reference before it needs to be so again (it seems) 197 $history_versions[] = (int)$h['version']; 198 $history_sessions[] = isset($h['session']) ? (int)$h['session'] : 0; 199} 200$history_versions = array_reverse($history_versions); 201$history_sessions = array_reverse($history_sessions); 202$history_versions[] = (int) $info['version']; // current is last one 203$history_sessions[] = 0; 204$smarty->assign_by_ref('history', $history); 205 206// for pagination 207$smarty->assign('ver_cant', count($history_versions)); 208 209if (isset($_REQUEST['clear_versions'])) { 210 unset($_REQUEST['clear_versions']); 211 unset($_REQUEST['newver']); 212 unset($_REQUEST['newver_idx']); 213 unset($_REQUEST['oldver']); 214 unset($_REQUEST['oldver_idx']); 215 unset($_REQUEST['compare']); 216 unset($_REQUEST['diff_style']); 217} 218// calculate version and offset 219if (isset($_REQUEST['bothver_idx'])) { 220 if ($_REQUEST['bothver_idx'] == 0) { 221 $_REQUEST['bothver_idx'] = 1; 222 } 223 $_REQUEST['oldver_idx'] = $_REQUEST['bothver_idx'] - 1; 224 $_REQUEST['newver_idx'] = $_REQUEST['bothver_idx']; 225 if ($_SESSION['show_all_versions'] == 'n' && ! empty($history_sessions[$_REQUEST['bothver_idx']])) { 226 $_REQUEST['oldver_idx'] = $_REQUEST['bothver_idx']; 227 } 228} 229if (isset($_REQUEST['newver_idx'])) { 230 $newver = $history_versions[$_REQUEST['newver_idx']]; 231} else { 232 if (isset($_REQUEST['newver']) && $_REQUEST['newver'] > 0) { 233 $newver = (int)$_REQUEST["newver"]; 234 if (in_array($newver, $history_versions)) { 235 $_REQUEST['newver_idx'] = array_search($newver, $history_versions); 236 } else { 237 $_REQUEST['newver_idx'] = array_search($newver, $history_sessions); 238 } 239 } else { 240 $newver = $history_versions[count($history_versions) - 1]; 241 $_REQUEST['newver_idx'] = count($history_versions) - 1; 242 } 243} 244if (isset($_REQUEST['oldver_idx'])) { 245 $oldver = $history_versions[$_REQUEST['oldver_idx']]; 246 if ($_SESSION['show_all_versions'] == 'n' && ! empty($history_sessions[$_REQUEST['oldver_idx']])) { 247 $oldver = $history_sessions[$_REQUEST['oldver_idx']]; 248 } 249} else { 250 if (isset($_REQUEST['oldver']) && $_REQUEST['oldver'] > 0) { 251 $oldver = (int)$_REQUEST["oldver"]; 252 if (in_array($oldver, $history_versions)) { 253 $_REQUEST['oldver_idx'] = array_search($oldver, $history_versions); 254 } else { 255 $_REQUEST['oldver_idx'] = array_search($oldver, $history_sessions); 256 } 257 } else { 258 $oldver = $history_versions[count($history_versions) - 1]; 259 $_REQUEST['oldver_idx'] = count($history_versions) - 1; 260 } 261} 262if ($_REQUEST['oldver_idx'] + 1 == $_REQUEST['newver_idx']) { 263 $_REQUEST['bothver_idx'] = $_REQUEST['newver_idx']; 264} 265$_REQUEST['oldver'] = $oldver; 266$_REQUEST['newver'] = $newver; 267 268// source view 269if (isset($_REQUEST['source_idx'])) { 270 $source = $history_versions[$_REQUEST['source_idx']]; 271} else { 272 if (isset($_REQUEST['source'])) { 273 $source = (int)$_REQUEST["source"]; 274 if ($source > 0) { 275 $_REQUEST['source_idx'] = array_search($source, $history_versions); 276 } else { 277 $_REQUEST['source_idx'] = count($history_versions) - 1; 278 $smarty->assign('noHistory', true); 279 } 280 } 281} 282if (isset($_REQUEST['preview_idx'])) { 283 $preview = $history_versions[$_REQUEST['preview_idx']]; 284} else { 285 if (isset($_REQUEST['preview_date'])) { 286 $_REQUEST['preview'] = (int)$histlib->get_version_by_time($page, $_REQUEST["preview_date"]); 287 } 288 289 if (isset($_REQUEST['preview'])) { 290 $preview = (int)$_REQUEST["preview"]; 291 if ($_REQUEST['preview'] > 0) { 292 $_REQUEST['preview_idx'] = array_search($preview, $history_versions); 293 } else { 294 $_REQUEST['preview_idx'] = count($history_versions) - 1; 295 $smarty->assign('noHistory', true); 296 } 297 } 298} 299 300if (isset($_REQUEST['version'])) { 301 $rversion = $_REQUEST['version']; 302} 303 304$smarty->assign('source', false); 305if (isset($source)) { 306 if ($source == '' && isset($rversion)) { 307 $source = $rversion; 308 } 309 if ($source == $info["version"] || $source == 0) { 310 $smarty->assign('sourced', $info["data"]); 311 $smarty->assign('source', $info['version']); 312 } else { 313 $version = $histlib->get_version($page, $source); 314 if ($version) { 315 $smarty->assign('sourced', $version["data"]); 316 $smarty->assign('source', $source); 317 } 318 } 319} 320$smarty->assign('preview', false); 321if (isset($preview)) { 322 if ($preview == '' && isset($rversion)) { 323 $preview = $rversion; 324 } 325 if ($preview == $info['version'] || $preview == 0) { 326 if ($prefs['flaggedrev_approval'] != 'y' || ! $flaggedrevisionlib->page_requires_approval($page) || $info['approved'] || $info['rejected'] || $tiki_p_wiki_approve == 'y') { 327 $previewd = (new WikiLibOutput($info, $info['data'], ['preview_mode' => true, 'is_html' => $info['is_html']]))->parsedValue; 328 $smarty->assign('previewd', $previewd); 329 } 330 $smarty->assign('preview', $info['version']); 331 } else { 332 $version = $histlib->get_version($page, $preview); 333 if ($version) { 334 $previewd = (new WikiLibOutput($version, $version['data'], ['preview_mode' => true, 'is_html' => $version['is_html']]))->parsedValue; 335 $smarty->assign('previewd', $previewd); 336 $smarty->assign('preview', $preview); 337 } 338 } 339 340 $smarty->assign('flaggedrev_preview_approved', isset($approved_versions) && in_array($preview, $approved_versions)); 341 $smarty->assign('flaggedrev_preview_rejected', isset($rejected_versions) && in_array($preview, $rejected_versions)); 342} 343if (isset($preview)) { 344 $smarty->assign('current', $preview); 345} elseif (isset($source)) { 346 $smarty->assign('current', $source); 347} elseif ($newver) { 348 $smarty->assign('current', $newver); 349} elseif ($oldver) { 350 $smarty->assign('current', $oldver); 351} else { 352 $smarty->assign('current', 0); 353} 354if ($prefs['feature_multilingual'] == 'y' && isset($_REQUEST['show_translation_history'])) { 355 $multilinguallib = TikiLib::lib('multilingual'); 356 $smarty->assign('show_translation_history', 1); 357 $sources = $multilinguallib->getSourceHistory($info['page_id']); 358 $targets = $multilinguallib->getTargetHistory($info['page_id']); 359} else { 360 $sources = []; 361 $targets = []; 362} 363$smarty->assign_by_ref('translation_sources', $sources); 364$smarty->assign_by_ref('translation_targets', $targets); 365if (isset($_REQUEST["diff2"])) { // previous compatibility 366 if ($_REQUEST["diff2"] == '' && isset($rversion)) { 367 $_REQUEST["diff2"] = $rversion; 368 } 369 $_REQUEST["compare"] = "y"; 370 $oldver = (int)$_REQUEST["diff2"]; 371} 372if (! isset($newver)) { 373 $newver = 0; 374} 375if ($prefs['feature_multilingual'] == 'y') { 376 $multilinguallib = TikiLib::lib('multilingual'); 377 $langLib = TikiLib::lib('language'); 378 $languages = $langLib->list_languages(); 379 $smarty->assign_by_ref('languages', $languages); 380 if (isset($_REQUEST["update_translation"])) { 381 // Update translation button clicked. Forward request to edit page of translation. 382 if (isset($_REQUEST['tra_lang'])) { 383 $target = $_REQUEST['tra_lang']; 384 } else { 385 die('Invalid call to this page. Specify tra_lang'); 386 } 387 // Find appropriate translation page 388 $langs = $multilinguallib->getTranslations('wiki page', $info['page_id'], $info['pageName'], true); 389 $pageName = ''; 390 foreach ($langs as $pageInfo) { 391 if ($target == (string)$pageInfo['lang']) { 392 $pageName = $pageInfo['objName']; 393 } 394 } 395 // Build URI / Redirect 396 $diff_style = isset($_REQUEST['diff_style']) ? rawurlencode($_REQUEST['diff_style']) : rawurlencode($info['is_html'] === '1' ? 'htmldiff' : $prefs['default_wiki_diff_style']); 397 $comment = rawurlencode("Updating from $page at version {$info['version']}"); 398 if ($newver == 0) { 399 $newver = $info['version']; 400 } 401 if ($pageName) { 402 $uri = "tiki-editpage.php?page=$pageName&source_page=$page&diff_style=$diff_style&oldver=$oldver&newver=$newver&comment=$comment"; 403 } else { 404 $uri = "tiki-edit_translation.php?page=$page"; 405 } 406 header("Location: $uri"); 407 exit; 408 } 409} 410$current_version = $info["version"]; 411$comparing = isset($_GET['newver']) || isset($_GET['oldver']); 412$not_comparing = $comparing ? 'false' : 'true'; 413 414$headerlib->add_jq_onready( 415<<<JS 416\$("input[name=oldver], input[name=newver]").change(function () { 417 var ver = parseInt(\$(this).val(), 10), ver2; 418 if (ver == 0) { ver = $current_version; } 419 if (\$(this).attr("name") == "oldver") { 420 \$("input[name=newver]").each(function () { 421 ver2 = parseInt(\$(this).val(), 10); 422 if (ver2 == 0) { ver2 = $current_version; } 423 \$(this).attr("disabled", (ver2 <= ver)); 424 }); 425 } else if (\$(this).attr("name") == "newver") { 426 \$("input[name=oldver]").each(function () { 427 ver2 = parseInt(\$(this).val(), 10); 428 if (ver2 == 0) { ver2 = $current_version; } 429 \$(this).attr("disabled", (ver2 >= ver)); 430 }); 431 } 432}); 433if (\$("input[name=newver][checked=checked]").length) { 434 \$("input[name=newver][checked=checked]").change(); 435 \$("input[name=oldver][checked=checked]").change(); 436} else if ($not_comparing) { 437 \$("input[name=newver]:eq(0)").prop("checked", "checked").change(); 438 \$("input[name=oldver]:eq(1)").prop("checked", "checked").change(); 439} 440JS 441); 442if ($comparing) { 443 histlib_helper_setup_diff($page, $oldver, $newver, (! empty($_REQUEST['diff_style']) ? $_REQUEST['diff_style'] : '')); 444 445 if (isset($approved_versions)) { 446 $smarty->assign('flaggedrev_compare_approve', ! in_array($newver, $approved_versions)); 447 } 448} else { 449 $smarty->assign('diff_style', $info['is_html'] === '1' ? 'htmldiff' : $prefs['default_wiki_diff_style']); 450} 451 452if ($info["flag"] == 'L') { 453 $smarty->assign('lock', true); 454} else { 455 $smarty->assign('lock', false); 456} 457 458if (isset($_REQUEST['nohistory'])) { 459 $smarty->assign('noHistory', true); 460} 461 462$smarty->assign('editable', TikiLib::lib('wiki')->is_editable($page, $user, $info)); 463 464TikiLib::events()->trigger( 465 'tiki.wiki.view', 466 array_merge( 467 [ 468 'type' => 'wiki page', 469 'object' => $page, 470 'user' => $GLOBALS['user'], 471 ], 472 $info 473 ) 474); 475 476// disallow robots to index page: 477$smarty->assign('page_user', $info['user']); 478$smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW'); 479 480include_once('tiki-section_options.php'); 481if ($prefs['feature_theme_control'] == 'y') { 482 $cat_type = 'wiki page'; 483 $cat_objid = $_REQUEST['page']; 484 include('tiki-tc.php'); 485} 486// Display the template 487$smarty->assign('mid', 'tiki-pagehistory.tpl'); 488$smarty->display("tiki.tpl"); 489