prepare intranet for first Dokploy deployment

This commit is contained in:
2026-08-26 12:59:51 +02:00
parent 5cfe688bdc
commit 29dfb85fef
1321 changed files with 227234 additions and 0 deletions
@@ -0,0 +1,79 @@
<?php
header('Content-Type: application/json; charset=utf-8');
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
try {
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.'], JSON_UNESCAPED_UNICODE);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT'] . "/intranet_repo/general_files/ini/database.php");
// Eingaben
$last_name = trim($_POST['last_name'] ?? '');
$first_name = trim($_POST['first_name'] ?? '');
$birth_date = trim($_POST['birth_date'] ?? '');
$address_street = trim($_POST['address_street'] ?? '');
$address_plz = trim($_POST['address_plz'] ?? '');
$address_link = trim($_POST['address_link'] ?? '');
$phone_raw = trim($_POST['phone'] ?? '');
$comment = trim($_POST['comment'] ?? '');
$letzter_besuch = trim($_POST['letzter_besuch'] ?? '');
$priority = isset($_POST['priority']) ? (int)$_POST['priority'] : 0;
$pr_bezirk_raw = trim($_POST['pr_bezirk'] ?? '');
// Pflichtfelder
if ($last_name === '' || $first_name === '' || $birth_date === '' || $address_street === '' || $address_plz === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Pflichtfelder fehlen.'], JSON_UNESCAPED_UNICODE);
exit;
}
// Telefon: nur Ziffern (robust gegen +49/Leerzeichen)
$phone = preg_replace('/\D+/', '', $phone_raw);
if ($phone === '') {
$phone = null; // phone darf NULL sein (laut Tabelle)
}
// WICHTIG: diese Spalten sind NOT NULL in deiner Tabelle -> niemals NULL senden
if ($address_link === '') $address_link = '';
if ($comment === '') $comment = '';
if ($letzter_besuch === '') $letzter_besuch = "2024-07-11";
if ($pr_bezirk_raw === '') $pr_bezirk_raw = ''; // pr_bezirk ist NOT NULL (varchar)
$sql = "INSERT INTO seelsorge_besuchsstellen
(last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk, reservation)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$last_name,
$first_name,
$birth_date,
$address_street,
$address_plz,
$address_link,
$phone,
$comment,
$letzter_besuch,
$priority,
$pr_bezirk_raw
]);
$newId = $pdo->lastInsertId();
echo json_encode(['status' => 'success', 'besuch_id' => $newId], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'DB-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Server-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
@@ -0,0 +1,24 @@
<?php /* Name: content/calendar.php
Beschreibung: Kalendarium
Aufgerufen über seelsorge.php */
?>
<?php
require_once('util/connector_feiertage.php');
$connector_feiertage = lib_Feiertage_Connector::getInstance();
require_once('util/connector_kalendertage.php');
$connector_kalendertage = lib_Kalendertage_Connector::getInstance();
?>
<div class='page_calendar unselectable active' id="calendar_view">
<?php include "content/calendar_view.php"; ?>
</div>
<?php include "content/calendar_help.php"; ?>
<?php
// Profiloverlay für Kalenderbereich
$isPageCalendar = true;
include "content/profile.php";
?>
@@ -0,0 +1,124 @@
<?php
/* Name: content/calendar_day.php
Beschreibung: AJAX-Endpoint: Liefert Inhalt fuer das Tages-Modal
Aufgerufen per fetch() aus seelsorge.js */
// CWD auf seelsorge/ setzen (Connector nutzt relative Pfade wie data/)
chdir(dirname(__DIR__));
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
if (isset($_POST['calendarDate'])):
$p_selectedDate = $_POST['calendarDate'];
require_once($g_projectsPath . 'seelsorge/util/connector_feiertage.php');
$connector_feiertage = lib_Feiertage_Connector::getInstance();
require_once($g_projectsPath . 'seelsorge/util/connector_kalendertage.php');
$connector_kalendertage = lib_Kalendertage_Connector::getInstance();
// Tagesinformationen
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_selectedDate);
$p_calendarWeekdayName = $connector_kalendertage->get_KalenderWochentag($p_selectedDate);
$p_dayNumber = date("j", strtotime($p_selectedDate));
$p_year = date("Y", strtotime($p_selectedDate));
$p_kw = date("W", strtotime($p_selectedDate));
$feiertagsname = $connector_feiertage->get_feiertagsname($p_selectedDate);
$p_dateTitle = $p_calendarWeekdayName . ", " . $p_dayNumber . ". " . $p_calendarMonthName . " " . $p_year;
// Verfuegbare Diakon*innen laden
$sql = "SELECT u.*, p.\"DiakonIn\" FROM user_general_information u
LEFT JOIN user_permissions p ON u.user_id = p.user_id
ORDER BY RANDOM()";
$result = $pdo->query($sql);
$availableUsers = [];
$allRows = $result->fetchAll();
if (count($allRows) > 0) {
foreach($allRows as $row) {
$userId = $row['user_id'];
$name = $row['first_name'] . " " . $row['last_name'];
if ($row['first_name'] != null && $row['last_name'] != null && $row['DiakonIn'] == 1) {
$stmt_av = $pdo->prepare("SELECT * FROM verfuegbarkeiten WHERE user_id = ? AND datum = ?");
$stmt_av->execute([$userId, $p_selectedDate]);
if ($stmt_av->rowCount() > 0) {
$availableUsers[$userId] = $name;
}
}
}
}
// Pruefe ob aktueller User eingetragen ist
$stmt_self = $pdo->prepare("SELECT COUNT(*) AS count FROM verfuegbarkeiten WHERE datum=? AND user_id=?");
$stmt_self->execute([$p_selectedDate, $_SESSION["user_id"]]);
$selfResult = $stmt_self->fetch();
$selfAvailable = $selfResult['count'] > 0;
// JSON-Metadaten fuer JS
echo '<script type="application/json" id="modal-meta">';
echo json_encode([
'title' => $p_dateTitle,
'kw' => $p_kw,
'feiertag' => $feiertagsname,
'selfAvailable' => $selfAvailable,
'date' => $p_selectedDate
], JSON_UNESCAPED_UNICODE);
echo '</script>';
?>
<!-- Tagesinformationen -->
<div class="seelsorge-modal-section">
<?php if ($feiertagsname): ?>
<div class="seelsorge-modal-field">
<div class="seelsorge-modal-field-label">Feiertag</div>
<div class="seelsorge-modal-field-value"><?= htmlspecialchars($feiertagsname) ?></div>
</div>
<?php endif; ?>
</div>
<!-- Verfuegbare Diakon*innen -->
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Verf&uuml;gbare Personen</div>
<?php if (count($availableUsers) > 0): ?>
<div class="diakon-grid" id="modal-galery">
<?php foreach ($availableUsers as $userId => $name):
$profileImg = glob($_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/profile_pictures/' . $userId . '-*.jpg');
if (!empty($profileImg)) {
usort($profileImg, function($a, $b) { return filemtime($b) - filemtime($a); });
$imgPath = str_replace($_SERVER['DOCUMENT_ROOT'], '', $profileImg[0]);
} else {
$imgPath = '/intranet_repo/general_files/profile_pictures/default.jpg';
}
?>
<div class="diakon-card" onclick="openCalendarProfile(<?= (int)$userId ?>)" title="Profil anzeigen">
<img class="diakon-card-img" src="<?= htmlspecialchars($imgPath) ?>" alt="<?= htmlspecialchars($name) ?>">
<div class="diakon-card-info">
<div class="diakon-card-name"><?= htmlspecialchars($name) ?></div>
<div class="diakon-card-role">Verfügbar</div>
</div>
<div class="diakon-card-arrow">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square"><path d="M9 18l6-6-6-6"/></svg>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="seelsorge-modal-empty">Keine Personen verf&uuml;gbar.</div>
<?php endif; ?>
</div>
<!-- Eintragen / Austragen -->
<div class="seelsorge-modal-actions">
<button type="button"
class="seelsorge-action-button <?= $selfAvailable ? 'seelsorge-remove-button' : 'seelsorge-add-button' ?>"
id="modal-toggle-btn"
onclick="toggleAvailabilityModal('<?= $p_selectedDate ?>')">
<?= $selfAvailable ? 'Verf&uuml;gbarkeit entfernen' : 'Als verf&uuml;gbar eintragen' ?>
</button>
</div>
<?php
$pdo = null;
endif;
?>
@@ -0,0 +1,138 @@
<?php /* Name: content/calendar_edit.php
Beschreibung: Kalenderblatt zum Bearbeiten der Verfügbarkeit des jeweiligen Users
Aufgerufen über calendar.php
*/
?>
<div class="calendar_title_modus">Bearbeitung der eigenen Verfügbarkeit</div>
<div id="toggleViewEdit" class="button tooltip borderradius_round" onclick="toggleViewEdit()">
<?php display_button('calendar', null, 'right'); ?>
<span class="tooltiptext">Kalender anzeigen</span>
</div>
<?php
// 2 Kalendermonate laden
for ($t = 1; $t <= 2; $t++) {
// Startdatum und Stile festlegen
$p_startDate = date("Y-m-d", strtotime($t === 1 ? "first day of this month" : "first day of next month"));
$p_style = $t === 1 ? "display:flex" : "display:none";
$p_class_arrow_left = $t === 1 ? "arrow_light" : "arrow_dark";
$p_class_arrow_right = $t === 1 ? "arrow_dark" : "arrow_light";
// Monatsnamen und Titel holen
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_startDate);
$p_calendarTitle = $p_calendarMonthName . " " . date("Y", strtotime($p_startDate));
// Kalenderkopf ausgeben
?>
<div class="calendar_header" style="<?= $p_style ?>" id="calendar_edit_header_<?= $t ?>">
<div class="arrow_item" onclick="switchCalendarEdit('left')">
<div class="<?= $p_class_arrow_left ?>" id="left">
<?php display_button('arrow_left', null, 'left'); ?>
</div>
</div>
<div class="calendar_title"><?= $p_calendarTitle ?></div>
<div class="arrow_item" onclick="switchCalendarEdit('right')">
<div class="<?= $p_class_arrow_right ?>" id="right">
<?php display_button('arrow_right', null, 'right'); ?>
</div>
</div>
</div>
<?php
}
?>
<div class="calendar_content">
<table>
<thead>
<tr>
<th class="calendar_head">MO</th>
<th class="calendar_head">DI</th>
<th class="calendar_head">MI</th>
<th class="calendar_head">DO</th>
<th class="calendar_head">FR</th>
<th class="calendar_head_sat">SA</th>
<th class="calendar_head_sun">SO</th>
</tr>
</thead>
<tbody>
<?php
for ($c = 1; $c <= 2; $c++) { // Zwei Monatsansichten laden
$p_startDate = $c === 1 ? date("Y-m-d", strtotime("first day of this month")) : date("Y-m-d", strtotime("first day of next month"));
$p_endDate = $c === 1 ? date("Y-m-d", strtotime("last day of this month")) : date("Y-m-d", strtotime("last day of next month"));
$p_style = $c === 1 ? "visibility:visible" : "visibility:collapse";
$p_calendarStartDate = $connector_kalendertage->get_KalenderStart($p_startDate);
// Kalender: 6 Wochen in Zeilen
for ($i = 0; $i < 42; $i++) {
$datum = date('Y-m-d', strtotime("$p_calendarStartDate +$i days"));
$tag = date('j', strtotime("$p_calendarStartDate +$i days"));
$wochentag = date("w", strtotime("$p_calendarStartDate +$i days"));
$wochennr = (int)date("W o", strtotime("$p_calendarStartDate +$i days"));
$isFeiertagInBerlin = $connector_feiertage->isFeiertagInBerlin($datum); // Nur Berlin
$feiertagsname = $connector_feiertage->get_feiertagsname($datum); // (alle Bundesländer)
if ($i % 7 === 0) { // Beginn der Tabellenzeile
echo "<tr name='calendar_edit_$c' style='$p_style'>";
}
// Sichtbarkeit
if ($datum < date("Y-m-d")) { // vor Heute - nicht anklickbar
echo "<td class='calendar_day_area' style='filter:brightness(60%);opacity:0.3;'>";
echo "<div class='calendar_day'>$tag</div>";
} elseif ($datum < $p_startDate || $datum > $p_endDate) { // außerhalb des Monats
echo "<td class='calendar_day_area' style='filter:brightness(100%);opacity:0.5;'>";
echo "<div class='calendar_day'>$tag</div>";
} else {
echo "<td class='calendar_day_area'>";
echo "<div class='calendar_day'>";
// Verfügbarkeit des Users nur für zukünftige Tage
$sql = "SELECT COUNT(datum) AS count FROM verfuegbarkeiten WHERE datum=? and user_id=?";
$stmt = $pdo->prepare($sql);
if ($stmt) {
$stmt->execute([$datum, $_SESSION["user_id"]]);
$row = $stmt->fetch();
if ($row) {
$count = $row['count'];
} else {
echo "Error retrieving result";
}
} else {
echo "Error preparing statement";
}
// Falls das Datum heute oder in der Zukunft liegt
$Id_cDayItem = "id='calendar_day_item'";
if ($count > 0) { // User ist schon eingetragen
echo "<div $Id_cDayItem class='calendar_day_item availableday editmode' title='Verfügbar' onclick='toggleAvailability(\"$datum\", this)'>";
} else { // User ist noch nicht eingetragen
echo "<div $Id_cDayItem class='calendar_day_item normalday editmode' onclick='toggleAvailability(\"$datum\", this)'>";
}
echo $tag;
if ($feiertagsname != null) {
echo "<div class='feiertagsname'>$feiertagsname</div>";
}
echo "</div>"; // END: calendar_day
}
echo "</td>"; // END: calendar_day_area
if ($i % 7 === 6) { // Ende der Tabellenzeile
echo "</tr>";
}
// Reset der Variablen
$feiertagsname = null;
}
} // Schleifenende: Zwei Monatsansichten laden
?>
</tbody>
</table> <!-- END: calendar -->
</div> <!-- END: calendar_content -->
@@ -0,0 +1,67 @@
<!-- Hilfe-Modal fuer Kalendarium -->
<div class="standard_overlay" id="calendar-help-modal" onclick="if(event.target===this)closeCalendarHelp()">
<div class="seelsorge-modal-card" style="max-width:460px;">
<button type="button" class="exit" aria-label="Schließen" onclick="closeCalendarHelp()">×</button>
<div class="seelsorge-modal-hero">
<div class="seelsorge-modal-hero-icon">
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="#FFFFFF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
</div>
<div>
<div class="seelsorge-modal-title">Hilfe zum Kalendarium</div>
<div class="seelsorge-modal-subtitle">So funktioniert der Seelsorgeplaner</div>
</div>
</div>
<div class="seelsorge-modal-body">
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Bedienung</div>
<p style="font-size:0.9em;line-height:1.6;color:#374151;margin:0 0 12px 0;">
Im Kalendarium siehst du auf einen Blick die Verfügbarkeiten aller Personen.
Mit einem Klick auf einen Tag öffnet sich ein Fenster mit den Tagesdetails.
Dort siehst du, wer an diesem Tag verfügbar ist, und kannst dich selbst
eintragen oder wieder austragen. Mithilfe der Pfeile wechselst du zwischen
aktuellem und nächstem Monat.
</p>
</div>
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Farblegende</div>
<div class="calendar-help-legend">
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:#1243a0;"></span>
<span>Heute (keine Verfügbarkeit)</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:#ffdc0f;"></span>
<span>Eine Person verfügbar</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:#006e14;"></span>
<span>Zwei oder mehr Personen verfügbar (Match)</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(297, 80%, 40%);"></span>
<span>Sonntag / Feiertag</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(297, 25%, 45%);"></span>
<span>Samstag</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(297, 10%, 98%);border:1px solid #e9ecef;"></span>
<span>Normaler Tag</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(0, 0%, 90%);border:1px solid #e9ecef;"></span>
<span>Vergangener Tag</span>
</div>
</div>
</div>
<div class="seelsorge-modal-section" style="margin-bottom:0;">
<div class="seelsorge-section-title">Benachrichtigungen</div>
<p style="font-size:0.9em;line-height:1.6;color:#374151;margin:0;">
Sobald sich zwei oder mehr Personen am selben Tag eintragen, werden alle
Beteiligten automatisch per SMS und E-Mail benachrichtigt.
</p>
</div>
</div>
</div>
</div>
@@ -0,0 +1,139 @@
<?php /* Name: content/calendar_view.php
Beschreibung: Kalenderblatt mit Übersicht und Interaktion per Modal
Aufgerufen über calendar.php */
?>
<?php
// 2 Kalendermonate laden
for ($t = 1; $t <= 2; $t++) {
$p_startDate = date("Y-m-d", strtotime($t === 1 ? "first day of this month" : "first day of next month"));
$p_style = $t === 1 ? "display:flex" : "display:none";
$p_class_arrow_left = $t === 1 ? "arrow_light" : "arrow_dark";
$p_class_arrow_right = $t === 1 ? "arrow_dark" : "arrow_light";
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_startDate);
$p_calendarTitle = $p_calendarMonthName . " " . date("Y", strtotime($p_startDate));
?>
<div class="calendar_header" style="<?= $p_style ?>" id="calendar_header_<?= $t ?>">
<div class="arrow_item" onclick="switchCalendar('left')">
<div class="<?= $p_class_arrow_left ?>" id="left">
<?php display_button('arrow_left', null, 'left'); ?>
</div>
</div>
<div class="calendar_title"><?= $p_calendarTitle ?></div>
<div class="arrow_item" onclick="switchCalendar('right')">
<div class="<?= $p_class_arrow_right ?>" id="right">
<?php display_button('arrow_right', null, 'right'); ?>
</div>
</div>
<button class="calendar-help-btn" onclick="openCalendarHelp()" aria-label="Hilfe" title="Hilfe">?</button>
</div>
<?php } ?>
<div class="calendar_content">
<table>
<thead>
<tr>
<td class="calendar_head">MO</td>
<td class="calendar_head">DI</td>
<td class="calendar_head">MI</td>
<td class="calendar_head">DO</td>
<td class="calendar_head">FR</td>
<td class="calendar_head_sat">SA</td>
<td class="calendar_head_sun">SO</td>
</tr>
</thead>
<tbody>
<?php
// Zwei Monatsansichten laden
for ($c = 1; $c <= 2; $c++) {
$p_startDate = date("Y-m-d", strtotime($c === 1 ? "first day of this month" : "first day of next month"));
$p_endDate = date("Y-m-d", strtotime($c === 1 ? "last day of this month" : "last day of next month"));
$p_style = $c === 1 ? "visibility:visible" : "visibility:collapse";
$p_calendarStartDate = $connector_kalendertage->get_KalenderStart($p_startDate);
//Kalender: 6 Wochen in Zeilen
for ($i = 0; $i < 42; $i++) {
$datum = date('Y-m-d', strtotime("$p_calendarStartDate +$i days"));
$tag = date('j', strtotime("$p_calendarStartDate +$i days"));
$wochentag = date("w", strtotime("$p_calendarStartDate +$i days"));
$isFeiertagInBerlin = $connector_feiertage->isFeiertagInBerlin($datum);
$feiertagsname = $connector_feiertage->get_feiertagsname($datum);
if ($i % 7 === 0) echo "<tr name='calendar_$c' style='$p_style'>";
$class = 'calendar_day_area';
$style = '';
if ($datum < $p_startDate || $datum > $p_endDate) {
$style = 'filter:brightness(100%);opacity:0.5;';
}
echo "<td class='$class' style='$style'><div class='calendar_day'>";
$Id_cDayItem = $datum >= date("Y-m-d") ? 'id="calendar_day_item" onclick="openDayModal(\'' . $datum . '\')"' : '';
$sql_count = "SELECT COUNT(datum) AS count FROM verfuegbarkeiten WHERE datum=?";
$stmt_count = $pdo->prepare($sql_count);
$count = 0;
if ($stmt_count) {
$stmt_count->execute([$datum]);
$row_count = $stmt_count->fetch();
if ($row_count) {
$count = $row_count['count'];
} else {
echo "Fehler beim Abrufen des Ergebnisses";
}
} else {
echo "Fehler beim Vorbereiten der Anweisung";
}
$sql_user_check = "SELECT user_id FROM verfuegbarkeiten WHERE datum=? AND user_id=?";
$stmt_user_check = $pdo->prepare($sql_user_check);
$userAvailable = false;
if ($stmt_user_check) {
$stmt_user_check->execute([$datum, $_SESSION["user_id"]]);
if ($stmt_user_check->fetch()) {
$userAvailable = true;
}
}
$class = 'calendar_day_item';
$title = '';
if ($datum < date("Y-m-d")) {
$class .= ' past';
} elseif ($count >= 2 && $datum >= date("Y-m-d")) {
$class .= ' available_multiple';
$title = $userAvailable ? "It&acute;s a Match!" : "$count Personen verfügbar";
} elseif ($count == 1 && $datum >= date("Y-m-d")) {
$class .= ' available_single';
$title = 'Eine Person verfügbar';
} elseif ($datum == date("Y-m-d")) {
$class .= ' today';
$title = 'Heute';
} elseif ($isFeiertagInBerlin) {
$class .= ' sunday';
} elseif ($feiertagsname != null) {
$class .= ' localholiday';
$title = 'Regionaler Feiertag';
} elseif ($wochentag == 0) {
$class .= ' sunday';
} elseif ($wochentag == 6) {
$class .= ' saturday';
} else {
$class .= ' normalday';
}
echo "<div $Id_cDayItem class='$class' title='$title'>$tag</div>";
// Feiertagsbezeichnungen im Kalenderblatt ausgeblendet
echo "</div></td>";
if ($i % 7 === 6) echo "</tr>";
}
}
//Schleifenende: Zwei Monatsansichten laden
?>
</tbody>
</table> <!-- END: calendar -->
</div> <!-- END: calendar_content -->
@@ -0,0 +1,28 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
header('Content-Type: application/json; charset=utf-8');
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.']);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
$besuch_id = isset($_POST['besuch_id']) ? (int)$_POST['besuch_id'] : 0;
if ($besuch_id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'Ungültige Besuchs-ID.']);
exit;
}
try {
$stmt = $pdo->prepare("DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
echo json_encode(['status' => 'success']);
} catch (PDOException $e) {
echo json_encode(['status' => 'error', 'message' => 'Löschen fehlgeschlagen: ' . $e->getMessage()]);
}
@@ -0,0 +1,161 @@
<?php
/* Name: manage_visits.php
Beschreibung: Verwaltung der Seelsorge-Besuchsstellen
- Hinzufügen, Bearbeiten und Löschen von Einträgen
*/
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
// Eintrag hinzufügen
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['add_entry'])) {
$last_name = $_POST['last_name'];
$first_name = $_POST['first_name'];
$birth_date = $_POST['birth_date'];
$address_street = $_POST['address_street'];
$address_plz = $_POST['address_plz'];
$address_link = $_POST['address_link'];
$phone = $_POST['phone'];
$comment = $_POST['comment'];
$letzter_besuch = $_POST['letzter_besuch'];
$priority = $_POST['priority'];
$pr_bezirk = $_POST['pr_bezirk'];
$reservation = $_POST['reservation'];
$sql = "INSERT INTO seelsorge_besuchsstellen (last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk, reservation)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$last_name, $first_name, $birth_date, $address_street, $address_plz, $address_link, $phone, $comment, $letzter_besuch, $priority, $pr_bezirk, $reservation])) {
echo "Neuer Eintrag hinzugefügt.";
} else {
echo "Fehler: " . implode(', ', $stmt->errorInfo());
}
}
// Eintrag löschen
if (isset($_GET['delete_id'])) {
$delete_id = $_GET['delete_id'];
$sql = "DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$delete_id])) {
echo "Eintrag gelöscht.";
} else {
echo "Fehler beim Löschen des Eintrags: " . implode(', ', $stmt->errorInfo());
}
}
// Daten abrufen
$sql = "SELECT * FROM seelsorge_besuchsstellen";
$result = $pdo->query($sql);
?>
<!DOCTYPE html>
<html lang="de" dir="ltr">
<head>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
<script src="/intranet_repo/projects/_central/scripts/seelsorge.js"></script>
<link rel="stylesheet" href="/intranet_repo/projects/_central/layouts/seelsorge.css">
</head>
<body class="theme-purple">
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
<div class="header_title ht_pastoral text_white" id="header_title">
<span class="header_title_text">Besuchsstellen Verwaltung</span>
</div>
<h1>Seelsorge Besuchsstellen Verwaltung</h1>
<!-- Formular zum Hinzufügen eines neuen Eintrags -->
<h2>Neuen Eintrag hinzufügen</h2>
<form method="POST" action="">
<label>Nachname:</label>
<input type="text" name="last_name" required><br>
<label>Vorname:</label>
<input type="text" name="first_name" required><br>
<label>Geburtsdatum:</label>
<input type="date" name="birth_date" required><br>
<label>Straße:</label>
<input type="text" name="address_street" required><br>
<label>PLZ:</label>
<input type="text" name="address_plz" required><br>
<label>Link zur Adresse:</label>
<input type="text" name="address_link"><br>
<label>Telefonnummer:</label>
<input type="number" name="phone"><br>
<label>Kommentar:</label>
<input type="text" name="comment"><br>
<label>Letzter Besuch:</label>
<input type="date" name="letzter_besuch"><br>
<label>Priorität:</label>
<input type="number" name="priority" required><br>
<label>Bezirk:</label>
<input type="text" name="pr_bezirk"><br>
<label>Reservierung:</label>
<input type="number" name="reservation"><br>
<input type="submit" name="add_entry" value="Eintrag hinzufügen">
</form>
<!-- Tabelle der vorhandenen Einträge -->
<h2>Vorhandene Einträge</h2>
<table border="1">
<tr>
<th>ID</th>
<th>Nachname</th>
<th>Vorname</th>
<th>Geburtsdatum</th>
<th>Adresse</th>
<th>PLZ</th>
<th>Link zur Adresse</th>
<th>Telefonnummer</th>
<th>Kommentar</th>
<th>Letzter Besuch</th>
<th>Priorität</th>
<th>Bezirk</th>
<th>Reservierung</th>
<th>Aktionen</th>
</tr>
<?php while ($row = $result->fetch()) { ?>
<tr>
<td><?php echo $row['besuch_id']; ?></td>
<td><?php echo $row['last_name']; ?></td>
<td><?php echo $row['first_name']; ?></td>
<td><?php echo $row['birth_date']; ?></td>
<td><?php echo $row['address_street']; ?></td>
<td><?php echo $row['address_plz']; ?></td>
<td><?php echo $row['address_link']; ?></td>
<td><?php echo $row['phone']; ?></td>
<td><?php echo $row['comment']; ?></td>
<td><?php echo $row['letzter_besuch']; ?></td>
<td><?php echo $row['priority']; ?></td>
<td><?php echo $row['pr_bezirk']; ?></td>
<td><?php echo $row['reservation']; ?></td>
<td>
<a href="manage_visits.php?delete_id=<?php echo $row['besuch_id']; ?>" onclick="return confirm('Eintrag wirklich löschen?');">Löschen</a>
</td>
</tr>
<?php } ?>
</table>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
</body>
</html>
<?php
$pdo = null;
?>
@@ -0,0 +1,13 @@
<?php /* Name: menue.php
Beschreibung: Seitenmenü des Seelsorgeplaners */
?>
<div class="menue" id="seelsorge">
<div class="list">
<div class="menu-item unselectable active" data-target="content_calendar">Kalendarium</div>
<div class="menu-item unselectable" data-target="content_visit">Besuchsstellen</div>
<div class="indicator" id="indicator"></div>
</div>
</div>
@@ -0,0 +1,33 @@
<?php
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Get the besuch_id from the GET request
$besuch_id = $_GET['besuch_id'];
// SQL query to update priority to 2
$stmt = $pdo->prepare("UPDATE seelsorge_besuchsstellen SET priority = 2 WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
if ($stmt->rowCount() >= 0) {
// Berechne die Monate seit dem letzten Besuch, um sie in der Antwort zurückzugeben
$stmtQ = $pdo->prepare("SELECT CURRENT_DATE - letzter_besuch AS days_since_last_visit FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmtQ->execute([$besuch_id]);
$row = $stmtQ->fetch();
$monthsSinceLastVisit = floor($row['days_since_last_visit'] / 30);
// Gib die aktualisierten Daten als JSON zurück
echo json_encode([
'status' => 'success',
'priority' => 2,
'months_since_last_visit' => $monthsSinceLastVisit
]);
} else {
// Fehlerbehandlung
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Setzen der Priorität"
]);
}
$pdo = null;
?>
@@ -0,0 +1,38 @@
<?php
/*
Name: content/profile.php
Beschreibung: Popup innerhalb von Kalendertag bzw. Besuchsstellen: Profilanzeige
Zur Verwendung ist die nachfolgende Unterscheidung zu treffen/erweitern
*/
// Unterscheidung zwischen den aufrufenden Seitenbereichen
// --> Name ist außerdem beim Aufruf der JS-Funktion openCloseProfile(id, name, overlay) zu bilden!
// --> Bei einem neuen Seitenbereich ist zusätzlich der Listener (Escape-Taste) zu erweitern!
// --> In overlay_profile.php wird bei Escape-Taste bzw. Klick auf Exit mit id=0 sowie den entsprechenden name und overlay weggeblendet!
if (($isPageVisit ?? false) === true) {
$profile_container_name = "profile_visit";
$profile_overlay_id = "profile_visit_overlay";
$isPageVisit = false;
} elseif (($isPageCalendar ?? false) === true) {
$profile_container_name = "profile_calendar";
$profile_overlay_id = "profile_calendar_overlay";
$isPageCalendar = false;
}
// Statement für alle Profile vorbereiten
$stmt_all_profiles = $pdo->prepare("SELECT * FROM user_general_information");
$stmt_all_profiles->execute();
?>
<div class="standard_overlay" id="<?= $profile_overlay_id ?>"> <!-- Overlay: Profile -->
<div class="bg_blur"></div>
<?php
while ($profile_all = $stmt_all_profiles->fetch()) {
?>
<div class="profile_container" name="<?= $profile_container_name ?>" id="<?= $profile_all['user_id'] ?>">
<?php $_SESSION["profile_id"] = $profile_all['user_id'];
include $g_phpSnippetsPath. "overlay_profile.php"; ?>
</div>
<?php } ?>
</div>
@@ -0,0 +1,48 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Hole die Besuchs-ID aus dem GET-Request
if (isset($_GET['besuch_id']) && is_numeric($_GET['besuch_id'])) {
$besuch_id = (int)$_GET['besuch_id'];
// Adresse laden für Haushalt-Tracking
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if ($current) {
// Reservation für alle im Haushalt entfernen
$sql = "UPDATE seelsorge_besuchsstellen SET reservation = NULL WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$current['address_street'], $current['address_plz']])) {
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode(['status' => 'success', 'household_ids' => $householdIds]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Entfernen der Reservation"
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Eintrag nicht gefunden.'
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Ungültige oder fehlende Besuchs-ID.'
]);
}
$pdo = null;
?>
@@ -0,0 +1,56 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Hole die Besuchs-ID aus dem GET-Request
if (isset($_GET['besuch_id']) && is_numeric($_GET['besuch_id'])) {
$besuch_id = (int)$_GET['besuch_id'];
// Hole die ID des aktuell angemeldeten Benutzers aus der Session
$user_id = $_SESSION['user_id'];
// Adresse laden für Haushalt-Tracking
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if ($current) {
// Alle Personen im Haushalt reservieren
$sql = "UPDATE seelsorge_besuchsstellen SET reservation = ? WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$user_id, $current['address_street'], $current['address_plz']])) {
// Alle betroffenen IDs zurückgeben
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode([
'status' => 'success',
'reservation_user_id' => $user_id,
'household_ids' => $householdIds
]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Setzen der Reservation"
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Eintrag nicht gefunden.'
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Ungültige oder fehlende Besuchs-ID.'
]);
}
$pdo = null;
?>
@@ -0,0 +1,24 @@
<?php
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Überprüfen, ob die erforderlichen Parameter übergeben wurden
if (isset($_GET['besuch_id']) && isset($_GET['comment'])) {
$besuch_id = $_GET['besuch_id'];
$comment = $_GET['comment'];
// SQL-Update-Statement vorbereiten und ausführen
$stmt = $pdo->prepare("UPDATE seelsorge_besuchsstellen SET comment = ? WHERE besuch_id = ?");
if ($stmt->execute([$comment, $besuch_id])) {
// Erfolgreich aktualisiert
echo "Hinweis erfolgreich aktualisiert";
} else {
// Fehler beim Aktualisieren
echo "Fehler beim Aktualisieren des Hinweises";
}
} else {
// Fehler: Fehlende Parameter
echo "Fehler: Nicht alle erforderlichen Parameter wurden übergeben";
}
$pdo = null;
?>
@@ -0,0 +1,57 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Get the besuch_id from the GET request
$besuch_id = (int)($_GET['besuch_id'] ?? 0);
if ($besuch_id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'Ungültige Besuchs-ID.']);
exit;
}
// Adresse der aktuellen Besuchsstelle laden
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if (!$current) {
echo json_encode(['status' => 'error', 'message' => 'Eintrag nicht gefunden.']);
exit;
}
// Alle Personen im gleichen Haushalt (gleiche Adresse) aktualisieren
$sql = "UPDATE seelsorge_besuchsstellen SET letzter_besuch = CURRENT_DATE, priority = 0 WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$current['address_street'], $current['address_plz']])) {
// Monate seit letztem Besuch berechnen (für den angefragten Eintrag)
$query = "SELECT CURRENT_DATE - letzter_besuch AS days_since_last_visit FROM seelsorge_besuchsstellen WHERE besuch_id = ?";
$stmtQ = $pdo->prepare($query);
$stmtQ->execute([$besuch_id]);
$row = $stmtQ->fetch();
$monthsSinceLastVisit = floor(($row['days_since_last_visit'] ?? 0) / 30);
// Alle IDs im Haushalt zurückgeben für Frontend-Aktualisierung
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode([
'status' => 'success',
'last_visit' => date('Y-m-d'),
'months_since_last_visit' => $monthsSinceLastVisit,
'household_ids' => $householdIds
]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Aktualisieren des Besuchsdatums"
]);
}
$pdo = null;
?>
@@ -0,0 +1,132 @@
<?php
header('Content-Type: application/json; charset=utf-8');
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
try {
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.'], JSON_UNESCAPED_UNICODE);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
$besuch_id = isset($_POST['besuch_id']) ? (int)$_POST['besuch_id'] : 0;
$last_name = trim($_POST['last_name'] ?? '');
$first_name = trim($_POST['first_name'] ?? '');
$birth_date = trim($_POST['birth_date'] ?? '');
$address_street = trim($_POST['address_street'] ?? '');
$address_plz = trim($_POST['address_plz'] ?? '');
$address_link = trim($_POST['address_link'] ?? '');
$phone_raw = trim($_POST['phone'] ?? '');
$comment = trim($_POST['comment'] ?? '');
$letzter_besuch = trim($_POST['letzter_besuch'] ?? '');
$priority = isset($_POST['priority']) ? (int)$_POST['priority'] : 0;
$pr_bezirk_raw = trim($_POST['pr_bezirk'] ?? '');
// einfache Validierung
if ($besuch_id <= 0 || $last_name === '' || $first_name === '' || $birth_date === '' || $address_street === '' || $address_plz === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Pflichtfelder fehlen.'], JSON_UNESCAPED_UNICODE);
exit;
}
// Telefon: nur Ziffern
$phone = preg_replace('/\D+/', '', $phone_raw);
if ($phone === '') $phone = null; // phone darf NULL sein
// NOT NULL Spalten: niemals NULL senden
if ($address_link === '') $address_link = '';
if ($comment === '') $comment = '';
if ($letzter_besuch === '') $letzter_besuch = "2024-07-11";
if ($pr_bezirk_raw === '') $pr_bezirk_raw = '';
// Alten Eintrag laden, um Änderungen zu erkennen
$stmtOld = $pdo->prepare("SELECT last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmtOld->execute([$besuch_id]);
$oldEntry = $stmtOld->fetch();
$sql = "UPDATE seelsorge_besuchsstellen
SET last_name = ?, first_name = ?, birth_date = ?, address_street = ?, address_plz = ?,
address_link = ?, phone = ?, comment = ?, letzter_besuch = ?, priority = ?, pr_bezirk = ?
WHERE besuch_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$last_name,
$first_name,
$birth_date,
$address_street,
$address_plz,
$address_link,
$phone,
$comment,
$letzter_besuch,
$priority,
$pr_bezirk_raw,
$besuch_id
]);
// Vermerk in erledigte Tasks wenn sich irgendein Feld geändert hat
if ($oldEntry) {
$newValues = [
'last_name' => $last_name,
'first_name' => $first_name,
'birth_date' => $birth_date,
'address_street' => $address_street,
'address_plz' => $address_plz,
'address_link' => $address_link,
'phone' => $phone,
'comment' => $comment,
'letzter_besuch' => $letzter_besuch,
'priority' => $priority,
'pr_bezirk' => $pr_bezirk_raw,
];
$fieldLabels = [
'last_name' => 'Nachname',
'first_name' => 'Vorname',
'birth_date' => 'Geburtsdatum',
'address_street' => 'Adresse',
'address_plz' => 'PLZ/Ort',
'address_link' => 'Karten-Link',
'phone' => 'Telefon',
'comment' => 'Kommentar',
'letzter_besuch' => 'Letzter Besuch',
'priority' => 'Priorität',
'pr_bezirk' => 'Priester-Bezirk',
];
$changedFields = [];
foreach ($newValues as $key => $newVal) {
$oldVal = $oldEntry[$key] ?? '';
if ((string)$oldVal !== (string)$newVal) {
$changedFields[] = $fieldLabels[$key];
}
}
if (!empty($changedFields)) {
$personName = ($oldEntry['last_name'] ?? $last_name) . ", " . ($oldEntry['first_name'] ?? $first_name);
$changedList = implode(', ', $changedFields);
$taskSubject = "Besuchsstelle geändert: {$personName}";
$taskMessage = "Besuchsstelle #{$besuch_id} ({$personName}) wurde geändert. Geänderte Felder: {$changedList}.";
$senderName = "Seelsorgeplaner";
$stmtLog = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', ?, '', ?, ?, 'done', NOW(), NOW())");
$stmtLog->execute([$senderName, $taskSubject, $taskMessage]);
}
}
echo json_encode(['status' => 'success', 'besuch_id' => $besuch_id], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'DB-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Server-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
{"Neujahrstag":"2024-01-01","Heilige Drei K\u00f6nige":"2024-01-06","Frauentag":"2024-03-08","Gr\u00fcndonnerstag":"2024-03-28","Karfreitag":"2024-03-29","Ostersonntag":"2024-03-31","Ostermontag":"2024-04-01","Tag der Arbeit":"2024-05-01","Christi Himmelfahrt":"2024-05-09","Pfingstsonntag":"2024-05-19","Pfingstmontag":"2024-05-20","Fronleichnam":"2024-05-30","Augsburger Friedensfest":"2024-08-08","Mari\u00e4 Himmelfahrt":"2024-08-15","Weltkindertag":"2024-09-20","Tag der Deutschen Einheit":"2024-10-03","Reformationstag":"2024-10-31","Allerheiligen":"2024-11-01","Bu\u00df- und Bettag":"2024-11-20","1. Weihnachtstag":"2024-12-25","2. Weihnachtstag":"2024-12-26"}
@@ -0,0 +1 @@
{"Neujahrstag":{"datum":"2024-01-01","hinweis":""},"Frauentag":{"datum":"2024-03-08","hinweis":""},"Karfreitag":{"datum":"2024-03-29","hinweis":""},"Ostermontag":{"datum":"2024-04-01","hinweis":""},"Tag der Arbeit":{"datum":"2024-05-01","hinweis":""},"Christi Himmelfahrt":{"datum":"2024-05-09","hinweis":""},"Pfingstmontag":{"datum":"2024-05-20","hinweis":""},"Tag der Deutschen Einheit":{"datum":"2024-10-03","hinweis":""},"1. Weihnachtstag":{"datum":"2024-12-25","hinweis":""},"2. Weihnachtstag":{"datum":"2024-12-26","hinweis":""},"Heiligabend":{"datum":"2024-12-24","hinweis":""},"Silvester":{"datum":"2024-12-31","hinweis":""}}
@@ -0,0 +1 @@
{"Neujahrstag":"2025-01-01","Heilige Drei K\u00f6nige":"2025-01-06","Frauentag":"2025-03-08","Karfreitag":"2025-04-18","Ostersonntag":"2025-04-20","Ostermontag":"2025-04-21","Tag der Arbeit":"2025-05-01","Christi Himmelfahrt":"2025-05-29","Pfingstsonntag":"2025-06-08","Pfingstmontag":"2025-06-09","Fronleichnam":"2025-06-19","Augsburger Friedensfest":"2025-08-08","Mari\u00e4 Himmelfahrt":"2025-08-15","Weltkindertag":"2025-09-20","Tag der Deutschen Einheit":"2025-10-03","Reformationstag":"2025-10-31","Allerheiligen":"2025-11-01","Bu\u00df- und Bettag":"2025-11-19","1. Weihnachtstag":"2025-12-25","2. Weihnachtstag":"2025-12-26"}
@@ -0,0 +1 @@
{"Neujahrstag":{"datum":"2025-01-01","hinweis":""},"Frauentag":{"datum":"2025-03-08","hinweis":""},"Karfreitag":{"datum":"2025-04-18","hinweis":""},"Ostermontag":{"datum":"2025-04-21","hinweis":""},"Tag der Arbeit":{"datum":"2025-05-01","hinweis":""},"Christi Himmelfahrt":{"datum":"2025-05-29","hinweis":""},"Pfingstmontag":{"datum":"2025-06-09","hinweis":""},"Tag der Deutschen Einheit":{"datum":"2025-10-03","hinweis":""},"1. Weihnachtstag":{"datum":"2025-12-25","hinweis":""},"2. Weihnachtstag":{"datum":"2025-12-26","hinweis":""},"Heiligabend":{"datum":"2025-12-24","hinweis":""},"Silvester":{"datum":"2025-12-31","hinweis":""}}
@@ -0,0 +1 @@
{"Neujahrstag":"2026-01-01","Heilige Drei K\u00f6nige":"2026-01-06","Frauentag":"2026-03-08","Karfreitag":"2026-04-03","Ostersonntag":"2026-04-05","Ostermontag":"2026-04-06","Tag der Arbeit":"2026-05-01","Christi Himmelfahrt":"2026-05-14","Pfingstsonntag":"2026-05-24","Pfingstmontag":"2026-05-25","Fronleichnam":"2026-06-04","Augsburger Friedensfest":"2026-08-08","Mari\u00e4 Himmelfahrt":"2026-08-15","Weltkindertag":"2026-09-20","Tag der Deutschen Einheit":"2026-10-03","Reformationstag":"2026-10-31","Allerheiligen":"2026-11-01","Bu\u00df- und Bettag":"2026-11-18","1. Weihnachtstag":"2026-12-25","2. Weihnachtstag":"2026-12-26"}
@@ -0,0 +1 @@
{"Neujahrstag":{"datum":"2026-01-01","hinweis":""},"Frauentag":{"datum":"2026-03-08","hinweis":""},"Karfreitag":{"datum":"2026-04-03","hinweis":""},"Ostermontag":{"datum":"2026-04-06","hinweis":""},"Tag der Arbeit":{"datum":"2026-05-01","hinweis":""},"Christi Himmelfahrt":{"datum":"2026-05-14","hinweis":""},"Pfingstmontag":{"datum":"2026-05-25","hinweis":""},"Tag der Deutschen Einheit":{"datum":"2026-10-03","hinweis":""},"1. Weihnachtstag":{"datum":"2026-12-25","hinweis":""},"2. Weihnachtstag":{"datum":"2026-12-26","hinweis":""},"Heiligabend":{"datum":"2026-12-24","hinweis":""},"Silvester":{"datum":"2026-12-31","hinweis":""}}
@@ -0,0 +1 @@
[{"start":"2024-02-05","end":"2024-02-10","year":2024,"stateCode":"BE","name":"winterferien berlin 2024","slug":"winterferien berlin 2024-2024-BE"},{"start":"2024-03-25","end":"2024-04-05","year":2024,"stateCode":"BE","name":"osterferien berlin 2024","slug":"osterferien berlin 2024-2024-BE"},{"start":"2024-05-10","end":"2024-05-10","year":2024,"stateCode":"BE","name":"pfingstferien berlin 2024 (beweglicher ferientag)","slug":"pfingstferien berlin 2024 (beweglicher ferientag)-2024-BE"},{"start":"2024-07-18","end":"2024-08-30","year":2024,"stateCode":"BE","name":"sommerferien berlin 2024","slug":"sommerferien berlin 2024-2024-BE"},{"start":"2024-10-04","end":"2024-10-04","year":2024,"stateCode":"BE","name":"herbstferien berlin 2024 (beweglicher ferientag)","slug":"herbstferien berlin 2024 (beweglicher ferientag)-2024-BE"},{"start":"2024-10-21","end":"2024-11-02","year":2024,"stateCode":"BE","name":"herbstferien berlin 2024","slug":"herbstferien berlin 2024-2024-BE"},{"start":"2024-12-23","end":"2024-12-31","year":2024,"stateCode":"BE","name":"weihnachtsferien berlin 2024","slug":"weihnachtsferien berlin 2024-2024-BE"}]
@@ -0,0 +1,67 @@
<?php /* Name: seelsorge.php
Beschreibung: Seelsorge Hauptseite
- Übersicht und Kalenderblätter */
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
?>
<!DOCTYPE html>
<html lang="de" dir="ltr">
<head>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
<script src="/intranet_repo/projects/_central/scripts/seelsorge.js"></script>
<link rel="stylesheet" href="/intranet_repo/projects/_central/layouts/seelsorge.css">
</head>
<body class="theme-purple">
<?php // Es folgen ab hier die HTML-Ausgaben beginnend mit dem HTML-Header: ?>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
<?php // Header (erweitert): Titel der Seite mit Untermenü ?>
<div class="header_title ht_pastoral text_white unselectable" id="header_title">
<span class="header_title_text">Seelsorgeplaner</span>
</div>
<div class="content" id="fullsize">
<div class="content-tab-bar" id="seelsorge-tabs">
<div class="content-tab-bar__item active" data-target="content_calendar">Kalendarium</div>
<div class="content-tab-bar__item" data-target="content_visit">Besuchsstellen</div>
</div>
<div class="content_seelsorge active" id="content_calendar">
<?php // Kalendarium:
include 'content/calendar.php'; ?>
</div>
<div class="content_seelsorge" id="content_visit">
<?php // Besuchsstellen:
include 'content/visit.php'; ?>
</div>
</div>
<!-- Modal für Kalendertag -->
<div class="standard_overlay" id="seelsorge-day-modal" onclick="closeDayModalOnBackdrop(event)">
<div class="seelsorge-modal-card">
<button type="button" class="exit" aria-label="Schließen" onclick="closeDayModal()">×</button>
<div class="seelsorge-modal-hero">
<div class="seelsorge-modal-hero-icon">
<svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="#FFFFFF" stroke-width="1.5"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
</div>
<div>
<div class="seelsorge-modal-title" id="modal-day-title">—</div>
<div class="seelsorge-modal-subtitle" id="modal-day-subtitle"></div>
</div>
</div>
<div class="seelsorge-modal-body" id="modal-day-body">
<div class="seelsorge-modal-loading"><div class="loading-spinner"></div></div>
</div>
</div>
</div>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
</body>
</html>
@@ -0,0 +1,118 @@
<?php
/* Name: toggle_availability.php
Beschreibung: Verfuegbarkeit eintragen/entfernen (AJAX-Endpoint)
Liefert JSON-Response, sendet SMS+Mail bei Match */
header('Content-Type: application/json; charset=utf-8');
session_start();
if (!isset($_SESSION["user_id"]) || !isset($_POST["date"])) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Fehlende Parameter']);
exit;
}
$date = $_POST["date"];
$formattedDate = date("d.m.Y", strtotime($date));
$userId = (int) $_SESSION["user_id"];
$pdo = require($_SERVER['DOCUMENT_ROOT'] . "/intranet_repo/general_files/ini/database.php");
// Pruefen ob Verfuegbarkeit bereits besteht
$stmt = $pdo->prepare("SELECT COUNT(*) AS count FROM verfuegbarkeiten WHERE datum = ? AND user_id = ?");
$stmt->execute([$date, $userId]);
$wasAvailable = $stmt->fetch()['count'] > 0;
// Eintragen oder Austragen
if ($wasAvailable) {
$stmt = $pdo->prepare("DELETE FROM verfuegbarkeiten WHERE datum = ? AND user_id = ?");
} else {
$stmt = $pdo->prepare("INSERT INTO verfuegbarkeiten (datum, user_id) VALUES (?, ?)");
}
if (!$stmt->execute([$date, $userId])) {
http_response_code(500);
echo json_encode(['ok' => false, 'error' => 'Datenbankfehler']);
$pdo = null;
exit;
}
$nowAvailable = !$wasAvailable;
$notifications = [];
// Bei neuem Eintrag: Match pruefen und benachrichtigen
if ($nowAvailable) {
// E-Mail-Spalte dynamisch ermitteln
$emailCol = null;
$emailCandidates = ['email', 'mail', 'email_address', 'e_mail', 'user_email'];
$inList = "'" . implode("','", $emailCandidates) . "'";
$res = $pdo->query("SELECT column_name FROM information_schema.columns WHERE table_name = 'user_general_information' AND column_name IN ($inList) LIMIT 1");
if ($res && $r = $res->fetch()) { $emailCol = $r['column_name']; }
$emailSelect = $emailCol ? ", u.\"{$emailCol}\" AS email" : ", '' AS email";
$sql = "SELECT u.user_id, u.first_name, u.last_name, u.phone{$emailSelect}
FROM verfuegbarkeiten v
JOIN user_general_information u ON v.user_id = u.user_id
WHERE v.datum = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$date]);
$matchUsers = $stmt->fetchAll();
if (count($matchUsers) > 1) {
$nameList = implode(', ', array_map(fn($u) => trim($u['first_name'] . ' ' . $u['last_name']), $matchUsers));
$smsText = mb_convert_encoding(
"Intranet NAK Reinickendorf\n\nIt's a match!\n\n{$nameList} haben am {$formattedDate} fuer einen Seelsorgebesuch Zeit!",
'UTF-8', 'auto'
);
// SMS an alle Beteiligten
foreach ($matchUsers as $u) {
if (!empty($u['phone'])) {
$smsData = json_encode([
'phone' => '+49' . $u['phone'],
'message' => $smsText
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$ctx = stream_context_create(['http' => [
'header' => "Content-Type: application/json; charset=utf-8",
'method' => 'POST',
'content' => $smsData,
'timeout' => 5
]]);
@file_get_contents(rtrim(intranet_env('SMS_GATEWAY_URL'), '/') . '/send_sms', false, $ctx);
$notifications[] = "SMS → " . $u['first_name'];
}
}
// E-Mail an alle Beteiligten
require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/send_mail.php';
$mailBetreff = "Seelsorge-Match am {$formattedDate}";
$mailNachricht = "It's a match!\n\n{$nameList} haben am {$formattedDate} für einen Seelsorgebesuch Zeit.\n\nBitte stimmt euch untereinander ab.";
$host = $_SERVER['HTTP_HOST'] ?? intranet_env('INTRANET_FQDN');
$btnUrl = "https://{$host}/intranet_repo/projects/seelsorge/seelsorge.php";
foreach ($matchUsers as $u) {
$email = trim($u['email'] ?? '');
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
@send_intranet_mail($email, $mailBetreff, $mailNachricht, null, 'intranet@nak-reinickendorf.de', 'Zum Seelsorgeplaner', $btnUrl);
$notifications[] = "Mail → " . $u['first_name'];
}
}
}
}
// Aktuellen Count der verfuegbaren Diakon*innen fuer diesen Tag zurueckgeben
$stmt = $pdo->prepare("SELECT COUNT(*) AS cnt FROM verfuegbarkeiten WHERE datum = ?");
$stmt->execute([$date]);
$availCount = $stmt->fetch()['cnt'];
$pdo = null;
echo json_encode([
'ok' => true,
'nowAvailable' => $nowAvailable,
'availCount' => (int) $availCount,
'notifications' => $notifications
], JSON_UNESCAPED_UNICODE);
?>
@@ -0,0 +1,143 @@
<?php
/*
Name: connector_feiertage.php
Beschreibung: Ermittlung von Feiertagen
*/
class lib_Feiertage_Connector
{
const BASE_URL = 'https://feiertage-api.de/api/';
const HOLIDAY_URL = 'https://ferien-api.de/api/v1/holidays/';
private static $cache = array();
private static $itsInstance = null;
private function __construct(){}
public static function getInstance()
{
if(self::$itsInstance == null)
self::$itsInstance = new lib_Feiertage_Connector();
return self::$itsInstance;
}
public function get_feiertagsname($datum)
{
$feiertagsname = null;
$jahr = date('Y',strtotime($datum));
$array = $this->get_FeiertageDesJahres($jahr);
$filter = array_filter($array, function ($wert) use ($datum) {
return $wert === $datum;
});
if ($filter !== null) {
$feiertagsname = implode(" ",array_keys($filter));
}
return $feiertagsname;
}
public function get_FeiertageDesJahres($jahr) //Lade Feiertage aus Datei (Alle Bundesländer)
{
if(isset(self::$cache['c0-'.$jahr]))
return self::$cache['c0-'.$jahr];
$file = "data/feiertage_$jahr.json";
if (!file_exists($file)) { //Ggf. Datei von externer API speichern
$extResult = $this->_file_get_contents_t_curl(lib_Feiertage_Connector::BASE_URL.'?jahr='.$jahr.'&nur_daten=1');
file_put_contents($file, $extResult);
}
self::$cache['c0-'.$jahr] = json_decode(file_get_contents($file), true);
return self::$cache['c0-'.$jahr];
}
public function getFeiertageVonLand($jahr,$land)
{
if(isset(self::$cache['c0-'.$jahr.$land]))
return self::$cache['c0-'.$jahr.$land];
$file = "data/feiertage_" . $jahr . "_" . $land . ".json";
if (!file_exists($file)) { //Ggf. Datei von externer API speichern
$extResult = $this->_file_get_contents_t_curl(lib_Feiertage_Connector::BASE_URL.'?jahr='.$jahr.'&nur_land='.$land);
$array = json_decode($extResult, true);
//Feste Feiertage hinzufügen
$array = array_merge($array, ["Heiligabend" => ["datum" => "$jahr-12-24","hinweis" => ""]]);
$array = array_merge($array, ["Silvester" => ["datum" => "$jahr-12-31","hinweis" => ""]]);
$array_json = json_encode($array);
file_put_contents($file, $array_json);
//file_put_contents($file, $extResult);
}
self::$cache['c0-'.$jahr.$land] = json_decode(file_get_contents($file), true);
return self::$cache['c0-'.$jahr.$land];
}
public function isFeiertagInBerlin($datum)
{
$feiertage_land = $this->getFeiertageVonLand(date('Y',strtotime($datum)),'BE');
foreach($feiertage_land as $feiertagsname => $feiertagsdatum)
if($feiertagsdatum['datum'] == date('Y-m-d',strtotime($datum)))
return true;
return false;
}
public function get_BerlinerFerientageDesJahres($jahr) //Lade Ferientage aus Datei
{
if(isset(self::$cache['c1-'.$jahr]))
return self::$cache['c1-'.$jahr];
$file = "data/ferientage_berlin_$jahr.json";
if (!file_exists($file)) { //Ggf. Datei von externer API speichern
$result = $this->_file_get_contents_t_curl(lib_Feiertage_Connector::HOLIDAY_URL.'BE/'.$jahr);
file_put_contents($file, $result);
}
self::$cache['c1-'.$jahr] = json_decode(file_get_contents($file), true);
return self::$cache['c1-'.$jahr];
}
private function _file_get_contents_t_curl($url) {
$ctx = stream_context_create(['http' => ['timeout' => 5]]);
$file = @file_get_contents($url, false, $ctx);
if(!empty($file))
return $file;
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$data = curl_exec($ch);
curl_close($ch);
if(empty($data))
throw new Exception('Verbindung zu feiertage-api.de war nicht moeglich.');
else
return $data;
}
throw new Exception('Verbindung zu feiertage-api.de war nicht moeglich.');
}
}
?>
@@ -0,0 +1,57 @@
<?php
/*
Name: connector_kalendertage.php
Beschreibung: Ermittlung von Kalendertagen
*/
class lib_Kalendertage_Connector
{
private static $cache = array();
private static $itsInstance = null;
private function __construct(){}
public static function getInstance()
{
if(self::$itsInstance == null)
self::$itsInstance = new lib_Kalendertage_Connector();
return self::$itsInstance;
}
public function get_KalenderMonatsname($datum) // Deutsche Monatsnamen
{
$monate = array(1 => "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember");
$timestamp = strtotime($datum);
$monatIndex = date("n", $timestamp);
return $monate[$monatIndex];
}
public function get_KalenderWochentag($datum) // Deutsche Wochentage
{
$wochentage = array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag");
$timestamp = strtotime($datum);
$wochentagIndex = date("w", $timestamp);
return $wochentage[$wochentagIndex];
}
public function get_KalenderStart($datum) //-> Montag der Woche, der den ersten Kalendertag enthält
{
$t_datum = strtotime($datum);
$t_firstMonday_Of_thisMonth = strtotime("first monday of this month", $t_datum);
$t_lastMonday_Of_lastMonth = strtotime("last monday of last month", $t_datum);
if ((int)date("d", $t_firstMonday_Of_thisMonth) === 1) {
return date("Y-m-d", $t_firstMonday_Of_thisMonth);
} else {
return date('Y-m-d', $t_lastMonday_Of_lastMonth);
}
}
}
?>