Completed
Push — master ( 14a591...98a333 )
by raphael
08:22 queued 02:07
created

LaravelLogViewer   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 270
Duplicated Lines 5.19 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

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

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getFolderName() 0 4 1
A getFileName() 0 4 1
A __construct() 0 7 2
D all() 0 78 16
A getFolders() 0 19 5
A getFolderFiles() 0 4 1
B getFiles() 0 28 9
A setFolder() 8 15 5
A setFile() 0 8 2
B pathToLogFile() 6 25 7

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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(is_array($this->storage_path)){
61 View Code Duplication
            foreach ($this->storage_path as $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
                $logsPath = $value . '/' . $folder;
63
                if (app('files')->exists($logsPath)) {
64
                    $this->folder = $folder;
65
                    break;
66
                }
67
            }
68
        }
69
    }
70
71
    /**
72
     * @param string $file
73
     * @throws \Exception
74
     */
75
    public function setFile($file)
76
    {
77
        $file = $this->pathToLogFile($file);
78
79
        if (app('files')->exists($file)) {
80
            $this->file = $file;
81
        }
82
    }
83
84
    /**
85
     * @param string $file
86
     * @return string
87
     * @throws \Exception
88
     */
89
    public function pathToLogFile($file)
90
    {
91
92
        if (app('files')->exists($file)) { // try the absolute path
93
            return $file;
94
        }
95
        if (is_array($this->storage_path)) {
96 View Code Duplication
            foreach ($this->storage_path as $folder) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

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