SimpleDiff   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 14
lcom 0
cbo 0
dl 0
loc 81
ccs 39
cts 39
cp 1
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
C diff() 0 32 8
B htmlDiff() 0 26 6
1
<?php
2
namespace CodeDruids;
3
4
/**
5
 *  Paul's Simple Diff Algorithm v 0.1
6
 *  (C) Paul Butler 2007 <http://www.paulbutler.org/>
7
 *  May be used and distributed under the zlib/libpng license.
8
 *
9
 *  Original by github/paulgb
10
 *  Includes fixes from github/angrychimp
11
 *  Class wrapper, updates, docs and tests by github/CodeDruids
12
 */
13
class SimpleDiff
14
{
15
    /**
16
     * Given two arrays, return an array of the changes.
17
     *
18
     * @param  array $old  Original array to compare to
19
     * @param  array $new  New array to compare against
20
     *
21
     * @return array       Original array, with differing elements replaced by an array showing deletions & insertions
22
     */
23 22
    public static function diff(array $old, array $new)
24
    {
25 22
        if (empty($old) && empty($new)) {
26 14
            return [];
27
        }
28
29 20
        $matrix = [];
30 20
        $maxlen = 0;
31 20
        $omax = 0;
32 20
        $nmax = 0;
33 20
        foreach ($old as $oindex => $ovalue) {
34 18
            $nkeys = array_keys($new, $ovalue);
35 18
            foreach ($nkeys as $nindex) {
36 12
                $matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ?
37 12
                    $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
38 12
                if ($matrix[$oindex][$nindex] > $maxlen) {
39 12
                    $maxlen = $matrix[$oindex][$nindex];
40 12
                    $omax = $oindex + 1 - $maxlen;
41 18
                    $nmax = $nindex + 1 - $maxlen;
42
                }
43
            }
44
        }
45 20
        if ($maxlen == 0) {
46 18
            return [['deleted' => $old, 'inserted' => $new]];
47
        }
48
49 12
        return array_merge(
50 12
            self::diff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)),
51 12
            array_slice($new, $nmax, $maxlen),
52 12
            self::diff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen))
53
        );
54
    }
55
56
    /**
57
     * Wrapper for the diff command to return the differences in HTML.
58
     *
59
     * The tags used for the diff are <ins> and <del>, which can easily be styled with CSS.
60
     * Using PREG_SPLIT_DELIM_CAPTURE ensures whitespace is diffed as well.
61
     *
62
     * @param  string $old  Original string to compare to
63
     * @param  string $new  New string to compare against
64
     *
65
     * @return string       Combination of both strings with <ins> and <del> tags to indicate differences
66
     */
67 14
    public static function htmlDiff($old, $new)
68
    {
69 14
        $ret = '';
70 14
        $diff = self::diff(
71 14
            preg_split("/([\s]+)/", $old, null, PREG_SPLIT_DELIM_CAPTURE),
72 14
            preg_split("/([\s]+)/", $new, null, PREG_SPLIT_DELIM_CAPTURE)
73
        );
74 14
        foreach ($diff as $k) {
75 14
            if (is_array($k)) {
76 12
                foreach (['deleted', 'inserted'] as $v) {
77 12
                    $$v = '';
78 12
                    if (!empty($k[$v])) {
79 12
                        $$v = implode('', $k[$v]);
80 12
                        if ($$v != '') {
81 12
                            $tag = substr($v, 0, 3);
82 12
                            $$v = "<$tag>".$$v."</$tag>";
83
                        }
84
                    }
85
                }
86 12
                $ret .= $deleted.$inserted;
87
            } else {
88 14
                $ret .= $k;
89
            }
90
        }
91 14
        return $ret;
92
    }
93
}
94