Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

renderer.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 18.52 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  /**
015  * @ignore
016  */
017  if (!defined('IN_PHPBB'))
018  {
019      exit;
020  }
021   
022  /**
023  * Code from pear.php.net, Text_Diff-1.1.0 package
024  * http://pear.php.net/package/Text_Diff/
025  *
026  * Modified by phpBB Limited to meet our coding standards
027  * and being able to integrate into phpBB
028  *
029  * A class to render Diffs in different formats.
030  *
031  * This class renders the diff in classic diff format. It is intended that
032  * this class be customized via inheritance, to obtain fancier outputs.
033  *
034  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
035  *
036  * @package diff
037  */
038  class diff_renderer
039  {
040      /**
041      * Number of leading context "lines" to preserve.
042      *
043      * This should be left at zero for this class, but subclasses may want to
044      * set this to other values.
045      */
046      var $_leading_context_lines = 0;
047   
048      /**
049      * Number of trailing context "lines" to preserve.
050      *
051      * This should be left at zero for this class, but subclasses may want to
052      * set this to other values.
053      */
054      var $_trailing_context_lines = 0;
055   
056      /**
057      * Constructor.
058      */
059      function diff_renderer($params = array())
060      {
061          foreach ($params as $param => $value)
062          {
063              $v = '_' . $param;
064              if (isset($this->$v))
065              {
066                  $this->$v = $value;
067              }
068          }
069      }
070   
071      /**
072      * Get any renderer parameters.
073      *
074      * @return array  All parameters of this renderer object.
075      */
076      function get_params()
077      {
078          $params = array();
079          foreach (get_object_vars($this) as $k => $v)
080          {
081              if ($k[0] == '_')
082              {
083                  $params[substr($k, 1)] = $v;
084              }
085          }
086   
087          return $params;
088      }
089   
090      /**
091      * Renders a diff.
092      *
093      * @param diff &$diff A diff object.
094      *
095      * @return string  The formatted output.
096      */
097      function render(&$diff)
098      {
099          $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">&nbsp;</span> ' . $user->lang['LINE_UNMODIFIED'] . '
610      <span class="added">&nbsp;</span> ' . $user->lang['LINE_ADDED'] . '
611      <span class="modified">&nbsp;</span> ' . $user->lang['LINE_MODIFIED'] . '
612      <span class="removed">&nbsp;</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 : '&nbsp;') . '<br /></pre></td>
642                              <td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<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">&nbsp;</td><td class="added"><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<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 : '&nbsp;') . '<br /></pre></td><td class="removed_empty">&nbsp;</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">&nbsp;</td>';
696                              }
697                              else
698                              {
699                                  $output .= '<td class="unmodified">&nbsp;</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">&nbsp;</td>';
709                              }
710                              else
711                              {
712                                  $output .= '<td class="unmodified">&nbsp;</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 : '&nbsp;') . '<br /></pre></td>';
726                      $output .= '<td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<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  }
862