Completed
Push — master ( c2e5a8...e52489 )
by raphael
03:33
created

LaravelLogViewer::all()   C

Complexity

Conditions 13
Paths 33

Size

Total Lines 53
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 12
Bugs 0 Features 0
Metric Value
cc 13
eloc 31
c 12
b 0
f 0
nc 33
nop 0
dl 0
loc 53
rs 6.3327

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
namespace Rap2hpoutre\LaravelLogViewer;
3
4
use Psr\Log\LogLevel;
5
6
/**
7
 * Class LaravelLogViewer
8
 * @package Rap2hpoutre\LaravelLogViewer
9
 */
10
class LaravelLogViewer
11
{
12
    /**
13
     * @var string file
14
     */
15
    private static $file;
16
17
    private static $levels_classes = [
18
        'debug' => 'info',
19
        'info' => 'info',
20
        'notice' => 'info',
21
        'warning' => 'warning',
22
        'error' => 'danger',
23
        'critical' => 'danger',
24
        'alert' => 'danger',
25
        'emergency' => 'danger',
26
        'processed' => 'info',
27
    ];
28
29
    private static $levels_imgs = [
30
        'debug' => 'info-circle',
31
        'info' => 'info-circle',
32
        'notice' => 'info-circle',
33
        'warning' => 'exclamation-triangle',
34
        'error' => 'exclamation-triangle',
35
        'critical' => 'exclamation-triangle',
36
        'alert' => 'exclamation-triangle',
37
        'emergency' => 'exclamation-triangle',
38
        'processed' => 'info-circle'
39
    ];
40
41
    /**
42
     * Log levels that are used
43
     * @var array
44
     */
45
    private static $log_levels = [
46
        'emergency',
47
        'alert',
48
        'critical',
49
        'error',
50
        'warning',
51
        'notice',
52
        'info',
53
        'debug',
54
        'processed'
55
    ];
56
57
    const MAX_FILE_SIZE = 52428800; // Why? Uh... Sorry
58
59
    /**
60
     * @param string $file
61
     */
62
    public static function setFile($file)
63
    {
64
        $file = self::pathToLogFile($file);
65
66
        if (app('files')->exists($file)) {
67
            self::$file = $file;
68
        }
69
    }
70
71
    /**
72
     * @param string $file
73
     * @return string
74
     * @throws \Exception
75
     */
76
    public static function pathToLogFile($file)
77
    {
78
        $logsPath = storage_path('logs');
79
80
        if (app('files')->exists($file)) { // try the absolute path
81
            return $file;
82
        }
83
84
        $file = $logsPath . '/' . $file;
85
86
        // check if requested file is really in the logs directory
87
        if (dirname($file) !== $logsPath) {
88
            throw new \Exception('No such log file');
89
        }
90
91
        return $file;
92
    }
93
94
    /**
95
     * @return string
96
     */
97
    public static function getFileName()
98
    {
99
        return basename(self::$file);
100
    }
101
102
    /**
103
     * @return array
104
     */
105
    public static function all()
106
    {
107
        $log = array();
108
109
        $pattern = '/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}([\+-]\d{4})?\].*/';
110
111
        if (!self::$file) {
112
            $log_file = self::getFiles();
113
            if(!count($log_file)) {
114
                return [];
115
            }
116
            self::$file = $log_file[0];
117
        }
118
119
        if (app('files')->size(self::$file) > self::MAX_FILE_SIZE) return null;
120
121
        $file = app('files')->get(self::$file);
122
123
        preg_match_all($pattern, $file, $headings);
124
125
        if (!is_array($headings)) return $log;
126
127
        $log_data = preg_split($pattern, $file);
128
129
        if ($log_data[0] < 1) {
130
            array_shift($log_data);
131
        }
132
133
        foreach ($headings as $h) {
134
            for ($i=0, $j = count($h); $i < $j; $i++) {
135
                foreach (self::$log_levels as $level) {
136
                    if (strpos(strtolower($h[$i]), '.' . $level) || strpos(strtolower($h[$i]), $level . ':')) {
137
138
                        preg_match('/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}([\+-]\d{4})?)\](?:.*?(\w+)\.|.*?)' . $level . ': (.*?)( in .*?:[0-9]+)?$/i', $h[$i], $current);
139
                        if (!isset($current[4])) continue;
140
141
                        $log[] = array(
142
                            'context' => $current[3],
143
                            'level' => $level,
144
                            'level_class' => self::$levels_classes[$level],
145
                            'level_img' => self::$levels_imgs[$level],
146
                            'date' => $current[1],
147
                            'text' => $current[4],
148
                            'in_file' => isset($current[5]) ? $current[5] : null,
149
                            'stack' => preg_replace("/^\n*/", '', $log_data[$i])
150
                        );
151
                    }
152
                }
153
            }
154
        }
155
156
        return array_reverse($log);
157
    }
158
159
    /**
160
     * @param bool $basename
161
     * @return array
162
     */
163
    public static function getFiles($basename = false)
164
    {
165
        $files = glob(storage_path() . '/logs/' . config('logviewer.pattern'));
166
        $files = array_reverse($files);
167
        $files = array_filter($files, 'is_file');
168
        if ($basename && is_array($files)) {
169
            foreach ($files as $k => $file) {
170
                $files[$k] = basename($file);
171
            }
172
        }
173
        return array_values($files);
174
    }
175
}
176