Skip to content

Commit 5fc18bc

Browse files
SpacePossumsebastianbergmann
authored andcommitted
Differ::diffToArray - fix diff. generate for arrays.
1 parent cf4120d commit 5fc18bc

File tree

2 files changed

+62
-62
lines changed

2 files changed

+62
-62
lines changed

src/Differ.php

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Differ
3131

3232
/**
3333
* @param string $header
34+
* @param bool $showNonDiffLines
3435
*/
3536
public function __construct($header = "--- Original\n+++ New\n", $showNonDiffLines = true)
3637
{
@@ -115,10 +116,10 @@ private function checkIfDiffInOld(array $diff)
115116
/**
116117
* Generates buffer in string format, returning the patch.
117118
*
118-
* @param $diff
119-
* @param $old
120-
* @param $start
121-
* @param $end
119+
* @param array $diff
120+
* @param array $old
121+
* @param int $start
122+
* @param int $end
122123
*
123124
* @return string
124125
*/
@@ -145,10 +146,10 @@ private function getBuffer($diff, $old, $start, $end)
145146
/**
146147
* Gets individual buffer element.
147148
*
148-
* @param $diff
149-
* @param $i
150-
* @param $newChunk
151-
* @param $buffer
149+
* @param array $diff
150+
* @param int $i
151+
* @param bool $newChunk
152+
* @param string $buffer
152153
*
153154
* @return string
154155
*/
@@ -175,7 +176,7 @@ private function getDiffBufferElement($diff, $i, $newChunk, $buffer)
175176
* Returns the diff between two arrays or strings as array.
176177
*
177178
* Each array element contains two elements:
178-
* - [0] => string $token
179+
* - [0] => mixed $token
179180
* - [1] => 2|1|0
180181
*
181182
* - 2: REMOVED: $token was removed from $from
@@ -190,18 +191,25 @@ private function getDiffBufferElement($diff, $i, $newChunk, $buffer)
190191
*/
191192
public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
192193
{
193-
$fromMatches = $this->getNewLineMatches($from);
194-
$toMatches = $this->getNewLineMatches($to);
195-
$from = $this->splitStringByLines($from);
196-
$to = $this->splitStringByLines($to);
197-
$start = array();
198-
$end = array();
199-
$fromLength = \count($from);
200-
$toLength = \count($to);
201-
$length = \min($fromLength, $toLength);
202-
203-
$this->adjustDiffStartPoint($length, $from, $to);
204-
$this->adjustDiffEndPoint($length, $from, $to, $end, $fromLength, $toLength);
194+
if (\is_string($from)) {
195+
$fromMatches = $this->getNewLineMatches($from);
196+
$from = $this->splitStringByLines($from);
197+
} elseif (\is_array($from)) {
198+
$fromMatches = array();
199+
} else {
200+
throw new \UnexpectedValueException('"from" must be an array or string.');
201+
}
202+
203+
if (\is_string($to)) {
204+
$toMatches = $this->getNewLineMatches($to);
205+
$to = $this->splitStringByLines($to);
206+
} elseif (\is_array($to)) {
207+
$toMatches = array();
208+
} else {
209+
throw new \UnexpectedValueException('"to" must be an array or string.');
210+
}
211+
212+
list($from, $to, $start, $end) = self::getArrayDiffParted($from, $to);
205213

206214
if ($lcs === null) {
207215
$lcs = $this->selectLcsImplementation($from, $to);
@@ -311,7 +319,7 @@ private function selectLcsImplementation(array $from, array $to)
311319
* @param array $from
312320
* @param array $to
313321
*
314-
* @return int
322+
* @return int|float
315323
*/
316324
private function calculateEstimatedFootprint(array $from, array $to)
317325
{
@@ -321,62 +329,54 @@ private function calculateEstimatedFootprint(array $from, array $to)
321329
}
322330

323331
/**
324-
* Adjust start point and removes common from/to lines.
332+
* Returns true if line ends don't match on fromMatches and toMatches.
325333
*
326-
* @param int $length
334+
* @param array $fromMatches
335+
* @param array $toMatches
336+
*
337+
* @return bool
338+
*/
339+
private function detectUnmatchedLineEndings(array $fromMatches, array $toMatches)
340+
{
341+
return isset($fromMatches[0], $toMatches[0]) &&
342+
\count($fromMatches[0]) === \count($toMatches[0]) &&
343+
$fromMatches[0] !== $toMatches[0];
344+
}
345+
346+
/**
327347
* @param array $from
328348
* @param array $to
349+
*
350+
* @return array
329351
*/
330-
private function adjustDiffStartPoint(&$length, array &$from, array &$to)
352+
private static function getArrayDiffParted(array &$from, array &$to)
331353
{
332-
for ($i = 0; $i < $length; ++$i) {
333-
if ($from[$i] === $to[$i]) {
334-
$start[] = $from[$i];
354+
$start = array();
355+
$end = array();
335356

336-
unset($from[$i], $to[$i]);
357+
\reset($to);
358+
foreach ($from as $k => $v) {
359+
$toK = \key($to);
360+
if ($toK === $k && $v === $to[$k]) {
361+
$start[$k] = $v;
362+
unset($from[$k], $to[$k]);
337363
} else {
338364
break;
339365
}
340366
}
341367

342-
$length -= $i;
343-
}
368+
$keys = \array_reverse(\array_keys($from));
369+
\end($to);
344370

345-
/**
346-
* Adjusts end point and removes common from/to lines.
347-
*
348-
* @param int $length
349-
* @param array $from
350-
* @param array $to
351-
* @param array $end
352-
* @param int $fromLength
353-
* @param int $toLength
354-
*/
355-
private function adjustDiffEndPoint(&$length, array &$from, array &$to, array $end, $fromLength, $toLength)
356-
{
357-
for ($i = 1; $i < $length; ++$i) {
358-
if ($from[$fromLength - $i] === $to[$toLength - $i]) {
359-
\array_unshift($end, $from[$fromLength - $i]);
360-
unset($from[$fromLength - $i], $to[$toLength - $i]);
371+
foreach ($keys as $k) {
372+
if (\key($to) === $k && $from[$k] === $to[$k]) {
373+
$end = array($k => $from[$k]) + $end;
374+
unset($from[$k], $to[$k]);
361375
} else {
362376
break;
363377
}
364378
}
365-
}
366379

367-
/**
368-
* Returns true if line ends don't match on fromMatches and toMatches.
369-
*
370-
* @param array $fromMatches
371-
* @param array $toMatches
372-
*
373-
* @return bool
374-
*/
375-
private function detectUnmatchedLineEndings(array $fromMatches, array $toMatches)
376-
{
377-
return isset($fromMatches[0]) &&
378-
$toMatches[0] &&
379-
\count($fromMatches[0]) === \count($toMatches[0]) &&
380-
$fromMatches[0] !== $toMatches[0];
380+
return array($from, $to, $start, $end);
381381
}
382382
}

tests/DifferTest.php

2.47 KB
Binary file not shown.

0 commit comments

Comments
 (0)