Completed
Pull Request — master (#175)
by Elminson
01:17
created

LaravelLogViewer::getFolders()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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