Passed
Push — dev ( 4d422b...b23d80 )
by Darko
08:43
created

InstallNntmux::handle()   C

Complexity

Conditions 16
Paths 54

Size

Total Lines 59
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 272

Importance

Changes 0
Metric Value
eloc 43
dl 0
loc 59
ccs 0
cts 42
cp 0
rs 5.5666
c 0
b 0
f 0
cc 16
nc 54
nop 0
crap 272

How to fix   Long Method    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
namespace App\Console\Commands;
4
5
use App\Models\User;
6
use App\Models\Settings;
7
use Illuminate\Console\Command;
8
use Illuminate\Support\Facades\File;
9
use Symfony\Component\Process\Process;
10
11
class InstallNntmux extends Command
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'nntmux:install';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Install NNTmux';
26
27
    /**
28
     * Create a new command instance.
29
     *
30
     * @return void
31
     */
32
    public function __construct()
33
    {
34
        parent::__construct();
35
    }
36
37
    /**
38
     * Execute the console command.
39
     *
40
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
41
     * @throws \Symfony\Component\Process\Exception\LogicException
42
     * @throws \Symfony\Component\Process\Exception\RuntimeException
43
     * @throws \Exception
44
     */
45
    public function handle()
46
    {
47
        $error = false;
48
49
        if (env('DB_CONNECTION') === 'mysql' && (! (new Settings())->isDbVersionAtLeast(NN_MINIMUM_MARIA_VERSION) || ! (new Settings())->isDbVersionAtLeast(NN_MINIMUM_MYSQL_VERSION))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression new App\Models\Settings(..._MINIMUM_MARIA_VERSION) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
Bug Best Practice introduced by
The expression new App\Models\Settings(..._MINIMUM_MYSQL_VERSION) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
50
            $this->error('Version of MariaDB/MySQL/ used is lower than required version: '.NN_MINIMUM_MARIA_VERSION.PHP_EOL.' Please update your install of Mariadb/MySQL');
51
            $error = true;
52
        }
53
54
        if (! $error) {
55
            if ($this->confirm('Are you sure you want to install NNTmux? This will wipe your database!!')) {
56
                if (file_exists(NN_ROOT.'_install/install.lock')) {
57
                    if ($this->confirm('Do you want to remove install.lock file so you can continue with install?')) {
58
                        $this->info('Removing install.lock file so we can continue with install process');
59
                        $remove = new Process('rm _install/install.lock');
0 ignored issues
show
Bug introduced by
'rm _install/install.lock' of type string is incompatible with the type array expected by parameter $command of Symfony\Component\Process\Process::__construct(). ( Ignorable by Annotation )

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

59
                        $remove = new Process(/** @scrutinizer ignore-type */ 'rm _install/install.lock');
Loading history...
60
                        $remove->setTimeout(600);
61
                        $remove->run(function ($type, $buffer) {
62
                            if (Process::ERR === $type) {
63
                                echo 'ERR > '.$buffer;
64
                            } else {
65
                                echo $buffer;
66
                            }
67
                        });
68
                    } else {
69
                        $this->info('Not removing install.lock, stopping install process');
70
                        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
71
                    }
72
                }
73
                $this->info('Migrating tables and seeding them with initial data');
74
                if (config('app.env') !== 'production') {
75
                    $this->call('migrate:fresh', ['--seed' => true]);
76
                } else {
77
                    $this->call('migrate:fresh', ['--force' => true, '--seed' => true]);
78
                }
79
80
                $paths = $this->updatePaths();
81
                if ($paths !== false) {
0 ignored issues
show
introduced by
The condition $paths !== false is always true.
Loading history...
82
                    $sql1 = Settings::query()->where('setting', '=', 'nzbpath')->update(['value' => $paths['nzb_path']]);
83
                    $sql2 = Settings::query()->where('setting', '=', 'tmpunrarpath')->update(['value' => $paths['unrar_path']]);
84
                    $sql3 = Settings::query()->where('setting', '=', 'coverspath')->update(['value' => $paths['covers_path']]);
85
                    if ($sql1 === null || $sql2 === null || $sql3 === null) {
0 ignored issues
show
introduced by
The condition $sql3 === null is always false.
Loading history...
introduced by
The condition $sql2 === null is always false.
Loading history...
86
                        $error = true;
87
                    } else {
88
                        $this->info('Settings table updated successfully');
89
                    }
90
                }
91
92
                if (! $error && $this->addAdminUser()) {
0 ignored issues
show
introduced by
The condition $error is always false.
Loading history...
93
                    File::put(base_path().'/_install/install.lock', 'application install locked on '.now());
94
                    $this->info('Generating application key');
95
                    $this->call('key:generate', ['--force' => true]);
96
                    $this->info('NNTmux installation completed successfully');
97
                    exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
98
                }
99
100
                $this->error('NNTmux installation failed. Fix reported problems and try again');
101
            } else {
102
                $this->info('Stopping install process');
103
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
104
            }
105
        }
106
    }
