Completed
Push — master ( 0d6573...bd21d3 )
by Fumio
07:02
created

sources/Commands/TailCommand.php (4 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace LaravelPlus\Extension\Commands;
4
5
use Illuminate\Console\Command;
6
use Symfony\Component\Process\Process;
7
use Carbon\Carbon;
8
9
class TailCommand extends Command
10
{
11
    /**
12
     * The console command signature.
13
     *
14
     * @var string
15
     */
16
    protected $signature = 'tail
17
        {connection? : The name of remote.}
18
        {--path= : The fully qualified path to the log file.}
19
        {--lines=20 : The number of lines to tail.}
20
    ';
21
22
    /**
23
     * The console command description.
24
     *
25
     * @var string
26
     */
27
    protected $description = '[+] Tail a log file';
28
29
    /**
30
     * Execute the console command.
31
     */
32 5
    public function handle()
33
    {
34
        // syslog not support
35 5
        if ($this->laravel['config']['app.log'] === 'syslog') {
36 1
            $this->error('syslog not support.');
37
38 1
            return;
39
        }
40
41 4
        $connection = $this->argument('connection');
42
43
        // on Local
44 4
        if (is_null($connection)) {
45 2
            $path = $this->option('path') ?: $this->getLocalPath();
46
47 2
            if ($path) {
48 1
                $this->tailLocalLogs($path);
0 ignored issues
show
It seems like $path defined by $this->option('path') ?: $this->getLocalPath() on line 45 can also be of type array; however, LaravelPlus\Extension\Co...ommand::tailLocalLogs() does only seem to accept string, 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...
49
            } else {
50 2
                $this->error('Could not determine path to log file.');
51
            }
52
        }
53
        // on Remote
54
        else {
55 2
            $path = $this->option('path') ?: $this->getRemotePath($connection);
0 ignored issues
show
It seems like $connection defined by $this->argument('connection') on line 41 can also be of type array; however, LaravelPlus\Extension\Co...ommand::getRemotePath() does only seem to accept string, 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...
56
57 2
            if ($path) {
58 1
                $this->tailRemoteLogs($path, $connection);
0 ignored issues
show
It seems like $path defined by $this->option('path') ?:...RemotePath($connection) on line 55 can also be of type array; however, LaravelPlus\Extension\Co...mmand::tailRemoteLogs() does only seem to accept string, 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...
It seems like $connection defined by $this->argument('connection') on line 41 can also be of type array; however, LaravelPlus\Extension\Co...mmand::tailRemoteLogs() does only seem to accept string, 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...
59
            } else {
60 1
                $this->error('Could not determine path to log file.');
61
            }
62
        }
63 4
    }
64
65
    /**
66
     * Get the path to the Laravel log file.
67
     *
68
     * @return string
69
     */
70 1 View Code Duplication
    protected function getLocalPath()
71
    {
72 1
        switch ($this->laravel['config']['app.log']) {
73 1
        case 'single':
74
            return storage_path('logs/laravel.log');
75
76 1
        case 'daily':
77
            $date = Carbon::today()->format('Y-m-d');
78
79
            return storage_path("logs/laravel-{$date}.log");
80
81 1
        case 'syslog':
82
            throw new \RuntimeException('syslog not support');
83
        }
84 1
    }
85
86
    /**
87
     * Tail a local log file for the application.
88
     *
89
     * @param string $path
90
     *
91
     * @return string
92
     */
93 1 View Code Duplication
    protected function tailLocalLogs($path)
94
    {
95 1
        $output = $this->output;
96
97 1
        $lines = $this->option('lines');
98
99
        (new Process('tail -f -n '.$lines.' '.escapeshellarg($path)))->setTimeout(null)->run(function ($type, $line) use ($output) {
100 1
            $output->write($line);
101 1
        });
102 1
    }
103
104
    /**
105
     * Get the path to the Laravel log file.
106
     *
107
     * @param string $connection
108
     *
109
     * @return string
110
     */
111 1
    protected function getRemotePath($connection)
112
    {
113 1
        return $this->getRoot($connection).str_replace(base_path(), '', $this->getRemotePathFromStorage());
114
    }
115
116
    /**
117
     * Get the path to the Laravel log file.
118
     *
119
     * @return string
120
     */
121 1 View Code Duplication
    protected function getRemotePathFromStorage()
122
    {
123 1
        switch ($this->laravel['config']['app.log']) {
124 1
        case 'single':
125
            return storage_path('logs/laravel.log');
126
127 1
        case 'daily':
128
            $date = Carbon::today()->format('Y-m-d');
129
130
            return storage_path("logs/laravel-{$date}.log");
131
132 1
        case 'syslog':
133
            throw new \RuntimeException('syslog not support');
134
        }
135 1
    }
136
137
    /**
138
     * Get the path to the Laravel install root.
139
     *
140
     * @param string $connection
141
     *
142
     * @return string
143
     */
144 1
    protected function getRoot($connection)
145
    {
146 1
        return $this->laravel['config']['remote.connections.'.$connection.'.root'];
147
    }
148
149
    /**
150
     * Tail a remote log file at the given path and connection.
151
     *
152
     * @param string $path
153
     * @param string $connection
154
     */
155 1 View Code Duplication
    protected function tailRemoteLogs($path, $connection)
156
    {
157 1
        $out = $this->output;
158
159 1
        $lines = $this->option('lines');
160
161 1
        $this->getRemote($connection)->run('tail -f -n '.$lines.' '.escapeshellarg($path), function ($line) use ($out) {
162
            $out->write($line);
163 1
        });
164 1
    }
165
166
    /**
167
     * Get a connection to the remote server.
168
     *
169
     * @param string $connection
170
     *
171
     * @return \Illuminate\Remote\Connection
172
     */
173 1
    protected function getRemote($connection)
174
    {
175 1
        return $this->laravel['remote']->connection($connection);
176
    }
177
}
178