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

LaravelLogViewer::pathToLogFile()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 25

Duplication

Lines 6
Ratio 24 %

Importance

Changes 0
Metric Value
cc 7
nc 8
nop 1
dl 6
loc 25
rs 8.5866
c 0
b 0
f 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
        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