Completed
Pull Request — master (#169)
by Elminson
01:09
created

LaravelLogViewer   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 270
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 49
lcom 1
cbo 2
dl 0
loc 270
rs 8.48
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A setFolder() 0 8 2
A setFile() 0 8 2
B pathToLogFile() 0 24 8
A getFolderName() 0 4 1
A getFileName() 0 4 1
C all() 0 77 16
B getFolders() 0 23 6
A getFolderFiles() 0 4 1
B getFiles() 0 32 10

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