ConvertHelper_ThrowableInfo_Call::getArguments()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AppUtils;
6
7
class ConvertHelper_ThrowableInfo_Call
8
{
9
    public const TYPE_FUNCTION_CALL = 'function';
10
    public const TYPE_METHOD_CALL = 'method';
11
    public const TYPE_SCRIPT_START = 'start';
12
    
13
   /**
14
    * @var ConvertHelper_ThrowableInfo
15
    */
16
    protected $info;
17
    
18
   /**
19
    * @var VariableInfo[]
20
    */
21
    protected $args = array();
22
    
23
   /**
24
    * The source file, if any
25
    * @var string
26
    */
27
    protected $file = '';
28
    
29
   /**
30
    * @var string
31
    */
32
    protected $class = '';
33
    
34
   /**
35
    * @var integer
36
    */
37
    protected $line = 0;
38
    
39
   /**
40
    * @var int
41
    */
42
    protected $position = 1;
43
    
44
   /**
45
    * @var string
46
    */
47
    protected $function = '';
48
    
49
   /**
50
    * @var string
51
    */
52
    protected $type = self::TYPE_SCRIPT_START;
53
54
    /**
55
     * @param ConvertHelper_ThrowableInfo $info
56
     * @param array<string,mixed> $data
57
     */
58
    protected function __construct(ConvertHelper_ThrowableInfo $info, array $data)
59
    {
60
        $this->info = $info;
61
        
62
        if(isset($data['serialized'])) 
63
        {
64
            $this->parseSerialized($data['serialized']);
65
        }
66
        else
67
        {
68
            $this->parseTrace($data['trace']);
69
            $this->position = $data['position'];
70
        }
71
        
72
        if($this->hasClass()) 
73
        {
74
            $this->type = self::TYPE_METHOD_CALL;
75
        }
76
        else if($this->hasFunction()) 
77
        {
78
            $this->type = self::TYPE_FUNCTION_CALL;
79
        }
80
    }
81
    
82
   /**
83
    * 1-based position of the call in the calls list.
84
    * @return int
85
    */
86
    public function getPosition() : int
87
    {
88
        return $this->position;
89
    }
90
    
91
    public function getLine() : int
92
    {
93
        return $this->line;
94
    }
95
    
96
   /**
97
    * Whether the call had any arguments.
98
    * @return bool
99
    */
100
    public function hasArguments() : bool
101
    {
102
        return !empty($this->args);
103
    }
104
    
105
   /**
106
    * @return VariableInfo[]
107
    */
108
    public function getArguments()
109
    {
110
        return $this->args;
111
    }
112
    
113
    public function hasFile() : bool
114
    {
115
        return $this->file !== '';
116
    }
117
    
118
    public function hasFunction() : bool
119
    {
120
        return !empty($this->function);
121
    }
122
    
123
    public function getFunction() : string
124
    {
125
        return $this->function;
126
    }
127
    
128
    public function getFilePath() : string
129
    {
130
        return $this->file;
131
    }
132
    
133
    public function getFileName() : string
134
    {
135
        if($this->hasFile()) {
136
            return basename($this->file);
137
        }
138
        
139
        return '';
140
    }
141
    
142
    public function getFileRelative() : string
143
    {
144
        if($this->hasFile()) {
145
            return FileHelper::relativizePathByDepth($this->file, $this->info->getFolderDepth());
146
        }
147
        
148
        return '';
149
    }
150
    
151
    public function hasClass() : bool
152
    {
153
        return $this->class !== '';
154
    }
155
    
156
    public function getClass() : string
157
    {
158
        return $this->class;
159
    }
160
161
    /**
162
     * @param array<string,mixed> $data
163
     * @throws BaseException
164
     */
165
    protected function parseSerialized(array $data) : void
166
    {
167
        $this->type = $data['type'];
168
        $this->line = $data['line'];
169
        $this->function = $data['function'];
170
        $this->file = $data['file'];
171
        $this->class = $data['class'];
172
        $this->position = $data['position'];
173
        
174
        foreach($data['arguments'] as $arg)
175
        {
176
            $this->args[] = VariableInfo::fromSerialized($arg);
177
        }
178
    }
179
180
    /**
181
     * @param array<string,mixed> $trace
182
     */
183
    protected function parseTrace(array $trace) : void
184
    {
185
        if(isset($trace['line']))
186
        {
187
            $this->line = intval($trace['line']);
188
        }
189
        
190
        if(isset($trace['function'])) 
191
        {
192
            $this->function = $trace['function'];
193
        }
194
        
195
        if(isset($trace['file']))
196
        {
197
            $this->file = FileHelper::normalizePath($trace['file']);
198
        }
199
        
200
        if(isset($trace['class'])) 
201
        {
202
            $this->class = $trace['class'];
203
        }
204
     
205
        if(isset($trace['args']) && !empty($trace['args']))
206
        {
207
            foreach($trace['args'] as $arg) 
208
            {
209
                $this->args[] = parseVariable($arg);
210
            }
211
        }
212
    }
213
    
214
    public function toString() : string
215
    {
216
        $tokens = array();
217
        
218
        $padLength = strlen((string)$this->info->countCalls());
219
        
220
        $tokens[] = '#'.sprintf('%0'.$padLength.'d', $this->getPosition()).' ';
221
        
222
        if($this->hasFile()) {
223
            $tokens[] = $this->getFileRelative().':'.$this->getLine();
224
        }
225
        
226
        if($this->hasClass()) {
227
            $tokens[] = $this->getClass().'::'.$this->getFunction().'('.$this->argumentsToString().')';
228
        } else if($this->hasFunction()) {
229
            $tokens[] = $this->getFunction().'('.$this->argumentsToString().')';
230
        }
231
        
232
        return implode(' ', $tokens);
233
    }
234
    
235
    public function argumentsToString() : string
236
    {
237
        $tokens = array();
238
        
239
        foreach($this->args as $arg) 
240
        {
241
            $tokens[] = $arg->toString();
242
        }
243
        
244
        return implode(', ', $tokens); 
245
    }
246
    
247
   /**
248
    * Retrieves the type of call: typically a function
249
    * call, or a method call of an object. Note that the
250
    * first call in a script does not have either.
251
    * 
252
    * @return string
253
    * 
254
    * @see ConvertHelper_ThrowableInfo_Call::TYPE_FUNCTION_CALL
255
    * @see ConvertHelper_ThrowableInfo_Call::TYPE_METHOD_CALL
256
    * @see ConvertHelper_ThrowableInfo_Call::TYPE_SCRIPT_START
257
    * @see ConvertHelper_ThrowableInfo_Call::hasFunction()
258
    * @see ConvertHelper_ThrowableInfo_Call::hasClass()
259
    */
260
    public function getType() : string
261
    {
262
        return $this->type;
263
    }
264
     
265
   /**
266
    * Serializes the call to an array, with all
267
    * necessary information. Can be used to restore
268
    * the call later using {@link ConvertHelper_ThrowableInfo_Call::fromSerialized()}.
269
    * 
270
    * @return array<string,mixed>
271
    */
272
    public function serialize() : array
273
    {
274
        $result = array(
275
            'type' => $this->getType(),
276
            'class' => $this->getClass(),
277
            'file' => $this->getFilePath(),
278
            'function' => $this->getFunction(),
279
            'line' => $this->getLine(),
280
            'position' => $this->getPosition(),
281
            'arguments' => array()
282
        );
283
        
284
        foreach($this->args as $argument)
285
        {
286
            $result['arguments'][] = $argument->serialize();
287
        }
288
        
289
        return $result;
290
    }
291
292
    /**
293
     * @param ConvertHelper_ThrowableInfo $info
294
     * @param int $position
295
     * @param array<string,mixed> $trace
296
     * @return ConvertHelper_ThrowableInfo_Call
297
     */
298
    public static function fromTrace(ConvertHelper_ThrowableInfo $info, int $position, array $trace) : ConvertHelper_ThrowableInfo_Call
299
    {
300
        return new ConvertHelper_ThrowableInfo_Call(
301
            $info, 
302
            array(
303
                'position' => $position,
304
                'trace' => $trace
305
            )
306
        );
307
    }
308
309
    /**
310
     * @param ConvertHelper_ThrowableInfo $info
311
     * @param array<string,mixed> $serialized
312
     * @return ConvertHelper_ThrowableInfo_Call
313
     */
314
    public static function fromSerialized(ConvertHelper_ThrowableInfo $info, array $serialized) : ConvertHelper_ThrowableInfo_Call
315
    {
316
        return new ConvertHelper_ThrowableInfo_Call(
317
            $info,
318
            array(
319
                'serialized' => $serialized
320
            )
321
        );
322
    }
323
}
324