[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 /** 15 * @ignore 16 */ 17 if (!defined('IN_PHPBB')) 18 { 19 exit; 20 } 21 22 /** 23 * Code from pear.php.net, Text_Diff-1.1.0 package 24 * http://pear.php.net/package/Text_Diff/ 25 * 26 * Modified by phpBB Limited to meet our coding standards 27 * and being able to integrate into phpBB 28 * 29 * A class to render Diffs in different formats. 30 * 31 * This class renders the diff in classic diff format. It is intended that 32 * this class be customized via inheritance, to obtain fancier outputs. 33 * 34 * Copyright 2004-2008 The Horde Project (http://www.horde.org/) 35 * 36 * @package diff 37 */ 38 class diff_renderer 39 { 40 /** 41 * Number of leading context "lines" to preserve. 42 * 43 * This should be left at zero for this class, but subclasses may want to 44 * set this to other values. 45 */ 46 var $_leading_context_lines = 0; 47 48 /** 49 * Number of trailing context "lines" to preserve. 50 * 51 * This should be left at zero for this class, but subclasses may want to 52 * set this to other values. 53 */ 54 var $_trailing_context_lines = 0; 55 56 /** 57 * Constructor. 58 */ 59 function diff_renderer($params = array()) 60 { 61 foreach ($params as $param => $value) 62 { 63 $v = '_' . $param; 64 if (isset($this->$v)) 65 { 66 $this->$v = $value; 67 } 68 } 69 } 70 71 /** 72 * Get any renderer parameters. 73 * 74 * @return array All parameters of this renderer object. 75 */ 76 function get_params() 77 { 78 $params = array(); 79 foreach (get_object_vars($this) as $k => $v) 80 { 81 if ($k[0] == '_') 82 { 83 $params[substr($k, 1)] = $v; 84 } 85 } 86 87 return $params; 88 } 89 90 /** 91 * Renders a diff. 92 * 93 * @param diff &$diff A diff object. 94 * 95 * @return string The formatted output. 96 */ 97 function render(&$diff) 98 { 99 $xi = $yi = 1; 100 $block = false; 101 $context = array(); 102 103 // Create a new diff object if it is a 3-way diff 104 if (is_a($diff, 'diff3')) 105 { 106 $diff3 = &$diff; 107 108 $diff_1 = $diff3->get_original(); 109 $diff_2 = $diff3->merged_output(); 110 111 unset($diff3); 112 113 $diff = new diff($diff_1, $diff_2); 114 } 115 116 $nlead = $this->_leading_context_lines; 117 $ntrail = $this->_trailing_context_lines; 118 119 $output = $this->_start_diff(); 120 $diffs = $diff->get_diff(); 121 122 foreach ($diffs as $i => $edit) 123 { 124 // If these are unchanged (copied) lines, and we want to keep leading or trailing context lines, extract them from the copy block. 125 if (is_a($edit, 'diff_op_copy')) 126 { 127 // Do we have any diff blocks yet? 128 if (is_array($block)) 129 { 130 // How many lines to keep as context from the copy block. 131 $keep = ($i == sizeof($diffs) - 1) ? $ntrail : $nlead + $ntrail; 132 if (sizeof($edit->orig) <= $keep) 133 { 134 // We have less lines in the block than we want for context => keep the whole block. 135 $block[] = $edit; 136 } 137 else 138 { 139 if ($ntrail) 140 { 141 // Create a new block with as many lines as we need for the trailing context. 142 $context = array_slice($edit->orig, 0, $ntrail); 143 $block[] = new diff_op_copy($context); 144 } 145 146 $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block); 147 $block = false; 148 } 149 } 150 // Keep the copy block as the context for the next block. 151 $context = $edit->orig; 152 } 153 else 154 { 155 // Don't we have any diff blocks yet? 156 if (!is_array($block)) 157 { 158 // Extract context lines from the preceding copy block. 159 $context = array_slice($context, sizeof($context) - $nlead); 160 $x0 = $xi - sizeof($context); 161 $y0 = $yi - sizeof($context); 162 $block = array(); 163 164 if ($context) 165 { 166 $block[] = new diff_op_copy($context); 167 } 168 } 169 $block[] = $edit; 170 } 171 172 $xi += ($edit->orig) ? sizeof($edit->orig) : 0; 173 $yi += ($edit->final) ? sizeof($edit->final) : 0; 174 } 175 176 if (is_array($block)) 177 { 178 $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block); 179 } 180 181 return $output . $this->_end_diff(); 182 } 183 184 function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) 185 { 186 $output = $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen)); 187 188 foreach ($edits as $edit) 189 { 190 switch (get_class($edit)) 191 { 192 case 'diff_op_copy': 193 $output .= $this->_context($edit->orig); 194 break; 195 196 case 'diff_op_add': 197 $output .= $this->_added($edit->final); 198 break; 199 200 case 'diff_op_delete': 201 $output .= $this->_deleted($edit->orig); 202 break; 203 204 case 'diff_op_change': 205 $output .= $this->_changed($edit->orig, $edit->final); 206 break; 207 } 208 } 209 210 return $output . $this->_end_block(); 211 } 212 213 function _start_diff() 214 { 215 return ''; 216 } 217 218 function _end_diff() 219 { 220 return ''; 221 } 222 223 function _block_header($xbeg, $xlen, $ybeg, $ylen) 224 { 225 if ($xlen > 1) 226 { 227 $xbeg .= ',' . ($xbeg + $xlen - 1); 228 } 229 230 if ($ylen > 1) 231 { 232 $ybeg .= ',' . ($ybeg + $ylen - 1); 233 } 234 235 // this matches the GNU Diff behaviour 236 if ($xlen && !$ylen) 237 { 238 $ybeg--; 239 } 240 else if (!$xlen) 241 { 242 $xbeg--; 243 } 244 245 return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg; 246 } 247 248 function _start_block($header) 249 { 250 return $header . "\n"; 251 } 252 253 function _end_block() 254 { 255 return ''; 256 } 257 258 function _lines($lines, $prefix = ' ') 259 { 260 return $prefix . implode("\n$prefix", $lines) . "\n"; 261 } 262 263 function _context($lines) 264 { 265 return $this->_lines($lines, ' '); 266 } 267 268 function _added($lines) 269 { 270 return $this->_lines($lines, '> '); 271 } 272 273 function _deleted($lines) 274 { 275 return $this->_lines($lines, '< '); 276 } 277 278 function _changed($orig, $final) 279 { 280 return $this->_deleted($orig) . "---\n" . $this->_added($final); 281 } 282 283 /** 284 * Our function to get the diff 285 */ 286 function get_diff_content($diff) 287 { 288 return $this->render($diff); 289 } 290 } 291 292 /** 293 * Renders a unified diff 294 * @package diff 295 */ 296 class diff_renderer_unified extends diff_renderer 297 { 298 var $_leading_context_lines = 4; 299 var $_trailing_context_lines = 4; 300 301 /** 302 * Our function to get the diff 303 */ 304 function get_diff_content($diff) 305 { 306 return nl2br($this->render($diff)); 307 } 308 309 function _block_header($xbeg, $xlen, $ybeg, $ylen) 310 { 311 if ($xlen != 1) 312 { 313 $xbeg .= ',' . $xlen; 314 } 315 316 if ($ylen != 1) 317 { 318 $ybeg .= ',' . $ylen; 319 } 320 return '<div class="diff"><big class="info">@@ -' . $xbeg . ' +' . $ybeg . ' @@</big></div>'; 321 } 322 323 function _context($lines) 324 { 325 return '<pre class="diff context">' . htmlspecialchars($this->_lines($lines, ' ')) . '<br /></pre>'; 326 } 327 328 function _added($lines) 329 { 330 return '<pre class="diff added">' . htmlspecialchars($this->_lines($lines, '+')) . '<br /></pre>'; 331 } 332 333 function _deleted($lines) 334 { 335 return '<pre class="diff removed">' . htmlspecialchars($this->_lines($lines, '-')) . '<br /></pre>'; 336 } 337 338 function _changed($orig, $final) 339 { 340 return $this->_deleted($orig) . $this->_added($final); 341 } 342 343 function _start_diff() 344 { 345 $start = '<div class="file">'; 346 347 return $start; 348 } 349 350 function _end_diff() 351 { 352 return '</div>'; 353 } 354 355 function _end_block() 356 { 357 return ''; 358 } 359 } 360 361 /** 362 * "Inline" diff renderer. 363 * 364 * This class renders diffs in the Wiki-style "inline" format. 365 * 366 * @author Ciprian Popovici 367 * @package diff 368 */ 369 class diff_renderer_inline extends diff_renderer 370 { 371 var $_leading_context_lines = 10000; 372 var $_trailing_context_lines = 10000; 373 374 // Prefix and suffix for inserted text 375 var $_ins_prefix = '<span class="ins">'; 376 var $_ins_suffix = '</span>'; 377 378 // Prefix and suffix for deleted text 379 var $_del_prefix = '<span class="del">'; 380 var $_del_suffix = '</span>'; 381 382 var $_block_head = ''; 383 384 // What are we currently splitting on? Used to recurse to show word-level 385 var $_split_level = 'lines'; 386 387 /** 388 * Our function to get the diff 389 */ 390 function get_diff_content($diff) 391 { 392 return '<pre>' . nl2br($this->render($diff)) . '<br /></pre>'; 393 } 394 395 function _start_diff() 396 { 397 return ''; 398 } 399 400 function _end_diff() 401 { 402 return ''; 403 } 404 405 function _block_header($xbeg, $xlen, $ybeg, $ylen) 406 { 407 return $this->_block_head; 408 } 409 410 function _start_block($header) 411 { 412 return $header; 413 } 414 415 function _lines($lines, $prefix = ' ', $encode = true) 416 { 417 if ($encode) 418 { 419 array_walk($lines, array(&$this, '_encode')); 420 } 421 422 if ($this->_split_level == 'words') 423 { 424 return implode('', $lines); 425 } 426 else 427 { 428 return implode("\n", $lines) . "\n"; 429 } 430 } 431 432 function _added($lines) 433 { 434 array_walk($lines, array(&$this, '_encode')); 435 $lines[0] = $this->_ins_prefix . $lines[0]; 436 $lines[sizeof($lines) - 1] .= $this->_ins_suffix; 437 return $this->_lines($lines, ' ', false); 438 } 439 440 function _deleted($lines, $words = false) 441 { 442 array_walk($lines, array(&$this, '_encode')); 443 $lines[0] = $this->_del_prefix . $lines[0]; 444 $lines[sizeof($lines) - 1] .= $this->_del_suffix; 445 return $this->_lines($lines, ' ', false); 446 } 447 448 function _changed($orig, $final) 449 { 450 // If we've already split on words, don't try to do so again - just display. 451 if ($this->_split_level == 'words') 452 { 453 $prefix = ''; 454 while ($orig[0] !== false && $final[0] !== false && substr($orig[0], 0, 1) == ' ' && substr($final[0], 0, 1) == ' ') 455 { 456 $prefix .= substr($orig[0], 0, 1); 457 $orig[0] = substr($orig[0], 1); 458 $final[0] = substr($final[0], 1); 459 } 460 461 return $prefix . $this->_deleted($orig) . $this->_added($final); 462 } 463 464 $text1 = implode("\n", $orig); 465 $text2 = implode("\n", $final); 466 467 // Non-printing newline marker. 468 $nl = "\0"; 469 470 // We want to split on word boundaries, but we need to preserve whitespace as well. 471 // Therefore we split on words, but include all blocks of whitespace in the wordlist. 472 $splitted_text_1 = $this->_split_on_words($text1, $nl); 473 $splitted_text_2 = $this->_split_on_words($text2, $nl); 474 475 $diff = new diff($splitted_text_1, $splitted_text_2); 476 unset($splitted_text_1, $splitted_text_2); 477 478 // Get the diff in inline format. 479 $renderer = new diff_renderer_inline(array_merge($this->get_params(), array('split_level' => 'words'))); 480 481 // Run the diff and get the output. 482 return str_replace($nl, "\n", $renderer->render($diff)) . "\n"; 483 } 484 485 function _split_on_words($string, $newline_escape = "\n") 486 { 487 // Ignore \0; otherwise the while loop will never finish. 488 $string = str_replace("\0", '', $string); 489 490 $words = array(); 491 $length = strlen($string); 492 $pos = 0; 493 494 $tab_there = true; 495 while ($pos < $length) 496 { 497 // Check for tabs... do not include them 498 if ($tab_there && substr($string, $pos, 1) === "\t") 499 { 500 $words[] = "\t"; 501 $pos++; 502 503 continue; 504 } 505 else 506 { 507 $tab_there = false; 508 } 509 510 // Eat a word with any preceding whitespace. 511 $spaces = strspn(substr($string, $pos), " \n"); 512 $nextpos = strcspn(substr($string, $pos + $spaces), " \n"); 513 $words[] = str_replace("\n", $newline_escape, substr($string, $pos, $spaces + $nextpos)); 514 $pos += $spaces + $nextpos; 515 } 516 517 return $words; 518 } 519 520 function _encode(&$string) 521 { 522 $string = htmlspecialchars($string); 523 } 524 } 525 526 /** 527 * "raw" diff renderer. 528 * This class could be used to output a raw unified patch file 529 * 530 * @package diff 531 */ 532 class diff_renderer_raw extends diff_renderer 533 { 534 var $_leading_context_lines = 4; 535 var $_trailing_context_lines = 4; 536 537 /** 538 * Our function to get the diff 539 */ 540 function get_diff_content($diff) 541 { 542 return '<textarea style="height: 290px;" rows="15" cols="76" class="full">' . htmlspecialchars($this->render($diff)) . '</textarea>'; 543 } 544 545 function _block_header($xbeg, $xlen, $ybeg, $ylen) 546 { 547 if ($xlen != 1) 548 { 549 $xbeg .= ',' . $xlen; 550 } 551 552 if ($ylen != 1) 553 { 554 $ybeg .= ',' . $ylen; 555 } 556 return '@@ -' . $xbeg . ' +' . $ybeg . ' @@'; 557 } 558 559 function _context($lines) 560 { 561 return $this->_lines($lines, ' '); 562 } 563 564 function _added($lines) 565 { 566 return $this->_lines($lines, '+'); 567 } 568 569 function _deleted($lines) 570 { 571 return $this->_lines($lines, '-'); 572 } 573 574 function _changed($orig, $final) 575 { 576 return $this->_deleted($orig) . $this->_added($final); 577 } 578 } 579 580 /** 581 * "chora (Horde)" diff renderer - similar style. 582 * This renderer class is a modified human_readable function from the Horde Framework. 583 * 584 * @package diff 585 */ 586 class diff_renderer_side_by_side extends diff_renderer 587 { 588 var $_leading_context_lines = 3; 589 var $_trailing_context_lines = 3; 590 591 var $lines = array(); 592 593 // Hold the left and right columns of lines for change blocks. 594 var $cols; 595 var $state; 596 597 var $data = false; 598 599 /** 600 * Our function to get the diff 601 */ 602 function get_diff_content($diff) 603 { 604 global $user; 605 606 $output = ''; 607 $output .= '<table cellspacing="0" class="hrdiff"> 608 <caption> 609 <span class="unmodified"> </span> ' . $user->lang['LINE_UNMODIFIED'] . ' 610 <span class="added"> </span> ' . $user->lang['LINE_ADDED'] . ' 611 <span class="modified"> </span> ' . $user->lang['LINE_MODIFIED'] . ' 612 <span class="removed"> </span> ' . $user->lang['LINE_REMOVED'] . ' 613 </caption> 614 <tbody> 615 '; 616 617 $this->render($diff); 618 619 // Is the diff empty? 620 if (!sizeof($this->lines)) 621 { 622 $output .= '<tr><th colspan="2">' . $user->lang['NO_VISIBLE_CHANGES'] . '</th></tr>'; 623 } 624 else 625 { 626 // Iterate through every header block of changes 627 foreach ($this->lines as $header) 628 { 629 $output .= '<tr><th>' . $user->lang['LINE'] . ' ' . $header['oldline'] . '</th><th>' . $user->lang['LINE'] . ' ' . $header['newline'] . '</th></tr>'; 630 631 // Each header block consists of a number of changes (add, remove, change). 632 $current_context = ''; 633 634 foreach ($header['contents'] as $change) 635 { 636 if (!empty($current_context) && $change['type'] != 'empty') 637 { 638 $line = $current_context; 639 $current_context = ''; 640 641 $output .= '<tr class="unmodified"><td><pre>' . ((strlen($line)) ? $line : ' ') . '<br /></pre></td> 642 <td><pre>' . ((strlen($line)) ? $line : ' ') . '<br /></pre></td></tr>'; 643 } 644 645 switch ($change['type']) 646 { 647 case 'add': 648 $line = ''; 649 650 foreach ($change['lines'] as $_line) 651 { 652 $line .= htmlspecialchars($_line) . '<br />'; 653 } 654 655 $output .= '<tr><td class="added_empty"> </td><td class="added"><pre>' . ((strlen($line)) ? $line : ' ') . '<br /></pre></td></tr>'; 656 break; 657 658 case 'remove': 659 $line = ''; 660 661 foreach ($change['lines'] as $_line) 662 { 663 $line .= htmlspecialchars($_line) . '<br />'; 664 } 665 666 $output .= '<tr><td class="removed"><pre>' . ((strlen($line)) ? $line : ' ') . '<br /></pre></td><td class="removed_empty"> </td></tr>'; 667 break; 668 669 case 'empty': 670 $current_context .= htmlspecialchars($change['line']) . '<br />'; 671 break; 672 673 case 'change': 674 // Pop the old/new stacks one by one, until both are empty. 675 $oldsize = sizeof($change['old']); 676 $newsize = sizeof($change['new']); 677 $left = $right = ''; 678 679 for ($row = 0, $row_max = max($oldsize, $newsize); $row < $row_max; ++$row) 680 { 681 $left .= isset($change['old'][$row]) ? htmlspecialchars($change['old'][$row]) : ''; 682 $left .= '<br />'; 683 $right .= isset($change['new'][$row]) ? htmlspecialchars($change['new'][$row]) : ''; 684 $right .= '<br />'; 685 } 686 687 $output .= '<tr>'; 688 689 if (!empty($left)) 690 { 691 $output .= '<td class="modified"><pre>' . $left . '<br /></pre></td>'; 692 } 693 else if ($row < $oldsize) 694 { 695 $output .= '<td class="modified"> </td>'; 696 } 697 else 698 { 699 $output .= '<td class="unmodified"> </td>'; 700 } 701 702 if (!empty($right)) 703 { 704 $output .= '<td class="modified"><pre>' . $right . '<br /></pre></td>'; 705 } 706 else if ($row < $newsize) 707 { 708 $output .= '<td class="modified"> </td>'; 709 } 710 else 711 { 712 $output .= '<td class="unmodified"> </td>'; 713 } 714 715 $output .= '</tr>'; 716 break; 717 } 718 } 719 720 if (!empty($current_context)) 721 { 722 $line = $current_context; 723 $current_context = ''; 724 725 $output .= '<tr class="unmodified"><td><pre>' . ((strlen($line)) ? $line : ' ') . '<br /></pre></td>'; 726 $output .= '<td><pre>' . ((strlen($line)) ? $line : ' ') . '<br /></pre></td></tr>'; 727 } 728 } 729 } 730 731 $output .= '</tbody></table>'; 732 733 return $output; 734 } 735 736 function _start_diff() 737 { 738 $this->lines = array(); 739 740 $this->data = false; 741 $this->cols = array(array(), array()); 742 $this->state = 'empty'; 743 744 return ''; 745 } 746 747 function _end_diff() 748 { 749 // Just flush any remaining entries in the columns stack. 750 switch ($this->state) 751 { 752 case 'add': 753 $this->data['contents'][] = array('type' => 'add', 'lines' => $this->cols[0]); 754 break; 755 756 case 'remove': 757 // We have some removal lines pending in our stack, so flush them. 758 $this->data['contents'][] = array('type' => 'remove', 'lines' => $this->cols[0]); 759 break; 760 761 case 'change': 762 // We have both remove and addition lines, so this is a change block. 763 $this->data['contents'][] = array('type' => 'change', 'old' => $this->cols[0], 'new' => $this->cols[1]); 764 break; 765 } 766 767 if ($this->data !== false) 768 { 769 $this->lines[] = $this->data; 770 } 771 772 return ''; 773 } 774 775 function _block_header($xbeg, $xlen, $ybeg, $ylen) 776 { 777 // Push any previous header information to the return stack. 778 if ($this->data !== false) 779 { 780 $this->lines[] = $this->data; 781 } 782 783 $this->data = array('type' => 'header', 'oldline' => $xbeg, 'newline' => $ybeg, 'contents' => array()); 784 $this->state = 'dump'; 785 } 786 787 function _added($lines) 788 { 789 array_walk($lines, array(&$this, '_perform_add')); 790 } 791 792 function _perform_add($line) 793 { 794 if ($this->state == 'empty') 795 { 796 return ''; 797 } 798 799 // This is just an addition line. 800 if ($this->state == 'dump' || $this->state == 'add') 801 { 802 // Start adding to the addition stack. 803 $this->cols[0][] = $line; 804 $this->state = 'add'; 805 } 806 else 807 { 808 // This is inside a change block, so start accumulating lines. 809 $this->state = 'change'; 810 $this->cols[1][] = $line; 811 } 812 } 813 814 function _deleted($lines) 815 { 816 array_walk($lines, array(&$this, '_perform_delete')); 817 } 818 819 function _perform_delete($line) 820 { 821 // This is a removal line. 822 $this->state = 'remove'; 823 $this->cols[0][] = $line; 824 } 825 826 function _context($lines) 827 { 828 array_walk($lines, array(&$this, '_perform_context')); 829 } 830 831 function _perform_context($line) 832 { 833 // An empty block with no action. 834 switch ($this->state) 835 { 836 case 'add': 837 $this->data['contents'][] = array('type' => 'add', 'lines' => $this->cols[0]); 838 break; 839 840 case 'remove': 841 // We have some removal lines pending in our stack, so flush them. 842 $this->data['contents'][] = array('type' => 'remove', 'lines' => $this->cols[0]); 843 break; 844 845 case 'change': 846 // We have both remove and addition lines, so this is a change block. 847 $this->data['contents'][] = array('type' => 'change', 'old' => $this->cols[0], 'new' => $this->cols[1]); 848 break; 849 } 850 851 $this->cols = array(array(), array()); 852 $this->data['contents'][] = array('type' => 'empty', 'line' => $line); 853 $this->state = 'dump'; 854 } 855 856 function _changed($orig, $final) 857 { 858 return $this->_deleted($orig) . $this->_added($final); 859 } 860 861 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |