178 lines
8.3 KiB
PHP
178 lines
8.3 KiB
PHP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<style type="text/css">
|
|
body {margin:0;border:0;padding:0;font:11pt sans-serif}
|
|
body > h1 {margin:0 0 0.5em 0;font:2em sans-serif;background-color:#def}
|
|
body > div {padding:2px}
|
|
p {margin-top:0}
|
|
ins {color:green;background:#dfd;text-decoration:none}
|
|
del {color:red;background:#fdd;text-decoration:none}
|
|
#params {margin:1em 0;font: 14px sans-serif}
|
|
.panecontainer > p {margin:0;border:1px solid #bcd;border-bottom:none;padding:1px 3px;background:#def;font:14px sans-serif}
|
|
.panecontainer > p + div {margin:0;padding:2px 0 2px 2px;border:1px solid #bcd;border-top:none}
|
|
.pane {margin:0;padding:0;border:0;width:100%;min-height:20em;overflow:auto;font:12px monospace}
|
|
#htmldiff {color:gray}
|
|
#htmldiff.onlyDeletions ins {display:none}
|
|
#htmldiff.onlyInsertions del {display:none}
|
|
</style>
|
|
<title>PHP Fine Diff: Online Diff Viewer</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
</head>
|
|
<body>
|
|
<a href="https://github.com/gorhill/PHP-FineDiff"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
|
|
<h1>PHP Fine Diff: Online Diff Viewer</h1>
|
|
<div>
|
|
<?php
|
|
// http://www.php.net/manual/en/function.get-magic-quotes-gpc.php#82524
|
|
function stripslashes_deep(&$value) {
|
|
$value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
|
|
return $value;
|
|
}
|
|
if ( (function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) || (ini_get('magic_quotes_sybase') && strtolower(ini_get('magic_quotes_sybase'))!="off") ) {
|
|
stripslashes_deep($_GET);
|
|
stripslashes_deep($_POST);
|
|
}
|
|
|
|
use GorHill\FineDiff\FineDiff;
|
|
|
|
$cache_lo_water_mark = 900;
|
|
$cache_hi_water_mark = 1100;
|
|
$compressed_serialized_filename_extension = '.store.gz';
|
|
|
|
$granularity = 2;
|
|
$from_text = '';
|
|
$to_text = '';
|
|
$diff_opcodes = '';
|
|
$diff_opcodes_len = 0;
|
|
$data_key = '';
|
|
|
|
$start_time = gettimeofday(true);
|
|
|
|
// restore from cache
|
|
if ( isset($_GET['data']) ) {
|
|
if ( ctype_alnum($_GET['data']) ) {
|
|
$filename = "{$_GET['data']}{$compressed_serialized_filename_extension}";
|
|
$compressed_serialized_data = @file_get_contents("./cache/{$filename}");
|
|
if ( $compressed_serialized_data !== false ) {
|
|
@touch("./cache/{$filename}");
|
|
$data_from_serialization = unserialize(gzuncompress($compressed_serialized_data));
|
|
$granularity = $data_from_serialization['granularity'];
|
|
$from_text = $data_from_serialization['from_text'];
|
|
$diff_opcodes = $data_from_serialization['diff_opcodes'];
|
|
$diff_opcodes_len = strlen($diff_opcodes);
|
|
$to_text = FineDiff::renderToTextFromOpcodes($from_text, $diff_opcodes);
|
|
$data_key = $data_from_serialization['data_key'];
|
|
}
|
|
else {
|
|
echo '<p style="font-size:smaller">The page you are looking for has expired.</p>', "\n";
|
|
}
|
|
}
|
|
$exec_time = gettimeofday(true) - $start_time;
|
|
}
|
|
// new diff
|
|
else {
|
|
if ( isset($_POST['granularity']) && ctype_digit($_POST['granularity']) ) {
|
|
$granularity = max(min(intval($_POST['granularity']),3),0);
|
|
}
|
|
if ( !empty($_POST['from']) || !empty($_POST['to'])) {
|
|
if ( !empty($_POST['from']) ) {
|
|
$from_text = $_POST['from'];
|
|
}
|
|
if ( !empty($_POST['to']) ) {
|
|
$to_text = $_POST['to'];
|
|
}
|
|
}
|
|
// limit input
|
|
$from_text = substr($from_text, 0, 1024*100);
|
|
$to_text = substr($to_text, 0, 1024*100);
|
|
|
|
// ensure input is suitable for diff
|
|
$from_text = mb_convert_encoding($from_text, 'HTML-ENTITIES', 'UTF-8');
|
|
$to_text = mb_convert_encoding($to_text, 'HTML-ENTITIES', 'UTF-8');
|
|
|
|
$granularityStacks = array(
|
|
FineDiff::$paragraphGranularity,
|
|
FineDiff::$sentenceGranularity,
|
|
FineDiff::$wordGranularity,
|
|
FineDiff::$characterGranularity
|
|
);
|
|
$diff_opcodes = FineDiff::getDiffOpcodes($from_text, $to_text, $granularityStacks[$granularity]);
|
|
$diff_opcodes_len = strlen($diff_opcodes);
|
|
$exec_time = gettimeofday(true) - $start_time;
|
|
if ( $diff_opcodes_len ) {
|
|
$data_key = sha1(serialize(array('granularity' => $granularity, 'from_text' => $from_text, 'diff_opcodes' => $diff_opcodes)));
|
|
$filename = "{$data_key}{$compressed_serialized_filename_extension}";
|
|
if ( !file_exists("./cache/{$filename}") ) {
|
|
// purge cache if too many files
|
|
if ( !(time() % 100) ) {
|
|
$files = glob("./cache/*{$compressed_serialized_filename_extension}");
|
|
$num_files = $files ? count($files) : 0;
|
|
if ( $num_files > $cache_hi_water_mark ) {
|
|
$sorted_files = array();
|
|
foreach ( $files as $file ) {
|
|
$sorted_files[strval(@filemtime("./cache/{$file}")).$file] = $file;
|
|
}
|
|
ksort($sorted_files);
|
|
foreach ( $sorted_files as $file ) {
|
|
@unlink("./cache/{$file}");
|
|
$num_files -= 1;
|
|
if ( $num_files < $cache_lo_water_mark ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// save diff in cache
|
|
$data_to_serialize = array(
|
|
'granularity' => $granularity,
|
|
'from_text' => $from_text,
|
|
'diff_opcodes' => $diff_opcodes,
|
|
'data_key' => $data_key,
|
|
);
|
|
$serialized_data = serialize($data_to_serialize);
|
|
@file_put_contents("./cache/{$filename}", gzcompress($serialized_data));
|
|
@chmod("./cache/{$filename}", 0666);
|
|
}
|
|
}
|
|
}
|
|
|
|
$rendered_diff = FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes);
|
|
$from_len = strlen($from_text);
|
|
$to_len = strlen($to_text);
|
|
|
|
if ( !empty($data_key) ) {
|
|
echo '<p style="margin-right:8em;font-size:smaller">Tempolink: <a href="viewdiff.php?data=', $data_key, '">http://', $_SERVER['HTTP_HOST'], '/viewdiff.php?data=', $data_key, '</a> <span style="color:#aaa">(This link is not viewable by others, unless it has been explicitly shared by the creator. This link will exist for a limited period of time, which depends on how often it is visited.)</span></p>', "\n";
|
|
}
|
|
?>
|
|
<div class="panecontainer" style="width:99%"><p>Diff <span style="color:gray">(diff: <?php printf('%.3f', $exec_time); ?> seconds, diff len: <?php echo $diff_opcodes_len; ?> chars)</span> / Show <input type="radio" name="htmldiffshow" onclick="setHTMLDiffVisibility('deletions');">Deletions only <input type="radio" name="htmldiffshow" checked="checked" onclick="setHTMLDiffVisibility();">All <input type="radio" name="htmldiffshow" onclick="setHTMLDiffVisibility('insertions');">Insertions only</p><div><div id="htmldiff" class="pane" style="white-space:pre-wrap"><?php
|
|
echo $rendered_diff; ?></div></div>
|
|
</div>
|
|
<form action="viewdiff.php" method="post">
|
|
<p style="margin:1em 0 0.5em 0">Enter text to diff below:</p>
|
|
<div class="panecontainer" style="display:inline-block;width:49.5%"><p>From</p><div><textarea name="from" class="pane"><?php echo htmlentities($from_text, ENT_QUOTES, 'UTF-8'); ?></textarea></div></div>
|
|
<div class="panecontainer" style="display:inline-block;width:49.5%"><p>To</p><div><textarea name="to" class="pane"><?php echo htmlentities($to_text, ENT_QUOTES, 'UTF-8'); ?></textarea></div></div>
|
|
<p id="params">Granularity:<input name="granularity" type="radio" value="0"<?php if ( $granularity === 0 ) { echo ' checked="checked"'; } ?>> Paragraph/lines <input name="granularity" type="radio" value="1"<?php if ( $granularity === 1 ) { echo ' checked="checked"'; } ?>> Sentence <input name="granularity" type="radio" value="2"<?php if ( $granularity === 2 ) { echo ' checked="checked"'; } ?>> Word <input name="granularity" type="radio" value="3"<?php if ( $granularity === 3 ) { echo ' checked="checked"'; } ?>> Character <input type="submit" value="View diff"> <a href="viewdiff.php"><button>Clear all</button></a></p>
|
|
</form>
|
|
<p style="margin-top:1em"><a href="viewdiff-ex.php">Go to main page</a></p>
|
|
<script type="text/javascript">
|
|
<!--
|
|
function setHTMLDiffVisibility(what) {
|
|
var htmldiffEl = document.getElementById('htmldiff'),
|
|
className = htmldiffEl.className;
|
|
className = className.replace(/\bonly(Insertions|Deletions)\b/g, '').replace(/\s{2,}/g, ' ').replace(/\s+$/, '').replace(/^\s+/, '');
|
|
if ( what === 'deletions' ) {
|
|
htmldiffEl.className = className + ' onlyDeletions';
|
|
}
|
|
else if ( what === 'insertions' ) {
|
|
htmldiffEl.className = className + ' onlyInsertions';
|
|
}
|
|
else {
|
|
htmldiffEl.className = className;
|
|
}
|
|
}
|
|
// -->
|
|
</script>
|
|
</body>
|
|
</html>
|