<?php
-include 'login/commits.php';
+if (!$User->admin('edit')) {
+ require '403.inc.html';
+ return;
+}
+
+$hash = ltrim($Page->path, '/');
+if (!$hash) {
+ return TRUE;
+}
+
+$this->title = "Wijzigingen in ".strtoupper($hash);
+print "<h2>{$this->title}</h2>\n";
+
+$gitcmd = "git show "
+ . "--word-diff=porcelain --no-prefix --pretty='%H%n%at\t%an\t%w(0,0,1)%B' "
+ . escapeshellarg($hash);
+$log = popen($gitcmd, 'r');
+if (!$log or strpos(fgets($log), $hash) !== 0) {
+ $Page->place['warn'] = "Kon inhoud niet ophalen met <code>$gitcmd</code>";
+ return;
+}
+
+# read metadata and commit message
+list ($atime, $author, $msg) = explode("\t", fgets($log), 3);
+while ( $line = fgets($log) ) {
+ if ($line == "\n") {
+ fgets($log); // assume another empty line
+ break;
+ }
+ $msg .= substr($line, 1);
+}
+
+# commit head
+print '<p>';
+printf('<small class="date">%s • %s</small>',
+ htmlspecialchars($author), strftime('%F %H:%M', $atime)
+);
+print "\n".nl2br(htmlspecialchars($msg));
+print "</p>\n";
+
+print '<style>
+.diff {
+ white-space: pre-wrap;
+ white-space: break-spaces;
+ font-family: monospace;
+}
+td:first-of-type.change,
+del {
+ background: #F002;
+ text-decoration: none;
+}
+td:last-of-type.change,
+ins {
+ background: #0F02;
+ text-decoration: none;
+}
+.diff .head {
+ background: #00F2;
+}
+</style>';
+
+# body
+$row = $ln = NULL;
+$col = ['', ''];
+print '<table class="diff">';
+while ( $line = fgets($log) ) {
+ preg_match(isset($ln) ? '/^(\W|\S+ )(.*)/' : '/^(\S+ )(.*)/', $line, $part);
+ $body = htmlspecialchars($part[2]);
+ switch ($part[1]) {
+ case 'diff ':
+ # file start
+ if (preg_match('/^--git (.+) (.*)/', $part[2], $diffhead)) {
+ $row = "$diffhead[1]";
+ if ($diffhead[1] !== $diffhead[2]) {
+ $row .= " → $diffhead[2]";
+ }
+ }
+ else {
+ $row = '?';
+ }
+ $ln = NULL;
+ break;
+ case '@@ ':
+ # chunk start
+ if (preg_match('/^[-](\d+)(?:,\d+)? [+](\d+)(?:,\d+)? @@/', $part[2], $diffstart)) {
+ array_shift($diffstart);
+ $ln = $diffstart;
+ }
+ else {
+ $ln = ['?', '?']; # unrecognised diff header
+ }
+ print '<tr class="head"><td colspan="4">'.$row.'</tr>'."\n";
+ break;
+ case '-':
+ $col[0] .= "<del>$body</del>";
+ break;
+ case '+':
+ $col[1] .= "<ins>$body</ins>";
+ break;
+ case ' ':
+ $col[0] .= $body;
+ $col[1] .= $body;
+ break;
+ case '~':
+ # part end
+ print '<tr>';
+ foreach ($col as $i => $line) {
+ if (empty($line)) {
+ print '<th><td>';
+ continue;
+ }
+ printf('<th>%s</th><td%s>%s</td>',
+ $ln[$i]++,
+ $col[0] == $col[1] ? '' : ' class="change"',
+ $line
+ );
+ }
+ print "</tr>\n";
+ $col = ['', ''];
+ break;
+ }
+}
+print "</table>\n";
+pclose($log);
+
+return;