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

Text_Diff_Renderer::_context()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace XoopsModules\Mylinks;
4
5
/**
6
 * A class to render Diffs in different formats.
7
 *
8
 * This class renders the diff in classic diff format. It is intended that
9
 * this class be customized via inheritance, to obtain fancier outputs.
10
 *
11
 * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.9 2005/05/04 20:21:52 chuck Exp $
12
 *
13
 * @package Text_Diff
14
 */
15
class Text_Diff_Renderer
16
{
17
    /**
18
     * Number of leading context "lines" to preserve.
19
     *
20
     * This should be left at zero for this class, but subclasses may want to
21
     * set this to other values.
22
     */
23
    public $_leading_context_lines = 0;
24
25
    /**
26
     * Number of trailing context "lines" to preserve.
27
     *
28
     * This should be left at zero for this class, but subclasses may want to
29
     * set this to other values.
30
     */
31
    public $_trailing_context_lines = 0;
32
33
    /**
34
     * Constructor.
35
     * @param array $params
36
     */
37
    public function __construct($params = [])
38
    {
39
        foreach ($params as $param => $value) {
40
            $v = '_' . $param;
41
            if (isset($this->$v)) {
42
                $this->$v = $value;
43
            }
44
        }
45
    }
46
47
    /**
48
     * Get any renderer parameters.
49
     *
50
     * @return array All parameters of this renderer object.
51
     */
52
    public function getParams()
53
    {
54
        $params = [];
55
        foreach (get_object_vars($this) as $k => $v) {
56
            if ('_' === $k[0]) {
57
                $params[mb_substr($k, 1)] = $v;
58
            }
59
        }
60
61
        return $params;
62
    }
63
64
    /**
65
     * Renders a diff.
66
     *
67
     * @param Text_Diff $diff A Text_Diff object.
68
     *
69
     * @return string The formatted output.
70
     */
71
    public function render($diff)
72
    {
73
        $xi      = $yi = 1;
74
        $block   = false;
75
        $context = [];
76
77
        $nlead  = $this->_leading_context_lines;
78
        $ntrail = $this->_trailing_context_lines;
79
80
        $output = $this->_startDiff();
81
82
        foreach ($diff->getDiff() as $edit) {
83
            if (is_a($edit, 'Text_Diff_Op_copy')) {
84
                if (is_array($block)) {
85
                    if (count($edit->orig) <= $nlead + $ntrail) {
86
                        $block[] = $edit;
87
                    } else {
88
                        if ($ntrail) {
89
                            $context = array_slice($edit->orig, 0, $ntrail);
90
                            $block[] = new Text_Diff_Op_copy($context);
91
                        }
92
                        $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $y0 does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $x0 does not seem to be defined for all execution paths leading up to this point.
Loading history...
93
                        $block  = false;
94
                    }
95
                }
96
                $context = $edit->orig;
97
            } else {
98
                if (!is_array($block)) {
99
                    $context = array_slice($context, count($context) - $nlead);
100
                    $x0      = $xi - count($context);
101
                    $y0      = $yi - count($context);
102
                    $block   = [];
103
                    if ($context) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $context of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
104
                        $block[] = new Text_Diff_Op_copy($context);
105
                    }
106
                }
107
                $block[] = $edit;
108
            }
109
110
            if ($edit->orig) {
111
                $xi += count($edit->orig);
112
            }
113
            if ($edit->final) {
114
                $yi += count($edit->final);
115
            }
116
        }
117
118
        if (is_array($block)) {
119
            $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
120
        }
121
122
        return $output . $this->_endDiff();
123
    }
124
125
    /**
126
     * @param $xbeg
127
     * @param $xlen
128
     * @param $ybeg
129
     * @param $ylen
130
     * @param $edits
131
     * @return string
132
     */
133
    public function _block($xbeg, $xlen, $ybeg, $ylen, $edits)
134
    {
135
        $output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
136
137
        foreach ($edits as $edit) {
138
            switch (mb_strtolower(get_class($edit))) {
139
                case 'text_diff_op_copy':
140
                    $output .= $this->_context($edit->orig);
141
                    break;
142
                case 'text_diff_op_add':
143
                    $output .= $this->_added($edit->final);
144
                    break;
145
                case 'text_diff_op_delete':
146
                    $output .= $this->_deleted($edit->orig);
147
                    break;
148
                case 'text_diff_op_change':
149
                    $output .= $this->_changed($edit->orig, $edit->final);
150
                    break;
151
            }
152
        }
153
154
        return $output . $this->_endBlock();
155
    }
156
157
    /**
158
     * @return string
159
     */
160
    public function _startDiff()
161
    {
162
        return '';
163
    }
164
165
    /**
166
     * @return string
167
     */
168
    public function _endDiff()
169
    {
170
        return '';
171
    }
172
173
    /**
174
     * @param $xbeg
175
     * @param $xlen
176
     * @param $ybeg
177
     * @param $ylen
178
     * @return string
179
     */
180
    public function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
181
    {
182
        if ($xlen > 1) {
183
            $xbeg .= ',' . ($xbeg + $xlen - 1);
184
        }
185
        if ($ylen > 1) {
186
            $ybeg .= ',' . ($ybeg + $ylen - 1);
187
        }
188
189
        return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
190
    }
191
192
    /**
193
     * @param $header
194
     * @return string
195
     */
196
    public function _startBlock($header)
197
    {
198
        return $header . "\n";
199
    }
200
201
    /**
202
     * @return string
203
     */
204
    public function _endBlock()
205
    {
206
        return '';
207
    }
208
209
    /**
210
     * @param         $lines
211
     * @param string  $prefix
212
     * @return string
213
     */
214
    public function _lines($lines, $prefix = ' ')
215
    {
216
        return $prefix . implode("\n$prefix", $lines) . "\n";
217
    }
218
219
    /**
220
     * @param $lines
221
     * @return string
222
     */
223
    public function _context($lines)
224
    {
225
        return $this->_lines($lines);
226
    }
227
228
    /**
229
     * @param $lines
230
     * @return string
231
     */
232
    public function _added($lines)
233
    {
234
        return $this->_lines($lines, '>');
235
    }
236
237
    /**
238
     * @param $lines
239
     * @return string
240
     */
241
    public function _deleted($lines)
242
    {
243
        return $this->_lines($lines, '<');
244
    }
245
246
    /**
247
     * @param $orig
248
     * @param $final
249
     * @return string
250
     */
251
    public function _changed($orig, $final)
252
    {
253
        return $this->_deleted($orig) . "---\n" . $this->_added($final);
254
    }
255
}
256