Passed
Branch dev (32180c)
by John
03:42
created

InstallerBase::delFile()   B

Complexity

Conditions 9
Paths 6

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 9
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 15
rs 8.0555
1
<?php
2
3
namespace App\Babel\Install;
4
5
use App\Models\OJModel;
6
use App\Models\CompilerModel;
7
use PharIo\Version\Version;
8
use PharIo\Version\VersionConstraintParser;
9
use PharIo\Version\InvalidVersionException;
10
use Illuminate\Support\Facades\DB;
11
use Exception;
12
use Throwable;
13
14
class InstallerBase
15
{
16
    protected $command;
17
    protected $versionParser;
18
    protected $oid=0;
19
    protected $babelConfig=[];
20
    protected $ocode=null;
21
    protected $worker=null;
22
23
    protected function _install($ocode)
24
    {
25
        try {
26
            $this->ocode=$ocode;
27
            $this->command->line("Installing <fg=green>$ocode</>");
28
            $this->babelConfig=json_decode(file_get_contents(babel_path("Extension/$ocode/babel.json")), true);
29
30
            // check version info
31
            $this->checkVersionInfo();
32
33
            // support __cur__ variables
34
            $this->parseVersion();
35
36
            // check requirement
37
            $this->checkRequirement();
38
39
            //writing database
40
            $this->transactionDB();
41
42
        }catch(Throwable $e){
43
            if ($e->getMessage()!==""){
44
                $this->command->line("\n  <bg=red;fg=white> {$e->getMessage()} </>\n");
45
            }
46
        }
47
    }
48
49
    protected function _uninstall($ocode)
50
    {
51
        $this->command->line("<fg=red>Warning: Removing an installed and already-used extension may cause severe consequences, including lossing user submission, problem data and contests regaring or involving the usage of this extension. </>");
52
        if ($this->command->confirm("Are you sure you want to uninstall $ocode?")) {
53
            //uninstall
54
            OJModel::removeOJ(["ocode"=>$ocode]);
55
            $this->command->line("Already removed <fg=green>$ocode</>");
56
        }
57
    }
58
59
    public function __construct($class)
60
    {
61
        $this->command=$class;
62
        $this->versionParser = new VersionConstraintParser();
63
    }
64
65
    private function parseVersion()
66
    {
67
        if(empty($this->babelConfig)){
68
            throw new Exception('Missing babel.json Config file.');
69
        }
70
71
        if ($this->babelConfig["version"]=="__cur__") {
72
            $this->babelConfig["version"]=explode("-", version())[0];
73
        }
74
75
        if ($this->babelConfig["require"]["NOJ"]=="__cur__") {
76
            $this->babelConfig["require"]["NOJ"]=explode("-", version())[0];
77
        }
78
    }
79
80
    private function checkVersionInfo()
81
    {
82
        // check version info
83
        if (!isset($this->babelConfig["version"]) || is_null($this->babelConfig["version"]) || trim($this->babelConfig["version"])=="") {
84
            throw new Exception('Lack version info.');
85
        }
86
87
        // check require info
88
        if (!isset($this->babelConfig["require"]["NOJ"]) || is_null($this->babelConfig["require"]["NOJ"]) || trim($this->babelConfig["require"]["NOJ"])=="") {
89
            throw new Exception('Lack NOJ compability info.');
90
        }
91
    }
92
93
    private function checkRequirement()
94
    {
95
        try {
96
            if (!($this->versionParser->parse($this->babelConfig["require"]["NOJ"])->complies(new Version(explode("-", version())[0])))) {
97
                if (!$this->command->option('ignore-platform-reqs')) {
98
                    $this->command->line("Your Current NOJ Version <fg=yellow>".version()."</> doesn't support the following extension: ");
99
                    $this->command->line("  - <fg=green>{$this->ocode}</> requires NOJ version <fg=yellow>{$this->babelConfig['require']['NOJ']}</>");
100
                    throw new Exception();
101
                }
102
            }
103
        } catch (InvalidVersionException $e) {
104
            throw new Exception('Illegal Compability Info.');
105
        }
106
    }
107
108
    private function transactionDB()
109
    {
110
        DB::beginTransaction();
111
        $ocode=$this->ocode;
112
        try {
113
            // get current installed version info
114
            $info=OJModel::basic(OJModel::oid($ocode));
115
116
            $this->insertWhenNotExist($info);
117
118
            // init worker
119
            $this->worker=new InstallerWorker($this->ocode, $this->babelConfig, $this->oid, $this->command);
120
121
            // retrieve compiler config and then import it
122
            $latest_timestamp=$this->worker->importCompilerInfo($info);
123
124
            // import css
125
            $this->worker->importCSS();
126
127
            // import icon
128
            $this->worker->importICON();
129
130
            $this->oid=OJModel::updateOJ(OJModel::oid($this->babelConfig["code"]), [
131
                "version"=>$this->babelConfig["version"],
132
                "compiler_timestamp"=>$latest_timestamp,
133
            ]);
134
135
            DB::commit();
136
137
        }catch(Throwable $e){
138
            DB::rollback();
139
            if ($e->getMessage()!=="") {
140
                $this->command->line("\n  <bg=red;fg=white> {$e->getMessage()} </>\n");
141
            }
142
            return;
143
        }
144
    }
145
146
    private function insertWhenNotExist($info)
147
    {
148
        $ocode=$this->ocode;
0 ignored issues
show
Unused Code introduced by
The assignment to $ocode is dead and can be removed.
Loading history...
149
150
        // if there isn't, create one
151
        if (empty($info)) {
152
            $this->oid=OJModel::insertOJ([
153
                "ocode"=>$this->babelConfig["code"],
154
                "name"=>$this->babelConfig["name"],
155
                "home_page"=>$this->babelConfig["website"],
156
                "logo"=>"/static/img/oj/default.png",
157
                "status"=>1,
158
                "version"=>"",
159
                "compiler_timestamp"=>"",
160
            ]);
161
        } else {
162
            // check legal version format
163
            try {
164
                $currentVersion=new Version($this->babelConfig["version"]);
165
            } catch (InvalidVersionException $e) {
166
                throw new Exception('Illegal Version Info, aborting.');
167
            }
168
169
            // check there is a not null version
170
            if (isset($info["version"]) && !is_null($info["version"]) && trim($info["version"])!="") {
171
                try {
172
                    $installedVersion=new Version($info["version"]);
173
                } catch (InvalidVersionException $e) {
174
                    throw new Exception('Illegal Version Info, aborting.');
175
                }
176
177
                if (!($currentVersion->isGreaterThan($installedVersion))) {
178
                    // lower version or even
179
                    $this->command->line("Nothing to install or update.");
180
                    throw new Exception();
181
                }
182
            }
183
184
            $this->oid=$info["oid"];
185
        }
186
    }
187
}
188