update
This commit is contained in:
@@ -3,6 +3,7 @@ $appBaseUrl = $GLOBALS['app_base_url'] ?? '';
|
||||
|
||||
$defaultNavLinks = [
|
||||
['id' => 'dashboard', 'label' => 'Dashboard', 'href' => $appBaseUrl . '/admin/dashboard.php'],
|
||||
['id' => 'system', 'label' => 'Systemeinstellungen', 'href' => $appBaseUrl . '/admin/system.php'],
|
||||
['id' => 'settings', 'label' => 'API & Tabellen', 'href' => $appBaseUrl . '/admin/settings.php'],
|
||||
['id' => 'users', 'label' => 'Userverwaltung', 'href' => $appBaseUrl . '/admin/users.php'],
|
||||
['id' => 'profile', 'label' => 'Mein Konto', 'href' => $appBaseUrl . '/admin/profile.php'],
|
||||
|
||||
@@ -68,11 +68,6 @@ require dirname(__DIR__) . '/../structure/layout_start.php';
|
||||
<button type="button" class="btn" data-rotate="external">Neu erstellen</button>
|
||||
</div>
|
||||
</div>
|
||||
<label class="block text-sm text-slate-600">Standard-Editor</label>
|
||||
<select name="editor_default" class="input">
|
||||
<option value="grapesjs">GrapesJS</option>
|
||||
<option value="craftjs">Craft.js</option>
|
||||
</select>
|
||||
<div class="flex justify-between gap-2 flex-wrap pt-2">
|
||||
<div class="flex gap-2" data-role="admin">
|
||||
<button type="button" class="btn" data-download="bridge">Bridge-Datei</button>
|
||||
@@ -83,20 +78,6 @@ require dirname(__DIR__) . '/../structure/layout_start.php';
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin" id="sectionsManager">
|
||||
<div class="flex items-center justify-between flex-wrap gap-3 mb-3">
|
||||
<div>
|
||||
<h4>Sections verwalten</h4>
|
||||
<p class="text-sm text-slate-600">Die Sortierung steuert, welche Inhalte in anderen Sections eingebunden werden dürfen.</p>
|
||||
</div>
|
||||
</div>
|
||||
<form id="sectionsCreateForm" class="flex flex-wrap gap-2 mb-4">
|
||||
<input type="text" id="sectionNameInput" class="input flex-1 min-w-[220px]" placeholder="Neue Section (Name)" required>
|
||||
<button type="submit" class="btn">Section hinzufügen</button>
|
||||
</form>
|
||||
<ul id="sectionsList" class="space-y-2"></ul>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin">
|
||||
<div class="flex items-center justify-between flex-wrap gap-3 mb-3">
|
||||
<div>
|
||||
@@ -267,21 +248,6 @@ require dirname(__DIR__) . '/../structure/layout_start.php';
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog id="sectionsDeleteDialog" class="rounded-xl max-w-md w-[90vw] p-5">
|
||||
<form id="sectionsDeleteForm" method="dialog" class="space-y-4">
|
||||
<div class="flex items-center justify-between gap-3 border-b border-slate-200 pb-3">
|
||||
<h3 class="text-lg font-semibold">Section löschen</h3>
|
||||
<button type="button" id="sectionsDeleteCancel" class="btn">Abbrechen</button>
|
||||
</div>
|
||||
<p id="sectionsDeleteText" class="text-sm text-slate-600"></p>
|
||||
<label class="block text-sm text-slate-600">Inhalte verschieben nach</label>
|
||||
<select id="sectionsDeleteTarget" class="input"></select>
|
||||
<div class="flex justify-end gap-2">
|
||||
<button type="submit" class="btn btn-danger">Löschen</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<dialog id="configExampleDialog" class="rounded-xl max-w-2xl w-[90vw]">
|
||||
<form method="dialog" class="space-y-3">
|
||||
<h3 class="text-lg font-semibold">Beispiel: Mapping einer Config-Datei</h3>
|
||||
|
||||
53
partials/landingpage/accountsetup/system.php
Normal file
53
partials/landingpage/accountsetup/system.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
$pageTitle = 'Email Template System – Systemeinstellungen';
|
||||
$pageId = 'admin';
|
||||
$navActive = 'system';
|
||||
require __DIR__ . '/accountsetup_config.php';
|
||||
require dirname(__DIR__) . '/../structure/layout_start.php';
|
||||
?>
|
||||
<main class="max-w-5xl mx-auto p-4 md:p-6 flex-1 w-full space-y-6">
|
||||
<section class="section-card" data-role="admin">
|
||||
<h4>Standard-Editor</h4>
|
||||
<p class="text-sm text-slate-600 mb-4">Standardauswahl für neue Inhalte. Kann pro Element spaeter angepasst werden.</p>
|
||||
<form id="settingsForm" class="space-y-3">
|
||||
<label class="block text-sm text-slate-600">Standard-Editor</label>
|
||||
<select name="editor_default" class="input">
|
||||
<option value="grapesjs">GrapesJS</option>
|
||||
<option value="craftjs">Craft.js</option>
|
||||
</select>
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="btn">Einstellungen speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin" id="sectionsManager">
|
||||
<div class="flex items-center justify-between flex-wrap gap-3 mb-3">
|
||||
<div>
|
||||
<h4>Sections verwalten</h4>
|
||||
<p class="text-sm text-slate-600">Die Sortierung steuert, welche Inhalte in anderen Sections eingebunden werden duerfen.</p>
|
||||
</div>
|
||||
</div>
|
||||
<form id="sectionsCreateForm" class="flex flex-wrap gap-2 mb-4">
|
||||
<input type="text" id="sectionNameInput" class="input flex-1 min-w-[220px]" placeholder="Neue Section (Name)" required>
|
||||
<button type="submit" class="btn">Section hinzufuegen</button>
|
||||
</form>
|
||||
<ul id="sectionsList" class="space-y-2"></ul>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<dialog id="sectionsDeleteDialog" class="rounded-xl max-w-md w-[90vw] p-5">
|
||||
<form id="sectionsDeleteForm" method="dialog" class="space-y-4">
|
||||
<div class="flex items-center justify-between gap-3 border-b border-slate-200 pb-3">
|
||||
<h3 class="text-lg font-semibold">Section loeschen</h3>
|
||||
<button type="button" id="sectionsDeleteCancel" class="btn">Abbrechen</button>
|
||||
</div>
|
||||
<p id="sectionsDeleteText" class="text-sm text-slate-600"></p>
|
||||
<label class="block text-sm text-slate-600">Inhalte verschieben nach</label>
|
||||
<select id="sectionsDeleteTarget" class="input"></select>
|
||||
<div class="flex justify-end gap-2">
|
||||
<button type="submit" class="btn btn-danger">Loeschen</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
<?php require dirname(__DIR__) . '/../structure/layout_end.php'; ?>
|
||||
2
public/admin/system.php
Normal file
2
public/admin/system.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../partials/landingpage/accountsetup/system.php';
|
||||
@@ -72,7 +72,7 @@ export function initCreate(){
|
||||
toast('Erstellt',true);
|
||||
window.loadList && window.loadList(section);
|
||||
} else {
|
||||
toast('Erstellen fehlgeschlagen',false,{duration:3000});
|
||||
toast(r?.error || 'Erstellen fehlgeschlagen',false,{duration:3000});
|
||||
console.error('Create failed',r);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -431,17 +431,15 @@ function fillProfileForm(user) {
|
||||
|
||||
function fillSettingsForm(settings) {
|
||||
state.settings = settings;
|
||||
if (!settingsForm) return;
|
||||
settingsForm.bridge_url.value = settings.bridge_url || '';
|
||||
settingsForm.bridge_token.value = settings.bridge_token || '';
|
||||
settingsForm.sender_token.value = settings.sender_token || '';
|
||||
settingsForm.external_api_token.value = settings.external_api_token || '';
|
||||
if (settingsForm.editor_default) {
|
||||
settingsForm.editor_default.value = settings.editor_default || 'grapesjs';
|
||||
}
|
||||
window.__editorDefault = settings.editor_default || 'grapesjs';
|
||||
window.__listSortDefault = settings.list_sort || 'created_asc';
|
||||
state.rotate = { bridge: false, sender: false, external: false };
|
||||
if (!settingsForm) return;
|
||||
if (settingsForm.bridge_url) settingsForm.bridge_url.value = settings.bridge_url || '';
|
||||
if (settingsForm.bridge_token) settingsForm.bridge_token.value = settings.bridge_token || '';
|
||||
if (settingsForm.sender_token) settingsForm.sender_token.value = settings.sender_token || '';
|
||||
if (settingsForm.external_api_token) settingsForm.external_api_token.value = settings.external_api_token || '';
|
||||
if (settingsForm.editor_default) settingsForm.editor_default.value = settings.editor_default || 'grapesjs';
|
||||
refreshAdminTables(settings.bridge_setup?.tables || [], settings.bridge_tables || []);
|
||||
}
|
||||
|
||||
@@ -480,18 +478,20 @@ async function submitPasswordForm(ev) {
|
||||
|
||||
async function submitSettingsForm(ev) {
|
||||
ev.preventDefault();
|
||||
const bridgeTables = normalizeTableList(state.settings.bridge_tables || []);
|
||||
const data = {
|
||||
bridge_url: settingsForm.bridge_url.value.trim(),
|
||||
bridge_token: settingsForm.bridge_token.value.trim(),
|
||||
sender_token: settingsForm.sender_token.value.trim(),
|
||||
external_api_token: settingsForm.external_api_token.value.trim(),
|
||||
editor_default: settingsForm.editor_default ? settingsForm.editor_default.value : undefined,
|
||||
bridge_tables: bridgeTables,
|
||||
rotate_bridge_token: state.rotate.bridge ? 1 : 0,
|
||||
rotate_sender_token: state.rotate.sender ? 1 : 0,
|
||||
rotate_external_token: state.rotate.external ? 1 : 0,
|
||||
};
|
||||
if (settingsForm.bridge_url) data.bridge_url = settingsForm.bridge_url.value.trim();
|
||||
if (settingsForm.bridge_token) data.bridge_token = settingsForm.bridge_token.value.trim();
|
||||
if (settingsForm.sender_token) data.sender_token = settingsForm.sender_token.value.trim();
|
||||
if (settingsForm.external_api_token) data.external_api_token = settingsForm.external_api_token.value.trim();
|
||||
if (settingsForm.editor_default) data.editor_default = settingsForm.editor_default.value;
|
||||
if (adminTablesAllSelect && adminTablesSelectedSelect) {
|
||||
const bridgeTables = normalizeTableList(state.settings.bridge_tables || []);
|
||||
data.bridge_tables = bridgeTables;
|
||||
}
|
||||
try {
|
||||
const res = await apiAction('account.settings.update', { method: 'POST', data });
|
||||
if (!res?.ok) throw new Error(res?.error || 'Einstellungen konnten nicht gespeichert werden');
|
||||
|
||||
@@ -342,6 +342,19 @@ class ApiKernel
|
||||
return $this->tableMap['content_sections'] ?? $this->lookupTableName('content_sections', 'emailtemplate_content_sections');
|
||||
}
|
||||
|
||||
private function resolveContentItemColumns(string $table): array
|
||||
{
|
||||
$cols = $this->tableColumns($table);
|
||||
return [
|
||||
'category' => $this->firstExisting($cols, ['category', 'cat']),
|
||||
'html' => $this->firstExisting($cols, ['html', 'html_content', 'body', 'markup', 'content']),
|
||||
'json' => $this->firstExisting($cols, ['json_content']),
|
||||
'editor' => $this->firstExisting($cols, ['editor_type', 'editor']),
|
||||
'craft' => $this->firstExisting($cols, ['craft_json', 'craft_content', 'craft_data']),
|
||||
'settings' => $this->firstExisting($cols, ['settings_json', 'settings']),
|
||||
];
|
||||
}
|
||||
|
||||
private function useUnifiedContent(): bool
|
||||
{
|
||||
return $this->tableExists($this->contentItemsTable()) && $this->tableExists($this->contentSectionsTable());
|
||||
@@ -514,6 +527,10 @@ class ApiKernel
|
||||
if (!$this->tableExists($itemsTable) || !$this->tableExists($sectionsTable)) {
|
||||
$this->fail('Content tables not available', null, 500);
|
||||
}
|
||||
$itemCols = $this->resolveContentItemColumns($itemsTable);
|
||||
$catCol = $itemCols['category'];
|
||||
$htmlCol = $itemCols['html'];
|
||||
$jsonCol = $itemCols['json'];
|
||||
|
||||
$section = $fixedSection ?: $this->resolveSectionFromInput($customerId);
|
||||
$q = trim((string)$this->val($this->in, 'q', ''));
|
||||
@@ -527,7 +544,11 @@ class ApiKernel
|
||||
$params[':sid'] = (int)$section['id'];
|
||||
}
|
||||
if ($q !== '') {
|
||||
$where .= " AND (i.`name` LIKE :q OR i.`category` LIKE :q) ";
|
||||
$where .= " AND (i.`name` LIKE :q";
|
||||
if ($catCol) {
|
||||
$where .= " OR i.`$catCol` LIKE :q";
|
||||
}
|
||||
$where .= ") ";
|
||||
$params[':q'] = '%' . $q . '%';
|
||||
}
|
||||
|
||||
@@ -550,7 +571,7 @@ class ApiKernel
|
||||
'id' => $r['id'] ?? null,
|
||||
'name' => $r['name'] ?? null,
|
||||
'api_name' => $r['api_name'] ?? null,
|
||||
'category' => $r['category'] ?? null,
|
||||
'category' => $catCol ? ($r[$catCol] ?? null) : null,
|
||||
'section_id' => $r['section_id'] ?? null,
|
||||
'section_name' => $r['section_name'] ?? null,
|
||||
'section_slug' => $r['section_slug'] ?? null,
|
||||
@@ -559,8 +580,8 @@ class ApiKernel
|
||||
'updated_at' => $r['updated_at'] ?? null,
|
||||
'created_at' => $r['created_at'] ?? null,
|
||||
];
|
||||
if (array_key_exists('html', $r)) $item['html'] = (string)($r['html'] ?? '');
|
||||
if (array_key_exists('json_content', $r)) $item['content'] = $r['json_content'];
|
||||
if ($htmlCol && array_key_exists($htmlCol, $r)) $item['html'] = (string)($r[$htmlCol] ?? '');
|
||||
if ($jsonCol && array_key_exists($jsonCol, $r)) $item['content'] = $r[$jsonCol];
|
||||
$out[] = $item;
|
||||
}
|
||||
|
||||
@@ -588,6 +609,11 @@ class ApiKernel
|
||||
if (!$this->tableExists($itemsTable) || !$this->tableExists($sectionsTable)) {
|
||||
$this->fail('Content tables not available', null, 500);
|
||||
}
|
||||
$itemCols = $this->resolveContentItemColumns($itemsTable);
|
||||
$htmlCol = $itemCols['html'];
|
||||
$jsonCol = $itemCols['json'];
|
||||
$craftCol = $itemCols['craft'];
|
||||
$editorCol = $itemCols['editor'];
|
||||
|
||||
$section = $fixedSection ?: $this->resolveSectionFromInput($customerId);
|
||||
$params = [':cid' => $customerId, ':id' => $id];
|
||||
@@ -608,8 +634,8 @@ class ApiKernel
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) $this->fail('Not found', ['id' => $id], 404);
|
||||
|
||||
$html = (string)($row['html'] ?? '');
|
||||
$json = $row['json_content'] ?? null;
|
||||
$html = $htmlCol ? (string)($row[$htmlCol] ?? '') : '';
|
||||
$json = $jsonCol ? ($row[$jsonCol] ?? null) : null;
|
||||
$gjsComponents = [];
|
||||
if ($json !== null) {
|
||||
$decoded = json_decode((string)$json, true);
|
||||
@@ -635,8 +661,8 @@ class ApiKernel
|
||||
'html' => $html,
|
||||
'content' => $json,
|
||||
'gjs_components' => $gjsComponents,
|
||||
'editor_type' => $row['editor_type'] ?? null,
|
||||
'craft_json' => $row['craft_json'] ?? null,
|
||||
'editor_type' => $editorCol ? ($row[$editorCol] ?? null) : null,
|
||||
'craft_json' => $craftCol ? ($row[$craftCol] ?? null) : null,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -650,6 +676,13 @@ class ApiKernel
|
||||
if (!$this->tableExists($itemsTable)) {
|
||||
$this->fail('Content table not available', null, 500);
|
||||
}
|
||||
$itemCols = $this->resolveContentItemColumns($itemsTable);
|
||||
$catCol = $itemCols['category'];
|
||||
$htmlCol = $itemCols['html'];
|
||||
$jsonCol = $itemCols['json'];
|
||||
$editorCol = $itemCols['editor'];
|
||||
$craftCol = $itemCols['craft'];
|
||||
$settingsCol = $itemCols['settings'];
|
||||
|
||||
$name = trim((string)$this->val($this->in, ['name', 'title'], ''));
|
||||
if ($name === '') $this->fail('name required', null, 422);
|
||||
@@ -683,22 +716,27 @@ class ApiKernel
|
||||
'name' => $name,
|
||||
'api_name' => $apiName,
|
||||
];
|
||||
if ($category !== null) $data['category'] = (string)$category;
|
||||
if ($editorType !== '') $data['editor_type'] = $editorType;
|
||||
if ($craftJson !== null) $data['craft_json'] = is_string($craftJson) ? $craftJson : $this->encodeJson($craftJson);
|
||||
if ($settings !== null) $data['settings_json'] = is_string($settings) ? $settings : $this->encodeJson($settings);
|
||||
if ($category !== null && $catCol) $data[$catCol] = (string)$category;
|
||||
if ($editorType !== '' && $editorCol) $data[$editorCol] = $editorType;
|
||||
if ($craftJson !== null && $craftCol) $data[$craftCol] = is_string($craftJson) ? $craftJson : $this->encodeJson($craftJson);
|
||||
if ($settings !== null && $settingsCol) $data[$settingsCol] = is_string($settings) ? $settings : $this->encodeJson($settings);
|
||||
|
||||
if ($json !== null) {
|
||||
if (!$jsonCol) $this->fail('json_content column missing', null, 500);
|
||||
$components = is_string($json) ? json_decode($json, true) : $json;
|
||||
if (is_array($components)) {
|
||||
$components = $this->cleanReferenceComponents($components);
|
||||
$data['json_content'] = $this->encodeJson($components);
|
||||
$data[$jsonCol] = $this->encodeJson($components);
|
||||
} else {
|
||||
$data['json_content'] = is_string($json) ? $json : '';
|
||||
$data[$jsonCol] = is_string($json) ? $json : '';
|
||||
}
|
||||
if ($html !== null) {
|
||||
if (!$htmlCol) $this->fail('html column missing', null, 500);
|
||||
$data[$htmlCol] = (string)$html;
|
||||
}
|
||||
if ($html !== null) $data['html'] = (string)$html;
|
||||
} elseif ($html !== null) {
|
||||
$data['html'] = (string)$html;
|
||||
if (!$htmlCol) $this->fail('html column missing', null, 500);
|
||||
$data[$htmlCol] = (string)$html;
|
||||
}
|
||||
|
||||
$columns = array_keys($data);
|
||||
@@ -721,6 +759,13 @@ class ApiKernel
|
||||
if (!$this->tableExists($itemsTable)) {
|
||||
$this->fail('Content table not available', null, 500);
|
||||
}
|
||||
$itemCols = $this->resolveContentItemColumns($itemsTable);
|
||||
$catCol = $itemCols['category'];
|
||||
$htmlCol = $itemCols['html'];
|
||||
$jsonCol = $itemCols['json'];
|
||||
$editorCol = $itemCols['editor'];
|
||||
$craftCol = $itemCols['craft'];
|
||||
$settingsCol = $itemCols['settings'];
|
||||
|
||||
$id = $this->pullId($this->in);
|
||||
if ($id === null || $id === '') $this->fail('id required', null, 422);
|
||||
@@ -741,7 +786,7 @@ class ApiKernel
|
||||
if ($name !== null) $data['name'] = (string)$name;
|
||||
|
||||
$category = $this->val($this->in, ['category', 'cat'], null);
|
||||
if ($category !== null) $data['category'] = (string)$category;
|
||||
if ($category !== null && $catCol) $data[$catCol] = (string)$category;
|
||||
|
||||
$apiRaw = $this->val($this->in, ['api_name', 'apiName', 'api'], null);
|
||||
$apiName = $apiRaw !== null ? $this->normalizeApiName((string)$apiRaw) : null;
|
||||
@@ -769,24 +814,29 @@ class ApiKernel
|
||||
$html = $this->val($this->in, ['html', 'body', 'markup', 'content'], null);
|
||||
$json = $this->val($this->in, ['content_json', 'json', 'structure_json'], null);
|
||||
if ($json !== null) {
|
||||
if (!$jsonCol) $this->fail('json_content column missing', null, 500);
|
||||
$components = is_string($json) ? json_decode($json, true) : $json;
|
||||
if (is_array($components)) {
|
||||
$components = $this->cleanReferenceComponents($components);
|
||||
$data['json_content'] = $this->encodeJson($components);
|
||||
$data[$jsonCol] = $this->encodeJson($components);
|
||||
} else {
|
||||
$data['json_content'] = is_string($json) ? $json : '';
|
||||
$data[$jsonCol] = is_string($json) ? $json : '';
|
||||
}
|
||||
if ($html !== null) {
|
||||
if (!$htmlCol) $this->fail('html column missing', null, 500);
|
||||
$data[$htmlCol] = (string)$html;
|
||||
}
|
||||
if ($html !== null) $data['html'] = (string)$html;
|
||||
} elseif ($html !== null) {
|
||||
$data['html'] = (string)$html;
|
||||
if (!$htmlCol) $this->fail('html column missing', null, 500);
|
||||
$data[$htmlCol] = (string)$html;
|
||||
}
|
||||
|
||||
$editorType = $this->val($this->in, ['editor_type', 'editor'], null);
|
||||
if ($editorType !== null) $data['editor_type'] = strtolower(trim((string)$editorType));
|
||||
if ($editorType !== null && $editorCol) $data[$editorCol] = strtolower(trim((string)$editorType));
|
||||
$craftJson = $this->val($this->in, ['craft_json', 'craft_content', 'craft_data'], null);
|
||||
if ($craftJson !== null) $data['craft_json'] = is_string($craftJson) ? $craftJson : $this->encodeJson($craftJson);
|
||||
if ($craftJson !== null && $craftCol) $data[$craftCol] = is_string($craftJson) ? $craftJson : $this->encodeJson($craftJson);
|
||||
$settings = $this->val($this->in, ['settings_json', 'settings'], null);
|
||||
if ($settings !== null) $data['settings_json'] = is_string($settings) ? $settings : $this->encodeJson($settings);
|
||||
if ($settings !== null && $settingsCol) $data[$settingsCol] = is_string($settings) ? $settings : $this->encodeJson($settings);
|
||||
|
||||
if (!$data) {
|
||||
$this->respond(['ok' => true, 'kind' => 'content', 'id' => $id, 'updated' => true]);
|
||||
@@ -2313,7 +2363,17 @@ class ApiKernel
|
||||
return null;
|
||||
}
|
||||
$itemsTable = $this->contentItemsTable();
|
||||
$sql = "SELECT `html`,`json_content` FROM `$itemsTable` WHERE `customer_id` = :cid AND `section_id` = :sid AND `id` = :id LIMIT 1";
|
||||
$itemCols = $this->resolveContentItemColumns($itemsTable);
|
||||
$htmlCol = $itemCols['html'];
|
||||
$jsonCol = $itemCols['json'];
|
||||
if (!$htmlCol && !$jsonCol) {
|
||||
$cache[$cacheKey] = null;
|
||||
return null;
|
||||
}
|
||||
$selectCols = [];
|
||||
if ($htmlCol) $selectCols[] = "`$htmlCol`";
|
||||
if ($jsonCol) $selectCols[] = "`$jsonCol`";
|
||||
$sql = "SELECT " . implode(',', $selectCols) . " FROM `$itemsTable` WHERE `customer_id` = :cid AND `section_id` = :sid AND `id` = :id LIMIT 1";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute([':cid' => $customerId, ':sid' => (int)$section['id'], ':id' => $id]);
|
||||
$row = $stmt->fetch();
|
||||
@@ -2321,7 +2381,7 @@ class ApiKernel
|
||||
$cache[$cacheKey] = null;
|
||||
return null;
|
||||
}
|
||||
$html = (string)($row['html'] ?? '');
|
||||
$html = $htmlCol ? (string)($row[$htmlCol] ?? '') : '';
|
||||
} else {
|
||||
if (!$kindKey) return null;
|
||||
$table = $this->tableMap[$kindKey] ?? null;
|
||||
|
||||
Reference in New Issue
Block a user