2021-02-01 02:33:45 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace Nexus\Install;
|
|
|
|
|
|
|
2021-06-13 22:21:42 +08:00
|
|
|
|
use App\Models\Attendance;
|
2021-06-21 02:01:26 +08:00
|
|
|
|
use App\Models\BonusLogs;
|
2021-05-29 21:48:50 +08:00
|
|
|
|
use App\Models\Category;
|
2021-06-11 20:32:57 +08:00
|
|
|
|
use App\Models\Exam;
|
|
|
|
|
|
use App\Models\ExamUser;
|
2021-06-22 01:04:50 +08:00
|
|
|
|
use App\Models\HitAndRun;
|
2021-05-29 21:48:50 +08:00
|
|
|
|
use App\Models\Icon;
|
2021-06-06 13:41:05 +08:00
|
|
|
|
use App\Models\Setting;
|
2022-03-08 15:08:56 +08:00
|
|
|
|
use App\Models\Tag;
|
|
|
|
|
|
use App\Models\Torrent;
|
|
|
|
|
|
use App\Models\TorrentTag;
|
2021-06-21 02:01:26 +08:00
|
|
|
|
use App\Models\User;
|
2022-02-10 22:30:26 +08:00
|
|
|
|
use App\Repositories\BonusRepository;
|
2021-06-11 20:32:57 +08:00
|
|
|
|
use App\Repositories\ExamRepository;
|
2022-03-08 15:08:56 +08:00
|
|
|
|
use App\Repositories\TagRepository;
|
2021-06-21 02:01:26 +08:00
|
|
|
|
use Carbon\Carbon;
|
2021-06-17 20:07:22 +08:00
|
|
|
|
use GuzzleHttp\Client;
|
2022-02-10 22:30:26 +08:00
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
2021-06-06 13:41:05 +08:00
|
|
|
|
use Illuminate\Support\Str;
|
2021-06-08 10:42:39 +08:00
|
|
|
|
use Nexus\Database\NexusDB;
|
2021-03-19 00:34:11 +08:00
|
|
|
|
|
2021-02-01 02:33:45 +08:00
|
|
|
|
class Update extends Install
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2022-03-08 15:08:56 +08:00
|
|
|
|
protected $steps = ['Env check', 'Get files', 'Update .env', 'Perform updates'];
|
2021-02-01 02:33:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getLogFile()
|
|
|
|
|
|
{
|
2021-06-05 17:04:53 +08:00
|
|
|
|
return sprintf('%s/nexus-update-%s.log', sys_get_temp_dir(), date('Ymd'));
|
2021-02-01 02:33:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function getUpdateDirectory()
|
|
|
|
|
|
{
|
|
|
|
|
|
return ROOT_PATH . 'public/update';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-02-01 20:19:39 +08:00
|
|
|
|
public function listTableFieldsFromCreateTable($createTableSql)
|
|
|
|
|
|
{
|
|
|
|
|
|
$arr = preg_split("/[\r\n]+/", $createTableSql);
|
|
|
|
|
|
$result = [];
|
|
|
|
|
|
foreach ($arr as $value) {
|
|
|
|
|
|
$value = trim($value);
|
|
|
|
|
|
if (substr($value, 0, 1) != '`') {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
$pos = strpos($value, '`', 1);
|
|
|
|
|
|
$field = substr($value, 1, $pos - 1);
|
|
|
|
|
|
$result[$field] = rtrim($value, ',');
|
|
|
|
|
|
}
|
|
|
|
|
|
return $result;
|
|
|
|
|
|
}
|
2021-02-01 02:33:45 +08:00
|
|
|
|
|
2021-02-01 20:19:39 +08:00
|
|
|
|
public function listTableFieldsFromDb($table)
|
2021-02-01 02:33:45 +08:00
|
|
|
|
{
|
2021-02-01 20:19:39 +08:00
|
|
|
|
$sql = "desc $table";
|
|
|
|
|
|
$res = sql_query($sql);
|
2021-02-01 02:33:45 +08:00
|
|
|
|
$data = [];
|
2021-02-01 20:19:39 +08:00
|
|
|
|
while ($row = mysql_fetch_assoc($res)) {
|
|
|
|
|
|
$data[$row['Field']] = $row;
|
2021-02-01 02:33:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
return $data;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-21 02:01:26 +08:00
|
|
|
|
private function addSetting($name, $value)
|
|
|
|
|
|
{
|
|
|
|
|
|
$attributes = [
|
|
|
|
|
|
'name' => $name,
|
|
|
|
|
|
];
|
|
|
|
|
|
$now = Carbon::now()->toDateTimeString();
|
|
|
|
|
|
$values = [
|
|
|
|
|
|
'value' => $value,
|
|
|
|
|
|
'created_at' => $now,
|
|
|
|
|
|
'updated_at' => $now,
|
|
|
|
|
|
];
|
|
|
|
|
|
return Setting::query()->firstOrCreate($attributes, $values);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-03-19 00:34:11 +08:00
|
|
|
|
public function runExtraQueries()
|
|
|
|
|
|
{
|
|
|
|
|
|
//custom field menu
|
|
|
|
|
|
$url = 'fields.php';
|
|
|
|
|
|
$table = 'adminpanel';
|
|
|
|
|
|
$count = get_row_count($table, "where url = " . sqlesc($url));
|
|
|
|
|
|
if ($count == 0) {
|
|
|
|
|
|
$insert = [
|
|
|
|
|
|
'name' => 'Custom Field Manage',
|
|
|
|
|
|
'url' => $url,
|
|
|
|
|
|
'info' => 'Manage custom fields',
|
|
|
|
|
|
];
|
2021-06-08 10:42:39 +08:00
|
|
|
|
$id = NexusDB::insert($table, $insert);
|
2021-03-19 00:34:11 +08:00
|
|
|
|
$this->doLog("[ADD CUSTOM FIELD MENU] insert: " . json_encode($insert) . " to table: $table, id: $id");
|
|
|
|
|
|
}
|
2021-06-06 13:41:05 +08:00
|
|
|
|
//since beta8
|
2022-03-08 15:08:56 +08:00
|
|
|
|
if (WITH_LARAVEL && !NexusDB::schema()->hasColumn('categories', 'icon_id')) {
|
2021-06-01 01:28:46 +08:00
|
|
|
|
$this->doLog('[INIT CATEGORY ICON_ID]');
|
2022-03-08 15:08:56 +08:00
|
|
|
|
$this->runMigrate('database/migrations/2022_03_08_040415_add_icon_id_to_categories_table.php');
|
2021-05-29 21:48:50 +08:00
|
|
|
|
$icon = Icon::query()->orderBy('id', 'asc')->first();
|
|
|
|
|
|
if ($icon) {
|
|
|
|
|
|
Category::query()->where('icon_id', 0)->update(['icon_id' => $icon->id]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-06-06 13:41:05 +08:00
|
|
|
|
//fix base url, since beta8
|
2021-06-08 10:42:39 +08:00
|
|
|
|
if (WITH_LARAVEL && NexusDB::schema()->hasTable('settings')) {
|
2021-06-06 13:41:05 +08:00
|
|
|
|
$settingBasic = get_setting('basic');
|
|
|
|
|
|
if (isset($settingBasic['BASEURL']) && Str::startsWith($settingBasic['BASEURL'], 'localhost')) {
|
|
|
|
|
|
$this->doLog('[RESET CONFIG basic.BASEURL]');
|
|
|
|
|
|
Setting::query()->where('name', 'basic.BASEURL')->update(['value' => '']);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isset($settingBasic['announce_url']) && Str::startsWith($settingBasic['announce_url'], 'localhost')) {
|
|
|
|
|
|
$this->doLog('[RESET CONFIG basic.announce_url]');
|
|
|
|
|
|
Setting::query()->where('name', 'basic.announce_url')->update(['value' => '']);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-01 01:28:46 +08:00
|
|
|
|
//torrent support sticky second level
|
|
|
|
|
|
if (WITH_LARAVEL) {
|
2021-06-08 10:42:39 +08:00
|
|
|
|
$columnInfo = NexusDB::getMysqlColumnInfo('torrents', 'pos_state');
|
2021-06-06 13:41:05 +08:00
|
|
|
|
$this->doLog("[TORRENT POS_STATE], column info: " . json_encode($columnInfo));
|
|
|
|
|
|
if ($columnInfo['DATA_TYPE'] == 'enum') {
|
2021-06-01 01:28:46 +08:00
|
|
|
|
$sql = "alter table torrents modify `pos_state` varchar(32) NOT NULL DEFAULT 'normal'";
|
|
|
|
|
|
$this->doLog("[ALTER TORRENT POS_STATE TYPE TO VARCHAR], $sql");
|
|
|
|
|
|
sql_query($sql);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-06-13 22:21:42 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @since 1.6.0-beta9
|
|
|
|
|
|
*
|
|
|
|
|
|
* attendance change, do migrate
|
|
|
|
|
|
*/
|
2022-02-10 22:30:26 +08:00
|
|
|
|
if (WITH_LARAVEL && !NexusDB::schema()->hasColumn('attendance', 'total_days')) {
|
2022-02-14 01:42:24 +08:00
|
|
|
|
$this->runMigrate('database/migrations/2021_06_13_215440_add_total_days_to_attendance_table.php');
|
2021-06-13 22:56:13 +08:00
|
|
|
|
$this->migrateAttendance();
|
2021-06-13 22:21:42 +08:00
|
|
|
|
}
|
2021-06-21 02:01:26 +08:00
|
|
|
|
|
2022-02-10 22:30:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @since 1.6.0-beta13
|
|
|
|
|
|
*
|
|
|
|
|
|
* add seed points to user
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (WITH_LARAVEL && !NexusDB::schema()->hasColumn('users', 'seed_points')) {
|
2022-02-14 01:42:24 +08:00
|
|
|
|
$this->runMigrate('database/migrations/2021_06_24_013107_add_seed_points_to_users_table.php');
|
2022-02-19 23:37:27 +08:00
|
|
|
|
//Don't do this, initial seed points = 0;
|
|
|
|
|
|
// $result = $this->initSeedPoints();
|
|
|
|
|
|
$this->doLog("[INIT SEED POINTS]");
|
2021-06-21 02:01:26 +08:00
|
|
|
|
}
|
2022-02-10 22:30:26 +08:00
|
|
|
|
|
2022-02-25 23:13:34 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @since 1.6.0-beta14
|
|
|
|
|
|
*
|
|
|
|
|
|
* add id to agent_allowed_exception
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (WITH_LARAVEL && !NexusDB::schema()->hasColumn('agent_allowed_exception', 'id')) {
|
|
|
|
|
|
$this->runMigrate('database/migrations/2022_02_25_021356_add_id_to_agent_allowed_exception_table.php');
|
|
|
|
|
|
$this->doLog("[ADD_ID_TO_AGENT_ALLOWED_EXCEPTION]");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-02-10 22:30:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-03-08 15:08:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function runExtraMigrate()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!WITH_LARAVEL) {
|
|
|
|
|
|
$this->doLog(__METHOD__ . ", laravel is not available");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (
|
|
|
|
|
|
NexusDB::schema()->hasColumn('torrents', 'tags')
|
|
|
|
|
|
&& Torrent::query()->where('tags', '>', 0)->count() > 0
|
|
|
|
|
|
&& TorrentTag::query()->count() == 0
|
|
|
|
|
|
) {
|
|
|
|
|
|
$this->doLog("[MIGRATE_TORRENT_TAG]...");
|
|
|
|
|
|
$tagRep = new TagRepository();
|
|
|
|
|
|
$tagRep->migrateTorrentTag();
|
|
|
|
|
|
$this->doLog("[MIGRATE_TORRENT_TAG] done!");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$this->doLog("no need to run [MIGRATE_TORRENT_TAG]");
|
|
|
|
|
|
}
|
2021-06-13 22:21:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function migrateAttendance()
|
|
|
|
|
|
{
|
|
|
|
|
|
$page = 1;
|
|
|
|
|
|
$size = 1000;
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
$logPrefix = "[MIGRATE_ATTENDANCE], page: $page, size: $size";
|
|
|
|
|
|
$result = Attendance::query()
|
2021-06-13 22:56:13 +08:00
|
|
|
|
->groupBy(['uid'])
|
|
|
|
|
|
->selectRaw('uid, max(id) as id, count(*) as counts')
|
2021-06-13 22:21:42 +08:00
|
|
|
|
->forPage($page, $size)
|
|
|
|
|
|
->get();
|
|
|
|
|
|
$this->doLog("$logPrefix, " . last_query() . ", count: " . $result->count());
|
|
|
|
|
|
if ($result->isEmpty()) {
|
|
|
|
|
|
$this->doLog("$logPrefix, no more data...");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach ($result as $row) {
|
|
|
|
|
|
$update = [
|
|
|
|
|
|
'total_days' => $row->counts,
|
|
|
|
|
|
];
|
|
|
|
|
|
$updateResult = $row->update($update);
|
|
|
|
|
|
$this->doLog(sprintf(
|
2021-06-13 22:56:13 +08:00
|
|
|
|
"$logPrefix, update user: %s(ID: %s) => %s, result: %s",
|
2021-06-13 22:21:42 +08:00
|
|
|
|
$row->uid, $row->id, json_encode($update), var_export($updateResult, true)
|
|
|
|
|
|
));
|
|
|
|
|
|
}
|
|
|
|
|
|
$page++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-11 20:32:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-17 20:07:22 +08:00
|
|
|
|
public function listVersions()
|
|
|
|
|
|
{
|
|
|
|
|
|
$url = "https://api.github.com/repos/xiaomlove/nexusphp/releases";
|
2022-02-12 19:46:04 +08:00
|
|
|
|
$versions = $this->requestGithub($url);
|
|
|
|
|
|
return array_reverse($versions);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function getLatestCommit()
|
|
|
|
|
|
{
|
|
|
|
|
|
$url = "https://api.github.com/repos/xiaomlove/nexusphp/commits/php8";
|
|
|
|
|
|
return $this->requestGithub($url);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function requestGithub($url)
|
|
|
|
|
|
{
|
|
|
|
|
|
$client = new Client();
|
|
|
|
|
|
$logPrefix = "请求 github: $url";
|
2021-06-17 20:07:22 +08:00
|
|
|
|
$response = $client->get($url, ['timeout' => 10,]);
|
|
|
|
|
|
if (($statusCode = $response->getStatusCode()) != 200) {
|
2022-02-12 19:46:04 +08:00
|
|
|
|
throw new \RuntimeException("$logPrefix 失败,状态码:$statusCode");
|
2021-06-17 20:07:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
if ($response->getBody()->getSize() <= 0) {
|
2022-02-12 19:46:04 +08:00
|
|
|
|
throw new \RuntimeException("$logPrefix 失败,结果为空");
|
2021-06-17 20:07:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
$bodyString = $response->getBody()->getContents();
|
2022-02-12 19:46:04 +08:00
|
|
|
|
$this->doLog("[REQUEST_GITHUB_RESPONSE]: $bodyString");
|
|
|
|
|
|
$results = json_decode($bodyString, true);
|
|
|
|
|
|
if (empty($results) || !is_array($results)) {
|
|
|
|
|
|
throw new \RuntimeException("$logPrefix 结果异常");
|
2021-06-17 20:07:22 +08:00
|
|
|
|
}
|
2022-02-12 19:46:04 +08:00
|
|
|
|
return $results;
|
2021-06-17 20:07:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-02-12 19:46:04 +08:00
|
|
|
|
public function downAndExtractCode($url): bool
|
2021-06-17 20:07:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
$arr = explode('/', $url);
|
|
|
|
|
|
$basename = last($arr);
|
2022-02-12 19:46:04 +08:00
|
|
|
|
$isZip = false;
|
|
|
|
|
|
if (Str::contains($basename,'.zip')) {
|
|
|
|
|
|
$isZip = true;
|
|
|
|
|
|
$basename = strstr($basename, '.zip', true);
|
|
|
|
|
|
$suffix = ".zip";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$suffix = '.tar.gz';
|
|
|
|
|
|
}
|
2021-06-17 20:07:22 +08:00
|
|
|
|
$filename = sprintf('%s/nexusphp-%s-%s%s', sys_get_temp_dir(), $basename, date('YmdHis'), $suffix);
|
2022-02-14 01:42:24 +08:00
|
|
|
|
$this->doLog("download from: $url, save to filename: $filename");
|
2021-06-17 20:07:22 +08:00
|
|
|
|
$client = new Client();
|
|
|
|
|
|
$response = $client->request('GET', $url, ['sink' => $filename]);
|
|
|
|
|
|
if (($statusCode = $response->getStatusCode()) != 200) {
|
|
|
|
|
|
throw new \RuntimeException("下载错误,状态码:$statusCode");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (($bodySize = $response->getBody()->getSize()) <= 0) {
|
|
|
|
|
|
throw new \RuntimeException("下载错误,文件体积:$bodySize");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!file_exists($filename)) {
|
|
|
|
|
|
throw new \RuntimeException("下载错误,文件不存在:$filename");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (filesize($filename) <= 0) {
|
|
|
|
|
|
throw new \RuntimeException("下载错误,文件大小为0");
|
|
|
|
|
|
}
|
|
|
|
|
|
$this->doLog('SUCCESS_DOWNLOAD');
|
|
|
|
|
|
$extractDir = str_replace($suffix, "", $filename);
|
|
|
|
|
|
$command = "mkdir -p $extractDir";
|
2022-02-12 19:46:04 +08:00
|
|
|
|
$this->executeCommand($command);
|
2021-06-17 20:07:22 +08:00
|
|
|
|
|
2022-02-12 19:46:04 +08:00
|
|
|
|
if ($isZip) {
|
|
|
|
|
|
$command = "unzip $filename -d $extractDir";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$command = "tar -xf $filename -C $extractDir";
|
2021-06-17 20:07:22 +08:00
|
|
|
|
}
|
2022-02-12 19:46:04 +08:00
|
|
|
|
$this->executeCommand($command);
|
2021-06-17 20:07:22 +08:00
|
|
|
|
|
|
|
|
|
|
foreach (glob("$extractDir/*") as $path) {
|
|
|
|
|
|
if (is_dir($path)) {
|
|
|
|
|
|
$command = sprintf('cp -Rf %s/* %s', $path, ROOT_PATH);
|
2022-02-12 19:46:04 +08:00
|
|
|
|
$this->executeCommand($command);
|
2021-06-17 20:07:22 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
$this->doLog('SUCCESS_EXTRACT');
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-02-10 22:30:26 +08:00
|
|
|
|
public function initSeedPoints(): int
|
|
|
|
|
|
{
|
|
|
|
|
|
$size = 10000;
|
|
|
|
|
|
$tableName = (new User())->getTable();
|
|
|
|
|
|
$result = 0;
|
|
|
|
|
|
do {
|
|
|
|
|
|
$affectedRows = NexusDB::table($tableName)
|
|
|
|
|
|
->whereNull('seed_points')
|
|
|
|
|
|
->limit($size)
|
|
|
|
|
|
->update([
|
2022-02-14 01:42:24 +08:00
|
|
|
|
'seed_points' => NexusDB::raw('seedbonus')
|
2022-02-10 22:30:26 +08:00
|
|
|
|
]);
|
|
|
|
|
|
$result += $affectedRows;
|
|
|
|
|
|
$this->doLog("affectedRows: $affectedRows, query: " . last_query());
|
|
|
|
|
|
} while ($affectedRows > 0);
|
|
|
|
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-02-12 15:48:26 +08:00
|
|
|
|
public function updateDependencies()
|
|
|
|
|
|
{
|
2022-02-12 20:57:34 +08:00
|
|
|
|
$command = "composer install -d " . ROOT_PATH;
|
2022-02-12 15:48:26 +08:00
|
|
|
|
$this->executeCommand($command);
|
|
|
|
|
|
$this->doLog("[COMPOSER INSTALL] SUCCESS");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-08 15:08:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
2021-05-01 02:02:01 +08:00
|
|
|
|
}
|