Completed
Pull Request — master (#377)
by Markus
03:25
created

DebugViewHelper::dumpVariable()   C

Complexity

Conditions 11
Paths 14

Size

Total Lines 57
Code Lines 42

Duplication

Lines 32
Ratio 56.14 %

Importance

Changes 0
Metric Value
cc 11
eloc 42
nc 14
nop 4
dl 32
loc 57
rs 6.4824
c 0
b 0
f 0

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 TYPO3Fluid\Fluid\ViewHelpers;
4
5
/*
6
 * This file belongs to the package "TYPO3 Fluid".
7
 * See LICENSE.txt that was shipped with this package.
8
 */
9
10
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
11
use TYPO3Fluid\Fluid\Core\Variables\VariableExtractor;
12
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
13
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
14
15
/**
16
 *
17
 *
18
 * <code title="inline notation and custom title">
19
 * {object -> f:debug(title: 'Custom title')}
20
 * </code>
21
 * <output>
22
 * all properties of {object} nicely highlighted (with custom title)
23
 * </output>
24
 *
25
 * <code title="only output the type">
26
 * {object -> f:debug(typeOnly: true)}
27
 * </code>
28
 * <output>
29
 * the type or class name of {object}
30
 * </output>
31
 *
32
 * Note: This view helper is only meant to be used during development
33
 *
34
 * @api
35
 */
36
class DebugViewHelper extends AbstractViewHelper
37
{
38
39
    use CompileWithRenderStatic;
40
41
    /**
42
     * @var boolean
43
     */
44
    protected $escapeChildren = false;
45
46
    /**
47
     * @var boolean
48
     */
49
    protected $escapeOutput = false;
50
51
    /**
52
     * @return void
53
     * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
54
     */
55
    public function initializeArguments()
56
    {
57
        parent::initializeArguments();
58
        $this->registerArgument(
59
            'typeOnly',
60
            'boolean',
61
            'If TRUE, debugs only the type of variables',
62
            false,
63
            false
64
        );
65
        $this->registerArgument(
66
            'levels',
67
            'integer',
68
            'Levels to render when rendering nested objects/arrays',
69
            false,
70
            5
71
        );
72
        $this->registerArgument(
73
            'html',
74
            'boolean',
75
            'Render HTML. If FALSE, output is indented plaintext',
76
            false,
77
            false
78
        );
79
    }
80
81
    /**
82
     * @param array $arguments
83
     * @param \Closure $renderChildrenClosure
84
     * @param RenderingContextInterface $renderingContext
85
     * @return string
86
     */
87
    public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
88
    {
89
        $typeOnly = $arguments['typeOnly'];
90
        $expressionToExamine = $renderChildrenClosure();
91
        if ($typeOnly === true) {
92
            return (
93
            \is_object($expressionToExamine) ? \get_class($expressionToExamine) : \gettype($expressionToExamine)
94
            );
95
        }
96
97
        return static::dumpVariable($expressionToExamine, $arguments['html'], 1, $arguments['levels']);
98
    }
99
100
101
    /**
102
     * @param mixed $variable
103
     * @param boolean $html
104
     * @param integer $level
105
     * @param integer $levels
106
     * @return string
107
     */
108
    protected static function dumpVariable($variable, $html, $level, $levels)
109
    {
110
        $typeLabel = \is_object($variable) ? \get_class($variable) : \gettype($variable);
111
112
        if (!$html) {
113
            if (is_scalar($variable)) {
114
                $string = sprintf('%s %s', $typeLabel, var_export($variable, true)) . PHP_EOL;
115
            } elseif ($variable === null) {
116
                $string = 'null' . PHP_EOL;
117 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
                $string = sprintf('%s: ', $typeLabel);
119
                if ($level > $levels) {
120
                    $string .= '*Recursion limited*';
121
                } else {
122
                    $string .= PHP_EOL;
123
                    foreach (static::getValuesOfNonScalarVariable($variable) as $property => $value) {
124
                        $string .= sprintf(
125
                            '%s"%s": %s',
126
                            str_repeat('  ', $level),
127
                            $property,
128
                            static::dumpVariable($value, $html, $level + 1, $levels)
129
                        );
130
                    }
131
                }
132
            }
133
        } else {
134
            if (is_scalar($variable) || $variable === null) {
135
                $string = sprintf(
136
                    '<code>%s = %s</code>',
137
                    $typeLabel,
138
                    htmlspecialchars(
139
                        var_export($variable, true),
140
                        ENT_COMPAT,
141
                        'UTF-8',
142
                        false
143
                    )
144
                );
145 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
                $string = sprintf('<code>%s</code>', $typeLabel);
147
                if ($level > $levels) {
148
                    $string .= '<i>Recursion limited</i>';
149
                } else {
150
                    $string .= '<ul>';
151
                    foreach (static::getValuesOfNonScalarVariable($variable) as $property => $value) {
152
                        $string .= sprintf(
153
                            '<li>%s: %s</li>',
154
                            $property,
155
                            static::dumpVariable($value, $html, $level + 1, $levels)
156
                        );
157
                    }
158
                    $string .= '</ul>';
159
                }
160
            }
161
        }
162
163
        return $string;
164
    }
165
166
    /**
167
     * @param mixed $variable
168
     * @return array
169
     */
170
    protected static function getValuesOfNonScalarVariable($variable)
171
    {
172
        if ($variable instanceof \ArrayObject || \is_array($variable)) {
173
            return (array)$variable;
174
        }
175
176
        if ($variable instanceof \Iterator) {
177
            return iterator_to_array($variable);
178
        }
179
180
        if (\is_resource($variable)) {
181
            return stream_get_meta_data($variable);
182
        }
183
184
        if ($variable instanceof \DateTimeInterface) {
185
            return [
186
                'class' => \get_class($variable),
187
                'ISO8601' => $variable->format(\DateTime::ISO8601),
188
                'UNIXTIME' => (integer)$variable->format('U')
189
            ];
190
        }
191
192
        $reflection = new \ReflectionObject($variable);
193
        $properties = $reflection->getProperties();
194
        $output = [];
195
        foreach ($properties as $property) {
196
            $propertyName = $property->getName();
197
            $output[$propertyName] = VariableExtractor::extract($variable, $propertyName);
198
        }
199
        return $output;
200
    }
201
}
202