Completed
Push — master ( 9075d8...1cf195 )
by Jacob
02:19
created

Display::__invoke()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 51
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 12
Bugs 0 Features 1
Metric Value
c 12
b 0
f 1
dl 0
loc 51
rs 9.411
cc 1
eloc 33
nc 1
nop 0

How to fix   Long Method   

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
/*****************************************
4
 * Title : Php Quick Profiler Display Class
5
 * Author : Created by Ryan Campbell
6
 * URL : http://particletree.com/features/php-quick-profiler/
7
 * Description : This is a hacky way of pushing profiling logic to the
8
 *  PQP HTML. This is great because it will just work in your project,
9
 *  but it is hard to maintain and read.
10
*****************************************/
11
12
namespace Particletree\Pqp;
13
14
class Display
15
{
16
17
    /** @var  array */
18
    protected $defaults = array(
19
        'script_path' => 'asset/script.js',
20
        'style_path'  => 'asset/style.css'
21
    );
22
23
    /** @var  array */
24
    protected $options;
25
26
    /** @var  double */
27
    protected $startTime;
28
29
    /** @var  Console */
30
    protected $console;
31
32
    /** @var  array */
33
    protected $speedData;
34
35
    /** @var  array */
36
    protected $queryData;
37
38
    /** @var  array */
39
    protected $memoryData;
40
41
    /** @var  array */
42
    protected $fileData;
43
44
    /**
45
     * @param array $options
46
     */
47
    public function __construct(array $options = array())
48
    {
49
        $options = array_intersect_key($options, $this->defaults);
50
        $this->options = array_replace($this->defaults, $options);
51
    }
52
53
    /**
54
     * @param double $startTime
55
     */
56
    public function setStartTime($startTime)
57
    {
58
        $this->startTime = $startTime;
59
    }
60
61
    /**
62
     * @param Console $console
63
     */
64
    public function setConsole(Console $console)
65
    {
66
        $this->console = $console;
67
    }
68
69
    /**
70
     * Sets memory data
71
     *
72
     * @param array $data
73
     */
74
    public function setMemoryData(array $data)
75
    {
76
        $this->memoryData = $data;
77
    }
78
79
    /**
80
     * Sets query data
81
     *
82
     * @param array $data
83
     */
84
    public function setQueryData(array $data)
85
    {
86
        $this->queryData = $data;
87
    }
88
89
    /**
90
     * Sets speed data
91
     *
92
     * @param array $data
93
     */
94
    public function setSpeedData(array $data)
95
    {
96
        $this->speedData = $data;
97
    }
98
99
    /**
100
     * Sets file data
101
     *
102
     * @param array $data
103
     */
104
    public function setFileData(array $data)
105
    {
106
        $this->fileData = $data;
107
    }
108
109
    /**
110
     * @return array
111
     */
112
    protected function getConsoleMeta()
113
    {
114
        $consoleMeta = array(
115
            'log' => 0,
116
            'memory' => 0,
117
            'error' => 0,
118
            'speed' => 0
119
        );
120
        foreach ($this->console->getLogs() as $log) {
121
            if (array_key_exists($log['type'], $consoleMeta)) {
122
                $consoleMeta[$log['type']]++;
123
            } else {
124
                $consoleMeta['error']++;
125
            }
126
        }
127
128
        return $consoleMeta;
129
    }
130
131
    /**
132
     * @return array
133
     */
134
    protected function getConsoleMessages()
135
    {
136
        $messages = array();
137
        foreach ($this->console->getLogs() as $log) {
138
            switch($log['type']) {
139
                case 'log':
140
                    $message = array(
141
                        'message' => print_r($log['data'], true),
142
                        'type'    => 'log'
143
                    );
144
                    break;
145
                case 'memory':
146
                    $message = array(
147
                        'message' => (!empty($log['data_type']) ? "{$log['data_type']}: " : '') . $log['name'],
148
                        'data'    => $this->getReadableMemory($log['data']),
149
                        'type'    => 'memory'
150
                    );
151
                    break;
152
                case 'error':
153
                    $message = array(
154
                        'message' => "Line {$log['line']}: {$log['data']} in {$log['file']}",
155
                        'type'    => 'error'
156
                    );
157
                    break;
158
                case 'speed':
159
                    $elapsedTime = $log['data'] - $this->startTime;
160
                    $message = array(
161
                        'message' => $log['name'],
162
                        'data'    => $this->getReadableTime($elapsedTime),
163
                        'type'    => 'speed'
164
                    );
165
                    break;
166
                default:
167
                    $message = array(
168
                        'message' => "Unrecognized console log type: {$log['type']}",
169
                        'type'    => 'error'
170
                    );
171
                    break;
172
            }
173
            array_push($messages, $message);
174
        }
175
        return $messages;
176
    }
177
178
    /**
179
     * @return array
180
     */
181
    protected function getSpeedMeta()
182
    {
183
        $elapsedTime = $this->getReadableTime($this->speedData['elapsed']);
184
        $allowedTime = $this->getReadableTime($this->speedData['allowed'], 0);
185
186
        return array(
187
            'elapsed' => $elapsedTime,
188
            'allowed' => $allowedTime,
189
        );
190
    }
191
192
    /**
193
     * @return array
194
     */
195
    public function getQueryMeta()
196
    {
197
        $queryCount = count($this->queryData);
198
        $queryTotalTime = array_reduce($this->queryData, function ($sum, $row) {
199
            return $sum + $row['time'];
200
        }, 0);
201
        $queryTotalTime = $this->getReadableTime($queryTotalTime);
202
        $querySlowestTime = array_reduce($this->queryData, function ($slowest, $row) {
203
            return ($slowest < $row['time']) ? $row['time'] : $slowest;
204
        }, 0);
205
        $querySlowestTime = $this->getReadableTime($querySlowestTime);
206
207
        return array(
208
            'count'   => $queryCount,
209
            'time'    => $queryTotalTime,
210
            'slowest' => $querySlowestTime
211
        );
212
    }
213
214
    /**
215
     * @return array
216
     */
217
    public function getQueryList()
218
    {
219
        $queryList = array();
220
        foreach ($this->queryData as $query) {
221
            array_push($queryList, array(
222
                'message'  => $query['sql'],
223
                'sub_data' => array_filter($query['explain']),
224
                'data'     => $this->getReadableTime($query['time'])
225
            ));
226
        }
227
        return $queryList;
228
    }
229
230
    /**
231
     * @return array
232
     */
233
    public function getMemoryMeta()
234
    {
235
        $usedMemory = $this->getReadableMemory($this->memoryData['used']);
236
        $allowedMemory = $this->memoryData['allowed']; // todo parse this, maybe?
237
238
        return array(
239
            'used'    => $usedMemory,
240
            'allowed' => $allowedMemory
241
        );
242
    }
243
244
    /**
245
     * @return array
246
     */
247
    protected function getFileMeta()
248
    {
249
        $fileCount = count($this->fileData);
250
        $fileTotalSize = array_reduce($this->fileData, function ($sum, $row) {
251
            return $sum + $row['size'];
252
        }, 0);
253
        $fileTotalSize = $this->getReadableMemory($fileTotalSize);
254
        $fileLargestSize = array_reduce($this->fileData, function ($largest, $row) {
255
            return ($largest < $row['size']) ? $row['size'] : $largest;
256
        }, 0);
257
        $fileLargestSize = $this->getReadableMemory($fileLargestSize);
258
259
        return array(
260
            'count' => $fileCount,
261
            'size' => $fileTotalSize,
262
            'largest' => $fileLargestSize
263
        );
264
    }
265
266
    /**
267
     * @return array
268
     */
269
    protected function getFileList()
270
    {
271
        $fileList = array();
272
        foreach ($this->fileData as $file) {
273
            array_push($fileList, array(
274
                'message' => $file['name'],
275
                'data'    => $this->getReadableMemory($file['size'])
276
            ));
277
        }
278
        return $fileList;
279
    }
280
281
    /**
282
     * Formatter for human-readable time
283
     * Only handles time up to 60 minutes gracefully
284
     *
285
     * @param double  $time
286
     * @param integer $percision
287
     * @return string
288
     */
289
    protected function getReadableTime($time, $percision = 3)
290
    {
291
        $unit = 's';
292
        if ($time < 1) {
293
            $time *= 1000;
294
            $unit = 'ms';
295
        } else if ($time > 60) {
296
            $time /= 60;
297
            $unit = 'm';
298
        }
299
        $time = number_format($time, $percision);
300
        return "{$time} {$unit}";
301
    }
302
303
    /**
304
     * Formatter for human-readable memory
305
     * Only handles time up to a few gigs gracefully
306
     *
307
     * @param double  $size
308
     * @param integer $percision
309
     */
310
    protected function getReadableMemory($size, $percision = 2)
311
    {
312
        $unitOptions = array('b', 'k', 'M', 'G');
313
314
        $base = log($size, 1024);
315
316
        $memory = round(pow(1024, $base - floor($base)), $percision);
317
        $unit = $unitOptions[floor($base)];
318
        return "{$memory} {$unit}";
319
    }
320
321
    /**
322
     * @param array  $messages
323
     * @param string $type
324
     * @return array
325
     */
326
    protected function filterMessages($messages, $type)
327
    {
328
        return array_filter($messages, function ($message) use ($type) {
329
            return $message['type'] == $type;
330
        });
331
    }
332
 
333
    public function __invoke()
334
    {
335
        $consoleMeta = $this->getConsoleMeta();
336
        $speedMeta = $this->getSpeedMeta();
337
        $queryMeta = $this->getQueryMeta();
338
        $memoryMeta = $this->getMemoryMeta();
339
        $fileMeta = $this->getFileMeta();
340
341
        $header = array(
0 ignored issues
show
Unused Code introduced by
$header is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
342
            'console' => array_sum($consoleMeta),
343
            'speed'   => $speedMeta['elapsed'],
344
            'query'   => $queryMeta['count'],
345
            'memory'  => $memoryMeta['used'],
346
            'files'   => $fileMeta['count']
347
        );
348
349
        $consoleMessages = $this->getConsoleMessages();
350
        $queryList = $this->getQueryList();
351
        $fileList = $this->getFileList();
352
353
        $console = array(
0 ignored issues
show
Unused Code introduced by
$console is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
354
            'meta' => $consoleMeta,
355
            'messages' => $consoleMessages
356
        );
357
358
        $speed = array(
0 ignored issues
show
Unused Code introduced by
$speed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
359
            'meta' => $speedMeta,
360
            'messages' => $this->filterMessages($consoleMessages, 'speed')
361
        );
362
363
        $query = array(
0 ignored issues
show
Unused Code introduced by
$query is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
364
            'meta' => $queryMeta,
365
            'messages' => $queryList
366
        );
367
368
        $memory = array(
0 ignored issues
show
Unused Code introduced by
$memory is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
369
            'meta' => $memoryMeta,
370
            'messages' => $this->filterMessages($consoleMessages, 'memory')
371
        );
372
373
        $files = array(
0 ignored issues
show
Unused Code introduced by
$files is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
374
            'meta' => $fileMeta,
375
            'messages' => $fileList
376
        );
377
378
        // todo is this really the best way to load these?
379
        $styles = file_get_contents(__DIR__ . "/../{$this->options['style_path']}");
0 ignored issues
show
Unused Code introduced by
$styles is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
380
        $script = file_get_contents(__DIR__ . "/../{$this->options['script_path']}");
0 ignored issues
show
Unused Code introduced by
$script is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
381
382
        require_once __DIR__ .'/../asset/display.html';
383
    }
384
}
385