Issues (378)

app/Console/Commands/InstallNntmux.php (6 issues)

1
<?php
2
3
namespace App\Console\Commands;
4
5
use App\Models\User;
6
use Illuminate\Console\Command;
7
use Illuminate\Support\Facades\File;
8
use Illuminate\Support\Facades\Process;
9
10
class InstallNntmux extends Command
11
{
12
    /**
13
     * The name and signature of the console command.
14
     *
15
     * @var string
16
     */
17
    protected $signature = 'nntmux:install {--y|yes : Skip confirmation prompts and proceed with installation}';
18
19
    /**
20
     * The console command description.
21
     *
22
     * @var string
23
     */
24
    protected $description = 'Install NNTmux';
25
26
    /**
27
     * Create a new command instance.
28
     *
29
     * @return void
30
     */
31
    public function __construct()
32
    {
33
        parent::__construct();
34
    }
35
36
    public function handle(): void
37
    {
38
        $yesMode = $this->option('yes');
39
        if (File::exists(base_path().'/_install/install.lock')) {
40
            if ($yesMode) {
41
                $this->info('Install is locked. The file "install.lock" is present. Use interactive mode to remove it.');
42
                exit;
0 ignored issues
show
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...
43
            } else {
44
                if ($this->confirm('Install is locked. Do you want to remove the "install.lock" file to continue?')) {
45
                    $this->info('Removing install.lock file so we can continue with install process...');
46
                    $remove = Process::timeout(600)->run('rm _install/install.lock');
47
                    echo $remove->output();
48
                    echo $remove->errorOutput();
49
                } else {
50
                    $this->info('Installation aborted. The file "install.lock" was not removed.');
51
                    exit;
0 ignored issues
show
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...
52
                }
53
            }
54
        }
55
56
        if (! $yesMode) {
57
            if (! $this->confirm('Are you sure you want to install NNTmux? This will wipe your database!!')) {
58
                $this->info('Installation aborted by user.');
59
                exit;
0 ignored issues
show
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...
60
            }
61
        }
62
63
        $this->info('Migrating tables and seeding them with initial data');
64
        if (config('app.env') !== 'production') {
65
            $this->call('migrate:fresh', ['--seed' => true]);
66
        } else {
67
            $this->call('migrate:fresh', ['--force' => true, '--seed' => true]);
68
        }
69
70
        $paths = $this->updatePaths();
71
        if ($paths !== false) {
72
            $this->info('Paths checked successfully');
73
        }
74
75
        if ($this->addAdminUser()) {
76
            File::put(base_path().'/_install/install.lock', 'application install locked on '.now());
77
            $this->info('Generating application key');
78
            $this->call('key:generate', ['--force' => true]);
79
            $this->info('NNTmux installation completed successfully');
80
            exit();
0 ignored issues
show
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...
81
        }
82
83
        $this->error('NNTmux installation failed. Fix reported problems and try again');
84
85
    }
86
87
    /**
88
     * @return array|bool
89
     *
90
     * @throws \Exception
91
     * @throws \RuntimeException
92
     */
93
    private function updatePaths()
94
    {
95
        $covers_path = config('nntmux_settings.covers_path');
96
        $nzb_path = config('nntmux_settings.path_to_nzbs');
97
        $zip_path = config('nntmux_settings.tmp_unzip_path');
98
        $unrar_path = config('nntmux.tmp_unrar_path');
99
100
        if (! File::isWritable($nzb_path)) {
101
            $this->warn($nzb_path.' is not writable. Please fix folder permissions');
102
103
            return false;
104
        }
105
106
        if (! file_exists($unrar_path)) {
107
            $this->info('Creating missing '.$unrar_path.' folder');
108
            if (! @File::makeDirectory($unrar_path) && ! File::isDirectory($unrar_path)) {
109
                throw new \RuntimeException('Unable to create '.$unrar_path.' folder');
110
            }
111
            $this->info('Folder '.$unrar_path.' successfully created');
112
        }
113
114
        if (! is_writable($unrar_path)) {
115
            $this->warn($unrar_path.' is not writable. Please fix folder permissions');
116
117
            return false;
118
        }
119
120
        if (! File::isWritable($covers_path)) {
121
            $this->warn($covers_path.' is not writable. Please fix folder permissions');
122
123
            return false;
124
        }
125
126
        if (! File::isWritable($zip_path)) {
127
            $this->warn($zip_path.' is not writable. Please fix folder permissions');
128
129
            return false;
130
        }
131
132
        return true;
133
    }
134
135
    private function addAdminUser(): bool
136
    {
137
        if (config('nntmux.admin_username') === '' || config('nntmux.admin_password') === '' || config('nntmux.admin_email') === '') {
138
            $this->error('Admin user data cannot be empty! Please edit .env file and fill in admin user details and run this script again!');
139
            exit();
0 ignored issues
show
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...
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...
140
        }
141
142
        $this->info('Adding admin user to database');
143
        try {
144
            User::add(config('nntmux.admin_username'), config('nntmux.admin_password'), config('nntmux.admin_email'), 2);
145
            User::where('username', config('nntmux.admin_username'))->update(['verified' => 1, 'email_verified_at' => now()]);
146
        } catch (\Throwable $e) {
147
            echo $e->getMessage();
148
            $this->error('Unable to add admin user!');
149
150
            return false;
151
        }
152
153
        return true;
154
    }
155
}
156