1087 lines
36 KiB
PHP
1087 lines
36 KiB
PHP
<?php
|
||
|
||
namespace App\Livewire\Ui\System;
|
||
|
||
use Illuminate\Support\Facades\Artisan;
|
||
use Illuminate\Support\Facades\Cache;
|
||
use Livewire\Component;
|
||
|
||
class UpdateCard extends Component
|
||
{
|
||
public ?string $current = null;
|
||
public ?string $latest = null;
|
||
public ?string $displayCurrent = null;
|
||
public ?string $displayLatest = null;
|
||
|
||
public bool $hasUpdate = false;
|
||
public string $state = 'idle';
|
||
public ?string $message = null;
|
||
public ?bool $messagePositive = null;
|
||
|
||
public bool $running = false;
|
||
public ?int $rc = null;
|
||
|
||
protected string $cacheStartedAtKey = 'mw.update.started_at';
|
||
protected int $failsafeSeconds = 20 * 60; // 20 Minuten
|
||
|
||
public function mount(): void
|
||
{
|
||
$this->reloadVersionsAndStatus();
|
||
$this->recompute();
|
||
if ($this->running) $this->state = 'running';
|
||
}
|
||
|
||
public function render()
|
||
{
|
||
return view('livewire.ui.system.update-card');
|
||
}
|
||
|
||
/* ========== Aktionen ========== */
|
||
|
||
public function refreshState(): void
|
||
{
|
||
$this->state = 'running';
|
||
$this->message = 'Prüfe auf Updates …';
|
||
$this->messagePositive = null;
|
||
|
||
try {
|
||
Artisan::call('mailwolt:check-updates');
|
||
} catch (\Throwable $e) {
|
||
// kein fataler Abbruch
|
||
}
|
||
|
||
$this->reloadVersionsAndStatus();
|
||
$this->recompute();
|
||
$this->finishUiIfNoUpdate();
|
||
}
|
||
|
||
public function runUpdate(): void
|
||
{
|
||
Cache::forget('mailwolt.update_available');
|
||
Cache::put($this->cacheStartedAtKey, time(), now()->addHour());
|
||
|
||
@shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
|
||
$this->latest = null;
|
||
$this->displayLatest = null;
|
||
$this->hasUpdate = false;
|
||
$this->state = 'running';
|
||
$this->running = true;
|
||
$this->message = 'Update läuft …';
|
||
}
|
||
|
||
public function tick(): void
|
||
{
|
||
$this->refreshLowLevelState();
|
||
|
||
$started = (int)Cache::get($this->cacheStartedAtKey, 0);
|
||
if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) {
|
||
$this->running = false;
|
||
$this->rc ??= 0;
|
||
}
|
||
|
||
if (!$this->running) {
|
||
Cache::forget($this->cacheStartedAtKey);
|
||
$this->reloadVersionsAndStatus();
|
||
$this->recompute();
|
||
$this->finishUiIfNoUpdate();
|
||
|
||
if ($this->rc === 0) {
|
||
$ver = $this->displayCurrent ?? 'aktuelle Version';
|
||
|
||
// ✅ zentraler Toastra-Toast
|
||
$this->dispatch('toast',
|
||
type: 'success',
|
||
title: 'Update erfolgreich',
|
||
text: "MailWolt wurde erfolgreich auf {$ver} aktualisiert. Die Seite wird in 5 Sekunden neu geladen …",
|
||
badge: 'System',
|
||
duration: 5000
|
||
);
|
||
|
||
// nach 5 Sekunden Seite neu laden
|
||
$this->dispatch('reload-page', delay: 5000);
|
||
} elseif ($this->rc !== null) {
|
||
$this->dispatch('toast',
|
||
type: 'error',
|
||
title: 'Update fehlgeschlagen',
|
||
text: "Update ist mit Rückgabecode {$this->rc} fehlgeschlagen. Bitte Logs prüfen.",
|
||
badge: 'System',
|
||
duration: 0
|
||
);
|
||
}
|
||
|
||
$this->state = 'idle';
|
||
}
|
||
}
|
||
|
||
/* ========== Helper ========== */
|
||
|
||
protected function reloadVersionsAndStatus(): void
|
||
{
|
||
$this->current = $this->readCurrentVersion();
|
||
$this->latest = Cache::get('mailwolt.update_available');
|
||
$this->refreshLowLevelState();
|
||
}
|
||
|
||
protected function finishUiIfNoUpdate(): void
|
||
{
|
||
if (!$this->hasUpdate) {
|
||
$this->state = 'idle';
|
||
$cur = $this->displayCurrent ?? '–';
|
||
$this->message = "Du bist auf dem neuesten Stand ({$cur})";
|
||
$this->messagePositive = true;
|
||
Cache::forget('mailwolt.update_available');
|
||
}
|
||
}
|
||
|
||
protected function recompute(): void
|
||
{
|
||
$curNorm = $this->normalizeVersion($this->current);
|
||
$latNorm = $this->normalizeVersion($this->latest);
|
||
|
||
$this->hasUpdate = ($curNorm && $latNorm)
|
||
? version_compare($latNorm, $curNorm, '>')
|
||
: false;
|
||
|
||
// Immer mit v-Präfix anzeigen
|
||
$this->displayCurrent = $curNorm ? 'v' . $curNorm : null;
|
||
$this->displayLatest = ($this->hasUpdate && $latNorm) ? 'v' . $latNorm : null;
|
||
}
|
||
|
||
protected function refreshLowLevelState(): void
|
||
{
|
||
$state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
$this->running = ($state === 'running');
|
||
|
||
$rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
$this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
}
|
||
|
||
protected function readCurrentVersion(): ?string
|
||
{
|
||
$build = @file_get_contents('/etc/mailwolt/build.info');
|
||
if ($build) {
|
||
foreach (preg_split('/\R+/', $build) as $line) {
|
||
if (str_starts_with($line, 'version=')) {
|
||
$v = trim(substr($line, 8));
|
||
return $v !== '' ? $v : null;
|
||
}
|
||
}
|
||
}
|
||
$v = config('app.version');
|
||
return $v !== '' ? $v : null;
|
||
}
|
||
|
||
protected function normalizeVersion(?string $v): ?string
|
||
{
|
||
if ($v === null) return null;
|
||
$v = trim($v);
|
||
return ltrim($v, "vV \t\n\r\0\x0B") ?: null;
|
||
}
|
||
}
|
||
|
||
|
||
//namespace App\Livewire\Ui\System;
|
||
//
|
||
//use Illuminate\Support\Facades\Artisan;
|
||
//use Illuminate\Support\Facades\Cache;
|
||
//use Livewire\Component;
|
||
//
|
||
//class UpdateCard extends Component
|
||
//{
|
||
// /** Rohwerte (so wie gelesen/aus Cache) */
|
||
// public ?string $current = null; // z.B. "v1.0.20" oder "1.0.20"
|
||
// public ?string $latest = null; // z.B. "1.0.20" oder "v1.0.20"
|
||
//
|
||
// /** Anzeige (immer mit v-Präfix) */
|
||
// public ?string $displayCurrent = null; // z.B. "v1.0.20"
|
||
// public ?string $displayLatest = null; // nur gesetzt, wenn wirklich neuer
|
||
//
|
||
// /** Status/UX */
|
||
// public bool $hasUpdate = false;
|
||
// public string $state = 'idle'; // idle|running
|
||
// public ?string $message = null;
|
||
// public ?bool $messagePositive = null;
|
||
//
|
||
// /** low-level / Wrapper */
|
||
// public bool $running = false;
|
||
// public ?int $rc = null;
|
||
//
|
||
// /** intern */
|
||
// protected string $cacheStartedAtKey = 'mw.update.started_at';
|
||
// protected int $failsafeSeconds = 20 * 60; // 20 Min
|
||
//
|
||
// public function mount(): void
|
||
// {
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
// $this->refreshLowLevelState();
|
||
//
|
||
// $this->recompute(); // setzt hasUpdate + display* + ggf. message
|
||
// if ($this->running) $this->state = 'running';
|
||
// }
|
||
//
|
||
// public function render()
|
||
// {
|
||
// return view('livewire.ui.system.update-card');
|
||
// }
|
||
//
|
||
// /* =================== Aktionen =================== */
|
||
//
|
||
// public function refreshState(): void
|
||
// {
|
||
// $this->state = 'running';
|
||
// $this->message = 'Prüfe auf Updates …';
|
||
// $this->messagePositive = null;
|
||
//
|
||
// try {
|
||
// Artisan::call('mailwolt:check-updates');
|
||
// } catch (\Throwable $e) {
|
||
// // weich fallen
|
||
// }
|
||
//
|
||
// $this->reloadVersionsAndStatus();
|
||
// $this->recompute();
|
||
// $this->finishUiIfNoUpdate(); // beendet progress, wenn nichts mehr offen ist
|
||
// }
|
||
//
|
||
// public function runUpdate(): void
|
||
// {
|
||
// // Hinweis sofort entfernen (Badge weg)
|
||
// Cache::forget('mailwolt.update_available');
|
||
// Cache::put($this->cacheStartedAtKey, time(), now()->addHour());
|
||
//
|
||
// // Wrapper asynchron starten
|
||
// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
//
|
||
// // UI-Status
|
||
// $this->latest = null;
|
||
// $this->displayLatest = null;
|
||
// $this->hasUpdate = false;
|
||
//
|
||
// $this->state = 'running';
|
||
// $this->running = true;
|
||
// $this->message = 'Update läuft …';
|
||
// $this->messagePositive = null;
|
||
// }
|
||
//
|
||
// /** Wird nur gepollt, solange $state==='running' (wire:poll) */
|
||
// public function tick(): void
|
||
// {
|
||
// $this->refreshLowLevelState();
|
||
//
|
||
// // Failsafe
|
||
// $started = (int)Cache::get($this->cacheStartedAtKey, 0);
|
||
// if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) {
|
||
// $this->running = false;
|
||
// }
|
||
//
|
||
// if (!$this->running) {
|
||
// Cache::forget($this->cacheStartedAtKey);
|
||
// $this->reloadVersionsAndStatus();
|
||
// $this->recompute();
|
||
// $this->finishUiIfNoUpdate();
|
||
// }
|
||
// }
|
||
//
|
||
// /* =================== Helpers =================== */
|
||
//
|
||
// protected function reloadVersionsAndStatus(): void
|
||
// {
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
// $this->refreshLowLevelState();
|
||
// }
|
||
//
|
||
// protected function finishUiIfNoUpdate(): void
|
||
// {
|
||
// if (!$this->hasUpdate) {
|
||
// $this->state = 'idle';
|
||
// $cur = $this->displayCurrent ?? '–';
|
||
// // <<< Klammern-Fix: erst coalescen, dann in den String einsetzen
|
||
// $this->message = "Du bist auf dem neuesten Stand ({$cur})";
|
||
// $this->messagePositive = true;
|
||
//
|
||
// // zur Sicherheit: Cache leeren
|
||
// Cache::forget('mailwolt.update_available');
|
||
// }
|
||
// }
|
||
//
|
||
// protected function recompute(): void
|
||
// {
|
||
// $curNorm = $this->normalizeVersion($this->current);
|
||
// $latNorm = $this->normalizeVersion($this->latest);
|
||
//
|
||
// $this->hasUpdate = ($curNorm && $latNorm)
|
||
// ? version_compare($latNorm, $curNorm, '>')
|
||
// : false;
|
||
//
|
||
// // Anzeige immer mit v-Präfix
|
||
// $this->displayCurrent = $curNorm ? 'v' . $curNorm : null;
|
||
// $this->displayLatest = ($this->hasUpdate && $latNorm) ? 'v' . $latNorm : null;
|
||
//
|
||
// // Initiale Message (nur wenn noch nicht gesetzt)
|
||
// if ($this->message === null) {
|
||
// if ($this->hasUpdate) {
|
||
// $this->message = "Neue Version verfügbar: {$this->displayLatest}";
|
||
// $this->messagePositive = false;
|
||
// } else {
|
||
// $cur = $this->displayCurrent ?? '–';
|
||
// $this->message = "Du bist auf dem neuesten Stand ({$cur})";
|
||
// $this->messagePositive = true;
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
// protected function refreshLowLevelState(): void
|
||
// {
|
||
// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
// $this->running = ($state === 'running');
|
||
//
|
||
// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
// }
|
||
//
|
||
// protected function readCurrentVersion(): ?string
|
||
// {
|
||
// // bevorzugt build.info
|
||
// $build = @file_get_contents('/etc/mailwolt/build.info');
|
||
// if ($build) {
|
||
// foreach (preg_split('/\R+/', $build) as $line) {
|
||
// if (str_starts_with($line, 'version=')) {
|
||
// $v = trim(substr($line, 8));
|
||
// return $v !== '' ? $v : null;
|
||
// }
|
||
// }
|
||
// }
|
||
// $v = config('app.version');
|
||
// return $v !== '' ? $v : null;
|
||
// }
|
||
//
|
||
// protected function normalizeVersion(?string $v): ?string
|
||
// {
|
||
// if ($v === null) return null;
|
||
// $v = trim($v);
|
||
// // führendes v/V + whitespace entfernen
|
||
// $v = ltrim($v, "vV \t\n\r\0\x0B");
|
||
// return $v === '' ? null : $v;
|
||
// }
|
||
//}
|
||
|
||
//namespace App\Livewire\Ui\System;
|
||
//
|
||
//use Illuminate\Support\Facades\Artisan;
|
||
//use Illuminate\Support\Facades\Cache;
|
||
//use Livewire\Component;
|
||
//
|
||
//class UpdateCard extends Component
|
||
//{
|
||
// public ?string $current = null; // installierte Version
|
||
// public ?string $latest = null; // verfügbare Version (oder null)
|
||
// public string $state = 'idle'; // idle | running
|
||
//
|
||
// public ?string $message = null;
|
||
// public ?bool $messagePositive = null;
|
||
//
|
||
// // low-level
|
||
// public bool $running = false;
|
||
// public ?int $rc = null;
|
||
//
|
||
// // intern
|
||
// protected string $cacheStartedAtKey = 'mw.update.started_at';
|
||
// protected int $failsafeSeconds = 20 * 60; // 20 Min
|
||
//
|
||
// public function mount(): void
|
||
// {
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
// $this->refreshLowLevelState();
|
||
//
|
||
// // initiale Message
|
||
// if ($this->message === null) {
|
||
// if ($this->getHasUpdateProperty()) {
|
||
// $this->message = "Neue Version verfügbar: {$this->latest}";
|
||
// $this->messagePositive = false;
|
||
// } else {
|
||
// $cur = $this->current ?: '–';
|
||
// $this->message = "Du bist auf dem neuesten Stand ({$cur})";
|
||
// $this->messagePositive = true;
|
||
// }
|
||
// }
|
||
//
|
||
// // falls der Wrapper gerade läuft → visuell „running“
|
||
// if ($this->running) {
|
||
// $this->state = 'running';
|
||
// }
|
||
// }
|
||
//
|
||
// public function render()
|
||
// {
|
||
// return view('livewire.ui.system.update-card');
|
||
// }
|
||
//
|
||
// /* =================== Aktionen =================== */
|
||
//
|
||
// public function refreshState(): void
|
||
// {
|
||
// $this->state = 'running';
|
||
// $this->message = 'Prüfe auf Updates …';
|
||
// $this->messagePositive = null;
|
||
//
|
||
// try {
|
||
// Artisan::call('mailwolt:check-updates');
|
||
// } catch (\Throwable $e) {
|
||
// // weich fallen
|
||
// }
|
||
//
|
||
// $this->reloadVersionsAndStatus();
|
||
// $this->finishUiIfNoUpdate();
|
||
// }
|
||
//
|
||
// public function runUpdate(): void
|
||
// {
|
||
// // Badge „Update verfügbar“ sofort ausblenden
|
||
// Cache::forget('mailwolt.update_available');
|
||
//
|
||
// // Startzeit merken (Failsafe)
|
||
// Cache::put($this->cacheStartedAtKey, time(), now()->addHours(1));
|
||
//
|
||
// // Wrapper asynchron starten
|
||
// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
//
|
||
// $this->latest = null;
|
||
// $this->state = 'running';
|
||
// $this->running = true;
|
||
// $this->message = 'Update läuft …';
|
||
// $this->messagePositive = null;
|
||
// }
|
||
//
|
||
// /**
|
||
// * Wird vom Blade nur während running gepollt (wire:poll="tick").
|
||
// * Bricht den Fortschritt ab, sobald der Wrapper „done“ meldet ODER
|
||
// * der Failsafe greift. Lädt danach Versionen & Badge neu.
|
||
// */
|
||
// public function tick(): void
|
||
// {
|
||
// $this->refreshLowLevelState();
|
||
//
|
||
// // Failsafe: nach N Minuten Fortschritt aus
|
||
// $started = (int)Cache::get($this->cacheStartedAtKey, 0);
|
||
// if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) {
|
||
// $this->running = false;
|
||
// }
|
||
//
|
||
// if (!$this->running) {
|
||
// // abgeschlossen → Startmarke löschen
|
||
// Cache::forget($this->cacheStartedAtKey);
|
||
//
|
||
// // Versionen/Caches neu laden
|
||
// $this->reloadVersionsAndStatus();
|
||
//
|
||
// // wenn erfolgreich (rc=0) und keine neue Version mehr → Done
|
||
// $this->finishUiIfNoUpdate();
|
||
// }
|
||
// // wenn weiterhin running: nichts tun, UI zeigt Progress weiter
|
||
// }
|
||
//
|
||
// /* =================== Computed =================== */
|
||
//
|
||
// // Blade nutzt $this->hasUpdate
|
||
// public function getHasUpdateProperty(): bool
|
||
// {
|
||
// $cur = $this->normalizeVersion($this->current ?? null);
|
||
// $lat = $this->normalizeVersion($this->latest ?? null);
|
||
// if ($lat === null || $cur === null) return false;
|
||
// return version_compare($lat, $cur, '>');
|
||
// }
|
||
//
|
||
// /* =================== Helpers =================== */
|
||
//
|
||
// protected function reloadVersionsAndStatus(): void
|
||
// {
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
// $this->refreshLowLevelState();
|
||
// }
|
||
//
|
||
// protected function finishUiIfNoUpdate(): void
|
||
// {
|
||
// if (!$this->getHasUpdateProperty()) {
|
||
// // alles aktuell → Fortschritt aus, Badge „Aktuell“, Hinweistext grün
|
||
// $this->state = 'idle';
|
||
// $this->message = "Du bist auf dem neuesten Stand (" . $this->current ?? '–' . ")";
|
||
// $this->messagePositive = true;
|
||
//
|
||
// // zur Sicherheit Badge-Cache entfernen
|
||
// Cache::forget('mailwolt.update_available');
|
||
// }
|
||
// }
|
||
//
|
||
// protected function refreshLowLevelState(): void
|
||
// {
|
||
// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
// $this->running = ($state === 'running');
|
||
//
|
||
// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
// }
|
||
//
|
||
// protected function readCurrentVersion(): ?string
|
||
// {
|
||
// $build = @file_get_contents('/etc/mailwolt/build.info');
|
||
// if ($build) {
|
||
// foreach (preg_split('/\R+/', $build) as $line) {
|
||
// if (str_starts_with($line, 'version=')) {
|
||
// $v = trim(substr($line, 8));
|
||
// if ($v !== '') return $v;
|
||
// }
|
||
// }
|
||
// }
|
||
// $v = config('app.version');
|
||
// return $v !== '' ? $v : null;
|
||
// }
|
||
//
|
||
// protected function normalizeVersion(?string $v): ?string
|
||
// {
|
||
// if ($v === null) return null;
|
||
// $v = trim($v);
|
||
// $v = ltrim($v, 'v'); // führt "v1.0.19" und "1.0.19" zusammen
|
||
// return $v === '' ? null : $v;
|
||
// }
|
||
//}
|
||
|
||
//namespace App\Livewire\Ui\System;
|
||
//
|
||
//use Illuminate\Support\Facades\Artisan;
|
||
//use Illuminate\Support\Facades\Cache;
|
||
//use Livewire\Component;
|
||
//
|
||
//class UpdateCard extends Component
|
||
//{
|
||
// public ?string $current = null; // installed (pretty)
|
||
// public ?string $latest = null; // available (pretty or null)
|
||
// public string $state = 'idle'; // idle|running
|
||
//
|
||
// public ?string $message = null; // inline message
|
||
// public ?bool $messagePositive = null;
|
||
//
|
||
// // low-level
|
||
// public bool $running = false;
|
||
// public ?int $rc = null;
|
||
//
|
||
// // ---- lifecycle ---------------------------------------------------------
|
||
//
|
||
// public function mount(): void
|
||
// {
|
||
// $this->readLowLevel();
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = $this->readCachedLatest();
|
||
//
|
||
// if ($this->message === null) {
|
||
// if ($this->hasUpdate()) {
|
||
// $this->message = "Neue Version verfügbar: {$this->latest}";
|
||
// $this->messagePositive = false;
|
||
// } else {
|
||
// $cur = $this->current ?? '–';
|
||
// $this->message = "Du bist auf dem neuesten Stand ({$cur})";
|
||
// $this->messagePositive = true;
|
||
// }
|
||
// }
|
||
//
|
||
// // if wrapper is already running when page loads, reflect that
|
||
// if ($this->running) {
|
||
// $this->state = 'running';
|
||
// }
|
||
// }
|
||
//
|
||
// public function render()
|
||
// {
|
||
// return view('livewire.ui.system.update-card');
|
||
// }
|
||
//
|
||
// // ---- UI actions --------------------------------------------------------
|
||
//
|
||
// /** Button: „Erneut prüfen“ (no toast; shows inline progress) */
|
||
// public function refreshState(): void
|
||
// {
|
||
// $this->state = 'running';
|
||
// $this->message = 'Prüfe auf Updates …';
|
||
// $this->messagePositive = null;
|
||
//
|
||
// try {
|
||
// // your checker should update the cache key below
|
||
// Artisan::call('mailwolt:check-updates');
|
||
// } catch (\Throwable $e) {
|
||
// // swallow but still continue to show something meaningful
|
||
// }
|
||
//
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = $this->readCachedLatest();
|
||
// $this->readLowLevel();
|
||
//
|
||
// if ($this->hasUpdate()) {
|
||
// $this->message = "Neue Version verfügbar: {$this->latest}";
|
||
// $this->messagePositive = false;
|
||
// } else {
|
||
// $this->message = "Du bist auf dem neuesten Stand ($this->current ?? '–')";
|
||
// $this->messagePositive = true;
|
||
// }
|
||
//
|
||
// $this->state = 'idle';
|
||
// }
|
||
//
|
||
// /** Button: „Jetzt aktualisieren“ (no toast; start wrapper + progress) */
|
||
// public function runUpdate(): void
|
||
// {
|
||
// // Hide the yellow badges immediately
|
||
// Cache::forget('mailwolt.update_available');
|
||
//
|
||
// // spawn wrapper in the background
|
||
// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
//
|
||
// // reflect “running” in UI
|
||
// $this->latest = null;
|
||
// $this->state = 'running';
|
||
// $this->running = true;
|
||
// $this->message = 'Update läuft …';
|
||
// $this->messagePositive = null;
|
||
// }
|
||
//
|
||
// /**
|
||
// * Called from the blade with `wire:poll.1200ms="tick"` – but **only**
|
||
// * when $state === 'running'. This finishes the UX once the wrapper ends.
|
||
// */
|
||
// public function tick(): void
|
||
// {
|
||
// if ($this->state !== 'running') return;
|
||
//
|
||
// $this->readLowLevel();
|
||
//
|
||
// if (!$this->running) { // wrapper finished
|
||
// // give build.info a split second to land on slow disks
|
||
// usleep(150000);
|
||
//
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = $this->readCachedLatest();
|
||
//
|
||
// if ($this->rc === 0) {
|
||
// // success path
|
||
// if ($this->hasUpdate()) {
|
||
// // very unlikely right after success, but handle anyway
|
||
// $this->message = "Neue Version verfügbar: {$this->latest}";
|
||
// $this->messagePositive = false;
|
||
// } else {
|
||
// $this->message = "Update erfolgreich – jetzt: {$this->current}";
|
||
// $this->messagePositive = true;
|
||
// }
|
||
// } else {
|
||
// // failure path
|
||
// $rc = $this->rc ?? 1;
|
||
// $this->message = "Update fehlgeschlagen (rc={$rc})";
|
||
// $this->messagePositive = false;
|
||
// }
|
||
//
|
||
// $this->state = 'idle';
|
||
// }
|
||
// }
|
||
//
|
||
// // ---- helpers -----------------------------------------------------------
|
||
//
|
||
// public function getHasUpdateProperty(): bool
|
||
// {
|
||
// // gleiche Logik wie in deiner Klasse:
|
||
// $cur = $this->normalizeVersion($this->current ?? null);
|
||
// $lat = $this->normalizeVersion($this->latest ?? null);
|
||
// if ($lat === null || $cur === null) return false;
|
||
// return version_compare($lat, $cur, '>');
|
||
// }
|
||
//
|
||
// protected function hasUpdate(): bool
|
||
// {
|
||
// $cur = $this->normalizeVersion($this->current);
|
||
// $lat = $this->normalizeVersion($this->latest);
|
||
//
|
||
// if ($lat === null || $cur === null) return false;
|
||
// return version_compare($lat, $cur, '>');
|
||
// }
|
||
//
|
||
// protected function readLowLevel(): void
|
||
// {
|
||
// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
// $this->running = ($state === 'running');
|
||
//
|
||
// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
// }
|
||
//
|
||
// protected function readCurrentVersion(): ?string
|
||
// {
|
||
// // Prefer the installer/updater stamp
|
||
// $build = @file_get_contents('/etc/mailwolt/build.info');
|
||
// if ($build) {
|
||
// foreach (preg_split('/\R+/', $build) as $line) {
|
||
// if (str_starts_with($line, 'version=')) {
|
||
// $v = trim(substr($line, 8));
|
||
// if ($v !== '') return $this->prettyVersion($v);
|
||
// }
|
||
// }
|
||
// }
|
||
// $v = trim((string)config('app.version', ''));
|
||
// return $v !== '' ? $this->prettyVersion($v) : null;
|
||
// }
|
||
//
|
||
// protected function readCachedLatest(): ?string
|
||
// {
|
||
// $v = Cache::get('mailwolt.update_available');
|
||
// if (!is_string($v) || $v === '') return null;
|
||
// return $this->prettyVersion($v);
|
||
// }
|
||
//
|
||
// /**
|
||
// * Return a “compare-safe” semver string: e.g. `v1.0.18` → `1.0.18`.
|
||
// * Accepts tags like `release-1.0.18` too.
|
||
// */
|
||
// protected function normalizeVersion(?string $v): ?string
|
||
// {
|
||
// if (!$v) return null;
|
||
// // keep only the first x.y.z like portion
|
||
// if (preg_match('/(\d+\.\d+\.\d+)/', $v, $m)) {
|
||
// return $m[1];
|
||
// }
|
||
// // fallback: bare digits (x.y)
|
||
// if (preg_match('/(\d+\.\d+)/', $v, $m)) {
|
||
// return $m[1];
|
||
// }
|
||
// return null;
|
||
// }
|
||
//
|
||
// /** Always render with a single leading `v` (no “vv…”) */
|
||
// protected function prettyVersion(string $v): string
|
||
// {
|
||
// $n = $this->normalizeVersion($v);
|
||
// return $n ? 'v' . $n : $v;
|
||
// }
|
||
//}
|
||
|
||
//namespace App\Livewire\Ui\System;
|
||
//
|
||
//use Livewire\Component;
|
||
//use Illuminate\Support\Facades\Artisan;
|
||
//use Illuminate\Support\Facades\Cache;
|
||
//
|
||
//class UpdateCard extends Component
|
||
//{
|
||
// public ?string $current = null; // installierte Version
|
||
// public ?string $latest = null; // verfügbare Version (oder null)
|
||
// public string $state = 'idle'; // idle | running
|
||
//
|
||
// // UI-Textausgabe nach einer Prüfung / Aktion
|
||
// public ?string $message = null; // z.B. "Du bist auf dem neuesten Stand (v1.0.16)"
|
||
// public ?bool $messagePositive = null; // true = grün, false = neutral/weiß
|
||
//
|
||
// // low-level (falls du sie später brauchst)
|
||
// public bool $running = false; // aus /var/lib/mailwolt/update/state
|
||
// public ?int $rc = null;
|
||
//
|
||
// public function mount(): void
|
||
// {
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
// $this->refreshLowLevelState();
|
||
//
|
||
// // Starttext, falls nichts geprüft wurde
|
||
// if ($this->message === null) {
|
||
// $this->message = $this->latest && $this->hasUpdate()
|
||
// ? "Neue Version verfügbar: {$this->latest}"
|
||
// : ($this->current ? "Du bist auf dem neuesten Stand ({$this->current})" : "Status unbekannt");
|
||
// $this->messagePositive = !$this->hasUpdate();
|
||
// }
|
||
// }
|
||
//
|
||
// public function render()
|
||
// {
|
||
// return view('livewire.ui.system.update-card');
|
||
// }
|
||
//
|
||
// /**
|
||
// * „Erneut prüfen“ – ohne Toast:
|
||
// * - Progress anzeigen
|
||
// * - Check-Command laufen lassen
|
||
// * - Message in der Box aktualisieren
|
||
// */
|
||
// public function refreshState(): void
|
||
// {
|
||
// $this->state = 'running';
|
||
// $this->message = 'Prüfe auf Updates …';
|
||
// $this->messagePositive = null;
|
||
//
|
||
// try {
|
||
// // Passe den Namen hier an dein tatsächliches Command an:
|
||
// Artisan::call('mailwolt:check-updates');
|
||
// } catch (\Throwable $e) {
|
||
// // weich fallen
|
||
// }
|
||
//
|
||
// // Daten neu einlesen
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
//
|
||
// if ($this->hasUpdate()) {
|
||
// $this->message = "Neue Version verfügbar: {$this->latest}";
|
||
// $this->messagePositive = false; // neutral
|
||
// } else {
|
||
// $cur = $this->current ?: '–';
|
||
// $this->message = "Du bist auf dem neuesten Stand ({$cur})";
|
||
// $this->messagePositive = true; // grün
|
||
// }
|
||
//
|
||
// $this->refreshLowLevelState();
|
||
// $this->state = 'idle';
|
||
// }
|
||
//
|
||
// /**
|
||
// * „Jetzt aktualisieren“ – ohne Toast:
|
||
// * - Hinweis sofort aus Cache entfernen (Badge weg)
|
||
// * - Update-Wrapper starten
|
||
// * - Running + Text in der Box anzeigen
|
||
// */
|
||
// public function runUpdate(): void
|
||
// {
|
||
// Cache::forget('mailwolt.update_available');
|
||
//
|
||
// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
//
|
||
// $this->latest = null;
|
||
// $this->state = 'running';
|
||
// $this->running = true;
|
||
// $this->message = 'Update läuft …';
|
||
// $this->messagePositive = null;
|
||
// }
|
||
//
|
||
// /** --------------------- helpers --------------------- */
|
||
//
|
||
// protected function hasUpdate(): bool
|
||
// {
|
||
// if (!$this->latest) return false;
|
||
// $cur = $this->current ?: '0.0.0';
|
||
// return version_compare($this->latest, $cur, '>');
|
||
// }
|
||
//
|
||
// protected function refreshLowLevelState(): void
|
||
// {
|
||
// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
// $this->running = ($state === 'running');
|
||
//
|
||
// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
// }
|
||
//
|
||
// protected function readCurrentVersion(): ?string
|
||
// {
|
||
// // bevorzugt /etc/mailwolt/build.info (wird im Installer/Updater gepflegt)
|
||
// $build = @file_get_contents('/etc/mailwolt/build.info');
|
||
// if ($build) {
|
||
// foreach (preg_split('/\R+/', $build) as $line) {
|
||
// if (str_starts_with($line, 'version=')) {
|
||
// $v = trim(substr($line, 8));
|
||
// if ($v !== '') return $v;
|
||
// }
|
||
// }
|
||
// }
|
||
// $v = config('app.version');
|
||
// return $v !== '' ? $v : null;
|
||
// }
|
||
//}
|
||
|
||
//
|
||
//
|
||
//namespace App\Livewire\Ui\System;
|
||
//
|
||
//use Livewire\Component;
|
||
//use Illuminate\Support\Facades\Artisan;
|
||
//use Illuminate\Support\Facades\Cache;
|
||
//
|
||
//class UpdateCard extends Component
|
||
//{
|
||
// public ?string $current = null; // z.B. v1.0.16 (aktuell installiert)
|
||
// public ?string $latest = null; // z.B. v1.0.17 (verfügbar) oder null
|
||
// public string $state = 'idle'; // idle | running
|
||
//
|
||
// // optional: Low-level-Infos, falls du sie irgendwo anders brauchst
|
||
// public bool $running = false; // Wrapper-/Updater läuft gerade (aus State-Datei)
|
||
// public string $log = '';
|
||
// public ?int $rc = null;
|
||
//
|
||
// public function mount(): void
|
||
// {
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
// $this->refreshLowLevelState(); // liest /var/lib/mailwolt/update/*
|
||
// }
|
||
//
|
||
// public function render()
|
||
// {
|
||
// return view('livewire.ui.system.update-card');
|
||
// }
|
||
//
|
||
// /**
|
||
// * „Erneut prüfen“:
|
||
// * - zeigt Running-Progress
|
||
// * - ruft den Checker (dein bestehendes Artisan-Command)
|
||
// * - aktualisiert $latest / $current
|
||
// * - dispatcht passenden Toast
|
||
// */
|
||
// public function refreshState(): void
|
||
// {
|
||
// $this->state = 'running';
|
||
//
|
||
// // Falls vorhanden: dein Command, der cache('mailwolt.update_available') setzt
|
||
// // -> Namen ggf. anpassen (du hattest z.B. mailwolt:check-updates erwähnt)
|
||
// try {
|
||
// Artisan::call('mailwolt:check-updates');
|
||
// } catch (\Throwable $e) {
|
||
// // Wenn das Command (noch) nicht existiert, nicht crashen – state einfach zurücksetzen
|
||
// }
|
||
//
|
||
// // App-Status neu einlesen
|
||
// $this->current = $this->readCurrentVersion();
|
||
// $this->latest = Cache::get('mailwolt.update_available');
|
||
//
|
||
// $hasUpdate = $this->hasUpdate();
|
||
//
|
||
// // Toast ausspielen
|
||
// $this->dispatch('toast',
|
||
// type: $hasUpdate ? 'info' : 'done',
|
||
// badge: 'Update',
|
||
// title: $hasUpdate ? 'Neue Version verfügbar' : 'Alles aktuell',
|
||
// text: $hasUpdate
|
||
// ? "Verfügbar: {$this->latest} – installiert: {$this->current}"
|
||
// : "Du bist auf dem neuesten Stand ({$this->current}).",
|
||
// duration: 6000
|
||
// );
|
||
//
|
||
// // Low-level-State (optional) und UI-State zurücksetzen
|
||
// $this->refreshLowLevelState();
|
||
// $this->state = 'idle';
|
||
// }
|
||
//
|
||
// /**
|
||
// * „Jetzt aktualisieren“:
|
||
// * - blendet die verfügbare-Version sofort aus
|
||
// * - startet den Root-Wrapper im Hintergrund
|
||
// * - zeigt einen Toast „Update gestartet“
|
||
// */
|
||
// public function runUpdate(): void
|
||
// {
|
||
// Cache::forget('mailwolt.update_available'); // Badge sofort weg
|
||
// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
//
|
||
// $this->state = 'running';
|
||
// $this->running = true;
|
||
//
|
||
// $this->dispatch('toast',
|
||
// type: 'info',
|
||
// badge: 'Update',
|
||
// title: 'Update gestartet',
|
||
// text: 'Das System wird aktualisiert …',
|
||
// duration: 6000
|
||
// );
|
||
// }
|
||
//
|
||
// /** ---- Helpers ------------------------------------------------------- */
|
||
//
|
||
// protected function hasUpdate(): bool
|
||
// {
|
||
// if (!$this->latest) return false;
|
||
// $cur = $this->current ?: '0.0.0';
|
||
// return version_compare($this->latest, $cur, '>');
|
||
// }
|
||
//
|
||
// protected function refreshLowLevelState(): void
|
||
// {
|
||
// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
// $this->running = ($state === 'running');
|
||
//
|
||
// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
//
|
||
// // Log bewusst NICHT angezeigt, aber verfügbar, falls du es später brauchst
|
||
// $this->log = @shell_exec('tail -n 200 /var/log/mailwolt-update.log 2>/dev/null') ?? '';
|
||
// }
|
||
//
|
||
// protected function readCurrentVersion(): ?string
|
||
// {
|
||
// // bevorzugt build.info, sonst config('app.version')
|
||
// $build = @file_get_contents('/etc/mailwolt/build.info');
|
||
// if ($build) {
|
||
// foreach (preg_split('/\R+/', $build) as $line) {
|
||
// if (str_starts_with($line, 'version=')) {
|
||
// $v = trim(substr($line, 8));
|
||
// if ($v !== '') return $v;
|
||
// }
|
||
// }
|
||
// }
|
||
// $v = config('app.version');
|
||
// return $v !== '' ? $v : null;
|
||
// }
|
||
//}
|
||
////
|
||
////namespace App\Livewire\Ui\System;
|
||
////
|
||
////use Livewire\Component;
|
||
////use Illuminate\Support\Facades\Artisan;
|
||
////use Illuminate\Support\Facades\Cache;
|
||
////
|
||
////class UpdateCard extends Component
|
||
////{
|
||
//// public ?string $current = null;
|
||
//// public ?string $latest = null;
|
||
//// public string $state = 'idle'; // idle|running
|
||
////
|
||
//// public bool $running = false;
|
||
//// public string $log = '';
|
||
//// public ?int $rc = null;
|
||
////
|
||
//// public function mount(): void
|
||
//// {
|
||
////// $this->refreshState();
|
||
//// $this->latest = cache('mailwolt.update_available');
|
||
////
|
||
//// }
|
||
////
|
||
//// public function render()
|
||
//// {
|
||
//// return view('livewire.ui.system.update-card');
|
||
//// }
|
||
////
|
||
//// public function refreshState(): void
|
||
//// {
|
||
//// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
|
||
//// $this->running = ($state === 'running');
|
||
////
|
||
//// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
|
||
//// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
|
||
////
|
||
//// // letzte 200 Zeilen Log
|
||
//// $this->log = @shell_exec('tail -n 200 /var/log/mailwolt-update.log 2>/dev/null') ?? '';
|
||
//// }
|
||
////
|
||
//// public function runUpdate(): void
|
||
//// {
|
||
//// // Hinweis „Update verfügbar“ ausblenden
|
||
//// cache()->forget('mailwolt.update_available');
|
||
////
|
||
//// // Update im Hintergrund starten
|
||
//// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &');
|
||
////
|
||
//// $this->running = true;
|
||
//// $this->dispatch('toast',
|
||
//// type: 'info',
|
||
//// badge: 'Update',
|
||
//// title: 'Update gestartet',
|
||
//// text: 'Das System wird aktualisiert …',
|
||
//// duration: 6000
|
||
//// );
|
||
//// }
|
||
////}
|