Completed
Pull Request — master (#237)
by
unknown
01:09
created

LogViewerController::redirect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Rap2hpoutre\LaravelLogViewer;
4
5
use Illuminate\Support\Facades\Crypt;
6
7
if (class_exists("\\Illuminate\\Routing\\Controller")) {	
8
    class BaseController extends \Illuminate\Routing\Controller {}	
9
} elseif (class_exists("Laravel\\Lumen\\Routing\\Controller")) {	
10
    class BaseController extends \Laravel\Lumen\Routing\Controller {}	
0 ignored issues
show
Comprehensibility Best Practice introduced by
The type Rap2hpoutre\LaravelLogViewer\BaseController has been defined more than once; this definition is ignored, only the first definition in this file (L8-8) is considered.

This check looks for classes that have been defined more than once in the same file.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
11
}
12
13
/**
14
 * Class LogViewerController
15
 * @package Rap2hpoutre\LaravelLogViewer
16
 */
17
class LogViewerController extends BaseController
18
{
19
    /**
20
     * @var \Illuminate\Http\Request
21
     */
22
    protected $request;
23
24
    /**
25
     * @var LaravelLogViewer
26
     */
27
    private $log_viewer;
28
29
    /**
30
     * @var Level
31
     */
32
    private $log_level;
33
34
    /**
35
     * @var string
36
     */
37
    protected $view_log = 'laravel-log-viewer::log';
38
39
    /**
40
     * LogViewerController constructor.
41
     */
42
    public function __construct()
43
    {
44
        $this->log_viewer = new LaravelLogViewer();
45
        $this->log_level = new Level();
46
        $this->request = app('request');
47
    }
48
49
    public function filterByLevel(array $logs, string $filter)
50
    {
51
        $c = count($logs);
52
        for ($i = 0; $i < $c; $i++) {
53
            if ($logs[$i]['level'] === $filter) {
54
                continue;
55
            }
56
57
            unset($logs[$i]);
58
        }
59
60
        return $logs;
61
    }
62
63
    /**
64
     * @return array|mixed
65
     * @throws \Exception
66
     */
67
    public function index()
68
    {
69
        $logs = $this->log_viewer->all();
70
        $levels_counts = $this->log_level->getLevelsCounts($logs);
71
        $folderFiles = [];
72
73
        if ($this->request->input('f')) {
74
            $this->log_viewer->setFolder(Crypt::decrypt($this->request->input('f')));
0 ignored issues
show
Bug introduced by
It seems like $this->request->input('f') targeting Illuminate\Http\Concerns...ractsWithInput::input() can also be of type array; however, Illuminate\Support\Facades\Crypt::decrypt() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
75
            $folderFiles = $this->log_viewer->getFolderFiles(true);
76
        }
77
        if ($this->request->input('l')) {
78
            $this->log_viewer->setFile(Crypt::decrypt($this->request->input('l')));
0 ignored issues
show
Bug introduced by
It seems like $this->request->input('l') targeting Illuminate\Http\Concerns...ractsWithInput::input() can also be of type array; however, Illuminate\Support\Facades\Crypt::decrypt() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
79
        }
80
        if ($filter = $this->request->input('filter')) {
81
            if (array_key_exists('level', $filter)) {
82
                $logs = $this->filterByLevel($logs, $filter['level']);
0 ignored issues
show
Bug introduced by
It seems like $logs can also be of type null; however, Rap2hpoutre\LaravelLogVi...roller::filterByLevel() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
83
            }
84
        }
85
86
        if ($early_return = $this->earlyReturn()) {
87
            return $early_return;
88
        }
89
90
        $data = [
91
            'logs' => $logs,
92
            'folders' => $this->log_viewer->getFolders(),
93
            'current_folder' => $this->log_viewer->getFolderName(),
94
            'folder_files' => $folderFiles,
95
            'files' => $this->log_viewer->getFiles(true),
96
            'current_file' => $this->log_viewer->getFileName(),
97
            'standardFormat' => true,
98
            'levels_classes' => $this->log_level->getLevelsClasses(),
99
            'levels_counts' => $levels_counts
100
        ];
101
102
        if ($this->request->wantsJson()) {
103
            return $data;
104
        }
105
106
        if (is_array($data['logs']) && count($data['logs']) > 0) {
107
            $firstLog = reset($data['logs']);
108
            if (!$firstLog['context'] && !$firstLog['level']) {
109
                $data['standardFormat'] = false;
110
            }
111
        }
112
113
        return app('view')->make($this->view_log, $data);
114
    }
115
116
    /**
117
     * @return bool|mixed
118
     * @throws \Exception
119
     */
120
    private function earlyReturn()
121
    {
122
        if ($this->request->input('f')) {
123
            $this->log_viewer->setFolder(Crypt::decrypt($this->request->input('f')));
0 ignored issues
show
Bug introduced by
It seems like $this->request->input('f') targeting Illuminate\Http\Concerns...ractsWithInput::input() can also be of type array; however, Illuminate\Support\Facades\Crypt::decrypt() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
124
        }
125
126
        if ($this->request->input('dl')) {
127
            return $this->download($this->pathFromInput('dl'));
128
        } elseif ($this->request->has('clean')) {
129
            app('files')->put($this->pathFromInput('clean'), '');
130
            return $this->redirect($this->request->headers->get('referer'));
131
        } elseif ($this->request->has('del')) {
132
            app('files')->delete($this->pathFromInput('del'));
133
            return $this->redirect($this->request->url());
134
        } elseif ($this->request->has('delall')) {
135
            $files = ($this->log_viewer->getFolderName())
136
                        ? $this->log_viewer->getFolderFiles(true)
137
                        : $this->log_viewer->getFiles(true);
138
            foreach ($files as $file) {
139
                app('files')->delete($this->log_viewer->pathToLogFile($file));
140
            }
141
            return $this->redirect($this->request->url());
142
        }
143
        return false;
144
    }
145
146
    /**
147
     * @param string $input_string
148
     * @return string
149
     * @throws \Exception
150
     */
151
    private function pathFromInput($input_string)
152
    {
153
        return $this->log_viewer->pathToLogFile(Crypt::decrypt($this->request->input($input_string)));
0 ignored issues
show
Bug introduced by
It seems like $this->request->input($input_string) targeting Illuminate\Http\Concerns...ractsWithInput::input() can also be of type array or null; however, Illuminate\Support\Facades\Crypt::decrypt() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
154
    }
155
156
    /**
157
     * @param $to
158
     * @return mixed
159
     */
160
    private function redirect($to)
161
    {
162
        if (function_exists('redirect')) {
163
            return redirect($to);
164
        }
165
166
        return app('redirect')->to($to);
167
    }
168
169
    /**
170
     * @param string $data
171
     * @return mixed
172
     */
173
    private function download($data)
174
    {
175
        if (function_exists('response')) {
176
            return response()->download($data);
0 ignored issues
show
Bug introduced by
The method download does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
177
        }
178
179
        // For laravel 4.2
180
        return app('\Illuminate\Support\Facades\Response')->download($data);
181
    }
182
}
183