up
This commit is contained in:
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
use DOMDocument;
|
||||
use DOMXPath;
|
||||
use RuntimeException;
|
||||
use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
|
||||
|
||||
// 💡 NEUE KORREKTUR: Starte Output Buffering so früh wie möglich, um Whitespace/Errors
|
||||
@@ -769,6 +770,9 @@ class ApiKernel
|
||||
$this->authService->logout();
|
||||
$this->respond(['ok' => true]);
|
||||
break;
|
||||
case 'placeholders.schema':
|
||||
$this->handlePlaceholderSchema();
|
||||
break;
|
||||
case 'templates.test_send':
|
||||
$this->handleTemplateTestSend();
|
||||
break;
|
||||
@@ -1023,4 +1027,74 @@ class ApiKernel
|
||||
|
||||
$node->appendChild($targetDoc->createTextNode($html));
|
||||
}
|
||||
|
||||
private function handlePlaceholderSchema(): void
|
||||
{
|
||||
$this->requireAuth();
|
||||
$bridge = $this->conf['placeholders']['bridge'] ?? [];
|
||||
$url = trim((string)($bridge['url'] ?? ''));
|
||||
$token = trim((string)($bridge['token'] ?? ''));
|
||||
if ($url === '' || $token === '') {
|
||||
$this->fail('Bridge not configured', null, 500);
|
||||
}
|
||||
|
||||
$ttl = (int)($bridge['cache_ttl'] ?? 300);
|
||||
try {
|
||||
$schema = $this->fetchPlaceholderSchema($url, $token, $ttl);
|
||||
} catch (Throwable $e) {
|
||||
$this->fail('Bridge request failed', $e->getMessage(), 502);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->respond([
|
||||
'ok' => true,
|
||||
'tables' => $schema['tables'] ?? [],
|
||||
'fetched' => $schema['fetched'] ?? date(DATE_ATOM),
|
||||
]);
|
||||
}
|
||||
|
||||
private function fetchPlaceholderSchema(string $url, string $token, int $ttl): array
|
||||
{
|
||||
$cacheFile = $this->placeholderCachePath($url, $token);
|
||||
if ($ttl > 0 && is_file($cacheFile) && (filemtime($cacheFile) + $ttl) > time()) {
|
||||
$cached = json_decode((string)@file_get_contents($cacheFile), true);
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
|
||||
$endpoint = $url;
|
||||
if (stripos($endpoint, 'action=') === false) {
|
||||
$endpoint .= (strpos($endpoint, '?') === false ? '?' : '&') . 'action=schema';
|
||||
}
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'GET',
|
||||
'header' => "Authorization: Bearer {$token}\r\nAccept: application/json\r\n",
|
||||
'timeout' => 10,
|
||||
],
|
||||
]);
|
||||
$response = @file_get_contents($endpoint, false, $context);
|
||||
if ($response === false) {
|
||||
throw new RuntimeException('Bridge endpoint unreachable');
|
||||
}
|
||||
|
||||
$decoded = json_decode($response, true);
|
||||
if (!is_array($decoded) || empty($decoded['ok'])) {
|
||||
throw new RuntimeException('Bridge did not return a valid schema');
|
||||
}
|
||||
|
||||
if ($ttl > 0) {
|
||||
@file_put_contents($cacheFile, json_encode($decoded));
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
private function placeholderCachePath(string $url, string $token): string
|
||||
{
|
||||
$hash = md5($url . '|' . $token);
|
||||
return sys_get_temp_dir() . '/emailtemplate_placeholder_' . $hash . '.json';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user