StacktraceFrame::__construct()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 14
c 1
b 0
f 0
nc 2
nop 12
dl 0
loc 29
ccs 15
cts 15
cp 1
crap 3
rs 9.7998

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace ZoiloMora\ElasticAPM\Events\Common;
4
5
class StacktraceFrame implements \JsonSerializable
6
{
7
    const CLASS_NAME = __CLASS__;
8
9
    /**
10
     * The absolute path of the file involved in the stack frame
11
     *
12
     * @var string|null
13
     */
14
    private $absPath;
15
16
    /**
17
     * Column number
18
     *
19
     * @var int|null
20
     */
21
    private $colno;
22
23
    /**
24
     * The line of code part of the stack frame
25
     *
26
     * @var string|null
27
     */
28
    private $contextLine;
29
30
    /**
31
     * The relative filename of the code involved in the stack frame, used e.g. to do error checksumming
32
     *
33
     * @var string|null
34
     */
35
    private $filename;
36
37
    /**
38
     * The classname of the code involved in the stack frame
39
     *
40
     * @var string|null
41
     */
42
    private $classname;
43
44
    /**
45
     * The function involved in the stack frame
46
     *
47
     * @var string|null
48
     */
49
    private $function;
50
51
    /**
52
     * A boolean, indicating if this frame is from a library or user code
53
     *
54
     * @var bool|null
55
     */
56
    private $libraryFrame;
57
58
    /**
59
     * The line number of code part of the stack frame, used e.g. to do error checksumming
60
     *
61
     * @var int|null
62
     */
63
    private $lineno;
64
65
    /**
66
     * The module to which frame belongs to
67
     *
68
     * @var string|null
69
     */
70
    private $module;
71
72
    /**
73
     * The lines of code after the stack frame
74
     *
75
     * @var array|null
76
     */
77
    private $postContext;
78
79
    /**
80
     * The lines of code before the stack frame
81
     *
82
     * @var array|null
83
     */
84
    private $preContext;
85
86
    /**
87
     * Local variables for this stack frame
88
     *
89
     * @var array|null
90
     */
91
    private $vars;
92
93
    /**
94
     * @param string|null $absPath
95
     * @param int|null $colno
96
     * @param string|null $contextLine
97
     * @param string $filename
98
     * @param string $classname
99
     * @param string|null $function
100
     * @param bool|null $libraryFrame
101
     * @param int|null $lineno
102
     * @param string|null $module
103
     * @param array|null $postContext
104
     * @param array|null $preContext
105
     * @param array|null $vars
106
     */
107 12
    public function __construct(
108
        $absPath = null,
109
        $colno = null,
110
        $contextLine = null,
111
        $filename = null,
112
        $classname = null,
113
        $function = null,
114
        $libraryFrame = null,
115
        $lineno = null,
116
        $module = null,
117
        array $postContext = null,
118
        array $preContext = null,
119
        array $vars = null
120
    ) {
121 12
        $this->absPath = $absPath;
122 12
        $this->colno = $colno;
123 12
        $this->contextLine = $contextLine;
124 12
        $this->filename = $filename;
125 12
        $this->classname = $classname;
126 12
        $this->function = $function;
127 12
        $this->libraryFrame = $libraryFrame;
128 12
        $this->lineno = $lineno;
129 12
        $this->module = $module;
130 12
        $this->postContext = $postContext;
131 12
        $this->preContext = $preContext;
132 12
        $this->vars = $vars;
133
134 12
        if (null === $this->classname && null === $this->filename) {
135 1
            throw new \InvalidArgumentException('At least one of the fields (classname, filename) must be a string');
136
        }
137 11
    }
138
139
    /**
140
     * @param array $debugBacktrace
141
     *
142
     * @return StacktraceFrame
143
     */
144 9
    public static function fromDebugBacktrace(array $debugBacktrace)
145
    {
146 9
        $file = self::valueOrNull($debugBacktrace, 'file');
147 9
        $class = self::valueOrNull($debugBacktrace, 'class');
148
149 9
        return new self(
150 9
            $file,
151 9
            null,
152 9
            null,
153 9
            null !== $file ? basename($file) : null,
154 9
            $class,
155 9
            self::valueOrNull($debugBacktrace, 'function'),
156 9
            null,
157 9
            self::valueOrNull($debugBacktrace, 'line'),
158 9
            $class,
159 9
            null,
160 9
            null,
161 9
            self::argsFromDebugBacktrace($debugBacktrace)
162 9
        );
163
    }
164
165
    /**
166
     * @param array $array
167
     * @param string $key
168
     *
169
     * @return mixed|null
170
     */
171 9
    private static function valueOrNull(array $array, $key)
172
    {
173 9
        return true === array_key_exists($key, $array)
174 9
            ? $array[$key]
175 9
            : null;
176
    }
177
178
    /**
179
     * @param array $debugBacktrace
180
     *
181
     * @return array|null
182
     */
183 9
    private static function argsFromDebugBacktrace(array $debugBacktrace)
184
    {
185 9
        if (false === array_key_exists('args', $debugBacktrace)) {
186 1
            return null;
187
        }
188
189 8
        $args = self::normalizeArguments($debugBacktrace['args']);
190
191 8
        return 0 === count($args)
192 8
            ? null
193 8
            : $args;
194
    }
195
196
    /**
197
     * @param array $arguments
198
     *
199
     * @return array
200
     */
201 8
    private static function normalizeArguments(array $arguments)
202
    {
203 8
        $args = [];
204
205 8
        foreach ($arguments as $argument) {
206 6
            $args[] = self::normalizeArgument($argument);
207 8
        }
208
209 8
        return $args;
210
    }
211
212
    /**
213
     * @param mixed $argument
214
     *
215
     * @return mixed
216
     */
217 6
    private static function normalizeArgument($argument)
218
    {
219 6
        if (true === is_object($argument)) {
220 5
            return 'Instance of ' . get_class($argument);
221
        }
222
223 6
        if (true === is_string($argument) && false === mb_check_encoding($argument, 'utf-8')) {
224 1
            return 'Malformed UTF-8 characters, possibly incorrectly encoded';
225
        }
226
227 5
        return $argument;
228
    }
229
230
    /**
231
     * @return array
232
     */
233 3
    public function jsonSerialize()
234
    {
235
        return [
236 3
            'abs_path' => $this->absPath,
237 3
            'colno' => $this->colno,
238 3
            'context_line' => $this->contextLine,
239 3
            'filename' => $this->filename,
240 3
            'classname' => $this->classname,
241 3
            'function' => $this->function,
242 3
            'library_frame' => $this->libraryFrame,
243 3
            'lineno' => $this->lineno,
244 3
            'module' => $this->module,
245 3
            'post_context' => $this->postContext,
246 3
            'pre_context' => $this->preContext,
247 3
            'vars' => null === $this->vars
248 3
                ? null
249 3
                : (object) $this->vars,
250 3
        ];
251
    }
252
}
253