From b18df2f20638a566e87087d481163ad49b2842bf Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Sun, 7 Dec 2025 01:20:22 +0100 Subject: [PATCH] up --- public/assets/js/ui-list.js | 26 ++++++++++++-- src/ApiKernel.php | 72 ++++++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/public/assets/js/ui-list.js b/public/assets/js/ui-list.js index f76c06e..1a9b529 100644 --- a/public/assets/js/ui-list.js +++ b/public/assets/js/ui-list.js @@ -1,5 +1,19 @@ import { apiList, apiGet, apiDelete, apiUpdate, toast } from './api.js'; +function formatUsage(usage){ + if (!usage || !usage.total) return ''; + const parts=[]; + if (usage.templates) parts.push(`${usage.templates} Template${usage.templates!==1?'s':''}`); + if (usage.sections) parts.push(`${usage.sections} Section${usage.sections!==1?'s':''}`); + if (usage.blocks) parts.push(`${usage.blocks} Block${usage.blocks!==1?'s':''}`); + if (usage.snippets) parts.push(`${usage.snippets} Snippet${usage.snippets!==1?'s':''}`); + if (!parts.length) return ''; + return `
+ Dieses Element wird aktuell verwendet in: ${parts.join(', ')}.
+ Das Löschen entfernt diese Referenzen. +
`; +} + function esc(s=''){ return String(s) .replace(/&/g,'&') @@ -145,10 +159,16 @@ export async function loadList(resource){ let pending=null; delCancel && (delCancel.onclick=()=>{pending=null;delDlg.close();}); - list.querySelectorAll('[data-del]').forEach(b=>b.addEventListener('click',()=>{ + list.querySelectorAll('[data-del]').forEach(b=>b.addEventListener('click', async ()=>{ const [res,id]=b.dataset.del.split(':'); const nm=b.dataset.name||''; - pending={res,id,nm}; - delText && (delText.innerHTML=`Soll ${nm || '(ohne Name)'} #${id} aus ${res} wirklich gelöscht werden?
Achtung: Kinder-Elemente werden nicht automatisch mit gelöscht.`); + let usage = null; + try { + const detail = await apiGet(res, id); + usage = detail?.usage || null; + } catch {} + pending={res,id,nm,usage}; + const usageWarn = formatUsage(usage); + delText && (delText.innerHTML=`Soll ${nm || '(ohne Name)'} #${id} aus ${res} wirklich gelöscht werden?
Achtung: Kinder-Elemente werden nicht automatisch mit gelöscht.${usageWarn}`); delDlg.showModal(); })); diff --git a/src/ApiKernel.php b/src/ApiKernel.php index b080128..3e2d198 100644 --- a/src/ApiKernel.php +++ b/src/ApiKernel.php @@ -392,6 +392,8 @@ class ApiKernel $gjsComponents = $this->parseHtmlToGjsComponents($topHtml); } + $usage = $this->calculateUsage($kind, (int)$rowOut['id'], $auth); + $this->respond([ 'ok' => true, 'kind' => $kind, @@ -400,7 +402,8 @@ class ApiKernel 'data' => $rowOut, 'html' => $topHtml, 'content' => $topContent, - 'gjs_components' => $gjsComponents + 'gjs_components' => $gjsComponents, + 'usage' => $usage, ]); } @@ -680,3 +683,70 @@ class ApiKernel } } } + private function lookupTableName(string $key, string $default): string + { + $tables = $this->conf['tables'] ?? []; + if (!empty($tables[$key])) return $tables[$key]; + $prefix = $this->conf['projectdb']['prefix'] ?? null; + if ($prefix && strpos($default, 'emailtemplate_') === 0) { + return $prefix . substr($default, strlen('emailtemplate_')); + } + return $default; + } + + private function countRefsInTable(string $table, string $where, array $params, array $auth): int + { + try { + [$tw, $tp] = $this->tenantWhere($auth); + $sql = "SELECT COUNT(*) AS c FROM `$table` WHERE $where" . $tw; + $stmt = $this->pdo->prepare($sql); + foreach ($params as $k => $v) $stmt->bindValue($k, $v); + foreach ($tp as $k => $v) $stmt->bindValue($k, $v); + $stmt->execute(); + $row = $stmt->fetch(); + return (int)($row['c'] ?? 0); + } catch (Throwable $e) { + return 0; + } + } + + private function calculateUsage(string $kind, int $id, array $auth): array + { + if ($id <= 0) return ['total' => 0]; + + $summary = []; + $templateItemsTable = $this->lookupTableName('template_items', 'emailtemplate_template_items'); + $sectionItemsTable = $this->lookupTableName('section_items', 'emailtemplate_section_items'); + + if ($kind === 'sections') { + $summary['templates'] = $this->countRefsInTable( + $templateItemsTable, + "`ref_type` = :rt AND `ref_id` = :rid", + [':rt' => 'section', ':rid' => $id], + $auth + ); + } elseif ($kind === 'blocks') { + $summary['templates'] = $this->countRefsInTable( + $templateItemsTable, + "`ref_type` = :rt AND `ref_id` = :rid", + [':rt' => 'block', ':rid' => $id], + $auth + ); + $summary['sections'] = $this->countRefsInTable( + $sectionItemsTable, + "`ref_id` = :rid", + [':rid' => $id], + $auth + ); + $summary['snippets'] = $this->countRefsInTable( + $this->tableMap['snippets'], + "`block_id` = :rid", + [':rid' => $id], + $auth + ); + } + + $summary = array_filter($summary, fn($v) => (int)$v > 0); + $summary['total'] = array_sum($summary); + return $summary; + }