forked from fa/breadcrumb-the-shire
Feature: Security Level mit Notiz für Domains
Implementiert ein Dialog-basiertes UI zum Bearbeiten des Security Levels mit optionaler Notiz-Funktion für Helpdesk-Domains. Backend: - DomainSecurityLevelRepository: CRUD für security_levels mit note-Spalte - DomainSecurityLevelService: Business-Logik mit Batch-Enrichment - security-level-data() Endpoint: AJAX + Full-Page POST mit CSRF - Migration 010: note TEXT-Spalte hinzugefügt - Bugfix: findByTenantAndDomainNo gibt null bei leerem Array zurück Frontend (Domain-Liste): - Badge in Grid klickbar → öffnet Modal-Dialog - Dialog mit Level-Select + Notiz-Textarea - AJAX-Save mit Live-Badge-Update ohne Reload - Event-Delegation für dynamische Grid-Inhalte Frontend (Domain-Detail): - Notiz-Feld im Security-Level-Formular - PRG-Pattern mit Flash-Messages Core: - app-http.js: DEFAULT_HEADERS auf XMLHttpRequest für CSRF-Kompatibilität i18n: - Keys: Priority, Note, Optional note, Security level updated Tests: - DomainSecurityLevelServiceTest: CRUD + Batch-Enrichment
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Module\Helpdesk\Repository;
|
||||
|
||||
use MintyPHP\DB;
|
||||
|
||||
class DomainSecurityLevelRepository
|
||||
{
|
||||
private const ALLOWED_LEVELS = ['niedrig', 'normal', 'hoch', 'kritisch'];
|
||||
|
||||
public function findByTenantAndDomainNo(int $tenantId, string $domainNo): ?array
|
||||
{
|
||||
if ($domainNo === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$row = DB::selectOne(
|
||||
'SELECT * FROM helpdesk_domain_security_levels WHERE tenant_id = ? AND domain_no = ? LIMIT 1',
|
||||
(string) $tenantId,
|
||||
$domainNo
|
||||
);
|
||||
|
||||
if (!is_array($row) || $row === []) {
|
||||
return null;
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $domainNos
|
||||
* @return array<string, string> Map of domain_no => security_level
|
||||
*/
|
||||
public function listLevelsByDomainNos(int $tenantId, array $domainNos): array
|
||||
{
|
||||
if ($domainNos === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$placeholders = implode(',', array_fill(0, count($domainNos), '?'));
|
||||
$params = array_map('strval', $domainNos);
|
||||
$params[] = (string) $tenantId;
|
||||
|
||||
$rows = DB::select(
|
||||
'SELECT domain_no, security_level FROM helpdesk_domain_security_levels WHERE tenant_id = ? AND domain_no IN (' . $placeholders . ')',
|
||||
...$params
|
||||
);
|
||||
|
||||
$result = [];
|
||||
if (is_array($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$domainNo = (string) ($row['domain_no'] ?? '');
|
||||
$level = (string) ($row['security_level'] ?? 'normal');
|
||||
if ($domainNo !== '') {
|
||||
$result[$domainNo] = in_array($level, self::ALLOWED_LEVELS, true) ? $level : 'normal';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $domainNos
|
||||
* @return array<string, array{level: string, note: string}> Map of domain_no => {level, note}
|
||||
*/
|
||||
public function listDetailsByDomainNos(int $tenantId, array $domainNos): array
|
||||
{
|
||||
if ($domainNos === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$placeholders = implode(',', array_fill(0, count($domainNos), '?'));
|
||||
$params = array_map('strval', $domainNos);
|
||||
$params[] = (string) $tenantId;
|
||||
|
||||
$rows = DB::select(
|
||||
'SELECT domain_no, security_level, note FROM helpdesk_domain_security_levels WHERE tenant_id = ? AND domain_no IN (' . $placeholders . ')',
|
||||
...$params
|
||||
);
|
||||
|
||||
$result = [];
|
||||
if (is_array($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$domainNo = (string) ($row['domain_no'] ?? '');
|
||||
$level = (string) ($row['security_level'] ?? 'normal');
|
||||
$note = (string) ($row['note'] ?? '');
|
||||
if ($domainNo !== '') {
|
||||
$result[$domainNo] = [
|
||||
'level' => in_array($level, self::ALLOWED_LEVELS, true) ? $level : 'normal',
|
||||
'note' => $note,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update security level for a domain.
|
||||
*
|
||||
* @return bool True on success
|
||||
*/
|
||||
public function upsert(int $tenantId, string $domainNo, string $level, ?int $userId, ?string $note = null): bool
|
||||
{
|
||||
if ($domainNo === '' || !in_array($level, self::ALLOWED_LEVELS, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$existing = $this->findByTenantAndDomainNo($tenantId, $domainNo);
|
||||
|
||||
if ($existing !== null) {
|
||||
$result = DB::update(
|
||||
'UPDATE helpdesk_domain_security_levels SET security_level = ?, note = ?, updated_by = ? WHERE tenant_id = ? AND domain_no = ?',
|
||||
$level,
|
||||
$note,
|
||||
$userId !== null ? (string) $userId : null,
|
||||
(string) $tenantId,
|
||||
$domainNo
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
$result = DB::insert(
|
||||
'INSERT INTO helpdesk_domain_security_levels (tenant_id, domain_no, security_level, note, created_by, updated_by) VALUES (?, ?, ?, ?, ?, ?)',
|
||||
(string) $tenantId,
|
||||
$domainNo,
|
||||
$level,
|
||||
$note,
|
||||
$userId !== null ? (string) $userId : null,
|
||||
$userId !== null ? (string) $userId : null
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api Reserved for future cleanup jobs
|
||||
*/
|
||||
public function deleteByTenantAndDomainNo(int $tenantId, string $domainNo): bool
|
||||
{
|
||||
if ($domainNo === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = DB::update(
|
||||
'DELETE FROM helpdesk_domain_security_levels WHERE tenant_id = ? AND domain_no = ?',
|
||||
(string) $tenantId,
|
||||
$domainNo
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user