Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Component / Diff / DiffFormatter.php
1 <?php
2
3 namespace Drupal\Component\Diff;
4
5 use Drupal\Component\Diff\Engine\DiffOpCopy;
6
7 /**
8  * A class to format Diffs
9  *
10  * This class formats the diff in classic diff format.
11  * It is intended that this class be customized via inheritance,
12  * to obtain fancier outputs.
13  * @todo document
14  * @private
15  * @subpackage DifferenceEngine
16  */
17 class DiffFormatter {
18   /**
19    * Should a block header be shown?
20    */
21   public $show_header = TRUE;
22
23   /**
24    * Number of leading context "lines" to preserve.
25    *
26    * This should be left at zero for this class, but subclasses
27    * may want to set this to other values.
28    */
29   public $leading_context_lines = 0;
30
31   /**
32    * Number of trailing context "lines" to preserve.
33    *
34    * This should be left at zero for this class, but subclasses
35    * may want to set this to other values.
36    */
37   public $trailing_context_lines = 0;
38
39   /**
40    * The line stats.
41    *
42    * @var array
43    */
44   protected $line_stats = [
45     'counter' => ['x' => 0, 'y' => 0],
46     'offset' => ['x' => 0, 'y' => 0],
47   ];
48
49   /**
50    * Format a diff.
51    *
52    * @param \Drupal\Component\Diff\Diff $diff
53    *   A Diff object.
54    *
55    * @return string
56    *   The formatted output.
57    */
58   public function format(Diff $diff) {
59     $xi = $yi = 1;
60     $block = FALSE;
61     $context = [];
62
63     $nlead = $this->leading_context_lines;
64     $ntrail = $this->trailing_context_lines;
65
66     $this->_start_diff();
67
68     foreach ($diff->getEdits() as $edit) {
69       if ($edit->type == 'copy') {
70         if (is_array($block)) {
71           if (sizeof($edit->orig) <= $nlead + $ntrail) {
72             $block[] = $edit;
73           }
74           else {
75             if ($ntrail) {
76               $context = array_slice($edit->orig, 0, $ntrail);
77               $block[] = new DiffOpCopy($context);
78             }
79             $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
80             $block = FALSE;
81           }
82         }
83         $context = $edit->orig;
84       }
85       else {
86         if (!is_array($block)) {
87           $context = array_slice($context, sizeof($context) - $nlead);
88           $x0 = $xi - sizeof($context);
89           $y0 = $yi - sizeof($context);
90           $block = [];
91           if ($context) {
92             $block[] = new DiffOpCopy($context);
93           }
94         }
95         $block[] = $edit;
96       }
97
98       if ($edit->orig) {
99         $xi += sizeof($edit->orig);
100       }
101       if ($edit->closing) {
102         $yi += sizeof($edit->closing);
103       }
104     }
105
106     if (is_array($block)) {
107       $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
108     }
109     $end = $this->_end_diff();
110
111     if (!empty($xi)) {
112       $this->line_stats['counter']['x'] += $xi;
113     }
114     if (!empty($yi)) {
115       $this->line_stats['counter']['y'] += $yi;
116     }
117
118     return $end;
119   }
120
121   protected function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
122     $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
123     foreach ($edits as $edit) {
124       if ($edit->type == 'copy') {
125         $this->_context($edit->orig);
126       }
127       elseif ($edit->type == 'add') {
128         $this->_added($edit->closing);
129       }
130       elseif ($edit->type == 'delete') {
131         $this->_deleted($edit->orig);
132       }
133       elseif ($edit->type == 'change') {
134         $this->_changed($edit->orig, $edit->closing);
135       }
136       else {
137         trigger_error('Unknown edit type', E_USER_ERROR);
138       }
139     }
140     $this->_end_block();
141   }
142
143   protected function _start_diff() {
144     ob_start();
145   }
146
147   protected function _end_diff() {
148     $val = ob_get_contents();
149     ob_end_clean();
150     return $val;
151   }
152
153   protected function _block_header($xbeg, $xlen, $ybeg, $ylen) {
154     if ($xlen > 1) {
155       $xbeg .= "," . ($xbeg + $xlen - 1);
156     }
157     if ($ylen > 1) {
158       $ybeg .= "," . ($ybeg + $ylen - 1);
159     }
160
161     return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
162   }
163
164   protected function _start_block($header) {
165     if ($this->show_header) {
166       echo $header . "\n";
167     }
168   }
169
170   protected function _end_block() {
171   }
172
173   protected function _lines($lines, $prefix = ' ') {
174     foreach ($lines as $line) {
175       echo "$prefix $line\n";
176     }
177   }
178
179   protected function _context($lines) {
180     $this->_lines($lines);
181   }
182
183   protected function _added($lines) {
184     $this->_lines($lines, '>');
185   }
186
187   protected function _deleted($lines) {
188     $this->_lines($lines, '<');
189   }
190
191   protected function _changed($orig, $closing) {
192     $this->_deleted($orig);
193     echo "---\n";
194     $this->_added($closing);
195   }
196
197 }