public function make($a, $b = null, $c = null)
{
$diff = $this->getDiff();
if (is_string($a) && is_string($b) && is_null($c)) {
// Method 1: text1, text2
// Compute diffs from text1 and text2.
$text1 = $a;
$diff->main($text1, $b);
if (count($diff->getChanges()) > 2) {
$diff->cleanupSemantic();
$diff->cleanupEfficiency();
}
$diffs = $diff->getChanges();
} elseif (is_array($a) && is_null($b)) {
// Method 2: diffs
// Compute text1 from diffs.
$diffs = $a;
$diff->setChanges($diffs);
$text1 = $diff->text1();
} elseif (is_string($a) && is_array($b) && is_null($c)) {
// Method 3: text1, diffs
$text1 = $a;
$diffs = $b;
} elseif (is_string($a) && is_string($b) && is_array($c)) {
// Method 4: text1, text2, diffs
$text1 = $a;
$diffs = $c;
} else {
throw new \InvalidArgumentException("Unknown call format");
}
$patches = array();
if (!isset($diffs)) {
// Get rid of the null case.
return $patches;
}
$patch = new PatchObject();
// Number of characters into the text1 string.
$charCount1 = 0;
// Number of characters into the text2 string.
$charCount2 = 0;
// Recreate the patches to determine context info.
$prePatchText = $text1;
$postPatchText = $text1;
for ($i = 0; $i < count($diffs); $i++) {
list($diffType, $diffText) = $diffs[$i];
$diffTextLen = mb_strlen($diffText);
if (count($patch->getChanges()) == 0 && $diffType != Diff::EQUAL) {
// A new patch starts here.
$patch->setStart1($charCount1);
$patch->setStart2($charCount2);
}
if ($diffType == Diff::INSERT) {
// Insertion.
$patch->appendChanges($diffs[$i]);
$patch->setLength2($patch->getLength2() + $diffTextLen);
$postPatchText = mb_substr($postPatchText, 0, $charCount2) . $diffText . mb_substr($postPatchText, $charCount2);
} elseif ($diffType == Diff::DELETE) {
// Deletion.
$patch->appendChanges($diffs[$i]);
$patch->setLength1($patch->getLength1() + $diffTextLen);
$postPatchText = mb_substr($postPatchText, 0, $charCount2) . mb_substr($postPatchText, $charCount2 + $diffTextLen);
} elseif ($diffType == Diff::EQUAL && $diffTextLen <= 2 * $this->getMargin() && count($patch->getChanges()) && $i + 1 != count($diffs)) {
// Small equality inside a patch.
$patch->appendChanges($diffs[$i]);
$patch->setLength1($patch->getLength1() + $diffTextLen);
$patch->setLength2($patch->getLength2() + $diffTextLen);
}
if ($diffType == Diff::EQUAL && $diffTextLen >= 2 * $this->getMargin()) {
// Time for a new patch.
if (count($patch->getChanges())) {
$this->addContext($patch, $prePatchText);
$patches[] = $patch;
$patch = new PatchObject();
// Unlike Unidiff, our patch lists have a rolling context.
// http://code.google.com/p/google-diff-match-patch/wiki/Unidiff
// Update prepatch text & pos to reflect the application of the
// just completed patch.
$prePatchText = $postPatchText;
$charCount1 = $charCount2;
}
}
// Update the current character count.
if ($diffType != Diff::INSERT) {
$charCount1 += $diffTextLen;
}
if ($diffType != Diff::DELETE) {
$charCount2 += $diffTextLen;
}
}
// Pick up the leftover patch if not empty.
if (count($patch->getChanges())) {
$this->addContext($patch, $prePatchText);
$patches[] = $patch;
}
return $patches;
}