Completed
Pull Request — master (#161)
by
unknown
01:06
created

LaravelLogViewer   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 266
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 46
lcom 1
cbo 2
dl 0
loc 266
rs 8.72
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A setFolder() 0 8 2
A setFile() 0 8 2
A pathToLogFile() 0 18 4
A getFolderName() 0 4 1
A getFileName() 0 4 1
A setFileAll() 0 10 4
C all() 0 65 12
B getArrayLog() 0 18 8
A getFolders() 0 10 3
A getFolderFiles() 0 4 1
A getFiles() 0 16 6

How to fix   Complexity   

Complex Class

Complex classes like LaravelLogViewer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LaravelLogViewer, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Rap2hpoutre\LaravelLogViewer;
4
5
/**
6
 * Class LaravelLogViewer
7
 * @package Rap2hpoutre\LaravelLogViewer
8
 */
9
class LaravelLogViewer
10
{
11
    /**
12
     * @var string file
13
     */
14
    private $file;
15
16
    /**
17
     * @var string folder
18
     */
19
    private $folder;
20
21
    /**
22
     * @var string storage_path
23
     */
24
    private $storage_path;
25
26
    /**
27
     * Why? Uh... Sorry
28
     */
29
    const MAX_FILE_SIZE = 52428800;
30
31
    /**
32
     * @var Level level
33
     */
34
    private $level;
35
36
    /**
37
     * @var Log Data log_data
38
     */
39
    private $log_data;
40
41
    /**
42
     * @var Pattern pattern
43
     */
44
    private $pattern;
45
46
    /**
47
     * LaravelLogViewer constructor.
48
     */
49
    public function __construct()
50
    {
51
        $this->level = new Level();
52
        $this->pattern = new Pattern();
53
        $this->storage_path = function_exists('config') ? config('logviewer.storage_path',
54
            storage_path('logs')) : storage_path('logs');
55
56
    }
57
58
    /**
59
     * @param string $folder
60
     */
61
    public function setFolder($folder)
62
    {
63
        $logsPath = $this->storage_path . '/' . $folder;
64
65
        if (app('files')->exists($logsPath)) {
66
            $this->folder = $folder;
67
        }
68
    }
69
70
    /**
71
     * @param string $file
72
     * @throws \Exception
73
     */
74
    public function setFile($file)
75
    {
76
        $file = $this->pathToLogFile($file);
77
78
        if (app('files')->exists($file)) {
79
            $this->file = $file;
80
        }
81
    }
82
83
    /**
84
     * @param string $file
85
     * @return string
86
     * @throws \Exception
87
     */
88
    public function pathToLogFile($file)
89
    {
90
        $logsPath = $this->storage_path;
91
        $logsPath .= ($this->folder) ? '/' . $this->folder : '';
92
93
        if (app('files')->exists($file)) { // try the absolute path
94
            return $file;
95
        }
96
97
        $file = $logsPath . '/' . $file;
98
99
        // check if requested file is really in the logs directory
100
        if (dirname($file) !== $logsPath) {
101
            throw new \Exception('No such log file');
102
        }
103
104
        return $file;
105
    }
106
107
    /**
108
     * @return string
109
     */
110
    public function getFolderName()
111
    {
112
        return $this->folder;
113
    }
114
115
    /**
116
     * @return string
117
     */
118
    public function getFileName()
119
    {
120
        return basename($this->file);
121
    }
122
123
    /**
124
     * @return array
125
     */
126
    protected function setFileAll()
127
    {
128
        if (!$this->file) {
129
            $log_file = (!$this->folder) ? $this->getFiles() : $this->getFolderFiles();
130
            if (!count($log_file)) {
131
                return [];
132
            }
133
            $this->file = $log_file[0];
134
        }
135
    }
136
137
    /**
138
     * @return array
139
     */
140
    public function all()
141
    {
142
        $log = array();
143
144
        //make sure $file is set
145
        $this->setFileAll();
146
147
        if (app('files')->size($this->file) > self::MAX_FILE_SIZE) {
148
            return null;
149
        }
150
151
        $file = app('files')->get($this->file);
152
153
        preg_match_all($this->pattern->getPattern('logs'), $file, $headings);
154
155
        if (!is_array($headings)) {
156
            return $log;
157
        }
158
159
        $this->log_data = preg_split($this->pattern->getPattern('logs'), $file);
0 ignored issues
show
Documentation Bug introduced by
It seems like preg_split($this->patter...Pattern('logs'), $file) of type array is incompatible with the declared type object<Rap2hpoutre\LaravelLogViewer\Log> of property $log_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
160
161
        if ($this->log_data[0] < 1) {
162
            array_shift($this->log_data);
163
        }
164
165
        foreach ($headings as $h) {
166
            for ($i = 0, $j = count($h); $i < $j; $i++) {
167
                foreach ($this->level->all() as $key => $level) {
168
                    if (strpos(strtolower($h[$i]), '.' . $level) || strpos(strtolower($h[$i]), $level . ':')) {
169
170
                        preg_match($this->pattern->getPattern('current_log',
171
                                0) . $level . $this->pattern->getPattern('current_log', 1), $h[$i], $current);
172
                        if (!isset($current[4])) {
173
                            continue;
174
                        }
175
                        $log[] = $this->getArrayLog([
176
                            'index' => $i,
177
                            'current' => $current,
178
                            'level' => $level,
179
                            'key' => $key,
180
                            'line' => ''
181
                        ]);
182
                    }
183
                }
184
            }
185
        }
186
187
        if (empty($log)) {
188
189
            $lines = explode(PHP_EOL, $file);
190
            $log = [];
191
192
            foreach ($lines as $key => $line) {
193
                $log[] = $this->getArrayLog([
194
                    'index' => '',
195
                    'current' => [],
196
                    'level' => '',
197
                    'key' => $key,
198
                    'line' => $line
199
                ]);
200
            }
201
        }
202
203
        return array_reverse($log);
204
    }
205
206
    /**
207
     * Create array data from log
208
     * @param $data
209
     * @return array
210
     */
211
    protected function getArrayLog($data)
212
    {
213
        $index = $data['index'];
214
        $current = $data['current'];
215
        $level = $data['level'];
216
        $key = $data['key'];
217
        $line = $data['line'];
218
        return array(
219
            'context' => isset($current[3]) ? $current[3] : '',
220
            'level' => isset($level) ? $level : '',
221
            'level_class' => isset($level) ? $this->level->cssClass($level) : '',
222
            'level_img' => isset($level) ? $this->level->img($level) : '',
223
            'date' => isset($current[1]) ? $current[1] : $key + 1,
224
            'text' => isset($current[4]) ? $current[4] : $line,
225
            'in_file' => isset($current[5]) ? $current[5] : null,
226
            'stack' => preg_replace("/^\n*/", '', $this->log_data[$index])
227
        );
228
    }
229
230
    /**
231
     * @return array
232
     */
233
    public function getFolders()
234
    {
235
        $folders = glob($this->storage_path . '/*', GLOB_ONLYDIR);
236
        if (is_array($folders)) {
237
            foreach ($folders as $k => $folder) {
238
                $folders[$k] = basename($folder);
239
            }
240
        }
241
        return array_values($folders);
242
    }
243
244
    /**
245
     * @param bool $basename
246
     * @return array
247
     */
248
    public function getFolderFiles($basename = false)
249
    {
250
        return $this->getFiles($basename, $this->folder);
251
    }
252
253
    /**
254
     * @param bool $basename
255
     * @param string $folder
256
     * @return array
257
     */
258
    public function getFiles($basename = false, $folder = '')
259
    {
260
        $pattern = function_exists('config') ? config('logviewer.pattern', '*.log') : '*.log';
261
        $files = glob(
262
            $this->storage_path . '/' . $folder . '/' . $pattern,
263
            preg_match($this->pattern->getPattern('files'), $pattern) ? GLOB_BRACE : 0
264
        );
265
        $files = array_reverse($files);
266
        $files = array_filter($files, 'is_file');
267
        if ($basename && is_array($files)) {
268
            foreach ($files as $k => $file) {
269
                $files[$k] = basename($file);
270
            }
271
        }
272
        return array_values($files);
273
    }
274
}
275