Completed
Push — master ( 234b0e...1578b3 )
by Michael
14s
created

Text_Diff_Renderer::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 9
rs 9.6666
cc 3
eloc 5
nc 3
nop 1
1
<?php
2
/**
3
 * A class to render Diffs in different formats.
4
 *
5
 * This class renders the diff in classic diff format. It is intended that
6
 * this class be customized via inheritance, to obtain fancier outputs.
7
 *
8
 * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.9 2005/05/04 20:21:52 chuck Exp $
9
 *
10
 * @package Text_Diff
11
 */
12
class Text_Diff_Renderer {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
13
14
    /**
15
     * Number of leading context "lines" to preserve.
16
     *
17
     * This should be left at zero for this class, but subclasses may want to
18
     * set this to other values.
19
     */
20
    var $_leading_context_lines = 0;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_leading_context_lines.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
21
22
    /**
23
     * Number of trailing context "lines" to preserve.
24
     *
25
     * This should be left at zero for this class, but subclasses may want to
26
     * set this to other values.
27
     */
28
    var $_trailing_context_lines = 0;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_trailing_context_lines.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
29
30
    /**
31
     * Constructor.
32
     */
33
    function __construct($params = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
34
    {
35
        foreach ($params as $param => $value) {
36
            $v = '_' . $param;
37
            if (isset($this->$v)) {
38
                $this->$v = $value;
39
            }
40
        }
41
    }
42
43
    /**
44
     * Get any renderer parameters.
45
     *
46
     * @return array All parameters of this renderer object.
47
     */
48
    function getParams()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
49
    {
50
        $params = array();
51
        foreach (get_object_vars($this) as $k => $v) {
52
            if ($k{0} == '_') {
53
                $params[substr($k, 1)] = $v;
54
            }
55
        }
56
57
        return $params;
58
    }
59
60
    /**
61
     * Renders a diff.
62
     *
63
     * @param Text_Diff $diff A Text_Diff object.
64
     *
65
     * @return string The formatted output.
66
     */
67
    function render($diff)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
68
    {
69
        $xi = $yi = 1;
70
        $block = false;
71
        $context = array();
72
73
        $nlead = $this->_leading_context_lines;
74
        $ntrail = $this->_trailing_context_lines;
75
76
        $output = $this->_startDiff();
77
78
        foreach ($diff->getDiff() as $edit) {
79
            if (is_a($edit, 'Text_Diff_Op_copy')) {
80
                if (is_array($block)) {
81
                    if (count($edit->orig) <= $nlead + $ntrail) {
82
                        $block[] = $edit;
83
                    } else {
84
                        if ($ntrail) {
85
                            $context = array_slice($edit->orig, 0, $ntrail);
86
                            $block[] = new Text_Diff_Op_copy($context);
87
                        }
88
                        $output .= $this->_block($x0, $ntrail + $xi - $x0,
0 ignored issues
show
Bug introduced by
The variable $x0 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
89
                                                 $y0, $ntrail + $yi - $y0,
0 ignored issues
show
Bug introduced by
The variable $y0 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
90
                                                 $block);
91
                        $block = false;
92
                    }
93
                }
94
                $context = $edit->orig;
95
            } else {
96
                if (!is_array($block)) {
97
                    $context = array_slice($context, count($context) - $nlead);
98
                    $x0 = $xi - count($context);
99
                    $y0 = $yi - count($context);
100
                    $block = array();
101
                    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...
102
                        $block[] = new Text_Diff_Op_copy($context);
103
                    }
104
                }
105
                $block[] = $edit;
106
            }
107
108
            if ($edit->orig) {
109
                $xi += count($edit->orig);
110
            }
111
            if ($edit->final) {
112
                $yi += count($edit->final);
113
            }
114
        }
115
116
        if (is_array($block)) {
117
            $output .= $this->_block($x0, $xi - $x0,
118
                                     $y0, $yi - $y0,
119
                                     $block);
120
        }
121
122
        return $output . $this->_endDiff();
123
    }
124
125
    function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
126
    {
127
        $output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
128
129
        foreach ($edits as $edit) {
130
            switch (strtolower(get_class($edit))) {
131
            case 'text_diff_op_copy':
132
                $output .= $this->_context($edit->orig);
133
                break;
134
135
            case 'text_diff_op_add':
136
                $output .= $this->_added($edit->final);
137
                break;
138
139
            case 'text_diff_op_delete':
140
                $output .= $this->_deleted($edit->orig);
141
                break;
142
143
            case 'text_diff_op_change':
144
                $output .= $this->_changed($edit->orig, $edit->final);
145
                break;
146
            }
147
        }
148
149
        return $output . $this->_endBlock();
150
    }
151
152
    function _startDiff()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
153
    {
154
        return '';
155
    }
156
157
    function _endDiff()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
158
    {
159
        return '';
160
    }
161
162
    function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
163
    {
164
        if ($xlen > 1) {
165
            $xbeg .= ',' . ($xbeg + $xlen - 1);
166
        }
167
        if ($ylen > 1) {
168
            $ybeg .= ',' . ($ybeg + $ylen - 1);
169
        }
170
171
        return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
172
    }
173
174
    function _startBlock($header)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
175
    {
176
        return $header . "\n";
177
    }
178
179
    function _endBlock()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
180
    {
181
        return '';
182
    }
183
184
    function _lines($lines, $prefix = ' ')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
185
    {
186
        return $prefix . implode("\n$prefix", $lines) . "\n";
187
    }
188
189
    function _context($lines)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
190
    {
191
        return $this->_lines($lines);
192
    }
193
194
    function _added($lines)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
195
    {
196
        return $this->_lines($lines, '>');
197
    }
198
199
    function _deleted($lines)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
200
    {
201
        return $this->_lines($lines, '<');
202
    }
203
204
    function _changed($orig, $final)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
205
    {
206
        return $this->_deleted($orig) . "---\n" . $this->_added($final);
207
    }
208
209
}
210