Test Failed
Push — master ( 5f8db2...b3d8d2 )
by Waaaaaaaaaa
02:26
created

Frame::getCaller()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php declare(strict_types=1);
2
3
namespace Logfile\Inspection;
4
5
use Logfile\Traits;
6
7
class Frame
8
{
9
    use Traits\Path;
10
11
    protected $file;
12
13
    protected $line;
14
15
    protected $caller;
16
17
    protected $args = [];
18
19
    public static function create(array $params): self
20
    {
21
        $frame = new self;
22
23
        if (isset($params['file'])) {
24
            $frame->setFile($params['file']);
25
        }
26
27
        if (isset($params['line'])) {
28
            $frame->setLine($params['line']);
29
        }
30
31
        if (isset($params['class'])) {
32
            $frame->setCaller(\sprintf('%s%s%s', $params['class'], $params['type'], $params['function']));
33
        } elseif (isset($params['function'])) {
34
            $frame->setCaller($params['function']);
35
        }
36
37
        if (isset($params['args'])) {
38
            $frame->setArguments($params['args']);
39
        } else {
40
            $frame->setArguments([]);
41
        }
42
43
        return $frame;
44
    }
45
46
    public function getRelativeFilepath(): string
47
    {
48
        if ($this->hasPath() && \strpos($this->getFile(), $this->getPath()) === 0) {
49
            return \mb_substr($this->getFile(), \mb_strlen($this->getPath()));
50
        }
51
        return $this->getFile();
52
    }
53
54
    public function getFile(): string
55
    {
56
        return $this->file;
57
    }
58
59
    public function setFile(string $file): void
60
    {
61
        $this->file = $file;
62
    }
63
64
    public function hasFile(): bool
65
    {
66
        return $this->file !== null && \is_readable($this->file);
67
    }
68
69
    public function getLine(): int
70
    {
71
        return $this->line;
72
    }
73
74
    public function setLine(int $line): void
75
    {
76
        $this->line = $line;
77
    }
78
79
    public function hasLine(): bool
80
    {
81
        return $this->line !== null;
82
    }
83
84
    public function hasCaller(): bool
85
    {
86
        return !empty($this->caller);
87
    }
88
89
    public function getCaller(): string
90
    {
91
        return $this->caller;
92
    }
93
94
    public function setCaller(string $caller): void
95
    {
96
        $this->caller = $caller;
97
    }
98
99
    public function getArguments(): array
100
    {
101
        return $this->args ?: [];
102
    }
103
104
    public function setArguments(array $args): void
105
    {
106
        $this->args = [];
107
108
        foreach (\array_values($args) as $index => $arg) {
109
            $this->args['param'.($index + 1)] = $this->normalise($arg);
110
        }
111
    }
112
113
    protected function normaliseArray($value): string
114
    {
115
        $count = count($value);
116
117
        if ($count > 100) {
118
            return 'Array of length ' . $count;
119
        }
120
121
        $types = [];
122
123
        foreach ($value as $item) {
124
            $type = gettype($item);
125
            if ('object' === $type) {
126
                $type = get_class($item);
127
            }
128
            if (!in_array($type, $types)) {
129
                $types[] = $type;
130
            }
131
        }
132
133
        if (count($types) > 3) {
134
            return 'Mixed Array of length ' . $count;
135
        }
136
137
        return 'Array<'.implode('|', $types).'> of length ' . $count;
138
    }
139
140
    protected function normalise($value): string
141
    {
142
        if ($value === null) {
143
            return 'null';
144
        } elseif ($value === false) {
145
            return 'false';
146
        } elseif ($value === true) {
147
            return 'true';
148
        } elseif (is_float($value) && (int) $value == $value) {
149
            return $value.'.0';
150
        } elseif (is_integer($value) || is_float($value)) {
151
            return (string) $value;
152
        } elseif (is_object($value) || gettype($value) == 'object') {
153
            return 'Object '.get_class($value);
154
        } elseif (is_resource($value)) {
155
            return 'Resource '.get_resource_type($value);
156
        } elseif (is_array($value)) {
157
            return $this->normaliseArray($value);
158
        }
159
160
        $truncation = new Truncation($value);
161
        return $truncation->truncate();
162
    }
163
164
    public function hasContext(): bool
165
    {
166
        return $this->hasFile() && $this->hasLine();
167
    }
168
169
    public function getContext(): Context
170
    {
171
        return new Context($this->getFile(), $this->getLine());
172
    }
173
174
    public function toArray(): array
175
    {
176
        $frame = [];
177
178
        if ($this->hasFile()) {
179
            $frame['file'] = $this->getRelativeFilepath();
180
        }
181
182
        if ($this->hasLine()) {
183
            $frame['line'] = $this->getLine();
184
        }
185
186
        if ($this->hasCaller()) {
187
            $frame['caller'] = $this->getCaller();
188
        }
189
190
        $frame['args'] = $this->getArguments();
191
192
        if ($this->hasContext()) {
193
            $frame['context'] = $this->getContext()->getPlaceInFile();
194
        }
195
196
        return $frame;
197
    }
198
}
199