ddsfds
This commit is contained in:
@@ -414,9 +414,10 @@ $renderField = function (array $field) use (&$current, $getNested, $driverOption
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$isSchedulerAutosave = isset($_POST['scheduler_autosave']) && (string) $_POST['scheduler_autosave'] === '1';
|
||||
$isSchedulerTest = isset($_POST['scheduler_test']) && (string) $_POST['scheduler_test'] === '1';
|
||||
$payload = [];
|
||||
|
||||
if ($isSchedulerAutosave) {
|
||||
if ($isSchedulerAutosave || $isSchedulerTest) {
|
||||
if ($cronTaskDefinitions !== []) {
|
||||
$postedSchedulerJobs = is_array($_POST['scheduler_jobs'] ?? null) ? $_POST['scheduler_jobs'] : [];
|
||||
$current['scheduler_jobs'] = $extractSchedulerJobs($postedSchedulerJobs, $cronTaskDefinitions, $current);
|
||||
@@ -425,15 +426,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$current = modules()->settings($moduleName);
|
||||
$refreshSchedulerState();
|
||||
|
||||
$testResult = null;
|
||||
if ($isSchedulerTest) {
|
||||
$jobName = trim((string) ($_POST['scheduler_job_name'] ?? ''));
|
||||
$entryIndex = max(0, (int) ($_POST['scheduler_entry_index'] ?? 0));
|
||||
$testResult = modules()->runCronTaskNow($moduleName, $jobName, $entryIndex);
|
||||
$refreshSchedulerState();
|
||||
}
|
||||
|
||||
while (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode([
|
||||
'ok' => true,
|
||||
'message' => 'Scheduler gespeichert.',
|
||||
'message' => $isSchedulerTest
|
||||
? (string) ($testResult['message'] ?? 'Cron-Test ausgefuehrt.')
|
||||
: 'Scheduler gespeichert.',
|
||||
'scheduler_jobs' => $current['scheduler_jobs'] ?? [],
|
||||
'statuses' => $cronTaskStatuses,
|
||||
'test_result' => $testResult,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
@@ -906,6 +918,7 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
<small class="muted">Letzter Erfolg: <?= e($formatRunTimestamp((string) ($task['state']['last_success_at'] ?? ''), (string) ($task['timezone'] ?? 'UTC'))) ?></small>
|
||||
<small class="muted">Naechster Lauf lokal: <?= e(!empty($task['enabled']) ? (string) (($task['next_due_at_local'] ?? '') !== '' ? $task['next_due_at_local'] : '-') : '-') ?></small>
|
||||
<small class="muted">Status: <?= e((string) (($task['state']['last_status'] ?? '') !== '' ? $task['state']['last_status'] : '-')) ?></small>
|
||||
<small class="muted">Meldung: <?= e((string) (($task['state']['last_message'] ?? '') !== '' ? $task['state']['last_message'] : '-')) ?></small>
|
||||
<?php if (trim((string) ($task['parse_error'] ?? '')) !== ''): ?>
|
||||
<small class="muted" style="color:#b42318;">Cron-Fehler: <?= e((string) $task['parse_error']) ?></small>
|
||||
<?php endif; ?>
|
||||
@@ -1281,6 +1294,7 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
<small class="muted">Letzter Erfolg: <?= e($formatRunTimestamp((string) ($task['state']['last_success_at'] ?? ''), (string) ($task['timezone'] ?? 'UTC'))) ?></small>
|
||||
<small class="muted">Naechster Lauf lokal: <?= e(!empty($task['enabled']) ? (string) (($task['next_due_at_local'] ?? '') !== '' ? $task['next_due_at_local'] : '-') : '-') ?></small>
|
||||
<small class="muted">Status: <?= e((string) (($task['state']['last_status'] ?? '') !== '' ? $task['state']['last_status'] : '-')) ?></small>
|
||||
<small class="muted">Meldung: <?= e((string) (($task['state']['last_message'] ?? '') !== '' ? $task['state']['last_message'] : '-')) ?></small>
|
||||
<?php if (trim((string) ($task['parse_error'] ?? '')) !== ''): ?>
|
||||
<small class="muted" style="color:#b42318;">Cron-Fehler: <?= e((string) $task['parse_error']) ?></small>
|
||||
<?php endif; ?>
|
||||
@@ -1754,6 +1768,15 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
return payload;
|
||||
};
|
||||
|
||||
const collectSchedulerTestPayload = (jobName, entryIndex) => {
|
||||
const payload = collectSchedulerPayload();
|
||||
payload.delete('scheduler_autosave');
|
||||
payload.append('scheduler_test', '1');
|
||||
payload.append('scheduler_job_name', jobName);
|
||||
payload.append('scheduler_entry_index', String(entryIndex));
|
||||
return payload;
|
||||
};
|
||||
|
||||
const persistScheduler = async () => {
|
||||
if (!form) return true;
|
||||
const url = form.action || window.location.href;
|
||||
@@ -1799,6 +1822,35 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
return true;
|
||||
};
|
||||
|
||||
const testScheduler = async (jobName, entryIndex) => {
|
||||
if (!form) return null;
|
||||
const url = form.action || window.location.href;
|
||||
console.log('[scheduler] test start', { jobName, entryIndex, url });
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
body: collectSchedulerTestPayload(jobName, entryIndex),
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
},
|
||||
});
|
||||
const raw = await response.text();
|
||||
console.log('[scheduler] test raw response', raw);
|
||||
let data = null;
|
||||
try {
|
||||
data = JSON.parse(raw);
|
||||
} catch (error) {
|
||||
console.error('[scheduler] test json parse failed', error);
|
||||
throw new Error(`Cron-Test Antwort war kein JSON: ${raw.slice(0, 160)}`);
|
||||
}
|
||||
if (!response.ok || !data || data.ok !== true) {
|
||||
throw new Error(data?.message || `Cron-Test fehlgeschlagen (${response.status}).`);
|
||||
}
|
||||
applyStatusUpdates(data.statuses || []);
|
||||
return data;
|
||||
};
|
||||
|
||||
const updateEntrySummary = (entry) => {
|
||||
const enabled = getEntryField(entry, '[data-enabled]')?.checked ?? false;
|
||||
const expression = getEntryField(entry, '[data-cron-expression]')?.value || '';
|
||||
@@ -1855,6 +1907,7 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
<small class="muted">${lastSuccess ? lastSuccess.textContent : 'Letzter Erfolg: -'}</small>
|
||||
<small class="muted">${nextLocal ? nextLocal.textContent : 'Naechster Lauf lokal: -'}</small>
|
||||
<small class="muted">${status ? status.textContent : 'Status: -'}</small>
|
||||
<small class="muted">${findStatusNode(entry, 'Meldung') ? findStatusNode(entry, 'Meldung').textContent : 'Meldung: -'}</small>
|
||||
${parseError ? `<small class="muted scheduler-entry__error">${parseError.textContent}</small>` : ''}
|
||||
`;
|
||||
};
|
||||
@@ -2012,6 +2065,7 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
<small class="muted">Letzter Erfolg: -</small>
|
||||
<small class="muted">Naechster Lauf lokal: -</small>
|
||||
<small class="muted">Status: -</small>
|
||||
<small class="muted">Meldung: -</small>
|
||||
`;
|
||||
|
||||
getEntryField(entry, '[data-enabled]').checked = Boolean(values.enabled);
|
||||
@@ -2061,12 +2115,34 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)
|
||||
actions.dataset.entryActions = '';
|
||||
actions.innerHTML = `
|
||||
<button class="nav-link" type="button" data-entry-edit>Bearbeiten</button>
|
||||
<button class="nav-link" type="button" data-entry-test>Cron testen</button>
|
||||
${job.dataset.jobMode === 'multi' ? '<button class="nav-link" type="button" data-remove-scheduler-entry>Entfernen</button>' : ''}
|
||||
`;
|
||||
entry.appendChild(actions);
|
||||
}
|
||||
|
||||
actions.querySelector('[data-entry-edit]')?.addEventListener('click', () => openModal(entry));
|
||||
actions.querySelector('[data-entry-test]')?.addEventListener('click', async () => {
|
||||
const testButton = actions.querySelector('[data-entry-test]');
|
||||
const originalText = testButton?.textContent || 'Cron testen';
|
||||
const jobName = job.dataset.jobName || '';
|
||||
const entryIndex = Number(entry.dataset.entryIndex || '0');
|
||||
if (testButton) {
|
||||
testButton.disabled = true;
|
||||
testButton.textContent = 'Teste...';
|
||||
}
|
||||
try {
|
||||
const result = await testScheduler(jobName, entryIndex);
|
||||
alert(result?.message || 'Cron-Test erfolgreich.');
|
||||
} catch (error) {
|
||||
alert(error instanceof Error ? error.message : 'Cron-Test fehlgeschlagen.');
|
||||
} finally {
|
||||
if (testButton) {
|
||||
testButton.disabled = false;
|
||||
testButton.textContent = originalText;
|
||||
}
|
||||
}
|
||||
});
|
||||
actions.querySelector('[data-remove-scheduler-entry]')?.addEventListener('click', async () => {
|
||||
entry.remove();
|
||||
reindexJob(job);
|
||||
|
||||
Reference in New Issue
Block a user