Quelltext des aktuellen Standes
<?php $this->layout('layouts/admin', [
'page_title' => 'Audit-Eintrag #' . $entry['id'],
'current_admin_page' => 'audit',
'hide_page_title' => true,
]);
$hashFork = $hash_fork ?? false;
$hashPreKey = $hash_pre_key ?? false;
$hashFormat = $hash_storage_format ?? false;
$recoveredCategory = $recovered_category ?? null;
// Anzeige-Label für Schweregrad (Spalte risk_level)
$riskLabels = ['low' => 'Niedrig', 'medium' => 'Mittel', 'high' => 'Hoch', 'critical' => 'Kritisch'];
$risk = (string)($entry['risk_level'] ?? 'low');
// JSON-Felder des Eintrags, sofern befüllt
$jsonSections = [
'Details' => $entry['details_json'] ?? null,
'Vorher' => $entry['old_value_json'] ?? null,
'Nachher' => $entry['new_value_json'] ?? null,
];
?>
<div class="audit-detail">
<header class="detail-header">
<div class="header-nav">
<?php if ($prev_id): ?>
<a href="/admin/audit/<?= (int)$prev_id ?>" class="btn btn-sm btn-secondary"><?= $this->te('← Vorheriger') ?></a>
<?php endif; ?>
<a href="/admin/audit" class="btn btn-sm btn-secondary"><?= $this->te('Zurück zur Übersicht') ?></a>
<?php if ($next_id): ?>
<a href="/admin/audit/<?= (int)$next_id ?>" class="btn btn-sm btn-secondary"><?= $this->te('Nächster →') ?></a>
<?php endif; ?>
</div>
<h1>
<?= $this->t('Audit-Eintrag #') ?><?= (int)$entry['id'] ?>
<?php if ($hashPreKey): ?>
<span class="badge badge-secondary" title="<?= $this->te('Vor Einrichtung des Anwendungsschlüssels geschrieben') ?>"><?= $this->te('Vor Schlüssel-Einrichtung') ?></span>
<?php elseif ($hashFormat): ?>
<span class="badge badge-secondary" title="<?= $this->te('Detailfelder werden von der Datenbank umformatiert zurückgegeben') ?>"><?= $this->te('Speicherformat abweichend') ?></span>
<?php elseif ($hashFork): ?>
<span class="badge badge-warning" title="<?= $this->te('Gültige Signatur, parallel geschriebener Eintrag') ?>"><?= $this->te('✓ Verifiziert (parallel geschrieben)') ?></span>
<?php elseif ($hash_valid): ?>
<span class="badge badge-success" title="<?= $this->te('Hash verifiziert') ?>"><?= $this->te('✓ Verifiziert') ?></span>
<?php else: ?>
<span class="badge badge-danger" title="<?= $this->te('Hash-Kette unterbrochen') ?>"><?= $this->te('⚠ Integritätsfehler') ?></span>
<?php endif; ?>
</h1>
</header>
<div class="detail-content">
<div class="detail-grid">
<section class="detail-section">
<h2><?= $this->te('Allgemein') ?></h2>
<dl class="detail-list">
<dt><?= $this->te('Zeitstempel') ?></dt>
<dd><?= $this->e(date('d.m.Y H:i:s', strtotime((string)$entry['event_timestamp']))) ?></dd>
<dt><?= $this->te('Ereignis-ID') ?></dt>
<dd><code class="hash"><?= $this->e($entry['event_id'] ?? '-') ?></code></dd>
<dt><?= $this->te('Benutzer') ?></dt>
<dd>
<?php if ($entry['user_id']): ?>
<a href="/admin/users/<?= (int)$entry['user_id'] ?>">
<?= $this->e($entry['display_name'] ?? 'Unbekannt') ?>
</a>
(<?= $this->e($entry['email'] ?? '') ?>)
<?php else: ?>
<span class="text-muted"><?= $this->te('System') ?></span>
<?php endif; ?>
</dd>
<dt><?= $this->te('Kategorie') ?></dt>
<dd>
<?php if ((string)$entry['action_category'] === '' && $recoveredCategory !== null): ?>
<span class="action-badge category-<?= $this->e($recoveredCategory) ?>">
<?= $this->e(ucfirst($recoveredCategory)) ?>
</span>
<span class="badge badge-secondary"
title="<?= $this->te('Die Spalte ist leer gespeichert; der Wert wurde über die Signatur des Eintrags bestimmt') ?>"><?= $this->te('aus der Signatur bestimmt') ?></span>
<?php else: ?>
<span class="action-badge category-<?= $this->e($entry['action_category']) ?>">
<?= $this->e(ucfirst((string)$entry['action_category'])) ?>
</span>
<?php endif; ?>
</dd>
<dt><?= $this->te('Aktion') ?></dt>
<dd><?= $this->e($entry['action_type']) ?></dd>
<dt><?= $this->te('Status') ?></dt>
<dd>
<?php if (($entry['result'] ?? '') === 'success'): ?>
<span class="badge badge-success"><?= $this->te('Erfolgreich') ?></span>
<?php else: ?>
<span class="badge badge-danger"><?= $this->e(ucfirst((string)($entry['result'] ?? 'unbekannt'))) ?></span>
<?php endif; ?>
</dd>
<dt><?= $this->te('Schweregrad') ?></dt>
<dd>
<span class="severity-badge severity-<?= $this->e($risk) ?>">
<?= $this->e($riskLabels[$risk] ?? ucfirst($risk)) ?>
</span>
</dd>
</dl>
</section>
<section class="detail-section">
<h2><?= $this->te('Objekt') ?></h2>
<dl class="detail-list">
<dt><?= $this->te('Typ') ?></dt>
<dd><?= $this->e($entry['object_type'] ?? '-') ?></dd>
<dt>ID</dt>
<dd><?= $this->e((string)($entry['object_id'] ?? '-')) ?></dd>
<dt><?= $this->te('Name') ?></dt>
<dd><?= $this->e($entry['object_name'] ?? '-') ?></dd>
</dl>
</section>
<section class="detail-section">
<h2><?= $this->te('Kontext') ?></h2>
<dl class="detail-list">
<dt><?= $this->te('IP-Adresse') ?></dt>
<dd>
<code><?= $this->e($entry['ip_address'] ?? '-') ?></code>
</dd>
<dt><?= $this->te('User-Agent') ?></dt>
<dd class="user-agent">
<?= $this->e($entry['user_agent'] ?? '-') ?>
</dd>
</dl>
</section>
</div>
<?php foreach ($jsonSections as $label => $json): ?>
<?php if (!empty($json)): ?>
<section class="detail-section full-width">
<h2><?= $this->e($label) ?></h2>
<pre class="details-json"><?php
$decoded = json_decode((string)$json, true);
echo $this->e($decoded !== null
? json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
: (string)$json);
?></pre>
</section>
<?php endif; ?>
<?php endforeach; ?>
<section class="detail-section full-width">
<h2><?= $this->te('Integrität') ?></h2>
<dl class="detail-list">
<dt><?= $this->te('Prüfsumme (HMAC-SHA-256)') ?></dt>
<dd>
<code class="hash"><?= $this->e($entry['checksum'] ?? '-') ?></code>
<?php if ($hashPreKey): ?>
<span class="badge badge-secondary"><?= $this->te('ohne Anwendungsschlüssel signiert') ?></span>
<?php elseif ($hashFormat): ?>
<span class="badge badge-secondary"><?= $this->te('nicht nachrechenbar (Speicherformat)') ?></span>
<?php elseif ($hashFork): ?>
<span class="badge badge-warning"><?= $this->te('✓ Gültig (parallel geschrieben)') ?></span>
<?php elseif ($hash_valid): ?>
<span class="badge badge-success"><?= $this->te('✓ Verifiziert') ?></span>
<?php else: ?>
<span class="badge badge-danger"><?= $this->te('⚠ Ungültig') ?></span>
<?php endif; ?>
</dd>
</dl>
<p class="hint">
<?= $this->te('Die Prüfsumme wird mit dem Anwendungsschlüssel aus allen Feldern dieses Eintrags und der Prüfsumme des Vorgängers berechnet und bildet eine manipulationssichere Kette.') ?>
<?php if ($hashPreKey): ?>
<?= $this->te('Dieser Eintrag entstand, bevor der Anwendungsschlüssel auf dieser Installation eingerichtet wurde: Er ist ohne Schlüssel signiert und mit dem heutigen Schlüssel nicht mehr nachrechenbar – kein Manipulationsverdacht.') ?>
<?php elseif ($hashFormat): ?>
<?= $this->te('Dieser Eintrag entstand, bevor die Prüfsumme unabhängig von der Speicher-Schreibweise gebildet wurde. Seine Detailfelder gibt die Datenbank umformatiert zurück – etwa mit anders sortierten Schlüsseln –, sodass der ursprünglich signierte Text nicht mehr vorliegt. Der Inhalt ist unverändert, ein Manipulationsverdacht besteht nicht.') ?>
<?php elseif ($hashFork): ?>
<?= $this->te('Dieser Eintrag verweist auf einen wenige Positionen älteren Vorgänger – das entsteht, wenn zwei Vorgänge gleichzeitig protokollieren, und ist keine Veränderung der Inhalte.') ?>
<?php endif; ?>
</p>
</section>
</div>
</div>