Completed
Pull Request — master (#209)
by Zacchaeus
01:20
created

LaravelLogViewer::getFileName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
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
        if (app('files')->exists($folder)) {
58
          
59
            $this->folder = $folder;
60
        }
61
        else if(is_array($this->storage_path)) {
62
           
63 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...
64
                $logsPath = $value . '/' . $folder;
65
                if (app('files')->exists($logsPath)) {
66
                    $this->folder = $folder;
67
                    break;
68
                }
69
            }
70
        } else {
71
            
72
                $logsPath = $this->storage_path . '/' . $folder;
73
                if (app('files')->exists($logsPath)) {
74
                    $this->folder = $folder;
75
                }
76
        
77
        }
78
    }
79
80
    /**
81
     * @param string $file
82
     * @throws \Exception
83
     */
84
    public function setFile($file)
85
    {
86
        $file = $this->pathToLogFile($file);
87
88
        if (app('files')->exists($file)) {
89
            $this->file = $file;
90
        }
91
    }
92
93
    /**
94
     * @param string $file
95
     * @return string
96
     * @throws \Exception
97
     */
98
    public function pathToLogFile($file)
99
    {
100
101
        if (app('files')->exists($file)) { // try the absolute path
102
      
103
            return $file;
104
        }
105
        if (is_array($this->storage_path)) {
106
     
107 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...
108
                if (app('files')->exists($folder . '/' . $file)) { // try the absolute path
109
                    $file = $folder . '/' . $file;
110
                    break;
111
                }
112
            }
113
            return $file;
114
        }
115
116
        $logsPath = $this->storage_path;
117
        $logsPath .= ($this->folder) ? '/' . $this->folder : '';
118
        $file = $logsPath . '/' . $file;
119
        // check if requested file is really in the logs directory
120
        if (dirname($file) !== $logsPath) {
121
            throw new \Exception('No such log file: '.$file);
122
        }
123
        
124
        return $file;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getFolderName()
131
    {
132
        return $this->folder;
133
    }
134
135
    /**
136
     * @return string
137
     */
138
    public function getFileName()
139
    {
140
        return basename($this->file);
141
    }
142
143
    /**
144
     * @return array
145
     */
146
    public function all()
147
    {
148
        $log = array();
149
150
        if (!$this->file) {
151
            $log_file = (!$this->folder) ? $this->getFiles() : $this->getFolderFiles();
152
            if (!count($log_file)) {
153
                return [];
154
            }
155
            $this->file = $log_file[0];
156
        }
157
158
        $max_file_size = function_exists('config') ? config('logviewer.max_file_size', self::MAX_FILE_SIZE) : self::MAX_FILE_SIZE;
159
        if (app('files')->size($this->file) > $max_file_size) {
160
            return null;
161
        }
162
163
        if (!is_readable($this->file)) {
164
            return [[
165
                'context' => '',
166
                'level' => '',
167
                'date' => null,
168
                'text' => 'Log file "' . $this->file . '" not readable',
169
                'stack' => '',
170
            ]];
171
        }
172
173
        $file = app('files')->get($this->file);
174
175
        preg_match_all($this->pattern->getPattern('logs'), $file, $headings);
176
177
        if (!is_array($headings)) {
178
            return $log;
179
        }
180
181
        $log_data = preg_split($this->pattern->getPattern('logs'), $file);
182
183
        if ($log_data[0] < 1) {
184
            array_shift($log_data);
185
        }
186
187
        foreach ($headings as $h) {
188
            for ($i = 0, $j = count($h); $i < $j; $i++) {
189
                foreach ($this->level->all() as $level) {
190
                    if (strpos(strtolower($h[$i]), '.' . $level) || strpos(strtolower($h[$i]), $level . ':')) {
191
192
                        preg_match($this->pattern->getPattern('current_log', 0) . $level . $this->pattern->getPattern('current_log', 1), $h[$i], $current);
193
                        if (!isset($current[4])) {
194
                            continue;
195
                        }
196
197
                        $log[] = array(
198
                            'context' => $current[3],
199
                            'level' => $level,
200
                            'folder' => $this->folder,
201
                            'level_class' => $this->level->cssClass($level),
202
                            'level_img' => $this->level->img($level),
203
                            'date' => $current[1],
204
                            'text' => $current[4],
205
                            'in_file' => isset($current[5]) ? $current[5] : null,
206
                            'stack' => preg_replace("/^\n*/", '', $log_data[$i])
207
                        );
208
                    }
209
                }
210
            }
211
        }
212
213
        if (empty($log)) {
214
215
            $lines = explode(PHP_EOL, $file);
216
            $log = [];
217
218
            foreach ($lines as $key => $line) {
219
                $log[] = [
220
                    'context' => '',
221
                    'level' => '',
222
                    'folder' => '',
223
                    'level_class' => '',
224
                    'level_img' => '',
225
                    'date' => $key + 1,
226
                    'text' => $line,
227
                    'in_file' => null,
228
                    'stack' => '',
229
                ];
230
            }
231
        }
232
233
        return array_reverse($log);
234
    }
