Completed
Push — master ( f6acf9...2f9c1b )
by raphael
01:08
created

LaravelLogViewer::setFolder()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 22

Duplication

Lines 8
Ratio 36.36 %

Importance

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