You've already forked Atomcms-edit
187 lines
7.6 KiB
PHP
Executable File
187 lines
7.6 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class UpdateHistoryService
|
|
{
|
|
private const string TABLE = 'update_history';
|
|
|
|
public function ensureTableExists(): void
|
|
{
|
|
if (! Schema::hasTable(self::TABLE)) {
|
|
Schema::create(self::TABLE, function ($table) {
|
|
$table->id();
|
|
$table->string('type'); // nitro, emulator, sql, config
|
|
$table->string('action'); // update, build, deploy, fix
|
|
$table->string('item')->nullable(); // filename, version, etc
|
|
$table->string('status'); // success, failed, pending
|
|
$table->text('message')->nullable();
|
|
$table->string('user')->nullable();
|
|
$table->string('ip')->nullable();
|
|
$table->timestamp('created_at')->useCurrent();
|
|
$table->index(['type', 'created_at']);
|
|
$table->index('status');
|
|
});
|
|
}
|
|
}
|
|
|
|
public function log(string $type, string $action, ?string $item = null, string $status = 'success', ?string $message = null): void
|
|
{
|
|
$this->ensureTableExists();
|
|
|
|
DB::table(self::TABLE)->insert([
|
|
'type' => $type,
|
|
'action' => $action,
|
|
'item' => $item,
|
|
'status' => $status,
|
|
'message' => $message,
|
|
'user' => auth()->user()?->name ?? 'System',
|
|
'ip' => request()->ip(),
|
|
'created_at' => now(),
|
|
]);
|
|
}
|
|
|
|
public function getRecent(int $limit = 50): array
|
|
{
|
|
$this->ensureTableExists();
|
|
|
|
return DB::table(self::TABLE)
|
|
->orderBy('created_at', 'desc')
|
|
->limit($limit)
|
|
->get()
|
|
->toArray();
|
|
}
|
|
|
|
public function getByType(string $type, int $limit = 50): array
|
|
{
|
|
$this->ensureTableExists();
|
|
|
|
return DB::table(self::TABLE)
|
|
->where('type', $type)
|
|
->orderBy('created_at', 'desc')
|
|
->limit($limit)
|
|
->get()
|
|
->toArray();
|
|
}
|
|
|
|
public function getByStatus(string $status, int $limit = 50): array
|
|
{
|
|
$this->ensureTableExists();
|
|
|
|
return DB::table(self::TABLE)
|
|
->where('status', $status)
|
|
->orderBy('created_at', 'desc')
|
|
->limit($limit)
|
|
->get()
|
|
->toArray();
|
|
}
|
|
|
|
public function getStats(): array
|
|
{
|
|
$this->ensureTableExists();
|
|
|
|
$total = DB::table(self::TABLE)->count();
|
|
$success = DB::table(self::TABLE)->where('status', 'success')->count();
|
|
$failed = DB::table(self::TABLE)->where('status', 'failed')->count();
|
|
|
|
$lastUpdate = DB::table(self::TABLE)
|
|
->orderBy('created_at', 'desc')
|
|
->first();
|
|
|
|
$byType = DB::table(self::TABLE)
|
|
->select('type', DB::raw('count(*) as count'))
|
|
->groupBy('type')
|
|
->pluck('count', 'type')
|
|
->toArray();
|
|
|
|
return [
|
|
'total' => $total,
|
|
'success' => $success,
|
|
'failed' => $failed,
|
|
'success_rate' => $total > 0 ? round(($success / $total) * 100) : 100,
|
|
'last_update' => $lastUpdate,
|
|
'by_type' => $byType,
|
|
];
|
|
}
|
|
|
|
public function getHtml(): string
|
|
{
|
|
$this->ensureTableExists();
|
|
|
|
$updates = $this->getRecent(20);
|
|
$stats = $this->getStats();
|
|
|
|
$html = '<div style="font-family: -apple-system, BlinkMacSystemFont, sans-serif;">';
|
|
|
|
// Stats
|
|
$html .= '<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px;">';
|
|
$html .= '<div style="background: rgba(255,255,255,0.05); padding: 12px; border-radius: 8px; text-align: center;">';
|
|
$html .= '<div style="font-size: 24px; font-weight: 700; color: #4ade80;">' . $stats['total'] . '</div>';
|
|
$html .= '<div style="font-size: 10px; color: #64748b; text-transform: uppercase;">Totaal</div></div>';
|
|
$html .= '<div style="background: rgba(255,255,255,0.05); padding: 12px; border-radius: 8px; text-align: center;">';
|
|
$html .= '<div style="font-size: 24px; font-weight: 700; color: #4ade80;">' . $stats['success'] . '</div>';
|
|
$html .= '<div style="font-size: 10px; color: #64748b; text-transform: uppercase;">Geslaagd</div></div>';
|
|
$html .= '<div style="background: rgba(255,255,255,0.05); padding: 12px; border-radius: 8px; text-align: center;">';
|
|
$html .= '<div style="font-size: 24px; font-weight: 700; color: #f87171;">' . $stats['failed'] . '</div>';
|
|
$html .= '<div style="font-size: 10px; color: #64748b; text-transform: uppercase;">Mislukt</div></div>';
|
|
$html .= '<div style="background: rgba(255,255,255,0.05); padding: 12px; border-radius: 8px; text-align: center;">';
|
|
$html .= '<div style="font-size: 24px; font-weight: 700; color: #60a5fa;">' . $stats['success_rate'] . '%</div>';
|
|
$html .= '<div style="font-size: 10px; color: #64748b; text-transform: uppercase;">Succes</div></div>';
|
|
$html .= '</div>';
|
|
|
|
// History list
|
|
if ($updates === []) {
|
|
$html .= '<div style="text-align: center; padding: 24px; color: #64748b;">';
|
|
$html .= '<div style="font-size: 32px; margin-bottom: 8px;">📋</div>';
|
|
$html .= 'Nog geen update geschiedenis</div>';
|
|
} else {
|
|
$html .= '<div style="max-height: 400px; overflow-y: auto;">';
|
|
foreach ($updates as $update) {
|
|
$icon = match ($update->status) {
|
|
'success' => '✅',
|
|
'failed' => '❌',
|
|
'pending' => '⏳',
|
|
default => '⚪'
|
|
};
|
|
|
|
$typeColor = match ($update->type) {
|
|
'nitro' => '#4ade80',
|
|
'emulator' => '#60a5fa',
|
|
'sql' => '#fbbf24',
|
|
'config' => '#a78bfa',
|
|
default => '#94a3b8'
|
|
};
|
|
|
|
$time = Carbon::parse($update->created_at)->diffForHumans();
|
|
|
|
$html .= '<div style="display: flex; align-items: center; gap: 12px; padding: 10px 12px; background: rgba(255,255,255,0.03); border-radius: 8px; margin-bottom: 6px;">';
|
|
$html .= '<div style="font-size: 16px;">' . $icon . '</div>';
|
|
$html .= '<div style="flex: 1;">';
|
|
$html .= '<div style="display: flex; align-items: center; gap: 8px;">';
|
|
$html .= '<span style="background: ' . $typeColor . '20; color: ' . $typeColor . '; padding: 2px 8px; border-radius: 12px; font-size: 10px; font-weight: 600; text-transform: uppercase;">' . e($update->type) . '</span>';
|
|
$html .= '<span style="color: #e2e8f0; font-size: 13px;">' . e($update->action) . '</span>';
|
|
if ($update->item) {
|
|
$html .= '<span style="color: #94a3b8; font-size: 12px;">' . e($update->item) . '</span>';
|
|
}
|
|
$html .= '</div>';
|
|
if ($update->message) {
|
|
$html .= '<div style="color: #64748b; font-size: 11px; margin-top: 2px;">' . e($update->message) . '</div>';
|
|
}
|
|
$html .= '</div>';
|
|
$html .= '<div style="text-align: right;">';
|
|
$html .= '<div style="color: #64748b; font-size: 10px;">' . e($update->user) . '</div>';
|
|
$html .= '<div style="color: #475569; font-size: 9px;">' . e($time) . '</div>';
|
|
$html .= '</div>';
|
|
$html .= '</div>';
|
|
}
|
|
$html .= '</div>';
|
|
}
|
|
|
|
return $html . '</div>';
|
|
}
|
|
}
|