- Add cleanupDisabledCronNotifications() method - Automatically mark notifications as read when cronjob is disabled - Fixes issue where "Cron-Job verpasst" kept reappearing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
224 lines
7 KiB
PHP
Executable file
224 lines
7 KiB
PHP
Executable file
<?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();
|