Passed
Pull Request — master (#9)
by Michael
03:24
created

HordeTextDiff::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
namespace XoopsModules\Mylinks;
4
5
/**
6
 * General API for generating and formatting diffs - the differences between
7
 * two sequences of strings.
8
 *
9
 * The original PHP version of this code was written by Geoffrey T. Dairiki
10
 * <[email protected]>, and is used/adapted with his permission.
11
 *
12
 * Copyright 2004 Geoffrey T. Dairiki <[email protected]>
13
 * Copyright 2004-2017 Horde LLC (http://www.horde.org/)
14
 *
15
 * See the enclosed file COPYING for license information (LGPL). If you did
16
 * not receive this file, see http://www.horde.org/licenses/lgpl21.
17
 *
18
 * @package Text_Diff
19
 * @author  Geoffrey T. Dairiki <[email protected]>
20
 */
21
class HordeTextDiff
22
{
23
    /**
24
     * Array of changes.
25
     *
26
     * @var array
27
     */
28
    protected $_edits;
29
30
    /**
31
     * Computes diffs between sequences of strings.
32
     *
33
     * @param string $engine     Name of the diffing engine to use.  'auto'
34
     *                           will automatically select the best.
35
     * @param array  $params     Parameters to pass to the diffing engine.
36
     *                           Normally an array of two arrays, each
37
     *                           containing the lines from a file.
38
     */
39
    public function __construct($engine, $params)
40
    {
41
        if ('auto' == $engine) {
42
            $engine = extension_loaded('xdiff') ? 'Xdiff' : 'Native';
43
        } else {
44
            $engine = Horde_String::ucfirst(basename($engine));
0 ignored issues
show
Bug introduced by
The type XoopsModules\Mylinks\Horde_String was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
45
        }
46
47
        $class       = 'HordeTextDiffEngine_' . $engine;
48
        $diff_engine = new $class();
49
50
        $this->_edits = call_user_func_array([$diff_engine, 'diff'], $params);
51
    }
52
53
    /**
54
     * Returns the array of differences.
55
     */
56
    public function getDiff()
57
    {
58
        return $this->_edits;
59
    }
60
61
    /**
62
     * returns the number of new (added) lines in a given diff.
63
     *
64
     * @return int The number of new lines
65
     */
66
    public function countAddedLines()
67
    {
68
        $count = 0;
69
        foreach ($this->_edits as $edit) {
70
            if ($edit instanceof HordeTextDiffOp_Add
0 ignored issues
show
Bug introduced by
The type XoopsModules\Mylinks\HordeTextDiffOp_Add was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
71
                || $edit instanceof HordeTextDiffOp_Change) {
0 ignored issues
show
Bug introduced by
The type XoopsModules\Mylinks\HordeTextDiffOp_Change was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
72
                $count += $edit->nfinal();
73
            }
74
        }
75
76
        return $count;
77
    }
78
79
    /**
80
     * Returns the number of deleted (removed) lines in a given diff.
81
     *
82
     * @return int The number of deleted lines
83
     */
84
    public function countDeletedLines()
85
    {
86
        $count = 0;
87
        foreach ($this->_edits as $edit) {
88
            if ($edit instanceof HordeTextDiffOp_Delete
0 ignored issues
show
Bug introduced by
The type XoopsModules\Mylinks\HordeTextDiffOp_Delete was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
89
                || $edit instanceof HordeTextDiffOp_Change) {
90
                $count += $edit->norig();
91
            }
92
        }
93
94
        return $count;
95
    }
96
97
    /**
98
     * Computes a reversed diff.
99
     *
100
     * Example:
101
     * <code>
102
     * $diff = new Horde_Text_Diff($lines1, $lines2);
103
     * $rev = $diff->reverse();
104
     * </code>
105
     *
106
     * @return \XoopsModules\Mylinks\HordeTextDiff A Diff object representing the inverse of the
107
     *                    original diff.  Note that we purposely don't return a
108
     *                    reference here, since this essentially is a clone()
109
     *                    method.
110
     */
111
    public function reverse()
112
    {
113
        if (version_compare(zend_version(), '2', '>')) {
114
            $rev = clone $this;
115
        } else {
116
            $rev = $this;
117
        }
118
        $rev->_edits = [];
119
        foreach ($this->_edits as $edit) {
120
            $rev->_edits[] = $edit->reverse();
121
        }
122
123
        return $rev;
124
    }
125
126
    /**
127
     * Checks for an empty diff.
128
     *
129
     * @return bool  True if two sequences were identical.
130
     */
131
    public function isEmpty()
132
    {
133
        foreach ($this->_edits as $edit) {
134
            if (!($edit instanceof HordeTextDiffOp_Copy)) {
0 ignored issues
show
Bug introduced by
The type XoopsModules\Mylinks\HordeTextDiffOp_Copy was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
135
                return false;
136
            }
137
        }
138
139
        return true;
140
    }
141
142
    /**
143
     * Computes the length of the Longest Common Subsequence (LCS).
144
     *
145
     * This is mostly for diagnostic purposes.
146
     *
147
     * @return int  The length of the LCS.
148
     */
149
    public function lcs()
150
    {
151
        $lcs = 0;
152
        foreach ($this->_edits as $edit) {
153
            if ($edit instanceof HordeTextDiffOp_Copy) {
154
                $lcs += count($edit->orig);
155
            }
156
        }
157
158
        return $lcs;
159
    }
160
161
    /**
162
     * Gets the original set of lines.
163
     *
164
     * This reconstructs the $from_lines parameter passed to the constructor.
165
     *
166
     * @return array  The original sequence of strings.
167
     */
168
    public function getOriginal()
169
    {
170
        $lines = [];
171
        foreach ($this->_edits as $edit) {
172
            if ($edit->orig) {
173
                array_splice($lines, count($lines), 0, $edit->orig);
174
            }
175
        }
176
177
        return $lines;
178
    }
179
180
    /**
181
     * Gets the final set of lines.
182
     *
183
     * This reconstructs the $to_lines parameter passed to the constructor.
184
     *
185
     * @return array  The sequence of strings.
186
     */
187
    public function getFinal()
188
    {
189
        $lines = [];
190
        foreach ($this->_edits as $edit) {
191
            if ($edit->final) {
192
                array_splice($lines, count($lines), 0, $edit->final);
193
            }
194
        }
195
196
        return $lines;
197
    }
198
199
    /**
200
     * Removes trailing newlines from a line of text. This is meant to be used
201
     * with array_walk().
202
     *
203
     * @param string $line The line to trim.
204
     * @param int    $key  The index of the line in the array. Not used.
205
     */
206
    public static function trimNewlines(&$line, $key)
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

206
    public static function trimNewlines(&$line, /** @scrutinizer ignore-unused */ $key)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
207
    {
208
        $line = str_replace(["\n", "\r"], '', $line);
209
    }
210
211
    /**
212
     * Checks a diff for validity.
213
     *
214
     * This is here only for debugging purposes.
215
     * @param $from_lines
216
     * @param $to_lines
217
     * @return bool
218
     */
219
    protected function _check($from_lines, $to_lines)
220
    {
221
        if (serialize($from_lines) != serialize($this->getOriginal())) {
222
            trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
223
        }
224
        if (serialize($to_lines) != serialize($this->getFinal())) {
225
            trigger_error("Reconstructed final doesn't match", E_USER_ERROR);
226
        }
227
228
        $rev = $this->reverse();
229
        if (serialize($to_lines) != serialize($rev->getOriginal())) {
230
            trigger_error("Reversed original doesn't match", E_USER_ERROR);
231
        }
232
        if (serialize($from_lines) != serialize($rev->getFinal())) {
233
            trigger_error("Reversed final doesn't match", E_USER_ERROR);
234
        }
235
236
        $prevtype = null;
237
        foreach ($this->_edits as $edit) {
238
            if ($prevtype == get_class($edit)) {
239
                trigger_error('Edit sequence is non-optimal', E_USER_ERROR);
240
            }
241
            $prevtype = get_class($edit);
242
        }
243
244
        return true;
245
    }
246
}
247