All checks were successful
Deploy mahnung / deploy (push) Successful in 14s
Umlaute in allen lang-Dateien korrigiert. Alle hardcodierten deutschen Strings
in 22 PHP-Dateien durch $langs->trans('Key') ersetzt. Neue Schlüssel für
Cron-Meldungen, Dokument-Aktionen, Bonität, Vorschlag-Status, Template-Vars u.a.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
2.9 KiB
PHP
94 lines
2.9 KiB
PHP
<?php
|
|
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License, version 3.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/custom/mahnung/class/mahnungntfy.class.php
|
|
* \ingroup mahnung
|
|
* \brief Schmaler Ntfy-Push für das Mahnwesen-Modul.
|
|
*
|
|
* Phase 3: standalone Ntfy.
|
|
* Phase 7: wird durch GlobalNotify-Integration ergänzt/ersetzt (notify-Skill).
|
|
*
|
|
* Konfig-Konstanten (Setup-Seite):
|
|
* MAHNUNG_NTFY_TOPIC Default 'vk-builds'
|
|
* MAHNUNG_NTFY_URL Default 'https://notify.data-it-solution.de'
|
|
* MAHNUNG_NTFY_AUTH Optional: 'Basic ...'
|
|
*/
|
|
class MahnungNtfy
|
|
{
|
|
/**
|
|
* Sendet einen Push. Nie blockierend — Fehler nur ins Syslog.
|
|
*
|
|
* @param string $title Titel (wird header-sanitisiert)
|
|
* @param string $message Body
|
|
* @param string $clickUrl Optional: Click-URL
|
|
* @param array $tags Optional: Emoji-Tags (z.B. ['envelope_with_arrow'])
|
|
* @return bool true wenn HTTP 2xx, sonst false
|
|
*/
|
|
public static function send($title, $message, $clickUrl = '', array $tags = array())
|
|
{
|
|
$url = trim((string) getDolGlobalString('MAHNUNG_NTFY_URL', 'https://notify.data-it-solution.de'));
|
|
$topic = trim((string) getDolGlobalString('MAHNUNG_NTFY_TOPIC', 'vk-builds'));
|
|
$auth = trim((string) getDolGlobalString('MAHNUNG_NTFY_AUTH', ''));
|
|
|
|
if (empty($url) || empty($topic)) {
|
|
dol_syslog('MahnungNtfy: URL oder Topic nicht konfiguriert', LOG_WARNING);
|
|
return false;
|
|
}
|
|
|
|
$endpoint = rtrim($url, '/').'/'.rawurlencode($topic);
|
|
|
|
$headers = array(
|
|
'Content-Type: text/plain; charset=utf-8',
|
|
'Title: '.self::sanitizeHeader($title),
|
|
'Priority: default',
|
|
);
|
|
if (!empty($tags)) {
|
|
$headers[] = 'Tags: '.self::sanitizeHeader(implode(',', $tags));
|
|
}
|
|
if (!empty($clickUrl)) {
|
|
$headers[] = 'Click: '.self::sanitizeHeader($clickUrl);
|
|
}
|
|
if (!empty($auth)) {
|
|
$headers[] = 'Authorization: '.$auth;
|
|
}
|
|
|
|
if (!function_exists('curl_init')) {
|
|
dol_syslog('MahnungNtfy: cURL nicht verfügbar', LOG_WARNING);
|
|
return false;
|
|
}
|
|
|
|
$ch = curl_init($endpoint);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $message);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
|
curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$error = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
if ($httpCode >= 200 && $httpCode < 300) {
|
|
return true;
|
|
}
|
|
dol_syslog('MahnungNtfy: Push fehlgeschlagen ('.$httpCode.') '.$error, LOG_WARNING);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Header-Werte müssen Single-Line sein. Newlines + Steuerzeichen entfernen.
|
|
*
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
private static function sanitizeHeader($value)
|
|
{
|
|
return trim(preg_replace('/[\r\n\x00-\x1F\x7F]/', ' ', (string) $value));
|
|
}
|
|
}
|