107
108
    /**
109
     * @return array|bool
110
     * @throws \Exception
111
     * @throws \RuntimeException
112
     */
113
    private function updatePaths()
114
    {
115
        $covers_path = base_path().'/resources/covers/';
0 ignored issues
show
Bug introduced by
Are you sure the usage of base_path() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
116
        $nzb_path = base_path().'/resources/nzb/';
0 ignored issues
show
Bug introduced by
Are you sure the usage of base_path() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
117
        $tmp_path = base_path().'/resources/tmp/';
0 ignored issues
show
Bug introduced by
Are you sure the usage of base_path() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
118
        $unrar_path = $tmp_path.'unrar/';
119
120
        $nzbPathCheck = File::isWritable($nzb_path);
121
        if ($nzbPathCheck === false) {
122
            $this->warn($nzb_path.' is not writable. Please fix folder permissions');
123
124
            return false;
125
        }
126
127
        if (! file_exists($unrar_path)) {
128
            $this->info('Creating missing '.$unrar_path.' folder');
129
            if (! @File::makeDirectory($unrar_path) && ! File::isDirectory($unrar_path)) {
130
                throw new \RuntimeException('Unable to create '.$unrar_path.' folder');
131
            }
132
            $this->info('Folder '.$unrar_path.' successfully created');
133
        }
134
        $unrarPathCheck = is_writable($unrar_path);
135
        if ($unrarPathCheck === false) {
136
            $this->warn($unrar_path.' is not writable. Please fix folder permissions');
137
138
            return false;
139
        }
140
141
        $coversPathCheck = File::isWritable($covers_path);
142
        if ($coversPathCheck === false) {
143
            $this->warn($covers_path.' is not writable. Please fix folder permissions');
144
145
            return false;
146
        }
147
148
        return [
149
            'nzb_path' => str_finish($nzb_path, '/'),
150
            'covers_path' => str_finish($covers_path, '/'),
151
            'unrar_path' => str_finish($unrar_path, '/'),
152
        ];
153
    }
154
155
    /**
156
     * @return bool
157
     */
158
    private function addAdminUser(): bool
159
    {
160
        if (config('nntmux.admin_username') === '' || config('nntmux.admin_password') === '' || config('nntmux.admin_email') === '') {
161
            $this->error('Admin user data cannot be empty! Please edit .env file and fill in admin user details and run this script again!');
162
            exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
163
        }
164
165
        $this->info('Adding admin user to database');
166
        try {
167
            User::add(config('nntmux.admin_username'), config('nntmux.admin_password'), config('nntmux.admin_email'), 2, '', '', '', '');
0 ignored issues
show
Bug introduced by
'' of type string is incompatible with the type integer expected by parameter $invitedBy of App\Models\User::add(). ( Ignorable by Annotation )

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

167
            User::add(config('nntmux.admin_username'), config('nntmux.admin_password'), config('nntmux.admin_email'), 2, '', '', '', /** @scrutinizer ignore-type */ '');
Loading history...
Bug introduced by
'' of type string is incompatible with the type integer expected by parameter $invites of App\Models\User::add(). ( Ignorable by Annotation )

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

167
            User::add(config('nntmux.admin_username'), config('nntmux.admin_password'), config('nntmux.admin_email'), 2, '', '', /** @scrutinizer ignore-type */ '', '');
Loading history...
168
            User::where('username', config('nntmux.admin_username'))->update(['verified' => 1]);
169
        } catch (\Throwable $e) {
170
            echo $e->getMessage();
171
            $this->error('Unable to add admin user!');
172
173
            return false;
174
        }
175
176
        return true;
177
    }
178
}
179