• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Info updated!

visavi / rotor / 26729174885

01 Jun 2026 12:38AM UTC coverage: 13.763% (-0.3%) from 14.072%
26729174885

push

github

visavi
Добавлено обновление ядра движка

1 of 131 new or added lines in 2 files covered. (0.76%)

3 existing lines in 1 file now uncovered.

790 of 5740 relevant lines covered (13.76%)

1.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

2.86
/app/Http/Controllers/Admin/UpgradeController.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace App\Http\Controllers\Admin;
6

7
use App\Services\GithubService;
8
use App\Services\MigrationService;
9
use App\Services\UpgradeService;
10
use Illuminate\Http\JsonResponse;
11
use Illuminate\Http\RedirectResponse;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Facades\Artisan;
14
use Illuminate\View\View;
15
use Throwable;
16

17
class UpgradeController extends AdminController
18
{
19
    public function __construct(
3✔
20
        private readonly MigrationService $migrations,
21
        private readonly UpgradeService $upgrade,
22
    ) {
23
    }
3✔
24

25
    /**
26
     * Страница обновлений
27
     */
UNCOV
28
    public function index(GithubService $githubService): View
×
29
    {
30
        $latestRelease = $githubService->getLatestRelease();
×
31
        $latestVersion = $githubService->getLatestVersionClean();
×
32

33
        $hasNewVersion = version_compare(ROTOR_VERSION, $latestVersion, '<');
×
NEW
34
        $pendingMigrations = $this->migrations->getPendingMigrations($this->migrationPaths());
×
NEW
35
        $newReleases = $this->upgrade->getNewReleases($githubService);
×
NEW
36
        $permErrors = $this->upgrade->checkPermissions();
×
37

NEW
38
        return view('admin/upgrade/index', compact(
×
NEW
39
            'hasNewVersion',
×
NEW
40
            'latestRelease',
×
NEW
41
            'pendingMigrations',
×
NEW
42
            'newReleases',
×
NEW
43
            'permErrors',
×
NEW
44
        ));
×
45
    }
46

47
    /**
48
     * Скачивает и распаковывает архив релиза
49
     */
NEW
50
    public function download(Request $request): JsonResponse
×
51
    {
NEW
52
        $tag = (string) $request->input('tag');
×
NEW
53
        $url = (string) $request->input('url');
×
54

NEW
55
        if (! $tag || ! $url) {
×
NEW
56
            return response()->json(['error' => __('admin.upgrade.invalid_params')], 422);
×
57
        }
58

NEW
59
        ini_set('max_execution_time', 0);
×
NEW
60
        set_time_limit(0);
×
61

62
        try {
NEW
63
            $this->upgrade->downloadRelease($tag, $url);
×
NEW
64
        } catch (Throwable $e) {
×
NEW
65
            return response()->json(['error' => $e->getMessage()], 500);
×
66
        }
67

NEW
68
        return response()->json(['success' => true]);
×
69
    }
70

71
    /**
72
     * Применяет скачанное обновление
73
     */
NEW
74
    public function apply(Request $request): JsonResponse
×
75
    {
NEW
76
        $tag = (string) $request->input('tag');
×
77

NEW
78
        if (! $tag) {
×
NEW
79
            return response()->json(['error' => __('admin.upgrade.invalid_params')], 422);
×
80
        }
81

82
        try {
NEW
83
            $errors = $this->upgrade->applyUpdate($tag);
×
NEW
84
            $this->upgrade->cleanup($tag);
×
NEW
85
        } catch (Throwable $e) {
×
NEW
86
            return response()->json(['error' => $e->getMessage()], 500);
×
87
        }
88

NEW
89
        Artisan::call('cache:clear');
×
NEW
90
        Artisan::call('route:clear');
×
NEW
91
        Artisan::call('config:clear');
×
92

NEW
93
        return response()->json([
×
NEW
94
            'success' => true,
×
NEW
95
            'errors'  => $errors,
×
NEW
96
        ]);
×
97
    }
98

99
    /**
100
     * Выполняет все миграции
101
     */
UNCOV
102
    public function migrate(Request $request): JsonResponse|RedirectResponse
×
103
    {
104
        Artisan::call('migrate', ['--force' => true]);
×
105
        $output = Artisan::output();
×
106

107
        if ($request->ajax()) {
×
108
            return response()->json(['output' => $output]);
×
109
        }
110

111
        return redirect()->route('admin.upgrade.index')->with('migrateOutput', $output);
×
112
    }
113

114
    /**
115
     * Выполняет одну следующую миграцию
116
     */
UNCOV
117
    public function migrateNext(): JsonResponse
×
118
    {
119
        ini_set('max_execution_time', 0);
×
120
        set_time_limit(0);
×
121

NEW
122
        $pending = $this->migrations->getPendingMigrations($this->migrationPaths());
×
123

124
        if (empty($pending)) {
×
125
            Artisan::call('cache:clear');
×
126
            Artisan::call('route:clear');
×
127
            Artisan::call('config:clear');
×
128

129
            return response()->json(['done' => true, 'migration' => null, 'output' => '']);
×
130
        }
131

132
        $name = $pending[0];
×
133
        $file = $this->migrations->findFile($name);
×
134

135
        if (! $file) {
×
136
            return response()->json(['error' => "Файл миграции не найден: {$name}"], 500);
×
137
        }
138

139
        $remaining = count($pending) - 1;
×
140

141
        return response()->json([
×
142
            'done'      => $remaining === 0,
×
143
            'migration' => $name,
×
144
            'output'    => $this->migrations->runOne($file),
×
145
            'remaining' => $remaining,
×
146
        ]);
×
147
    }
148

149
    /**
150
     * Пути к папкам с миграциями
151
     */
NEW
152
    private function migrationPaths(): array
×
153
    {
154
        return [database_path('migrations'), database_path('upgrades')];
×
155
    }
156
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc