Passed
Push — master ( 34b43e...0017b2 )
by Hesham
04:42
created

UpdateCommand::handle()   C

Complexity

Conditions 13
Paths 144

Size

Total Lines 42
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 42
rs 6.25
c 0
b 0
f 0
cc 13
nc 144
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Update adminer
4
 *
5
 * @author    Hesham A. Meneisi [email protected]
6
 * @copyright 2019 Hesham Meneisi
7
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
 */
9
10
namespace Lumener\Console;
11
12
use Illuminate\Console\Command;
13
use Lumener\Helpers\ShellHelper;
14
15
/**
16
 * A command to update the file for adminer.php
17
 *
18
 * @author Charles A. Peterson <[email protected]>
19
 */
20
class UpdateCommand extends Command
21
{
22
    /**
23
     * @var Filesystem $files
0 ignored issues
show
Bug introduced by
The type Lumener\Console\Filesystem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
     */
25
    protected $files;
26
27
    /**
28
     * @var String $version
29
     */
30
    protected $version;
31
32
    /**
33
     * @var String $filename
34
     */
35
    protected $filename;
36
37
    /**
38
     * The name and signature of the console command.
39
     *
40
     * @var string
41
     */
42
    protected $signature = 'lumener:update {--force}';
43
44
    /**
45
     * @param Filesystem $files
46
     */
47
    public function __construct()
48
    {
49
        parent::__construct();
50
51
        $this->filename = LUMENER_STORAGE.'/adminer.php';
52
    }
53
54
    /**
55
     * Execute the console command.
56
     *
57
     * @return void
58
     */
59
    public function handle()
60
    {
61
        $force = $this->option('force', false);
1 ignored issue
show
Unused Code introduced by
The call to Illuminate\Console\Command::option() has too many arguments starting with false. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
        /** @scrutinizer ignore-call */ 
62
        $force = $this->option('force', false);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
62
        if ($force) {
63
            $this->error("Force mode active.");
64
        }
65
        $current_version = false;
66
        try {
67
            if (file_exists($this->filename)) {
68
                $fn = fopen($this->filename, "r");
69
                for ($i=0; !$current_version && $i < 20 && !feof($fn); $i++) {
0 ignored issues
show
Bug introduced by
It seems like $fn can also be of type false; however, parameter $handle of feof() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
                for ($i=0; !$current_version && $i < 20 && !feof(/** @scrutinizer ignore-type */ $fn); $i++) {
Loading history...
70
                    $line = fgets($fn, 30);
0 ignored issues
show
Bug introduced by
It seems like $fn can also be of type false; however, parameter $handle of fgets() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
                    $line = fgets(/** @scrutinizer ignore-type */ $fn, 30);
Loading history...
71
                    preg_match_all("/@version ((\d([\.-]|$))+)/", $line, $m);
72
                    if (!empty($m[1])) {
73
                        $current_version = $m[1][0];
74
                    }
75
                }
76
            }
77
        } catch (\Throwable $e) {
78
            // current_version is false
79
        }
80
        if ($current_version) {
81
            $this->info("Lumener: Current ".$current_version);
82
        } else {
83
            $this->error("Lumener: Adminer not found.");
84
        }
85
        $vsource = config(
86
            'lumener.adminer_version',
87
            'https://api.github.com/repos/vrana/adminer/releases/latest'
88
        );
89
        if (config('lumener.adminer.version_type', 'url') == 'url') {
90
            $version = $this->_getLatestAdminerVersion($vsource);
91
            $this->info("Lumener: Latest Adminer Version " . $version);
92
        } else {
93
            $version = $vsource;
94
            $this->info("Lumener: Required Adminer Version " . $version);
95
        }
96
        if ($force || !file_exists($this->filename)
97
            || $version != $current_version) {
98
            $this->_downloadVersion($version);
99
        } else {
100
            $this->info('Lumener: Up to date.');
101
        }
102
    }
103
104
    /**
105
     * Rename functions already defined in Laravel/Lumen public helper
106
     */
107
    private function _patchAdminer()
108
    {
109
        foreach (config(
110
            'lumener.adminer.rename_list',
111
            ['redirect','cookie','view', 'exit', 'ob_flush']
112
        ) as $var) {
113
            ShellHelper::rename($var, $this->filename);
114
        }
115
    }
116
117
    /**
118
     * Retreives the most recent adminer release version
119
     * @return string Version
120
     */
121
    private function _getLatestAdminerVersion($vsource)
122
    {
123
        $this->info("Lumener: Checking latest adminer version...");
124
        $response = ShellHelper::get($vsource);
125
        if (!$response || $response->getStatusCode() != '200') {
126
            $this->error(
127
                'Lumener: Could not retrieve version information from url.'
128
                .
129
                (
130
                    $response ? "\r\n[{$response->getStatusCode()}]
131
                    {$response->getReasonPhrase()} {(string)$response->getBody()}"
132
                    : "Connection Failed.\r\n" . ShellHelper::$LastError
133
                )
134
            );
135
            return;
136
        }
137
        return
138
            ltrim(json_decode((string) $response->getBody())->tag_name, 'v');
139
    }
140
141
    /**
142
     * Downloads the speicifed adminer.php version
143
     * @param  string $version
144
     * @return bool Success
145
     */
146
    private function _downloadVersion($version)
147
    {
148
        $this->info("Lumener: Downloading...");
149
        $url = config(
150
            'lumener.adminer.source',
151
            'https://github.com/vrana/adminer/releases/download/v{version}/adminer-{version}.php'
152
        );
153
        $url = str_replace("{version}", ltrim($version, 'v'), $url);
154
        $response = ShellHelper::get($url, ['sink' => $this->filename]);
155
        if ($response && $response->getStatusCode() == '200') {
156
            $this->info("Patching adminer.php...");
157
            $this->_patchAdminer();
158
            $this->info("Lumener: Updated!");
159
            return true;
160
        } else {
161
            $this->error(
162
                'Lumener: Could not download adminer.php.'
163
                .
164
                (
165
                    $response ? "\r\n[{$response->getStatusCode()}]
166
                    {$response->getReasonPhrase()} {(string)$response->getBody()}"
167
                    : "Connection Failed.\r\n" . ShellHelper::$LastError
168
                )
169
            );
170
            return false;
171
        }
172
    }
173
}
174