Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Component / Diff / Diff.php
1 <?php
2
3 namespace Drupal\Component\Diff;
4
5 use Drupal\Component\Diff\Engine\DiffEngine;
6
7 /**
8  * Class representing a 'diff' between two sequences of strings.
9  * @todo document
10  * @subpackage DifferenceEngine
11  *
12  * Copied from https://www.drupal.org/project/diff which was based PHP diff
13  * engine for phpwiki. (Taken from phpwiki-1.3.3) The original code in phpwiki
14  * was copyright (C) 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org> and
15  * licensed under GPL.
16  */
17 class Diff {
18
19   /**
20    * The list of differences as an array of diff operations.
21    *
22    * @var \Drupal\Component\Diff\Engine\DiffOp[]
23    */
24   protected $edits;
25
26   /**
27    * Constructor.
28    * Computes diff between sequences of strings.
29    *
30    * @param $from_lines array An array of strings.
31    *      (Typically these are lines from a file.)
32    * @param $to_lines array An array of strings.
33    */
34   public function __construct($from_lines, $to_lines) {
35     $eng = new DiffEngine();
36     $this->edits = $eng->diff($from_lines, $to_lines);
37     //$this->_check($from_lines, $to_lines);
38   }
39
40   /**
41    * Compute reversed Diff.
42    *
43    * SYNOPSIS:
44    *
45    *  $diff = new Diff($lines1, $lines2);
46    *  $rev = $diff->reverse();
47    * @return object A Diff object representing the inverse of the
48    *          original diff.
49    */
50   public function reverse() {
51     $rev = $this;
52     $rev->edits = [];
53     foreach ($this->edits as $edit) {
54       $rev->edits[] = $edit->reverse();
55     }
56     return $rev;
57   }
58
59   /**
60    * Check for empty diff.
61    *
62    * @return bool True iff two sequences were identical.
63    */
64   public function isEmpty() {
65     foreach ($this->edits as $edit) {
66       if ($edit->type != 'copy') {
67         return FALSE;
68       }
69     }
70     return TRUE;
71   }
72
73   /**
74    * Compute the length of the Longest Common Subsequence (LCS).
75    *
76    * This is mostly for diagnostic purposed.
77    *
78    * @return int The length of the LCS.
79    */
80   public function lcs() {
81     $lcs = 0;
82     foreach ($this->edits as $edit) {
83       if ($edit->type == 'copy') {
84         $lcs += sizeof($edit->orig);
85       }
86     }
87     return $lcs;
88   }
89
90   /**
91    * Gets the original set of lines.
92    *
93    * This reconstructs the $from_lines parameter passed to the
94    * constructor.
95    *
96    * @return array The original sequence of strings.
97    */
98   public function orig() {
99     $lines = [];
100
101     foreach ($this->edits as $edit) {
102       if ($edit->orig) {
103         array_splice($lines, sizeof($lines), 0, $edit->orig);
104       }
105     }
106     return $lines;
107   }
108
109   /**
110    * Gets the closing set of lines.
111    *
112    * This reconstructs the $to_lines parameter passed to the
113    * constructor.
114    *
115    * @return array The sequence of strings.
116    */
117   public function closing() {
118     $lines = [];
119
120     foreach ($this->edits as $edit) {
121       if ($edit->closing) {
122         array_splice($lines, sizeof($lines), 0, $edit->closing);
123       }
124     }
125     return $lines;
126   }
127
128   /**
129    * Check a Diff for validity.
130    *
131    * This is here only for debugging purposes.
132    */
133   public function check($from_lines, $to_lines) {
134     if (serialize($from_lines) != serialize($this->orig())) {
135       trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
136     }
137     if (serialize($to_lines) != serialize($this->closing())) {
138       trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
139     }
140
141     $rev = $this->reverse();
142     if (serialize($to_lines) != serialize($rev->orig())) {
143       trigger_error("Reversed original doesn't match", E_USER_ERROR);
144     }
145     if (serialize($from_lines) != serialize($rev->closing())) {
146       trigger_error("Reversed closing doesn't match", E_USER_ERROR);
147     }
148
149
150     $prevtype = 'none';
151     foreach ($this->edits as $edit) {
152       if ( $prevtype == $edit->type ) {
153         trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
154       }
155       $prevtype = $edit->type;
156     }
157
158     $lcs = $this->lcs();
159     trigger_error('Diff okay: LCS = ' . $lcs, E_USER_NOTICE);
160   }
161
162   /**
163    * Gets the list of differences as an array of diff operations.
164    *
165    * @return \Drupal\Component\Diff\Engine\DiffOp[]
166    *   The list of differences as an array of diff operations.
167    */
168   public function getEdits() {
169     return $this->edits;
170   }
171
172 }