function showDiffs($a, $b) { $ota = explode("\n", str_replace("\r\n", "\n", $a)); $nta = explode("\n", str_replace("\r\n", "\n", $b)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); $funky = $formatter->format($diffs); preg_match_all('/<span class="diffchange">(.*?)<\\/span>/', $funky, $matches); foreach ($matches[1] as $bit) { $hex = bin2hex($bit); echo "\t{$hex}\n"; } }
function test_white_between_words() { // From FS#2161 global $lang; $df = new Diff(explode("\n", "example"), explode("\n", "example example2")); $idf = new InlineDiffFormatter(); $tdf = new TableDiffFormatter(); $this->assertEqual($idf->format($df), '<tr><td colspan="4" class="diff-blockheader">@@ ' . $lang['line'] . ' -1 +1 @@ <span class="diff-deletedline"><del>' . $lang['deleted'] . '</del></span> <span class="diff-addedline">' . $lang['created'] . '</span></td></tr> <tr><td colspan="4">example <span class="diff-addedline">example2</span></td></tr> '); $this->assertEqual($tdf->format($df), '<tr><td class="diff-blockheader" colspan="2">' . $lang['line'] . ' 1:</td> <td class="diff-blockheader" colspan="2">' . $lang['line'] . ' 1:</td> </tr> <tr><td>-</td><td class="diff-deletedline">example</td><td>+</td><td class="diff-addedline">example <strong>example2</strong></td></tr> '); }
function show_texts_diff($text1, $text2, $display_line_numbers = false) { if (is_null($text1)) { $text1 = ''; } if (is_null($text2)) { $text2 = ''; } if ($text1 == $text2 || !is_scalar($text1) || !is_scalar($text2)) { // arguments are not scalars or are identical => do nothing return ''; } $lines1 = explode("\n", $text1); $lines2 = explode("\n", $text2); $diffs = new Diff($lines1, $lines2); $formatter = new TableDiffFormatter($display_line_numbers); return $formatter->format($diffs); }
/** * show diff * * @author Andreas Gohr <*****@*****.**> */ function html_diff($text = '', $intro = true) { require_once DOKU_INC . 'inc/DifferenceEngine.php'; global $ID; global $REV; global $lang; global $conf; // we're trying to be clever here, revisions to compare can be either // given as rev and rev2 parameters, with rev2 being optional. Or in an // array in rev2. $rev1 = $REV; if (is_array($_REQUEST['rev2'])) { $rev1 = (int) $_REQUEST['rev2'][0]; $rev2 = (int) $_REQUEST['rev2'][1]; if (!$rev1) { $rev1 = $rev2; unset($rev2); } } else { $rev2 = (int) $_REQUEST['rev2']; } if ($text) { // compare text to the most current revision $l_rev = ''; $l_text = rawWiki($ID, ''); $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . strftime($conf['dformat'], @filemtime(wikiFN($ID))) . '</a> ' . $lang['current']; $r_rev = ''; $r_text = cleanText($text); $r_head = $lang['yours']; } else { if ($rev1 && $rev2) { // two specific revisions wanted // make sure order is correct (older on the left) if ($rev1 < $rev2) { $l_rev = $rev1; $r_rev = $rev2; } else { $l_rev = $rev2; $r_rev = $rev1; } } elseif ($rev1) { // single revision given, compare to current $r_rev = ''; $l_rev = $rev1; } else { // no revision was given, compare previous to current $r_rev = ''; $revs = getRevisions($ID, 0, 1); $l_rev = $revs[0]; } // when both revisions are empty then the page was created just now if (!$l_rev && !$r_rev) { $l_text = ''; } else { $l_text = rawWiki($ID, $l_rev); } $r_text = rawWiki($ID, $r_rev); if (!$l_rev) { $l_head = '—'; } else { $l_info = getRevisionInfo($ID, $l_rev, true); if ($l_info['user']) { $l_user = editorinfo($l_info['user']); if (auth_ismanager()) { $l_user .= ' (' . $l_info['ip'] . ')'; } } else { $l_user = $l_info['ip']; } $l_user = '******' . $l_user . '</span>'; $l_sum = $l_info['sum'] ? '<span class="sum">' . hsc($l_info['sum']) . '</span>' : ''; if ($l_info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) { $l_minor = 'class="minor"'; } $l_head = '<a class="wikilink1" href="' . wl($ID, "rev={$l_rev}") . '">' . $ID . ' [' . strftime($conf['dformat'], $l_rev) . ']</a>' . '<br />' . $l_user . ' ' . $l_sum; } if ($r_rev) { $r_info = getRevisionInfo($ID, $r_rev, true); if ($r_info['user']) { $r_user = editorinfo($r_info['user']); if (auth_ismanager()) { $r_user .= ' (' . $r_info['ip'] . ')'; } } else { $r_user = $r_info['ip']; } $r_user = '******' . $r_user . '</span>'; $r_sum = $r_info['sum'] ? '<span class="sum">' . hsc($r_info['sum']) . '</span>' : ''; if ($r_info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) { $r_minor = 'class="minor"'; } $r_head = '<a class="wikilink1" href="' . wl($ID, "rev={$r_rev}") . '">' . $ID . ' [' . strftime($conf['dformat'], $r_rev) . ']</a>' . '<br />' . $r_user . ' ' . $r_sum; } elseif ($_rev = @filemtime(wikiFN($ID))) { $_info = getRevisionInfo($ID, $_rev, true); if ($_info['user']) { $_user = editorinfo($_info['user']); if (auth_ismanager()) { $_user .= ' (' . $_info['ip'] . ')'; } } else { $_user = $_info['ip']; } $_user = '******' . $_user . '</span>'; $_sum = $_info['sum'] ? '<span class="sum">' . hsc($_info['sum']) . '</span>' : ''; if ($_info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) { $r_minor = 'class="minor"'; } $r_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' [' . strftime($conf['dformat'], $_rev) . ']</a> ' . '(' . $lang['current'] . ')' . '<br />' . $_user . ' ' . $_sum; } else { $r_head = '— (' . $lang['current'] . ')'; } } $df = new Diff(explode("\n", htmlspecialchars($l_text)), explode("\n", htmlspecialchars($r_text))); $tdf = new TableDiffFormatter(); if ($intro) { print p_locale_xhtml('diff'); } ?> <table class="diff"> <tr> <th colspan="2" <?php echo $l_minor; ?> > <?php echo $l_head; ?> </th> <th colspan="2" <?php echo $r_minor; ?> > <?php echo $r_head; ?> </th> </tr> <?php echo $tdf->format($df); ?> </table> <?php }
/** * show diff * * @author Andreas Gohr <*****@*****.**> * Modified by Brandon Zehm, pulled from dokuwiki. * Requires DifferenceEngine.php from dokuwiki. * * Input: two strings * Output: html */ function html_diff($old, $new, $oldname = '', $newname = '', $stdout = 1) { global $conf; $html = ''; if (!($old and $new)) { return 'ERROR => Insufficient parameters passed to html_diff()!'; } // Load diff code require_once $conf['inc_diff']; $df = new Diff(explode("\n", htmlspecialchars($old)), explode("\n", htmlspecialchars($new))); $tdf = new TableDiffFormatter(); $html .= <<<EOL <table class="diff" width="100%"> <tr> <td colspan="2" width="50%" class="diff-header"> {$oldname} </td> <td colspan="2" width="50%" class="diff-header"> {$newname} </td> </tr> EOL; $html .= $tdf->format($df) . "</table>"; if ($stdout) { echo $html; } else { return $html; } }
/** * Return an HTML table allowing to display differences between two texts, the same way MediaWiki does * * @param string $value1 * @param string $value2 * @param array $table_options attributes to add on the <table> tag */ function format_differences($value1, $value2, $table_options = array()) { if (!is_array($value1)) { $value1 = explode("\r\n", $value1); } if (!is_array($value2)) { $value2 = explode("\r\n", $value2); } require_once App::pluginPath('alaxos') . '/lib/DifferenceEngine.php'; $formatter = new TableDiffFormatter(); $formatter->line_name = __d('alaxos', 'line', true); $table_rows = $formatter->format(new Diff($value1, $value2)); if (!empty($table_rows)) { return $this->Html->tag('table', $table_rows, $table_options); } else { return null; } }
/** * Generates diff, to be wrapped internally in a logging/instrumentation * * @param string $otext Old text, must be already segmented * @param string $ntext New text, must be already segmented * @return bool|string */ protected function textDiff($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); if ($wgExternalDiffEngine == 'wikidiff' || $wgExternalDiffEngine == 'wikidiff3') { wfDeprecated("\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.27'); $wgExternalDiffEngine = false; } if ($wgExternalDiffEngine == 'wikidiff2') { if (function_exists('wikidiff2_do_diff')) { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself $text = wikidiff2_do_diff($otext, $ntext, 2); $text .= $this->debug('wikidiff2'); return $text; } } elseif ($wgExternalDiffEngine !== false) { # Diff via the shell $tmpDir = wfTempDir(); $tempName1 = tempnam($tmpDir, 'diff_'); $tempName2 = tempnam($tmpDir, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); $difftext = wfShellExec($cmd); $difftext .= $this->debug("external {$wgExternalDiffEngine}"); unlink($tempName1); unlink($tempName2); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); $difftext = $wgContLang->unsegmentForDiff($formatter->format($diffs)); return $difftext; }
/** * Compare two versions of a wiki page * * @return void */ public function compareTask() { include_once dirname(dirname(__DIR__)) . DS . 'helpers' . DS . 'differenceengine.php'; $this->view->page = $this->page; $this->view->config = $this->config; $this->view->base_path = $this->_base_path; $this->view->sub = $this->_sub; // Incoming $oldid = Request::getInt('oldid', 0); $diff = Request::getInt('diff', 0); // Do some error checking if (!$diff) { $this->setError(Lang::txt('COM_WIKI_ERROR_MISSING_VERSION')); $this->displayTask(); return; } if ($diff == $oldid) { $this->setError(Lang::txt('COM_WIKI_ERROR_SAME_VERSIONS')); $this->displayTask(); return; } // If no initial page is given, compare to the current revision $this->view->revision = $this->page->revision('current'); $this->view->or = $this->page->revision($oldid); $this->view->dr = $this->page->revision($diff); // Diff the two versions $ota = explode("\n", $this->view->or->get('pagetext')); $nta = explode("\n", $this->view->dr->get('pagetext')); //$diffs = new Diff($ota, $nta); $formatter = new \TableDiffFormatter(); $this->view->content = $formatter->format(new \Diff($ota, $nta)); // Prep the pagename for display // e.g. "MainPage" becomes "Main Page" $this->view->title = $this->page->get('title'); // Set the page's <title> tag Document::setTitle(Lang::txt(strtoupper($this->_option)) . ': ' . $this->view->title . ': ' . Lang::txt(strtoupper($this->_option . '_' . $this->_task))); // Set the pathway if (Pathway::count() <= 0) { Pathway::append(Lang::txt(strtoupper($this->_option)), 'index.php?option=' . $this->_option); } Pathway::append($this->view->title, $this->page->link()); Pathway::append(Lang::txt(strtoupper($this->_option . '_' . $this->_task)), $this->page->link() . '&' . ($this->_sub ? 'action' : 'task') . '=' . $this->_task); $this->view->sub = $this->_sub; $this->view->message = $this->_message; $this->view->name = Lang::txt(strtoupper($this->_option)); foreach ($this->getErrors() as $error) { $this->view->setError($error); } $this->view->display(); }
/** * show diff * * @author Andreas Gohr <*****@*****.**> * @param string $text - compare with this text with most current version * @param bool $intr - display the intro text */ function html_diff($text = '', $intro = true, $type = null) { global $ID; global $REV; global $lang; global $conf; if (!$type) { $type = $_REQUEST['difftype']; } if ($type != 'inline') { $type = 'sidebyside'; } // we're trying to be clever here, revisions to compare can be either // given as rev and rev2 parameters, with rev2 being optional. Or in an // array in rev2. $rev1 = $REV; if (is_array($_REQUEST['rev2'])) { $rev1 = (int) $_REQUEST['rev2'][0]; $rev2 = (int) $_REQUEST['rev2'][1]; if (!$rev1) { $rev1 = $rev2; unset($rev2); } } else { $rev2 = (int) $_REQUEST['rev2']; } $r_minor = ''; $l_minor = ''; if ($text) { // compare text to the most current revision $l_rev = ''; $l_text = rawWiki($ID, ''); $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' . $lang['current']; $r_rev = ''; $r_text = cleanText($text); $r_head = $lang['yours']; } else { if ($rev1 && $rev2) { // two specific revisions wanted // make sure order is correct (older on the left) if ($rev1 < $rev2) { $l_rev = $rev1; $r_rev = $rev2; } else { $l_rev = $rev2; $r_rev = $rev1; } } elseif ($rev1) { // single revision given, compare to current $r_rev = ''; $l_rev = $rev1; } else { // no revision was given, compare previous to current $r_rev = ''; $revs = getRevisions($ID, 0, 1); $l_rev = $revs[0]; $REV = $l_rev; // store revision back in $REV } // when both revisions are empty then the page was created just now if (!$l_rev && !$r_rev) { $l_text = ''; } else { $l_text = rawWiki($ID, $l_rev); } $r_text = rawWiki($ID, $r_rev); list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev); } $df = new Diff(explode("\n", htmlspecialchars($l_text)), explode("\n", htmlspecialchars($r_text))); if ($type == 'inline') { $tdf = new InlineDiffFormatter(); } else { $tdf = new TableDiffFormatter(); } if ($intro) { print p_locale_xhtml('diff'); } if (!$text) { ptln('<div class="diffoptions">'); $form = new Doku_Form(array('action' => wl())); $form->addHidden('id', $ID); $form->addHidden('rev2[0]', $l_rev); $form->addHidden('rev2[1]', $r_rev); $form->addHidden('do', 'diff'); $form->addElement(form_makeListboxField('difftype', array('sidebyside' => $lang['diff_side'], 'inline' => $lang['diff_inline']), $type, $lang['diff_type'], '', '', array('class' => 'quickselect'))); $form->addElement(form_makeButton('submit', 'diff', 'Go')); $form->printForm(); $diffurl = wl($ID, array('do' => 'diff', 'rev2[0]' => $l_rev, 'rev2[1]' => $r_rev, 'difftype' => $type)); ptln('<p><a class="wikilink1" href="' . $diffurl . '">' . $lang['difflink'] . '</a></p>'); ptln('</div>'); } ?> <table class="diff diff_<?php echo $type; ?> "> <tr> <th colspan="2" <?php echo $l_minor; ?> > <?php echo $l_head; ?> </th> <th colspan="2" <?php echo $r_minor; ?> > <?php echo $r_head; ?> </th> </tr> <?php echo $tdf->format($df); ?> </table> <?php }
/** * Generate a diff, no caching * $otext and $ntext must be already segmented */ function generateDiffBody($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; $fname = 'DifferenceEngine::generateDiffBody'; $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); if ($wgExternalDiffEngine == 'wikidiff') { # For historical reasons, external diff engine expects # input text to be HTML-escaped already $otext = htmlspecialchars($wgContLang->segmentForDiff($otext)); $ntext = htmlspecialchars($wgContLang->segmentForDiff($ntext)); if (!function_exists('wikidiff_do_diff')) { dl('php_wikidiff.so'); } return $wgContLang->unsegementForDiff(wikidiff_do_diff($otext, $ntext, 2)); } if ($wgExternalDiffEngine == 'wikidiff2') { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself if (!function_exists('wikidiff2_do_diff')) { //wfProfileIn( "$fname-dl" ); @dl('php_wikidiff2.so'); //wfProfileOut( "$fname-dl" ); } if (function_exists('wikidiff2_do_diff')) { //wfProfileIn( 'wikidiff2_do_diff' ); $text = wikidiff2_do_diff($otext, $ntext, 2); //wfProfileOut( 'wikidiff2_do_diff' ); return $text; } } if ($wgExternalDiffEngine !== false) { # Diff via the shell global $wgTmpDirectory; $tempName1 = tempnam($wgTmpDirectory, 'diff_'); $tempName2 = tempnam($wgTmpDirectory, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { //wfProfileOut( $fname ); return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { //wfProfileOut( $fname ); return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); //wfProfileIn( "$fname-shellexec" ); $difftext = wfShellExec($cmd); //wfProfileOut( "$fname-shellexec" ); unlink($tempName1); unlink($tempName2); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); return $wgContLang->unsegmentForDiff($formatter->format($diffs)); }
/** * Add recent changed pages to a feed object * * @author Andreas Gohr <*****@*****.**> * @param object $rss - the FeedCreator Object * @param array $data - the items to add * @param array $opt - the feed options */ function rss_buildItems(&$rss, &$data, $opt) { global $conf; global $lang; global $auth; $eventData = array('rss' => &$rss, 'data' => &$data, 'opt' => &$opt); $event = new Doku_Event('FEED_DATA_PROCESS', $eventData); if ($event->advise_before(false)) { foreach ($data as $ditem) { if (!is_array($ditem)) { // not an array? then only a list of IDs was given $ditem = array('id' => $ditem); } $item = new FeedItem(); $id = $ditem['id']; $meta = p_get_metadata($id); // add date if ($ditem['date']) { $date = $ditem['date']; } elseif ($meta['date']['modified']) { $date = $meta['date']['modified']; } else { $date = @filemtime(wikiFN($id)); } if ($date) { $item->date = date('r', $date); } // add title if ($conf['useheading'] && $meta['title']) { $item->title = $meta['title']; } else { $item->title = $ditem['id']; } if ($conf['rss_show_summary'] && !empty($ditem['sum'])) { $item->title .= ' - ' . strip_tags($ditem['sum']); } // add item link switch ($opt['link_to']) { case 'page': $item->link = wl($id, 'rev=' . $date, true, '&'); break; case 'rev': $item->link = wl($id, 'do=revisions&rev=' . $date, true, '&'); break; case 'current': $item->link = wl($id, '', true, '&'); break; case 'diff': default: $item->link = wl($id, 'rev=' . $date . '&do=diff', true, '&'); } // add item content switch ($opt['item_content']) { case 'diff': case 'htmldiff': require_once DOKU_INC . 'inc/DifferenceEngine.php'; $revs = getRevisions($id, 0, 1); $rev = $revs[0]; if ($rev) { $df = new Diff(explode("\n", htmlspecialchars(rawWiki($id, $rev))), explode("\n", htmlspecialchars(rawWiki($id, '')))); } else { $df = new Diff(array(''), explode("\n", htmlspecialchars(rawWiki($id, '')))); } if ($opt['item_content'] == 'htmldiff') { $tdf = new TableDiffFormatter(); $content = '<table>'; $content .= '<tr><th colspan="2" width="50%">' . $rev . '</th>'; $content .= '<th colspan="2" width="50%">' . $lang['current'] . '</th></tr>'; $content .= $tdf->format($df); $content .= '</table>'; } else { $udf = new UnifiedDiffFormatter(); $content = "<pre>\n" . $udf->format($df) . "\n</pre>"; } break; case 'html': $content = p_wiki_xhtml($id, $date, false); // no TOC in feeds $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $content); // make URLs work when canonical is not set, regexp instead of rerendering! if (!$conf['canonical']) { $base = preg_quote(DOKU_REL, '/'); $content = preg_replace('/(<a href|<img src)="(' . $base . ')/s', '$1="' . DOKU_URL, $content); } break; case 'abstract': default: $content = $meta['description']['abstract']; } $item->description = $content; //FIXME a plugin hook here could be senseful // add user # FIXME should the user be pulled from metadata as well? $user = null; $user = @$ditem['user']; // the @ spares time repeating lookup $item->author = ''; if ($user && $conf['useacl'] && $auth) { $userInfo = $auth->getUserData($user); $item->author = $userInfo['name']; if ($userInfo && !$opt['guardmail']) { $item->authorEmail = $userInfo['mail']; } else { //cannot obfuscate because some RSS readers may check validity $item->authorEmail = $user . '@' . $ditem['ip']; } } elseif ($user) { // this happens when no ACL but some Apache auth is used $item->author = $user; $item->authorEmail = $user . '@' . $ditem['ip']; } else { $item->authorEmail = 'anonymous@' . $ditem['ip']; } // add category if ($meta['subject']) { $item->category = $meta['subject']; } else { $cat = getNS($id); if ($cat) { $item->category = $cat; } } // finally add the item to the feed object, after handing it to registered plugins $evdata = array('item' => &$item, 'opt' => &$opt, 'ditem' => &$ditem, 'rss' => &$rss); $evt = new Doku_Event('FEED_ITEM_ADD', $evdata); if ($evt->advise_before()) { $rss->addItem($item); } $evt->advise_after(); // for completeness } } $event->advise_after(); }
/** * Show diff * between current page version and provided $text * or between the revisions provided via GET or POST * * @author Andreas Gohr <*****@*****.**> * @param string $text when non-empty: compare with this text with most current version * @param bool $intro display the intro text * @param string $type type of the diff (inline or sidebyside) */ function html_diff($text = '', $intro = true, $type = null) { global $ID; global $REV; global $lang; global $INPUT; global $INFO; $pagelog = new PageChangeLog($ID); /* * Determine diff type */ if (!$type) { $type = $INPUT->str('difftype'); if (empty($type)) { $type = get_doku_pref('difftype', $type); if (empty($type) && $INFO['ismobile']) { $type = 'inline'; } } } if ($type != 'inline') { $type = 'sidebyside'; } /* * Determine requested revision(s) */ // we're trying to be clever here, revisions to compare can be either // given as rev and rev2 parameters, with rev2 being optional. Or in an // array in rev2. $rev1 = $REV; $rev2 = $INPUT->ref('rev2'); if (is_array($rev2)) { $rev1 = (int) $rev2[0]; $rev2 = (int) $rev2[1]; if (!$rev1) { $rev1 = $rev2; unset($rev2); } } else { $rev2 = $INPUT->int('rev2'); } /* * Determine left and right revision, its texts and the header */ $r_minor = ''; $l_minor = ''; if ($text) { // compare text to the most current revision $l_rev = ''; $l_text = rawWiki($ID, ''); $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' . $lang['current']; $r_rev = ''; $r_text = cleanText($text); $r_head = $lang['yours']; } else { if ($rev1 && isset($rev2) && $rev2) { // two specific revisions wanted // make sure order is correct (older on the left) if ($rev1 < $rev2) { $l_rev = $rev1; $r_rev = $rev2; } else { $l_rev = $rev2; $r_rev = $rev1; } } elseif ($rev1) { // single revision given, compare to current $r_rev = ''; $l_rev = $rev1; } else { // no revision was given, compare previous to current $r_rev = ''; $revs = $pagelog->getRevisions(0, 1); $l_rev = $revs[0]; $REV = $l_rev; // store revision back in $REV } // when both revisions are empty then the page was created just now if (!$l_rev && !$r_rev) { $l_text = ''; } else { $l_text = rawWiki($ID, $l_rev); } $r_text = rawWiki($ID, $r_rev); list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline'); } /* * Build navigation */ $l_nav = ''; $r_nav = ''; if (!$text) { list($l_nav, $r_nav) = html_diff_navigation($pagelog, $type, $l_rev, $r_rev); } /* * Create diff object and the formatter */ $diff = new Diff(explode("\n", $l_text), explode("\n", $r_text)); if ($type == 'inline') { $diffformatter = new InlineDiffFormatter(); } else { $diffformatter = new TableDiffFormatter(); } /* * Display intro */ if ($intro) { print p_locale_xhtml('diff'); } /* * Display type and exact reference */ if (!$text) { ptln('<div class="diffoptions group">'); $form = new Doku_Form(array('action' => wl())); $form->addHidden('id', $ID); $form->addHidden('rev2[0]', $l_rev); $form->addHidden('rev2[1]', $r_rev); $form->addHidden('do', 'diff'); $form->addElement(form_makeListboxField('difftype', array('sidebyside' => $lang['diff_side'], 'inline' => $lang['diff_inline']), $type, $lang['diff_type'], '', '', array('class' => 'quickselect'))); $form->addElement(form_makeButton('submit', 'diff', 'Go')); $form->printForm(); ptln('<p>'); // link to exactly this view FS#2835 echo html_diff_navigationlink($type, 'difflink', $l_rev, $r_rev ? $r_rev : $INFO['currentrev']); ptln('</p>'); ptln('</div>'); // .diffoptions } /* * Display diff view table */ ?> <div class="table"> <table class="diff diff_<?php echo $type; ?> "> <?php //navigation and header if ($type == 'inline') { if (!$text) { ?> <tr> <td class="diff-lineheader">-</td> <td class="diffnav"><?php echo $l_nav; ?> </td> </tr> <tr> <th class="diff-lineheader">-</th> <th <?php echo $l_minor; ?> > <?php echo $l_head; ?> </th> </tr> <?php } ?> <tr> <td class="diff-lineheader">+</td> <td class="diffnav"><?php echo $r_nav; ?> </td> </tr> <tr> <th class="diff-lineheader">+</th> <th <?php echo $r_minor; ?> > <?php echo $r_head; ?> </th> </tr> <?php } else { if (!$text) { ?> <tr> <td colspan="2" class="diffnav"><?php echo $l_nav; ?> </td> <td colspan="2" class="diffnav"><?php echo $r_nav; ?> </td> </tr> <?php } ?> <tr> <th colspan="2" <?php echo $l_minor; ?> > <?php echo $l_head; ?> </th> <th colspan="2" <?php echo $r_minor; ?> > <?php echo $r_head; ?> </th> </tr> <?php } //diff view echo html_insert_softbreaks($diffformatter->format($diff)); ?> </table> </div> <?php }
function compare_diff($old, $cur, $titles = array()) { $this->add_tag_head('compare_diff.css'); include_once $this->root->mytrustdirpath . '/include/DifferenceEngine.php'; $this->compare_diff_pre($old); $this->compare_diff_pre($cur); $df = new Diff($old, $cur); $tdf = new TableDiffFormatter(); $html = $tdf->format($df); if ($titles) { $title = <<<EOD <tr> <th colspan="2">{$titles[0]}</th> <th colspan="2">{$titles[1]}</th> </tr> EOD; } else { $title = ''; } return <<<EOD <table class="diff"> {$title} {$html} </table> EOD; }
// Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('item'); // Check permission: $current_User->check_perm('item_post!CURSTATUS', 'edit', true, $edited_Item); param('r1', 'integer', 0); $r2 = (int) param('r2', 'string', 0); $Revision_1 = $edited_Item->get_revision($r1); $Revision_2 = $edited_Item->get_revision($r2); load_class('_core/model/_diff.class.php', 'Diff'); // Compare the titles of two revisions $revisions_difference_title = new Diff(explode("\n", $Revision_1->iver_title), explode("\n", $Revision_2->iver_title)); $format = new TitleDiffFormatter(); $revisions_difference_title = $format->format($revisions_difference_title); // Compare the contents of two revisions $revisions_difference_content = new Diff(explode("\n", $Revision_1->iver_content), explode("\n", $Revision_2->iver_content)); $format = new TableDiffFormatter(); $revisions_difference_content = $format->format($revisions_difference_content); break; case 'history_restore': // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('item'); // Check permission: $current_User->check_perm('item_post!CURSTATUS', 'edit', true, $edited_Item); param('r', 'integer', 0); if ($r > 0) { // Update item only from revisions ($r == 0 for current version) $Revision = $edited_Item->get_revision($r); $edited_Item->set('status', $Revision->iver_status); $edited_Item->set('title', $Revision->iver_title); $edited_Item->set('content', $Revision->iver_content); if ($edited_Item->dbupdate()) {
/** * Generates diff, to be wrapped internally in a logging/instrumentation * * @param string $otext Old text, must be already segmented * @param string $ntext New text, must be already segmented * @return bool|string */ protected function textDiff($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); if ($wgExternalDiffEngine == 'wikidiff' || $wgExternalDiffEngine == 'wikidiff3') { wfDeprecated("\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.27'); $wgExternalDiffEngine = false; } elseif ($wgExternalDiffEngine == 'wikidiff2') { // Same as above, but with no deprecation warnings $wgExternalDiffEngine = false; } elseif (!is_string($wgExternalDiffEngine) && $wgExternalDiffEngine !== false) { // And prevent people from shooting themselves in the foot... wfWarn('$wgExternalDiffEngine is set to a non-string value, forcing it to false'); $wgExternalDiffEngine = false; } if (function_exists('wikidiff2_do_diff') && $wgExternalDiffEngine === false) { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself $text = wikidiff2_do_diff($otext, $ntext, 2); $text .= $this->debug('wikidiff2'); return $text; } elseif ($wgExternalDiffEngine !== false && is_executable($wgExternalDiffEngine)) { # Diff via the shell $tmpDir = wfTempDir(); $tempName1 = tempnam($tmpDir, 'diff_'); $tempName2 = tempnam($tmpDir, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); $difftext = wfShellExec($cmd); $difftext .= $this->debug("external {$wgExternalDiffEngine}"); unlink($tempName1); unlink($tempName2); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); $difftext = $wgContLang->unsegmentForDiff($formatter->format($diffs)); return $difftext; }
/** * Get a diff table. * * @param string $origCode Original code * @param string $newCode New code * @param boolean $showAll Set true to show all lines | false to show only changed lines * * @return return_type */ public function getDiffTable($origCode, $newCode, $showAll = true) { $codeOrig = explode("\n", htmlentities($origCode)); $codeNew = explode("\n", htmlentities($newCode)); ecrLoadHelper('DifferenceEngine'); //--we are adding a blank line to the end.. this is somewhat 'required' by PHPdiff if ($codeOrig[count($codeOrig) - 1] != '') { $codeOrig[] = ''; } if ($codeNew[count($codeNew) - 1] != '') { $codeNew[] = ''; } $dwDiff = new Diff($codeOrig, $codeNew); $dwFormatter = new TableDiffFormatter(); //-- Small hack to display the whole file - :| if ($showAll) { $dwFormatter->leading_context_lines = 99999; $dwFormatter->trailing_context_lines = 99999; } return $dwFormatter->format($dwDiff); }
/** * Process a diff for one setting * * @param $name String: setting name * @patam $old Mixed: old value * @param $new Mixed: new value * @param $type String: setting type * @return String: XHTML */ function processDiffSetting($name, $old, $new, $type) { $msg = $this->msg('configure-setting-' . $name); $rawVal = Xml::element('tt', null, "\${$name}"); if ($msg->exists()) { $msgVal = $msg->parse() . " ({$rawVal})"; } else { $msgVal = $rawVal; } $oldSet = $this->getSettingAsArray(WebConfiguration::filterVar($old), $name, $type); $newSet = $this->getSettingAsArray(WebConfiguration::filterVar($new), $name, $type); $diffs = new Diff($oldSet, $newSet); $formatter = new TableDiffFormatter(); return "<tr><td class=\"diff-lineno configure-setting\" colspan=\"4\">{$msgVal}</td></tr>\n" . $formatter->format($diffs); }
private function outputDiffHtml($localXMLArray, $remoteXMLArray) { $diffObj = new Diff($localXMLArray, $remoteXMLArray); $dft = new TableDiffFormatter(); return $dft->format($diffObj); }
$current = explode("\n", $pageVersion->content('raw')); $previousVersion = $pageVersion->get('version') - 1; if ($previousVersion == 0) { $previous = array(); } else { $previous = $this->page->version($previousVersion); // make view OK with the LIMIT if (!empty($previous)) { $previous = explode("\n", $previous->content('raw')); } } // define function to format context's // basically make sure lines that are not different // are outputted as code not rendered html $contextFormatter = function ($context) { return htmlentities($context); }; // out formatted diff table $formatter = new TableDiffFormatter(); $diff = $formatter->format(new Diff($previous, $current), $contextFormatter); echo $diff; ?> </div> </div> <?php } ?> </div> </div> </div> </section>
/** * show diff between the local and remote versions of the page */ function _diff($id) { if (!$this->_connect()) { return false; } $no = $this->profno; $ok = $this->client->query('wiki.getPage', $id); if (!$ok) { echo $this->getLang('pullfail') . ' ' . hsc($id) . ' '; echo hsc($this->client->getErrorMessage()); die; } $remote = $this->client->getResponse(); $local = rawWiki($id); $df = new Diff(explode("\n", htmlspecialchars($local)), explode("\n", htmlspecialchars($remote))); $tdf = new TableDiffFormatter(); echo '<table class="diff">'; echo '<tr>'; echo '<th colspan="2">' . $this->getLang('local') . '</th>'; echo '<th colspan="2">' . $this->getLang('remote') . '</th>'; echo '</tr>'; echo $tdf->format($df); echo '</table>'; }
/** * show diff * * @author Andreas Gohr <*****@*****.**> */ function html_diff($text = '', $intro = true) { require_once DOKU_INC . 'inc/DifferenceEngine.php'; global $ID; global $REV; global $lang; global $conf; if ($text) { $df = new Diff(explode("\n", htmlspecialchars(rawWiki($ID, ''))), explode("\n", htmlspecialchars(cleanText($text)))); $left = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . date($conf['dformat'], @filemtime(wikiFN($ID))) . '</a>' . $lang['current']; $right = $lang['yours']; } else { if ($REV) { $r = $REV; } else { //use last revision if none given $revs = getRevisions($ID, 0, 1); $r = $revs[0]; } if ($r) { $df = new Diff(explode("\n", htmlspecialchars(rawWiki($ID, $r))), explode("\n", htmlspecialchars(rawWiki($ID, '')))); $left = '<a class="wikilink1" href="' . wl($ID, "rev={$r}") . '">' . $ID . ' ' . date($conf['dformat'], $r) . '</a>'; } else { $df = new Diff(array(''), explode("\n", htmlspecialchars(rawWiki($ID, '')))); $left = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . '</a>'; } $right = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . date($conf['dformat'], @filemtime(wikiFN($ID))) . '</a> ' . $lang['current']; } $tdf = new TableDiffFormatter(); if ($intro) { print p_locale_xhtml('diff'); } ?> <table class="diff"> <tr> <th colspan="2"> <?php echo $left; ?> </th> <th colspan="2"> <?php echo $right; ?> </th> </tr> <?php echo $tdf->format($df); ?> </table> <?php }
/** * Comparaison de deux fichiers * * @param string $sFile * @param string $sSourceDir * @param string $sDestDir * @param boolean $bTestBackup * @param boolean $bOptional * @return void */ protected function compareFile($sFile, $sSourceDir, $sDestDir, $bTestBackup = false, $bOptional = false) { $sSourceFile = $sSourceDir . $sFile; $sSourceBase = str_replace(OKT_ROOT_PATH, '', $sSourceDir); $sDestBase = str_replace(OKT_ROOT_PATH, '', $sDestDir); $sBaseSourceFile = $sSourceBase . $sFile; if ($bTestBackup) { $sFile .= '.bak'; } $sBaseDestFile = $sDestBase . $sFile; if (!file_exists($sDestDir . $sFile)) { if (!$bTestBackup) { $this->checklist->addItem('file_exists_' . $sFile, $bOptional ? null : false, sprintf(__('c_a_modules_file_%s_not_exists'), '<code>' . $sBaseDestFile . '</code>'), sprintf(__('c_a_modules_file_%s_not_exists'), '<code>' . $sBaseDestFile . '</code>')); } } else { $l_text = file_get_contents($sSourceFile); $r_text = file_get_contents($sDestDir . $sFile); $df = new Diff(explode("\n", htmlspecialchars($l_text)), explode("\n", htmlspecialchars($r_text))); $tdf = new TableDiffFormatter(); if (count($df->edits) > 1) { $ze_string = sprintf(__('c_a_modules_file_%s_different_%s'), '<code>' . $sBaseDestFile . '</code>', self::getComparaisonTable($sBaseSourceFile, $sBaseDestFile, $tdf->format($df))); $this->checklist->addItem('file_' . $sFile . '_different', null, $ze_string, $ze_string); } else { $this->checklist->addItem('files_' . $sFile . '_identical', true, sprintf(__('c_a_modules_file_%s_identical'), '<code>' . $sDestBase . $sFile . '</code>'), sprintf(__('c_a_modules_file_%s_identical'), '<code>' . $sDestBase . $sFile . '</code>')); } } }
/** * Displays the actual file and a selected version side by side. * * @param integer $revNo Revision number * @param string $lang Language tag e.g. en-GB * * @return void */ public function displayVersion($revNo, $lang) { $fileName = $this->getFileName($lang, $this->_scope, $this->project); $sRev = '.r' . $revNo; $fileNameOrig = $fileName; $fileNameRev = $fileName . '.r' . $revNo; $fileOrig = ''; $fileRev = ''; if (JFile::exists($fileNameOrig)) { $fileOrig = JFile::read($fileNameOrig); if ($fileOrig) { $fileOrig = explode("\n", $fileOrig); } } if (JFile::exists($fileNameRev)) { $fileRev = JFile::read($fileNameRev); if ($fileRev) { $fileRev = explode("\n", $fileRev); } } ecrLoadHelper('DifferenceEngine'); //--we are adding a blank line to the end.. this is somewhat 'required' by PHPdiff if ($fileOrig[count($fileOrig) - 1] != '') { $fileOrig[] = ''; } if ($fileRev[count($fileRev) - 1] != '') { $fileRev[] = ''; } $dwDiff = new Diff($fileRev, $fileOrig); $dwFormatter = new TableDiffFormatter(); ?> <table class="diff"> <tr> <th colspan="2"><?php echo sprintf(jgettext('Version No. %s'), $revNo); ?> </th> <th colspan="2"><?php echo jgettext('Actual file'); ?> </th> </tr> <?php echo $dwFormatter->format($dwDiff); ?> </table> <?php /* PHP */ ?> <!-- <table width="100%"> <tr> <th><?php echo jgettext('Actual file'); ?> </th> <th><?php echo sprintf(jgettext('Version No. %s'), $revNo); ?> </th> </tr> <tr valign="top"> <?php ?> <td><?php if (!$fileOrig) { echo '<strong style="color: red;">' . jgettext('File not found') . '</strong>'; } else { $this->displayFields($lang, $fileOrig); } ?> </td> <td><?php if (!$fileRev) { echo '<strong style="color: red;">' . jgettext('File not found') . '</strong>'; } else { $this->displayFields($lang, $fileRev); } ?> </td> </tr> </table> --> <?php }
/** * Compare two versions of a wiki page * * @return void */ public function compareTask() { include_once dirname(dirname(__DIR__)) . DS . 'helpers' . DS . 'differenceengine.php'; // Incoming $oldid = Request::getInt('oldid', 0); $diff = Request::getInt('diff', 0); // Do some error checking if (!$diff) { $this->setError(Lang::txt('COM_WIKI_ERROR_MISSING_VERSION')); return $this->displayTask(); } if ($diff == $oldid) { $this->setError(Lang::txt('COM_WIKI_ERROR_SAME_VERSIONS')); return $this->displayTask(); } // If no initial page is given, compare to the current revision $oldid = $oldid ?: $this->page->get('version_id'); $or = $this->page->versions()->whereEquals('version', $oldid)->row(); $dr = $this->page->versions()->whereEquals('version', $diff)->row(); // Diff the two versions $ota = explode("\n", $or->get('pagetext')); $nta = explode("\n", $dr->get('pagetext')); $formatter = new \TableDiffFormatter(); $result = $formatter->format(new \Diff($ota, $nta)); // Set the page's <title> tag Document::setTitle(Lang::txt(strtoupper($this->_option)) . ': ' . $this->page->title . ': ' . Lang::txt(strtoupper($this->_option . '_' . $this->_task))); // Set the pathway if (Pathway::count() <= 0) { Pathway::append(Lang::txt(strtoupper($this->_option)), 'index.php?option=' . $this->_option); } $parents = array(); if ($this->page->get('parent')) { $parents = $this->page->ancestors(); foreach ($parents as $p) { Pathway::append($p->get('title'), $p->link()); } } Pathway::append($this->page->title, $this->page->link()); Pathway::append(Lang::txt(strtoupper($this->_option . '_' . $this->_task)), $this->page->link() . '&' . ($this->_sub ? 'action' : 'task') . '=' . $this->_task); // Output view $this->view->set('parents', $parents)->set('page', $this->page)->set('sub', $this->page->get('scope') != 'site')->set('content', $result)->set('or', $or)->set('dr', $dr)->setErrors($this->getErrors())->display(); }
/** * Add recent changed pages to a feed object * * @author Andreas Gohr <*****@*****.**> * @param FeedCreator $rss the FeedCreator Object * @param array $data the items to add * @param array $opt the feed options */ function rss_buildItems(&$rss, &$data, $opt) { global $conf; global $lang; /* @var auth_basic $auth */ global $auth; $eventData = array('rss' => &$rss, 'data' => &$data, 'opt' => &$opt); $event = new Doku_Event('FEED_DATA_PROCESS', $eventData); if ($event->advise_before(false)) { foreach ($data as $ditem) { if (!is_array($ditem)) { // not an array? then only a list of IDs was given $ditem = array('id' => $ditem); } $item = new FeedItem(); $id = $ditem['id']; if (!$ditem['media']) { $meta = p_get_metadata($id); } else { $meta = array(); } // add date if ($ditem['date']) { $date = $ditem['date']; } elseif ($ditem['media']) { $date = @filemtime(mediaFN($id)); } elseif (@file_exists(wikiFN($id))) { $date = @filemtime(wikiFN($id)); } elseif ($meta['date']['modified']) { $date = $meta['date']['modified']; } else { $date = 0; } if ($date) { $item->date = date('r', $date); } // add title if ($conf['useheading'] && $meta['title']) { $item->title = $meta['title']; } else { $item->title = $ditem['id']; } if ($conf['rss_show_summary'] && !empty($ditem['sum'])) { $item->title .= ' - ' . strip_tags($ditem['sum']); } // add item link switch ($opt['link_to']) { case 'page': if ($ditem['media']) { $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id), 'rev' => $date), '&', true); } else { $item->link = wl($id, 'rev=' . $date, true, '&'); } break; case 'rev': if ($ditem['media']) { $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id), 'rev' => $date, 'tab_details' => 'history'), '&', true); } else { $item->link = wl($id, 'do=revisions&rev=' . $date, true, '&'); } break; case 'current': if ($ditem['media']) { $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id)), '&', true); } else { $item->link = wl($id, '', true, '&'); } break; case 'diff': default: if ($ditem['media']) { $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id), 'rev' => $date, 'tab_details' => 'history', 'mediado' => 'diff'), '&', true); } else { $item->link = wl($id, 'rev=' . $date . '&do=diff', true, '&'); } } // add item content switch ($opt['item_content']) { case 'diff': case 'htmldiff': if ($ditem['media']) { $revs = getRevisions($id, 0, 1, 8192, true); $rev = $revs[0]; $src_r = ''; $src_l = ''; if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)), 300)) { $more = 'w=' . $size[0] . '&h=' . $size[1] . 't=' . @filemtime(mediaFN($id)); $src_r = ml($id, $more); } if ($rev && ($size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), 300))) { $more = 'rev=' . $rev . '&w=' . $size[0] . '&h=' . $size[1]; $src_l = ml($id, $more); } $content = ''; if ($src_r) { $content = '<table>'; $content .= '<tr><th width="50%">' . $rev . '</th>'; $content .= '<th width="50%">' . $lang['current'] . '</th></tr>'; $content .= '<tr align="center"><td><img src="' . $src_l . '" alt="" /></td><td>'; $content .= '<img src="' . $src_r . '" alt="' . $id . '" /></td></tr>'; $content .= '</table>'; } } else { require_once DOKU_INC . 'inc/DifferenceEngine.php'; $revs = getRevisions($id, 0, 1); $rev = $revs[0]; if ($rev) { $df = new Diff(explode("\n", rawWiki($id, $rev)), explode("\n", rawWiki($id, ''))); } else { $df = new Diff(array(''), explode("\n", rawWiki($id, ''))); } if ($opt['item_content'] == 'htmldiff') { // note: no need to escape diff output, TableDiffFormatter provides 'safe' html $tdf = new TableDiffFormatter(); $content = '<table>'; $content .= '<tr><th colspan="2" width="50%">' . $rev . '</th>'; $content .= '<th colspan="2" width="50%">' . $lang['current'] . '</th></tr>'; $content .= $tdf->format($df); $content .= '</table>'; } else { // note: diff output must be escaped, UnifiedDiffFormatter provides plain text $udf = new UnifiedDiffFormatter(); $content = "<pre>\n" . hsc($udf->format($df)) . "\n</pre>"; } } break; case 'html': if ($ditem['media']) { if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) { $more = 'w=' . $size[0] . '&h=' . $size[1] . 't=' . @filemtime(mediaFN($id)); $src = ml($id, $more); $content = '<img src="' . $src . '" alt="' . $id . '" />'; } else { $content = ''; } } else { if (@filemtime(wikiFN($id)) === $date) { $content = p_wiki_xhtml($id, '', false); } else { $content = p_wiki_xhtml($id, $date, false); } // no TOC in feeds $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $content); // add alignment for images $content = preg_replace('/(<img .*?class="medialeft")/s', '\\1 align="left"', $content); $content = preg_replace('/(<img .*?class="mediaright")/s', '\\1 align="right"', $content); // make URLs work when canonical is not set, regexp instead of rerendering! if (!$conf['canonical']) { $base = preg_quote(DOKU_REL, '/'); $content = preg_replace('/(<a href|<img src)="(' . $base . ')/s', '$1="' . DOKU_URL, $content); } } break; case 'abstract': default: if ($ditem['media']) { if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) { $more = 'w=' . $size[0] . '&h=' . $size[1] . 't=' . @filemtime(mediaFN($id)); $src = ml($id, $more); $content = '<img src="' . $src . '" alt="' . $id . '" />'; } else { $content = ''; } } else { $content = $meta['description']['abstract']; } } $item->description = $content; //FIXME a plugin hook here could be senseful // add user # FIXME should the user be pulled from metadata as well? $user = @$ditem['user']; // the @ spares time repeating lookup $item->author = ''; if ($user && $conf['useacl'] && $auth) { $userInfo = $auth->getUserData($user); if ($userInfo) { switch ($conf['showuseras']) { case 'username': $item->author = $userInfo['name']; break; default: $item->author = $user; break; } } else { $item->author = $user; } if ($userInfo && !$opt['guardmail']) { $item->authorEmail = $userInfo['mail']; } else { //cannot obfuscate because some RSS readers may check validity $item->authorEmail = $user . '@' . $ditem['ip']; } } elseif ($user) { // this happens when no ACL but some Apache auth is used $item->author = $user; $item->authorEmail = $user . '@' . $ditem['ip']; } else { $item->authorEmail = 'anonymous@' . $ditem['ip']; } // add category if (isset($meta['subject'])) { $item->category = $meta['subject']; } else { $cat = getNS($id); if ($cat) { $item->category = $cat; } } // finally add the item to the feed object, after handing it to registered plugins $evdata = array('item' => &$item, 'opt' => &$opt, 'ditem' => &$ditem, 'rss' => &$rss); $evt = new Doku_Event('FEED_ITEM_ADD', $evdata); if ($evt->advise_before()) { $rss->addItem($item); } $evt->advise_after(); // for completeness } } $event->advise_after(); }
private function html_diff($frame, $device, $l_text = '', $r_text = '', $show = 1) { global $ID, $REV, $lang, $INPUT, $INFO; /* * Determine diff type */ if ($INFO['ismobile']) { $type = 'inline'; } else { $type = 'sidebyside'; } /* * Create diff object and the formatter */ require_once DOKU_INC . 'inc/DifferenceEngine.php'; $diff = new Diff(explode("\n", $l_text), explode("\n", $r_text)); if ($type == 'inline') { $diffformatter = new InlineDiffFormatter(); } else { $diffformatter = new TableDiffFormatter(); } if ($show == 1) { $class = ' show'; } /* * Display diff view table */ ?> <div class="table frame-<?php echo $frame; ?> -diff<?php echo $class; ?> " data-frame="<?php echo $frame; ?> " data-device="<?php echo $device; ?> "> <table class="diff diff_<?php echo $type; ?> "> <?php //navigation and header if ($type == 'inline') { ?> <tr> <td class="diff-lineheader">-</td> <td>Current Version</td> </tr> <tr> <th class="diff-lineheader">+</th> <th><?php echo $this->devices[$device]['name']; ?> 's Version</th> </tr> <?php } else { ?> <tr> <th colspan="2">Current Version</th> <th colspan="2"><?php echo $this->devices[$device]['name']; ?> 's Version</th> </tr> <?php } //diff view echo html_insert_softbreaks($diffformatter->format($diff)); ?> </table> <form class="mode-action"> <input type="hidden" name="frame" value="<?php echo $frame; ?> "> <input type="hidden" name="device" value="<?php echo $device; ?> "> <textarea name="content" class="door43gitmerge-content" rows="5" cols="50"><?php echo htmlspecialchars($r_text); ?> </textarea> <div class="door43gitmerge-actions"> <span class="door43gitmerge-action-interface"> <input name="do[door43gitmerge-dismiss]" type="submit" class="door43gitmerge-dismiss" value="<?php echo $this->getLang('dismiss'); ?> " data-page="<?php echo $ID; ?> " data-frame="<?php echo $frame; ?> " data-device="<?php echo $device; ?> " data-action="dismiss"> <input type="button" class="door43gitmerge-edit" value="<?php echo $this->getLang('edit_and_apply'); ?> " data-frame="<?php echo $frame; ?> " data-device="<?php echo $device; ?> "> <input name="do[door43gitmerge-apply]" type="submit" class="door43gitmerge-apply" value="<?php echo $this->getLang('apply'); ?> " data-page="<?php echo $ID; ?> " data-frame="<?php echo $frame; ?> " data-device="<?php echo $device; ?> " data-action="apply"> </span> <span class="door43gitmerge-edit-interface"> <input type="button" class="door43gitmerge-cancel" value="<?php echo $this->getLang('cancel'); ?> " data-frame="<?php echo $frame; ?> " data-device="<?php echo $device; ?> "> <input type="reset" value="<?php echo $this->getLang('reset'); ?> "> <input name="do[door43gitmerge-apply-edited]" type="submit" class="door43gitmerge-apply-edited" value="<?php echo $this->getLang('apply'); ?> " data-page="<?php echo $ID; ?> " data-frame="<?php echo $frame; ?> " data-device="<?php echo $device; ?> " data-action="apply-edited"> </span> </div> </form> </div> <?php }
function getMultiLineRow($msg, $old, $new) { if (!is_array($old)) { $old = explode("\n", $old); } if (!is_array($new)) { $new = explode("\n", $new); } if ($old == $new) { $old = implode("<br />\n", $old); $new = implode("<br />\n", $new); return $this->getSimpleRow($msg, $old, $new, 'text'); } $row = ''; $row .= Xml::tags('th', null, wfMsgExt($msg, 'parseinline')); $diff = new Diff($old, $new); $formatter = new TableDiffFormatter(); $formattedDiff = $formatter->format($diff); $formattedDiff = "<table class='mw-abusefilter-diff-multiline'><tbody>{$formattedDiff}</tbody></table>"; $row .= Xml::tags('td', array('colspan' => 2), $formattedDiff); return Xml::tags('tr', null, $row) . "\n"; }
/** * Generate a diff, no caching * * @param $otext String: old text, must be already segmented * @param $ntext String: new text, must be already segmented */ function generateDiffBody($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; wfProfileIn(__METHOD__); $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); $this->initDiffEngines(); if ($wgExternalDiffEngine == 'wikidiff' && function_exists('wikidiff_do_diff')) { # For historical reasons, external diff engine expects # input text to be HTML-escaped already $otext = htmlspecialchars($wgContLang->segmentForDiff($otext)); $ntext = htmlspecialchars($wgContLang->segmentForDiff($ntext)); wfProfileOut(__METHOD__); return $wgContLang->unsegmentForDiff(wikidiff_do_diff($otext, $ntext, 2)) . $this->debug('wikidiff1'); } if ($wgExternalDiffEngine == 'wikidiff2' && function_exists('wikidiff2_do_diff')) { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself wfProfileIn('wikidiff2_do_diff'); $text = wikidiff2_do_diff($otext, $ntext, 2); $text .= $this->debug('wikidiff2'); wfProfileOut('wikidiff2_do_diff'); wfProfileOut(__METHOD__); return $text; } if ($wgExternalDiffEngine != 'wikidiff3' && $wgExternalDiffEngine !== false) { # Diff via the shell global $wgTmpDirectory; $tempName1 = tempnam($wgTmpDirectory, 'diff_'); $tempName2 = tempnam($wgTmpDirectory, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { wfProfileOut(__METHOD__); return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { wfProfileOut(__METHOD__); return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); wfProfileIn(__METHOD__ . "-shellexec"); $difftext = wfShellExec($cmd); $difftext .= $this->debug("external {$wgExternalDiffEngine}"); wfProfileOut(__METHOD__ . "-shellexec"); unlink($tempName1); unlink($tempName2); wfProfileOut(__METHOD__); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); $difftext = $wgContLang->unsegmentForDiff($formatter->format($diffs)) . wfProfileOut(__METHOD__); return $difftext; }
/** * Zeigt die Historie eines Contents an. * */ function print_history() { global $content_id, $sprache, $version, $method, $filterstr; if ($method == 'history_changes') { if (!isset($_GET['v1']) || !isset($_GET['v2'])) { echo 'Invalid Parameter'; return false; } $v1 = $_GET['v1']; $v2 = $_GET['v2']; $content_old = new content(); $content_old->getContent($content_id, $sprache, $v1); $dom = new DOMDocument(); $dom->loadXML($content_old->content); $content_old = $dom->getElementsByTagName('inhalt')->item(0)->nodeValue; $content_new = new content(); $content_new->getContent($content_id, $sprache, $v2); $dom = new DOMDocument(); $dom->loadXML($content_new->content); $content_new = $dom->getElementsByTagName('inhalt')->item(0)->nodeValue; $arr_old = explode("\n", trim($content_old)); $arr_new = explode("\n", trim($content_new)); $diff = new Diff($arr_new, $arr_old); $tdf = new TableDiffFormatter(); echo '<table>'; echo html_entity_decode($tdf->format($diff)); echo '</table>'; } else { $content = new content(); $content->loadVersionen($content_id, $sprache); $datum_obj = new datum(); echo '<h3>Versionen</h3>'; echo '<form action="' . $_SERVER['PHP_SELF'] . '" method="GET">'; echo ' <input type="hidden" name="action" value="history"> <input type="hidden" name="method" value="history_changes"> <input type="hidden" name="sprache" value="' . $sprache . '"> <input type="hidden" name="version" value="' . $version . '"> <input type="hidden" name="filter" value="' . implode(' ', $filterstr) . '"> <input type="hidden" name="content_id" value="' . $content_id . '">'; echo 'Änderungen von Version <input type="text" value="1" size="2" name="v1"> zu <input type="text" value="2" size="2" name="v2"> <input type="submit" value="Anzeigen"> </form>'; echo '<ul>'; foreach ($content->result as $row) { echo '<li>'; echo '<b>Version ' . $row->version . '</b><br>Erstellt am ' . $datum_obj->formatDatum($row->insertamum, 'd.m.Y') . ' von ' . $row->insertvon; if ($row->updateamum != '' || $row->updatevon != '') { echo '<br>Letzte Änderung von ' . $row->updatevon . ' am ' . $datum_obj->formatDatum($row->updateamum, 'd.m.Y'); } if ($row->reviewvon != '' || $row->reviewamum != '') { echo '<br>Review von ' . $row->reviewvon . ' am ' . $datum_obj->formatDatum($row->reviewamum, 'd.m.Y'); } echo '<br><br>'; echo '</li>'; } echo '</ul>'; } }