ycasdasd
This commit is contained in:
@@ -12,10 +12,11 @@ require dirname(__DIR__) . '/../structure/layout_start.php';
|
|||||||
Diese Angaben werden nur verwendet, um die <strong>emailtemplate_bridge.php</strong> zu generieren. Das EmailTemplate-System selbst behält Zugriff auf alle Tabellen; die hier definierten Whitelists greifen ausschließlich in der Bridge-Datei.
|
Diese Angaben werden nur verwendet, um die <strong>emailtemplate_bridge.php</strong> zu generieren. Das EmailTemplate-System selbst behält Zugriff auf alle Tabellen; die hier definierten Whitelists greifen ausschließlich in der Bridge-Datei.
|
||||||
</p>
|
</p>
|
||||||
<div class="text-sm text-slate-600 mb-4 space-y-2">
|
<div class="text-sm text-slate-600 mb-4 space-y-2">
|
||||||
|
<p><strong>Voraussetzung:</strong> Bridge-URL + Token in den <a class="underline" href="<?= htmlspecialchars($appBaseUrl . '/admin/settings.php') ?>">Einstellungen</a> hinterlegen.</p>
|
||||||
<p><strong>Moegliche Wege zur DB-Anbindung:</strong></p>
|
<p><strong>Moegliche Wege zur DB-Anbindung:</strong></p>
|
||||||
<ul class="list-disc ps-5">
|
<ul class="list-disc ps-5">
|
||||||
<li>Bridge-URL + Token laden Tabellen/Spalten (Standard, nur Schema).</li>
|
<li>Bridge-URL + Token laden Tabellen/Spalten (Standard, nur Schema).</li>
|
||||||
<li>Bridge kann zusaetzlich DB-Settings mitsenden (Host, Port, User, Passwort).</li>
|
<li>Bridge kann zusaetzlich DB-Settings mitsenden (Host, Port, User, Passwort) und hier uebernommen werden.</li>
|
||||||
<li>DB-Settings hier direkt eintragen (wird in die Bridge-Datei geschrieben).</li>
|
<li>DB-Settings hier direkt eintragen (wird in die Bridge-Datei geschrieben).</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -96,14 +97,11 @@ require dirname(__DIR__) . '/../structure/layout_start.php';
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2 items-center">
|
||||||
<button type="button" id="btn-load-remote" class="btn" data-role="admin">Tabellen vom Bridge-Endpunkt laden</button>
|
<button type="button" id="btn-load-remote" class="btn" data-role="admin">Tabellen/DB-Settings ueber Bridge-URL laden</button>
|
||||||
<span class="text-xs text-slate-500 self-center">Nutzt Bridge-URL/Token aus den Einstellungen und uebernimmt optional DB-Settings aus der Bridge-Datei.</span>
|
<span class="text-xs text-slate-500">Nutzt Bridge-URL/Token aus den Einstellungen.</span>
|
||||||
<button type="button" id="btn-import-bridge" class="btn" data-role="admin">Bridge-Datei importieren …</button>
|
|
||||||
<input type="file" id="bridgeImportInput" accept="application/x-php,text/plain" class="hidden" />
|
|
||||||
<button type="submit" class="btn">Bridge-Setup speichern</button>
|
<button type="submit" class="btn">Bridge-Setup speichern</button>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-slate-500">Der Import liest nur den automatisch generierten Kommentarblock aus einer Bridge-Datei.</p>
|
|
||||||
<div id="setupStatus" class="text-xs text-slate-500">Noch nicht gespeichert.</div>
|
<div id="setupStatus" class="text-xs text-slate-500">Noch nicht gespeichert.</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ let directFields;
|
|||||||
let configFields;
|
let configFields;
|
||||||
let statusLabel;
|
let statusLabel;
|
||||||
let loadBtn;
|
let loadBtn;
|
||||||
let importBtn;
|
|
||||||
let importInput;
|
|
||||||
let configExampleBtn;
|
let configExampleBtn;
|
||||||
let configExampleDialog;
|
let configExampleDialog;
|
||||||
|
|
||||||
@@ -27,8 +25,6 @@ export function initBridgeSetupPage() {
|
|||||||
configFields = document.getElementById('configFields');
|
configFields = document.getElementById('configFields');
|
||||||
statusLabel = document.getElementById('setupStatus');
|
statusLabel = document.getElementById('setupStatus');
|
||||||
loadBtn = document.getElementById('btn-load-remote');
|
loadBtn = document.getElementById('btn-load-remote');
|
||||||
importBtn = document.getElementById('btn-import-bridge');
|
|
||||||
importInput = document.getElementById('bridgeImportInput');
|
|
||||||
configExampleBtn = document.getElementById('btn-config-example');
|
configExampleBtn = document.getElementById('btn-config-example');
|
||||||
configExampleDialog = document.getElementById('configExampleDialog');
|
configExampleDialog = document.getElementById('configExampleDialog');
|
||||||
modeInputs = Array.from(form.querySelectorAll('input[name="db_mode"]'));
|
modeInputs = Array.from(form.querySelectorAll('input[name="db_mode"]'));
|
||||||
@@ -36,8 +32,6 @@ export function initBridgeSetupPage() {
|
|||||||
form.addEventListener('submit', submitBridgeSetup);
|
form.addEventListener('submit', submitBridgeSetup);
|
||||||
tablesInput?.addEventListener('input', () => updateTablesPreview(parseTablesInput()));
|
tablesInput?.addEventListener('input', () => updateTablesPreview(parseTablesInput()));
|
||||||
loadBtn?.addEventListener('click', loadTablesFromBridge);
|
loadBtn?.addEventListener('click', loadTablesFromBridge);
|
||||||
importBtn?.addEventListener('click', () => importInput?.click());
|
|
||||||
importInput?.addEventListener('change', handleBridgeImport);
|
|
||||||
configExampleBtn?.addEventListener('click', () => {
|
configExampleBtn?.addEventListener('click', () => {
|
||||||
if (configExampleDialog?.showModal) configExampleDialog.showModal();
|
if (configExampleDialog?.showModal) configExampleDialog.showModal();
|
||||||
});
|
});
|
||||||
@@ -134,29 +128,6 @@ function fillForm(setup) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleBridgeImport(ev) {
|
|
||||||
const file = ev.target?.files?.[0];
|
|
||||||
if (!file) return;
|
|
||||||
try {
|
|
||||||
const text = await file.text();
|
|
||||||
const parsed = parseBridgeFile(text);
|
|
||||||
if (!parsed) {
|
|
||||||
toast('Bridge-Datei konnte nicht erkannt werden', false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fillForm({ ...state.setup, ...parsed });
|
|
||||||
updateStatus('Bridge-Datei importiert');
|
|
||||||
toast('Bridge-Daten übernommen', true);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
toast('Bridge-Datei konnte nicht gelesen werden', false);
|
|
||||||
} finally {
|
|
||||||
if (importInput) {
|
|
||||||
importInput.value = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyModeVisibility(mode) {
|
function applyModeVisibility(mode) {
|
||||||
const direct = mode === 'config' ? 'add' : 'remove';
|
const direct = mode === 'config' ? 'add' : 'remove';
|
||||||
const config = mode === 'config' ? 'remove' : 'add';
|
const config = mode === 'config' ? 'remove' : 'add';
|
||||||
@@ -284,79 +255,6 @@ function escapeHtml(str) {
|
|||||||
.replace(/'/g, ''');
|
.replace(/'/g, ''');
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseBridgeFile(text) {
|
|
||||||
if (typeof text !== 'string' || !text.includes('EmailTemplate Bridge')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const result = defaultSetup();
|
|
||||||
const tablesMatch = text.match(/'tables_allow'\s*=>\s*\[([^\]]*)\]/s);
|
|
||||||
if (tablesMatch) {
|
|
||||||
result.tables = tablesMatch[1]
|
|
||||||
.split(',')
|
|
||||||
.map(entry => entry.replace(/['\s]/g, '').trim())
|
|
||||||
.filter(Boolean)
|
|
||||||
.filter((value, index, arr) => arr.indexOf(value) === index);
|
|
||||||
}
|
|
||||||
|
|
||||||
const dsnMatch = text.match(/'dsn'\s*=>\s*'([^']+)'/);
|
|
||||||
const userMatch = text.match(/'user'\s*=>\s*'([^']*)'/);
|
|
||||||
const passMatch = text.match(/'pass'\s*=>\s*'([^']*)'/);
|
|
||||||
if (dsnMatch) {
|
|
||||||
const dsn = dsnMatch[1];
|
|
||||||
const dsnParts = Object.fromEntries(dsn.split(';').map(part => {
|
|
||||||
const [key, value] = part.split('=');
|
|
||||||
return [key?.trim(), value?.trim()];
|
|
||||||
}));
|
|
||||||
result.direct.host = dsnParts['mysql:host'] || '';
|
|
||||||
result.direct.port = Number(dsnParts.port || 3306) || 3306;
|
|
||||||
result.direct.database = dsnParts.dbname || '';
|
|
||||||
result.direct.charset = dsnParts.charset || 'utf8mb4';
|
|
||||||
result.mode = 'direct';
|
|
||||||
}
|
|
||||||
if (userMatch) result.direct.user = userMatch[1];
|
|
||||||
if (passMatch) result.direct.password = passMatch[1];
|
|
||||||
|
|
||||||
const snippetMatch = text.match(/\*\* Bridge DB Setup: automatisch generiertes Mapping \*\/([\s\S]+?)\n\}/);
|
|
||||||
if (snippetMatch) {
|
|
||||||
result.mode = 'config';
|
|
||||||
const snippet = snippetMatch[1];
|
|
||||||
result.config.file = parseConfigFileExpression(snippet);
|
|
||||||
result.config.base = parseBridgeBasePath(snippet);
|
|
||||||
result.config.host_key = parseBridgeArrayPath(snippet, 'bridgeDbHost');
|
|
||||||
result.config.port_key = parseBridgeArrayPath(snippet, 'bridgeDbPort');
|
|
||||||
result.config.database_key = parseBridgeArrayPath(snippet, 'bridgeDbName');
|
|
||||||
result.config.user_key = parseBridgeArrayPath(snippet, 'bridgeDbUser');
|
|
||||||
result.config.password_key = parseBridgeArrayPath(snippet, 'bridgeDbPass');
|
|
||||||
result.config.charset_key = parseBridgeArrayPath(snippet, 'bridgeDbCharset');
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseConfigFileExpression(snippet) {
|
|
||||||
const match = snippet.match(/\$bridgeConfigFile\s*=\s*(.+);/);
|
|
||||||
if (!match) return '';
|
|
||||||
const expr = match[1].trim();
|
|
||||||
const dirMatch = expr.match(/__DIR__\s*\.\s*'([^']+)'/);
|
|
||||||
if (dirMatch) {
|
|
||||||
return dirMatch[1];
|
|
||||||
}
|
|
||||||
const quoteMatch = expr.match(/'([^']+)'/);
|
|
||||||
return quoteMatch ? quoteMatch[1] : expr.replace(/[';]/g, '').trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseBridgeArrayPath(snippet, variableName) {
|
|
||||||
const regex = new RegExp('\\$' + variableName + "[\\s=\\(\\)a-zA-Z0-9]*bridge_array_get\\\\(\\$bridgeConfigData,\\s*'([^']*)'", 'i');
|
|
||||||
const match = snippet.match(regex);
|
|
||||||
return match ? match[1] : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseBridgeBasePath(snippet) {
|
|
||||||
const regex = /bridge_array_get\(\$bridgeConfigSource,\s*'([^']*)',\s*\$bridgeConfigData\)/;
|
|
||||||
const match = snippet.match(regex);
|
|
||||||
return match ? match[1] : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeSetupInput(input) {
|
function normalizeSetupInput(input) {
|
||||||
const base = defaultSetup();
|
const base = defaultSetup();
|
||||||
if (!input || typeof input !== 'object') return base;
|
if (!input || typeof input !== 'object') return base;
|
||||||
|
|||||||
Reference in New Issue
Block a user