Upload via GUI (258 Dateien)

This commit is contained in:
2026-10-16 19:12:18 +00:00
parent 56deade877
commit 6cced3beda
50 changed files with 11148 additions and 0 deletions
@@ -0,0 +1,148 @@
<?php
/**
* includes/crontab_installer.php
*
* Installiert/entfernt die 6 DeskHub-Cronjobs direkt in der System-Crontab des
* aktuellen Benutzers (crontab -l / crontab -). Nur sinnvoll auf einem eigenen
* (v)Server mit Shell-Zugriff für den Web-User – auf klassischem Shared-Hosting
* ist exec()/proc_open() fast immer gesperrt, siehe crontab_capability_check().
*
* Sicherheitsprinzip: Es wird NIE ein von außen beeinflussbarer String als
* Shell-Befehl ausgeführt. Die Crontab-Zeilen sind fest im Code hinterlegt
* (nur der erkannte PHP-Pfad und der DeskHub-Installationspfad sind variabel,
* beide serverseitig ermittelt, nicht aus einer Nutzereingabe). Nur der klar
* markierte "# DESKHUB-CRON-…"-Block wird verwaltet, alle anderen vorhandenen
* Crontab-Einträge des Nutzers bleiben unangetastet.
*/
const DESKHUB_CRON_MARKER_START = '# DESKHUB-CRON-START (automatisch verwaltet von DeskHub – Einstellungen → Cron-Jobs. Manuelle Änderungen hier werden beim erneuten Installieren überschrieben.)';
const DESKHUB_CRON_MARKER_END = '# DESKHUB-CRON-END';
/** Prüft, ob dieser Server eine automatische Installation überhaupt technisch zulässt. */
function crontab_capability_check(): array
{
// Crontab ist ein Unix-Mechanismus; auf Windows (z.B. lokale Entwicklung) von vornherein ausschließen,
// statt uns auf lokalisierte/unvorhersehbare Fehlertexte von cmd.exe verlassen zu müssen.
if (PHP_OS_FAMILY === 'Windows') {
return ['available' => false, 'reason' => 'Windows-Server werden nicht unterstützt (Crontab ist ein Unix/Linux-Mechanismus).'];
}
$disabled = array_map('trim', explode(',', (string) ini_get('disable_functions')));
foreach (['proc_open', 'shell_exec'] as $fn) {
if (!function_exists($fn) || in_array($fn, $disabled, true)) {
return ['available' => false, 'reason' => "PHP-Funktion \"$fn\" ist auf diesem Server gesperrt (typisch für Shared-Hosting)."];
}
}
$out = @shell_exec('crontab -l 2>&1');
if ($out === null) {
return ['available' => false, 'reason' => 'Der Befehl "crontab" konnte nicht ausgeführt werden.'];
}
// "no crontab for <user>" ist der normale Zustand, wenn noch keine Crontab existiert – das ist OK.
if (stripos($out, 'not found') !== false || stripos($out, 'command not found') !== false) {
return ['available' => false, 'reason' => 'Das Programm "crontab" ist auf diesem Server nicht installiert.'];
}
if (stripos($out, 'permission denied') !== false) {
return ['available' => false, 'reason' => 'Der Web-Server-Benutzer hat keine Berechtigung für crontab.'];
}
return ['available' => true, 'reason' => ''];
}
/** Versucht, den echten CLI-PHP-Pfad zu ermitteln (PHP_BINARY zeigt unter Apache/FPM auf den falschen Binary). */
function detect_php_cli_binary(): string
{
$which = trim((string) @shell_exec('command -v php 2>/dev/null'));
if ($which !== '' && is_executable($which)) {
return $which;
}
foreach (['/usr/bin/php', '/usr/local/bin/php', '/opt/php/bin/php'] as $candidate) {
if (is_executable($candidate)) {
return $candidate;
}
}
return 'php'; // Fallback: hoffen, dass PATH im Cron-Kontext passt
}
/** Baut den verwalteten DeskHub-Block mit den 6 Job-Zeilen (fest hinterlegte Kommandos, keine Nutzereingabe). */
function crontab_marker_block(): string
{
$php = detect_php_cli_binary();
$root = realpath(__DIR__ . '/..');
$lines = [
DESKHUB_CRON_MARKER_START,
"*/5 * * * * $php $root/cron/fetch_emails.php >> $root/cron/fetch_emails.log 2>&1",
"*/15 * * * * $php $root/cron/check_sla.php >> $root/cron/check_sla.log 2>&1",
"0 * * * * $php $root/cron/check_escalations.php >> $root/cron/check_escalations.log 2>&1",
"0 6 * * * $php $root/cron/process_recurring.php >> $root/cron/process_recurring.log 2>&1",
"0 2 * * * $php $root/cron/process_backups.php >> $root/cron/process_backups.log 2>&1",
"0 3 * * * $php $root/cron/anonymize_data.php >> $root/cron/anonymize_data.log 2>&1",
DESKHUB_CRON_MARKER_END,
];
return implode("\n", $lines);
}
function crontab_get_current(): string
{
$out = @shell_exec('crontab -l 2>/dev/null');
return $out !== null ? $out : '';
}
function crontab_is_installed(): bool
{
return str_contains(crontab_get_current(), DESKHUB_CRON_MARKER_START);
}
/** Entfernt einen ggf. vorhandenen DeskHub-Block aus einem Crontab-Text (Hilfsfunktion für install+remove). */
function crontab_strip_marker_block(string $content): string
{
$pattern = '/^' . preg_quote(DESKHUB_CRON_MARKER_START, '/') . '.*?^' . preg_quote(DESKHUB_CRON_MARKER_END, '/') . '\n?/ms';
return preg_replace($pattern, '', $content) ?? $content;
}
/** Schreibt einen kompletten neuen Crontab-Inhalt für den aktuellen Benutzer. */
function crontab_write(string $content): array
{
$descriptors = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
$proc = @proc_open('crontab -', $descriptors, $pipes);
if (!is_resource($proc)) {
return ['ok' => false, 'error' => 'crontab-Prozess konnte nicht gestartet werden.'];
}
fwrite($pipes[0], $content);
fclose($pipes[0]);
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($proc);
if ($code !== 0) {
return ['ok' => false, 'error' => trim($stderr) ?: trim($stdout) ?: "crontab beendete mit Fehlercode $code"];
}
return ['ok' => true, 'error' => ''];
}
/** Installiert/aktualisiert den DeskHub-Block in der Crontab des aktuellen Benutzers. */
function crontab_install(): array
{
$check = crontab_capability_check();
if (!$check['available']) {
return ['ok' => false, 'error' => $check['reason']];
}
$current = crontab_strip_marker_block(crontab_get_current());
$current = rtrim($current, "\n");
$new = ($current !== '' ? $current . "\n\n" : '') . crontab_marker_block() . "\n";
return crontab_write($new);
}
/** Entfernt den DeskHub-Block aus der Crontab, lässt alle anderen Einträge unangetastet. */
function crontab_uninstall(): array
{
$check = crontab_capability_check();
if (!$check['available']) {
return ['ok' => false, 'error' => $check['reason']];
}
$current = crontab_get_current();
if (!str_contains($current, DESKHUB_CRON_MARKER_START)) {
return ['ok' => true, 'error' => '']; // war gar nicht installiert
}
$new = crontab_strip_marker_block($current);
return crontab_write($new);
}