235
236
    /**Creates a multidimensional array
237
	 * of subdirectories and files
238
	 *
239
	 * @param null $path
240
	 *
241
	 * @return array
242
	 */
243
    public function foldersAndFiles($path = null)
244
    {
245
	    $contents = array();
246
	    $dir = $path ? $path : $this->storage_path;
247
	    foreach (scandir($dir) as $node) {
248
		    if ($node == '.' || $node == '..') continue;
249
		    $path = $dir . '\\' . $node;
250
		    if (is_dir($path)) {
251
			    $contents[$path] = $this->foldersAndFiles($path);
252
		    } else {
253
			    $contents[] = $path;
254
		    }
255
	    }
256
257
	    return $contents;
258
    }
259
260
   /**Returns an array of
261
	 * all subdirectories of specified directory
262
	 *
263
	 * @param string $folder
264
	 *
265
	 * @return array
266
	 */
267
    public function getFolders($folder = '')
268
    {
269
	    $folders = [];
270
	    $listObject = new \RecursiveIteratorIterator(
271
		    new \RecursiveDirectoryIterator($this->storage_path.'/'.$folder, \RecursiveDirectoryIterator::SKIP_DOTS),
272
		    \RecursiveIteratorIterator::CHILD_FIRST
273
	    );
274
	    foreach ($listObject as $fileinfo) {
275
		    if($fileinfo->isDir()) $folders[] = $fileinfo->getRealPath();
276
	    }
277
	    return $folders;
278
    }
279
280
281
    /**
282
     * @param bool $basename
283
     * @return array
284
     */
285
    public function getFolderFiles($basename = false)
286
    {
287
        return $this->getFiles($basename, $this->folder);
288
    }
289
290
    /**
291
     * @param bool $basename
292
     * @param string $folder
293
     * @return array
294
     */
295
    public function getFiles($basename = false, $folder = '')
296
    {
297
        $files = [];
298
	    $pattern = function_exists('config') ? config('logviewer.pattern', '*.log') : '*.log';
299
	    $fullPath = $this->storage_path.'/'.$folder;
300
301
	    $listObject = new \RecursiveIteratorIterator(
302
		    new \RecursiveDirectoryIterator($fullPath, \RecursiveDirectoryIterator::SKIP_DOTS),
303
		    \RecursiveIteratorIterator::CHILD_FIRST
304
	    );
305
306
	    foreach ($listObject as $fileinfo) {
307
		    if(!$fileinfo->isDir() && strtolower(pathinfo($fileinfo->getRealPath(), PATHINFO_EXTENSION)) == explode('.', $pattern)[1])
308
			    $files[] = $basename ? basename($fileinfo->getRealPath()) : $fileinfo->getRealPath();
309
	    }
310
	    return $files;
311
312
    }
313
314
    /**
315
	 * @return string
316
	 */
317
    public function getStoragePath()
318
    {
319
    	return $this->storage_path;
320
    }
321
322
	/**
323
	 * @param $path
324
	 *
325
	 * @return void
326
	 */
327
	public function setStoragePath($path)
328
	{
329
		$this->storage_path = $path;
330
	}
331
332
    public static function directoryTreeStructure($storage_path, array $array)
333
    {
334
	    foreach ($array as $k => $v) {
335
		    if(is_dir( $k )) {
336
337
			    $exploded = explode( "\\", $k );
338
			    $show = last( $exploded );
339
340
			    echo '<div class="list-group folder">
341
				    <a href="?f='. \Illuminate\Support\Facades\Crypt::encrypt($k).'">
342
					    <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
343
						    class="fa fa-folder"></span> '.$show.'
344
				    </a>
345
			    </div>';
346
347
			    if ( is_array( $v ) ) {
348
				    self::directoryTreeStructure( $storage_path, $v );
349
			    }
350
351
		    }
352
		    else {
353
354
			    $exploded = explode( "\\", $v );
355
			    $show2 = last( $exploded );
356
			    $folder = str_replace( $storage_path, "", rtrim( str_replace( $show2, "", $v ), "\\" ) );
357
			    $file = $v;
358
359
360
			   echo '<div class="list-group">
361
				    <a href="?l='.\Illuminate\Support\Facades\Crypt::encrypt($file).'&f='.\Illuminate\Support\Facades\Crypt::encrypt($folder).'">
362
					    <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span
363
						    class="fa fa-file"></span> '.$show2.'
364
				    </a>
365
			    </div>';
366
367
		    }
368
	    }
369
370
        return;
371
    }
372
373
374
}
375