diff --git a/src/ApiKernel.php b/src/ApiKernel.php index fc1ff29..40a0346 100644 --- a/src/ApiKernel.php +++ b/src/ApiKernel.php @@ -1,6 +1,8 @@ (Dieses Template enthält noch keine HTML-Inhalte.)
'; } + + $renderCache = []; + $renderStack = []; + $html = $this->renderHtmlWithReferences($html, $auth, $renderCache, $renderStack); $html = $this->prepareEmailHtml($html); if (!$this->dispatchTestMail($recipient, $subject, $html)) { @@ -867,4 +873,119 @@ class ApiKernel $summary['total'] = array_sum($summary); return $summary; } + + private function normalizeResourceKind(string $kind): ?string + { + $kind = strtolower(trim($kind)); + $map = [ + 'template' => 'templates', + 'templates' => 'templates', + 'section' => 'sections', + 'sections' => 'sections', + 'block' => 'blocks', + 'blocks' => 'blocks', + 'snippet' => 'snippets', + 'snippets' => 'snippets', + ]; + return $map[$kind] ?? null; + } + + private function resolveHtmlColumn(array $columns, string $kindKey): ?string + { + $candidates = ($kindKey === 'snippets') + ? ['content', 'html', 'body', 'markup'] + : ['html', 'body', 'markup', 'content']; + return $this->firstExisting($columns, $candidates); + } + + private function fetchResourceHtml(string $kind, int $id, array $auth, array &$cache, array &$stack): ?string + { + $kindKey = $this->normalizeResourceKind($kind); + if (!$kindKey || $id <= 0) return null; + + $cacheKey = $kindKey . ':' . $id; + if (array_key_exists($cacheKey, $cache)) return $cache[$cacheKey]; + if (!empty($stack[$cacheKey])) return null; + + $table = $this->tableMap[$kindKey] ?? null; + if (!$table) return null; + [$idCol, $allCols] = $this->resolveIdCol($kindKey); + [$tw, $tp] = $this->tenantWhere($auth); + + $sql = "SELECT * FROM `$table` WHERE `$idCol` = :id" . $tw . " LIMIT 1"; + $stmt = $this->pdo->prepare($sql); + $stmt->bindValue(':id', $id); + foreach ($tp as $k => $v) $stmt->bindValue($k, $v); + $stmt->execute(); + $row = $stmt->fetch(); + if (!$row) { + $cache[$cacheKey] = null; + return null; + } + + $htmlCol = $this->resolveHtmlColumn($allCols, $kindKey); + $html = $htmlCol && isset($row[$htmlCol]) ? (string)$row[$htmlCol] : ''; + + $stack[$cacheKey] = true; + $html = $this->renderHtmlWithReferences($html, $auth, $cache, $stack); + unset($stack[$cacheKey]); + + $cache[$cacheKey] = $html; + return $html; + } + + private function renderHtmlWithReferences(string $html, array $auth, array &$cache, array &$stack): string + { + $trimmed = trim($html); + if ($trimmed === '') return $html; + if (!class_exists(DOMDocument::class)) return $html; + + $flags = 0; + if (defined('LIBXML_HTML_NOIMPLIED')) { + $flags |= LIBXML_HTML_NOIMPLIED; + } + if (defined('LIBXML_HTML_NODEFDTD')) { + $flags |= LIBXML_HTML_NODEFDTD; + } + + $doc = new DOMDocument('1.0', 'UTF-8'); + libxml_use_internal_errors(true); + $wrapper = '