Completed
Push — master ( 24da9e...18bd75 )
by Josh
05:16
created

ListDiffNew::diffLists()   F

Complexity

Conditions 27
Paths 528

Size

Total Lines 121
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 121
rs 2.7195
cc 27
eloc 72
nc 528
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Caxy\HtmlDiff;
4
5
use Caxy\HtmlDiff\ListDiff\DiffList;
6
use Caxy\HtmlDiff\ListDiff\DiffListItem;
7
8
class ListDiffNew extends AbstractDiff
9
{
10
    protected static $listTypes = array('ul', 'ol', 'dl');
11
12
    public function build()
13
    {
14
        $this->splitInputsToWords();
15
16
        return $this->diffLists(
17
            $this->buildDiffList($this->oldWords),
18
            $this->buildDiffList($this->newWords)
19
        );
20
    }
21
22
    protected function diffLists(DiffList $oldList, DiffList $newList)
23
    {
24
        $oldMatchData = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
25
        $newMatchData = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
26
        $oldListIndices = array();
27
        $newListIndices = array();
28
        $oldListItems = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
29
        $newListItems = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
30
31
        foreach ($oldList->getListItems() as $oldIndex => $oldListItem) {
32
            if ($oldListItem instanceof DiffListItem) {
33
                $oldListItems[$oldIndex] = $oldListItem;
34
35
                $oldListIndices[] = $oldIndex;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
36
                $oldMatchData[$oldIndex] = array();
37
38
                // Get match percentages
39
                foreach ($newList->getListItems() as $newIndex => $newListItem) {
40
                    if ($newListItem instanceof DiffListItem) {
41
                        if (!in_array($newListItem, $newListItems)) {
42
                            $newListItems[$newIndex] = $newListItem;
43
                        }
44
                        if (!in_array($newIndex, $newListIndices)) {
45
                            $newListIndices[] = $newIndex;
46
                        }
47
                        if (!array_key_exists($newIndex, $newMatchData)) {
48
                            $newMatchData[$newIndex] = array();
49
                        }
50
51
                        $oldText = implode('', $oldListItem->getText());
52
                        $newText = implode('', $newListItem->getText());
53
54
                        // similar_text
55
                        $percentage = null;
56
                        similar_text($oldText, $newText, $percentage);
57
58
                        $oldMatchData[$oldIndex][$newIndex] = $percentage;
59
                        $newMatchData[$newIndex][$oldIndex] = $percentage;
60
                    }
61
                }
62
            }
63
        }
64
65
        $currentIndexInOld = 0;
66
        $currentIndexInNew = 0;
67
        $oldCount = count($oldListIndices);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
68
        $newCount = count($newListIndices);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
69
        $difference = max($oldCount, $newCount) - min($oldCount, $newCount);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
70
71
        $diffOutput = '';
72
73
        foreach ($newList->getListItems() as $newIndex => $newListItem) {
74
            if ($newListItem instanceof DiffListItem) {
75
                $operation = null;
0 ignored issues
show
Unused Code introduced by
$operation is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
76
77
                $oldListIndex = array_key_exists($currentIndexInOld, $oldListIndices) ? $oldListIndices[$currentIndexInOld] : null;
78
                $class = 'normal';
0 ignored issues
show
Unused Code introduced by
$class is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
79
80
                if (null !== $oldListIndex && array_key_exists($oldListIndex, $oldMatchData)) {
81
                    // Check percentage matches of upcoming list items in old.
82
                    $matchPercentage = $oldMatchData[$oldListIndex][$newIndex];
83
84
                    // does the old list item match better?
85
                    $otherMatchBetter = false;
86
                    foreach ($oldMatchData[$oldListIndex] as $index => $percentage) {
87
                        if ($index > $newIndex && $percentage > $matchPercentage) {
88
                            $otherMatchBetter = $index;
89
                        }
90
                    }
91
92
                    if (false !== $otherMatchBetter && $newCount > $oldCount && $difference > 0) {
93
                        $diffOutput .= sprintf('%s', $newListItem->getHtml('normal new', 'ins'));
94
                        $currentIndexInNew++;
95
                        $difference--;
96
97
                        continue;
98
                    }
99
100
                    $nextOldListIndex = array_key_exists($currentIndexInOld + 1, $oldListIndices) ? $oldListIndices[$currentIndexInOld + 1] : null;
101
102
                    $replacement = false;
103
104
                    if ($nextOldListIndex !== null && $oldMatchData[$nextOldListIndex][$newIndex] > $matchPercentage && $oldMatchData[$nextOldListIndex][$newIndex] > $this->matchThreshold) {
105
                        // Following list item in old is better match, use that.
106
                        $diffOutput .= sprintf('%s', $oldListItems[$oldListIndex]->getHtml('removed', 'del'));
107
108
                        $currentIndexInOld++;
109
                        $oldListIndex = $nextOldListIndex;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
110
                        $matchPercentage = $oldMatchData[$oldListIndex];
111
                        $replacement = true;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
112
                    }
113
114
                    if ($matchPercentage > $this->matchThreshold || $currentIndexInNew === $currentIndexInOld) {
115
                        // Diff the two lists.
116
                        $htmlDiff = new HtmlDiff($oldListItems[$oldListIndex]->getInnerHtml(), $newListItem->getInnerHtml(), $this->encoding, $this->specialCaseTags, $this->groupDiffs);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
117
                        $diffContent = $htmlDiff->build();
118
119
                        $diffOutput .= sprintf('%s%s%s', $newListItem->getStartTagWithDiffClass($replacement ? 'replacement' : 'normal'), $diffContent, $newListItem->getEndTag());
120
121
                    } else {
122
                        $diffOutput .= sprintf('%s', $oldListItems[$oldListIndex]->getHtml('removed', 'del'));
123
                        $diffOutput .= sprintf('%s', $newListItem->getHtml('replacement', 'ins'));
124
                    }
125
                    $currentIndexInOld++;
126
                } else {
127
                    $diffOutput .= sprintf('%s', $newListItem->getHtml('normal new', 'ins'));
128
                }
129
130
                $currentIndexInNew++;
131
            }
132
        }
133
134
        // Output any additional list items
135
        while (array_key_exists($currentIndexInOld, $oldListIndices)) {
136
            $oldListIndex = $oldListIndices[$currentIndexInOld];
137
            $diffOutput .= sprintf('%s', $oldListItems[$oldListIndex]->getHtml('removed', 'del'));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
138
            $currentIndexInOld++;
139
        }
140
141
        return sprintf('%s%s%s', $newList->getStartTagWithDiffClass(), $diffOutput, $newList->getEndTag());
142
    }
143
144
    protected function buildDiffList($words)
145
    {
146
        $listType = null;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
147
        $listStartTag = null;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
148
        $listEndTag = null;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
149
        $attributes = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
150
        $openLists = 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
151
        $openListItems = 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
152
        $list = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 12 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
153
        $currentListItem = null;
154
        $listItemType = null;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
155
        $listItemStart = null;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
156
        $listItemEnd = null;
0 ignored issues
show
Unused Code introduced by
$listItemEnd is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
157
158
        foreach ($words as $i => $word) {
159
            if ($this->isOpeningListTag($word, $listType)) {
160
                if ($openLists > 0) {
161
                    if ($openListItems > 0) {
162
                        $currentListItem[] = $word;
163
                    } else {
164
                        $list[] = $word;
165
                    }
166
                } else {
167
                    $listType = substr($word, 1, 2);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
168
                    $listStartTag = $word;
169
                }
170
171
                $openLists++;
172
            } elseif ($this->isClosingListTag($word, $listType)) {
173
                if ($openLists > 1) {
174
                    if ($openListItems > 0) {
175
                        $currentListItem[] = $word;
176
                    } else {
177
                        $list[] = $word;
178
                    }
179
                } else {
180
                    $listEndTag = $word;
181
                }
182
183
                $openLists--;
184
            } elseif ($this->isOpeningListItemTag($word, $listItemType)) {
185
                if ($openListItems === 0) {
186
                    // New top-level list item
187
                    $currentListItem = array();
188
                    $listItemType = substr($word, 1, 2);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
189
                    $listItemStart = $word;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
190
                } else {
191
                    $currentListItem[] = $word;
192
                }
193
194
                $openListItems++;
195
            } elseif ($this->isClosingListItemTag($word, $listItemType)) {
196
                if ($openListItems === 1) {
197
                    $listItemEnd = $word;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
198
                    $listItem = new DiffListItem($currentListItem, array(), $listItemStart, $listItemEnd);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
199
                    $list[] = $listItem;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
200
                    $currentListItem = null;
201
                } else {
202
                    $currentListItem[] = $word;
203
                }
204
205
                $openListItems--;
206
            } else {
207
                if ($openListItems > 0) {
208
                    $currentListItem[] = $word;
209
                } else {
210
                    $list[] = $word;
211
                }
212
            }
213
        }
214
215
        $diffList = new DiffList($listType, $listStartTag, $listEndTag, $list, $attributes);
216
217
        return $diffList;
218
    }
219
220
    protected function isOpeningListTag($word, $type = null)
221
    {
222
        $filter = $type !== null ? array('<' . $type) : array('<ul', '<ol', '<dl');
223
        return in_array(substr($word, 0, 3), $filter);
224
    }
225
226
    protected function isClosingListTag($word, $type = null)
227
    {
228
        $filter = $type !== null ? array('</' . $type) : array('</ul', '</ol', '</dl');
229
230
        return in_array(substr($word, 0, 4), $filter);
231
    }
232
233
    protected function isOpeningListItemTag($word, $type = null)
234
    {
235
        $filter = $type !== null ? array('<' . $type) : array('<li', '<dd', '<dt');
236
237
        return in_array(substr($word, 0, 3), $filter);
238
    }
239
240
    protected function isClosingListItemTag($word, $type = null)
241
    {
242
        $filter = $type !== null ? array('</' . $type) : array('</li', '</dd', '</dt');
243
244
        return in_array(substr($word, 0, 4), $filter);
245
    }
246
}
247