diff --git a/config/current.ver b/config/current.ver index 3a1f10e..7e099ec 100644 --- a/config/current.ver +++ b/config/current.ver @@ -1 +1 @@ -1.2.5 \ No newline at end of file +1.2.6 \ No newline at end of file diff --git a/public/assets/js/ui-editor.js b/public/assets/js/ui-editor.js index 07ce5f1..6394455 100644 --- a/public/assets/js/ui-editor.js +++ b/public/assets/js/ui-editor.js @@ -276,6 +276,13 @@ export function initEditor() { async function confirmUnsavedChanges() { const dirty = await hasUnsavedChanges(); if (!dirty) return 'ok'; + try { + const currentSnapshot = await buildCurrentSnapshot(); + if (currentSnapshot && savedSnapshot && currentSnapshot === savedSnapshot) { + clearDirty(); + return 'ok'; + } + } catch {} const choice = await showUnsavedDialog(); if (choice === 'save') { const okSave = await save(); diff --git a/src/ApiKernel.php b/src/ApiKernel.php index d34f52d..4f7f24a 100644 --- a/src/ApiKernel.php +++ b/src/ApiKernel.php @@ -2231,17 +2231,44 @@ class ApiKernel { $out = []; $seen = []; - $matches = function (?string $html) use ($templateId): bool { + $matches = function (?string $html, array $libKinds = []) use ($templateId): bool { if (!$html) return false; $id = preg_quote((string)$templateId, '/'); $typePattern = '/data-ref-type\s*=\s*(["\"])template\1/i'; $idPattern = '/data-ref-id\s*=\s*(["\"])' . $id . '\1/i'; - return (bool)(preg_match($typePattern, $html) && preg_match($idPattern, $html)); + $jsonTypePattern = '/"data-ref-type"\s*:\s*"template"/i'; + $jsonIdPattern = '/"data-ref-id"\s*:\s*("?)(?:' . $id . ')\1/i'; + $hasHtmlAttrs = (bool)(preg_match($typePattern, $html) && preg_match($idPattern, $html)); + if ($hasHtmlAttrs) return true; + if (preg_match($jsonTypePattern, $html) && preg_match($jsonIdPattern, $html)) return true; + + $kindPattern = '/data-lib-(?:kind|section)\s*=\s*(["\"])([^"\']+)\1/i'; + $libIdPattern = '/data-lib-id\s*=\s*(["\"])' . $id . '\1/i'; + if (preg_match($libIdPattern, $html)) { + if (!$libKinds) return true; + if (preg_match($kindPattern, $html, $m)) { + $kind = strtolower(trim((string)($m[2] ?? ''))); + if ($kind !== '' && in_array($kind, $libKinds, true)) return true; + } + } + + $jsonLibIdPattern = '/"data-lib-id"\s*:\s*("?)(?:' . $id . ')\1/i'; + $jsonLibKindPattern = '/"data-lib-(?:kind|section)"\s*:\s*"([^"]+)"/i'; + if (preg_match($jsonLibIdPattern, $html)) { + if (!$libKinds) return true; + if (preg_match($jsonLibKindPattern, $html, $m)) { + $kind = strtolower(trim((string)($m[1] ?? ''))); + if ($kind !== '' && in_array($kind, $libKinds, true)) return true; + } + } + + return false; }; if ($this->useUnifiedContent()) { $section = $this->ensureEmailtemplateSection($customerId); if (!$section) return []; + $libKinds = [strtolower((string)($section['slug'] ?? 'emailtemplate'))]; $itemsTable = $this->contentItemsTable(); if (!$this->tableExists($itemsTable)) return []; @@ -2291,7 +2318,7 @@ class ApiKernel ]; $found = false; foreach ($blobs as $blob) { - if ($matches($blob)) { $found = true; break; } + if ($matches($blob, $libKinds)) { $found = true; break; } } if ($found) { $id = (int)($row['id'] ?? 0); @@ -2307,6 +2334,7 @@ class ApiKernel if (!$this->useUnifiedContent()) { $table = $this->tableMap['templates'] ?? null; if ($table && $this->tableExists($table)) { + $libKinds = ['templates', 'template', 'emailtemplate']; [$idCol, $allCols] = $this->resolveIdCol('templates'); $htmlCol = $this->firstExisting($allCols, ['html', 'body', 'markup', 'content']); $jsonCol = $this->firstExisting($allCols, ['json_content']); @@ -2332,7 +2360,7 @@ class ApiKernel ]; $found = false; foreach ($blobs as $blob) { - if ($matches($blob)) { $found = true; break; } + if ($matches($blob, $libKinds)) { $found = true; break; } } if ($found) { $id = (int)($row['id'] ?? 0);