• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visavi / rotor / 26764888553

01 Jun 2026 03:32PM UTC coverage: 13.665%. Remained the same
26764888553

push

github

visavi
Обновление движка перенес под уровен boss

0 of 1 new or added line in 1 file covered. (0.0%)

790 of 5781 relevant lines covered (13.67%)

1.21 hits per line

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

2.78
/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
     */
28
    public function index(GithubService $githubService): View
×
29
    {
30
        $latestRelease = $githubService->getLatestRelease();
×
31
        $latestVersion = $githubService->getLatestVersionClean();
×
32

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

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

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

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

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

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

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

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

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

82
        Artisan::call('down');
×
83

84
        try {
85
            $errors = $this->upgrade->applyUpdate($tag);
×
86
            $this->upgrade->cleanup($tag);
×
87
        } catch (Throwable $e) {
×
88
            return response()->json(['error' => $e->getMessage()], 500);
×
89
        } finally {
90
            Artisan::call('up');
×
91
        }
92

93
        Artisan::call('cache:clear');
×
94
        Artisan::call('route:clear');
×
95
        Artisan::call('config:clear');
×
96

97
        return response()->json([
×
98
            'success' => true,
×
99
            'errors'  => $errors,
×
100
        ]);
×
101
    }
102

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

111
        if ($request->ajax()) {
×
112
            return response()->json(['output' => $output]);
×
113
        }
114

115
        return redirect()->route('admin.upgrade.index')->with('migrateOutput', $output);
×
116
    }
117

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

126
        $pending = $this->migrations->getPendingMigrations($this->migrationPaths());
×
127

128
        if (empty($pending)) {
×
129
            Artisan::call('cache:clear');
×
130
            Artisan::call('route:clear');
×
131
            Artisan::call('config:clear');
×
132

133
            return response()->json(['done' => true, 'migration' => null, 'output' => '']);
×
134
        }
135

136
        $name = $pending[0];
×
137
        $file = $this->migrations->findFile($name);
×
138

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

143
        $remaining = count($pending) - 1;
×
144

145
        return response()->json([
×
146
            'done'      => $remaining === 0,
×
147
            'migration' => $name,
×
148
            'output'    => $this->migrations->runOne($file),
×
149
            'remaining' => $remaining,
×
150
        ]);
×
151
    }
152

153
    /**
154
     * Пути к папкам с миграциями
155
     */
156
    private function migrationPaths(): array
×
157
    {
158
        return [database_path('migrations'), database_path('upgrades')];
×
159
    }
160
}
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