dolibarr.globalnotify/admin/setup.php
data 197d87c663 feat: Konfigurierbares Cron-Prüfintervall und Dokumentation
- Admin-Seite mit Einstellung für Cron-Prüfintervall (10-3600 Sek)
- checkStuckCronJobs() nutzt jetzt konfigurierbare Einstellung
- README.md mit vollständiger Integrations-Dokumentation
- Sichere Nutzung ohne Fatal Error wenn Modul nicht installiert
- Version 1.3.0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-23 11:22:29 +01:00

224 lines
7 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* GlobalNotify Admin Setup Page
*/
// Load Dolibarr environment
$res = 0;
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
}
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME'];
$tmp2 = realpath(__FILE__);
$i = strlen($tmp) - 1;
$j = strlen($tmp2) - 1;
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
$i--;
$j--;
}
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
$res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
}
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
$res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include "../../../main.inc.php";
}
if (!$res) {
die("Include of main fails");
}
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
dol_include_once('/globalnotify/class/globalnotify.class.php');
/**
* @var Conf $conf
* @var DoliDB $db
* @var Translate $langs
* @var User $user
*/
$langs->loadLangs(array("admin", "globalnotify@globalnotify"));
// Access control
if (!$user->admin) {
accessforbidden();
}
$action = GETPOST('action', 'aZ09');
/*
* Actions
*/
if ($action == 'update') {
$cronCheckInterval = GETPOST('GLOBALNOTIFY_CRON_CHECK_INTERVAL', 'int');
if ($cronCheckInterval < 10) {
$cronCheckInterval = 10; // Minimum 10 seconds
}
if ($cronCheckInterval > 3600) {
$cronCheckInterval = 3600; // Maximum 1 hour
}
dolibarr_set_const($db, 'GLOBALNOTIFY_CRON_CHECK_INTERVAL', $cronCheckInterval, 'chaine', 0, '', $conf->entity);
setEventMessages("Einstellungen gespeichert", null, 'mesgs');
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
}
if ($action == 'clearall') {
// Clear all notifications
$sql = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name LIKE 'GLOBALNOTIFY_%'";
$db->query($sql);
setEventMessages("Alle Benachrichtigungen gelöscht", null, 'mesgs');
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
}
if ($action == 'resetcronjobs') {
// Reset all stuck cron jobs
$sql = "UPDATE ".MAIN_DB_PREFIX."cronjob SET processing = 0 WHERE processing = 1";
$resql = $db->query($sql);
$affected = $db->affected_rows($resql);
setEventMessages("{$affected} Cron-Jobs zurückgesetzt", null, 'mesgs');
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
}
/*
* View
*/
$page_name = "GlobalNotify - ".$langs->trans("Settings");
llxHeader('', $page_name);
print load_fiche_titre($page_name, '', 'title_setup');
// Settings Form
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="2">Einstellungen</th>';
print '</tr>';
// Cron check interval
$cronCheckInterval = getDolGlobalInt('GLOBALNOTIFY_CRON_CHECK_INTERVAL', 60);
print '<tr class="oddeven">';
print '<td><label for="GLOBALNOTIFY_CRON_CHECK_INTERVAL">Cron-Prüfintervall (Sekunden)</label>';
print '<br><small class="opacitymedium">Wie oft soll auf hängende Cron-Jobs geprüft werden? (10-3600 Sekunden)</small></td>';
print '<td><input type="number" name="GLOBALNOTIFY_CRON_CHECK_INTERVAL" id="GLOBALNOTIFY_CRON_CHECK_INTERVAL" value="'.$cronCheckInterval.'" min="10" max="3600" style="width:100px"> Sekunden</td>';
print '</tr>';
print '</table>';
print '<br><div class="center">';
print '<input type="submit" class="button button-save" value="Speichern">';
print '</div>';
print '</form>';
print '<br>';
// Get all notifications
$notify = new GlobalNotify($db);
$allNotifications = $notify->getAllNotifications(0, false); // All, including read
// Get stuck cron jobs
$sql = "SELECT rowid, label, module_name, datelastrun, processing, status
FROM ".MAIN_DB_PREFIX."cronjob
WHERE status = 1
ORDER BY processing DESC, label";
$resql = $db->query($sql);
print '<div class="div-table-responsive">';
// Actions
print '<div class="tabsAction">';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=clearall" onclick="return confirm(\'Alle Benachrichtigungen löschen?\')">Alle Benachrichtigungen löschen</a>';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=resetcronjobs" onclick="return confirm(\'Alle hängenden Cron-Jobs zurücksetzen?\')">Hängende Cron-Jobs zurücksetzen</a>';
print '</div>';
// Cron Jobs Overview
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>Cron-Job</th>';
print '<th>Modul</th>';
print '<th>Status</th>';
print '<th>Letzter Lauf</th>';
print '</tr>';
if ($resql) {
while ($obj = $db->fetch_object($resql)) {
print '<tr class="oddeven">';
print '<td>'.$obj->label.'</td>';
print '<td>'.($obj->module_name ?: '-').'</td>';
print '<td>';
if ($obj->processing) {
print '<span class="badge badge-status1" style="background-color:#ff9800">HÄNGT</span>';
} else {
print '<span class="badge badge-status4">OK</span>';
}
print '</td>';
print '<td>'.dol_print_date($db->jdate($obj->datelastrun), 'dayhour').'</td>';
print '</tr>';
}
}
print '</table>';
// All Notifications
print '<br>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>Benachrichtigungen ('.count($allNotifications).')</th>';
print '<th>Modul</th>';
print '<th>Typ</th>';
print '<th>Datum</th>';
print '<th>Status</th>';
print '</tr>';
if (empty($allNotifications)) {
print '<tr class="oddeven"><td colspan="5" class="center opacitymedium">Keine Benachrichtigungen</td></tr>';
} else {
foreach ($allNotifications as $notif) {
print '<tr class="oddeven">';
print '<td>';
print '<strong>'.dol_escape_htmltag($notif['title']).'</strong><br>';
print '<small>'.dol_escape_htmltag($notif['message']).'</small>';
if (!empty($notif['action_url'])) {
print '<br><a href="'.dol_escape_htmltag($notif['action_url']).'">'.$notif['action_label'].'</a>';
}
print '</td>';
print '<td>'.$notif['module'].'</td>';
print '<td>';
$typeLabels = array(
'error' => '<span class="badge badge-status8">Fehler</span>',
'warning' => '<span class="badge badge-status1" style="background:#ff9800">Warnung</span>',
'info' => '<span class="badge badge-status4">Info</span>',
'success' => '<span class="badge badge-status4">Erfolg</span>',
'action' => '<span class="badge badge-status6">Aktion</span>',
);
print $typeLabels[$notif['type']] ?? $notif['type'];
print '</td>';
print '<td>'.dol_print_date($notif['created'], 'dayhour').'</td>';
print '<td>';
if (!empty($notif['read'])) {
print '<span class="opacitymedium">Gelesen</span>';
} else {
print '<strong>Ungelesen</strong>';
}
print '</td>';
print '</tr>';
}
}
print '</table>';
print '</div>';
llxFooter();
$db->close();