Completed
Pull Request — master (#189)
by Elminson
01:13
created

LaravelLogViewer   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 287
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 50
lcom 1
cbo 2
dl 0
loc 287
rs 8.4
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
A setFolder() 0 12 4
A setFile() 0 8 2
B pathToLogFile() 0 25 7
A getFolderName() 0 4 1
A getFileName() 0 4 1
D all() 0 78 16
A getFolders() 0 21 5
A getFolderFiles() 0 4 1
B getFiles() 0 30 9
A getFilesWithPath() 0 12 2

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 Pattern pattern
38
     */
39
    private $pattern;
40
41
    /**
42
     * LaravelLogViewer constructor.
43
     */
44
    public function __construct()
45
    {
46
        $this->level = new Level();
47
        $this->pattern = new Pattern();
48
        $this->storage_path = function_exists('config') ? config('logviewer.storage_path', storage_path('logs')) : storage_path('logs');
49
50
    }
51
52
    /**
53
     * @param string $folder
54
     */
55
    public function setFolder($folder)
56
    {
57
        if (app('files')->exists($folder)) {
58
            $this->folder = $folder;
59
        }
60
        if ($this->storage_path) {
61
            $logsPath = $this->storage_path . '/' . $folder;
62
            if (app('files')->exists($logsPath)) {
63
                $this->folder = $folder;
64
            }
65
        }
66
    }
67
68
    /**
69
     * @param string $file
70
     * @throws \Exception
71
     */
72
    public function setFile($file)
73
    {
74
        $file = $this->pathToLogFile($file);
75
76
        if (app('files')->exists($file)) {
77
            $this->file = $file;
78
        }
79
    }
80
81
    /**
82
     * @param string $file
83
     * @return string
84
     * @throws \Exception
85
     */
86
    public function pathToLogFile($file)
87
    {
88
89
        if (app('files')->exists($file)) { // try the absolute path
90
            return $file;
91
        }
92
        if (is_array($this->storage_path)) {
93
            foreach ($this->storage_path as $folder) {
94
                if (app('files')->exists($folder . '/' . $file)) { // try the absolute path
95
                    $file = $folder . '/' . $file;
96
                    break;
97
                }
98
            }
99
            return $file;
100
        }
101
102
        $logsPath = $this->storage_path;
103
        $logsPath .= ($this->folder) ? '/' . $this->folder : '';
104
        $file = $logsPath . '/' . $file;
105
        // check if requested file is really in the logs directory
106
        if (dirname($file) !== $logsPath) {
107
            throw new \Exception('No such log file');
108
        }
109
        return $file;
110
    }
111
112
    /**
113
     * @return string
114
     */
115
    public function getFolderName()
116
    {
117
        return $this->folder;
118
    }
119
120
    /**
121
     * @return string
122
     */
123
    public function getFileName()
124
    {
125
        return basename($this->file);
126
    }
127
128
    /**
129
     * @return array
130
     */
131
    public function all()
132
    {
133
        $log = array();
134
135
        if (!$this->file) {
136
            $log_file = (!$this->folder) ? $this->getFiles() : $this->getFolderFiles();
137
            if (!count($log_file)) {
138
                return [];
139
            }
140
            $this->file = $log_file[0];
141
        }
142
143
        if (app('files')->size($this->file) > self::MAX_FILE_SIZE) {
144
            return null;
145
        }
146
147
        $file = app('files')->get($this->file);
148
149
        preg_match_all($this->pattern->getPattern('logs'), $file, $headings);
150
151
        if (!is_array($headings)) {
152
            return $log;
153
        }
154
155
        $log_data = preg_split($this->pattern->getPattern('logs'), $file);
156
157
        if ($log_data[0] < 1) {
158
            array_shift($log_data);
159
        }
160
161
        foreach ($headings as $h) {
162
            for ($i = 0, $j = count($h); $i < $j; $i++) {
163
                foreach ($this->level->all() as $level) {
164
                    if (strpos(strtolower($h[$i]), '.' . $level) || strpos(strtolower($h[$i]), $level . ':')) {
165
166
                        preg_match($this->pattern->getPattern('current_log', 0) . $level . $this->pattern->getPattern('current_log', 1), $h[$i], $current);
167
                        if (!isset($current[4])) {
168
                            continue;
169
                        }
170
171
                        $log[] = array(
172
                            'context' => $current[3],
173
                            'level' => $level,
174
                            'folder' => $this->folder,
175
                            'level_class' => $this->level->cssClass($level),
176
                            'level_img' => $this->level->img($level),
177
                            'date' => $current[1],
178
                            'text' => $current[4],
179
                            'in_file' => isset($current[5]) ? $current[5] : null,
180
                            'stack' => preg_replace("/^\n*/", '', $log_data[$i])
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[] = [
194
                    'context' => '',
195
                    'level' => '',
196
                    'folder' => '',
197
                    'level_class' => '',
198
                    'level_img' => '',
199
                    'date' => $key + 1,
200
                    'text' => $line,
201
                    'in_file' => null,
202
                    'stack' => '',
203
                ];
204
            }
205
        }
206
207
        return array_reverse($log);
208
    }
209
210
    /**
211
     * @return array
212
     */
213
    public function getFolders()
214
    {
215
        $folders = [];
216
        if (is_array($this->storage_path)) {
217
            foreach ($this->storage_path as $value) {
218
                $folders = array_merge(
219
                    $folders,
220
                    glob($value . '/*', GLOB_ONLYDIR)
221
                );
222
            }
223
        } else {
224
            $folders = glob($this->storage_path . '/*', GLOB_ONLYDIR);
225
        }
226
227
        if (is_array($folders)) {
228
            foreach ($folders as $k => $folder) {
229
                $folders[$k] = basename($folder);
230
            }
231
        }
232
        return array_values($folders);
233
    }
234
235
    /**
236
     * @param bool $basename
237
     * @return array
238
     */
239
    public function getFolderFiles($basename = false)
240
    {
241
        return $this->getFiles($basename, $this->folder);
242
    }
243
244
    /**
245
     * @param bool $basename
246
     * @param string $folder
247
     * @return array
248
     */
249
    public function getFiles($basename = false, $folder = '')
250
    {
251
        $pattern = function_exists('config') ? config('logviewer.pattern', '*.log') : '*.log';
252
        $files = [];
253
        if (is_array($this->storage_path)) {
254
            foreach ($this->storage_path as $value) {
255
                $files = array_merge(
256
                  $files,
257
                  glob(
258
                      $value . '/' . $folder . '/' . $pattern,
259
                      preg_match($this->pattern->getPattern('files'), $pattern) ? GLOB_BRACE : 0
260
                  )
261
                );
262
            }
263
        } else {
264
            $files = glob(
265
              $this->storage_path . '/' . $folder . '/' . $pattern,
266
              preg_match($this->pattern->getPattern('files'), $pattern) ? GLOB_BRACE : 0
267
            );
268
        }
269
270
        $files = array_reverse($files);
271
        $files = array_filter($files, 'is_file');
272
        if ($basename && is_array($files)) {
273
            foreach ($files as $k => $file) {
274
                $files[$k] = basename($file);
275
            }
276
        }
277
        return array_values($files);
278
    }
279
280
    /**
281
     * @throws \Exception
282
     */
283
    public function getFilesWithPath()
284
    {
285
        $files = $this->getFiles(true);
286
        $filesWithPath = [];
287
        foreach ($files as $file){
288
            $path = $this->pathToLogFile($file);
289
            $filesWithPath['fullpath'][] = $path;
290
            $filesWithPath['path'][] = dirname($path);
291
            $filesWithPath['file'][] = $file;
292
        }
293
        return $filesWithPath;
294
    }
295
}
296