Reorganize into monorepo layout, move mitarbeiter-app to legacy reference
Consolidates the previously separate omsorgapp and omsorgCore repos (each had their own nested .git with GitHub history) plus the old root-level website/mitarbeiter-app into a single monorepo, matching the structure already documented in the root CLAUDE.md. Also moves the PHP employee app aside as omsorgWeb/mitarbeiter-app-legacy/ to serve as a template for a ground-up rewrite. Fixes .gitignore in the same pass: the config-secrets/uploads/data patterns were unanchored (relative to repo root, not depth-agnostic), so they silently stopped matching once the app moved under omsorgWeb/. Patterns are now **/-prefixed and cover both mitarbeiter-app and mitarbeiter-app-legacy, keeping DB/SMTP credentials and uploaded employee documents out of version control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8beb0fcf52
commit
b6c1389c55
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_admin();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/admin.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ── Login attempts ────────────────────────────────────────────────── */
|
||||
if (($_POST['_login_action'] ?? '') === 'clear') {
|
||||
db()->exec('DELETE FROM login_attempts');
|
||||
header('Location: ../pages/admin.php?tab=login&cleared=1');
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ── User actions ──────────────────────────────────────────────────── */
|
||||
if (!empty($_POST['_user_action'])) {
|
||||
$action = $_POST['_user_action'];
|
||||
$user_id = (int)($_POST['user_id'] ?? 0);
|
||||
$back = '../pages/admin.php?tab=nutzer';
|
||||
|
||||
switch ($action) {
|
||||
|
||||
case 'add_user': {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$uname = trim($_POST['name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$telefon = trim($_POST['telefon'] ?? '');
|
||||
$role = in_array($_POST['role'] ?? '', ['user', 'admin'], true) ? $_POST['role'] : 'user';
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if ($username === '' || $uname === '' || strlen($password) < 6) {
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Benutzername, Name und Passwort (mind. 6 Zeichen) sind Pflichtfelder.'));
|
||||
exit;
|
||||
}
|
||||
try {
|
||||
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
|
||||
$stmt = db()->prepare(
|
||||
'INSERT INTO users (username, name, role, password_hash, active, created_at, email, telefon)
|
||||
VALUES (?, ?, ?, ?, 1, ?, ?, ?)'
|
||||
);
|
||||
$stmt->execute([$username, $uname, $role, $hash, date('c'), $email, $telefon]);
|
||||
} catch (\PDOException $ex) {
|
||||
$msg = str_contains($ex->getMessage(), 'UNIQUE') ? 'Benutzername bereits vergeben.' : 'Datenbankfehler.';
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode($msg));
|
||||
exit;
|
||||
}
|
||||
header('Location: ' . $back . '&user_ok=1&user_msg=' . urlencode('Nutzer erstellt.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
case 'edit_user': {
|
||||
$uname = trim($_POST['name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$telefon = trim($_POST['telefon'] ?? '');
|
||||
$role = in_array($_POST['role'] ?? '', ['user', 'admin'], true) ? $_POST['role'] : 'user';
|
||||
$active = (int)(bool)($_POST['active'] ?? 0);
|
||||
|
||||
if ($user_id < 1 || $uname === '') {
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Ungültige Eingabe.'));
|
||||
exit;
|
||||
}
|
||||
$stmt = db()->prepare(
|
||||
'UPDATE users SET name=?, email=?, telefon=?, role=?, active=? WHERE id=?'
|
||||
);
|
||||
$stmt->execute([$uname, $email, $telefon, $role, $active, $user_id]);
|
||||
header('Location: ' . $back . '&user_ok=1&user_msg=' . urlencode('Nutzer gespeichert.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
case 'change_password': {
|
||||
$password = $_POST['new_password'] ?? '';
|
||||
if ($user_id < 1 || strlen($password) < 6) {
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Passwort muss mindestens 6 Zeichen lang sein.'));
|
||||
exit;
|
||||
}
|
||||
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
|
||||
$stmt = db()->prepare('UPDATE users SET password_hash=? WHERE id=?');
|
||||
$stmt->execute([$hash, $user_id]);
|
||||
header('Location: ' . $back . '&user_ok=1&user_msg=' . urlencode('Passwort geändert.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
case 'delete_user': {
|
||||
if ($user_id < 1) {
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Ungültige Nutzer-ID.'));
|
||||
exit;
|
||||
}
|
||||
$stmt = db()->prepare('SELECT username FROM users WHERE id=?');
|
||||
$stmt->execute([$user_id]);
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) {
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Nutzer nicht gefunden.'));
|
||||
exit;
|
||||
}
|
||||
if ($row['username'] === current_username()) {
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Den eigenen Account kann man nicht löschen.'));
|
||||
exit;
|
||||
}
|
||||
$stmt = db()->prepare('DELETE FROM users WHERE id=?');
|
||||
$stmt->execute([$user_id]);
|
||||
header('Location: ' . $back . '&user_ok=1&user_msg=' . urlencode('Nutzer gelöscht.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
default:
|
||||
header('Location: ' . $back . '&user_msg=' . urlencode('Unbekannte Aktion.'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Request actions ───────────────────────────────────────────────── */
|
||||
$request_id = (int)($_POST['request_id'] ?? 0);
|
||||
$action = $_POST['action'] ?? '';
|
||||
$admin_note = trim($_POST['admin_note'] ?? '');
|
||||
$type = $_POST['type'] ?? '';
|
||||
|
||||
$allowed_types = ['urlaubsantrag', 'abwesenheitsantrag', 'benefitsantrag', 'werben', 'fortbildungsantrag', 'stundennachweis'];
|
||||
|
||||
if (!in_array($type, $allowed_types, true)) {
|
||||
header('Location: ../pages/admin.php?error=' . urlencode('Ungültiger Antragstyp.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ── Delete request ────────────────────────────────────────────────── */
|
||||
if ($action === 'delete') {
|
||||
if ($request_id < 1) {
|
||||
header('Location: ../pages/admin.php?error=' . urlencode('Ungültige Antrags-ID.'));
|
||||
exit;
|
||||
}
|
||||
$table = 'requests_' . $type;
|
||||
$stmt = db()->prepare("SELECT * FROM $table WHERE id = ?");
|
||||
$stmt->execute([$request_id]);
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) {
|
||||
header('Location: ../pages/admin.php?error=' . urlencode('Antrag nicht gefunden.'));
|
||||
exit;
|
||||
}
|
||||
// Delete associated file for types that have uploads
|
||||
if (in_array($type, ['stundennachweis', 'fortbildungsantrag'], true) && !empty($row['filename'])) {
|
||||
$file_path = __DIR__ . '/../uploads/' . $row['filename'];
|
||||
if (is_file($file_path)) {
|
||||
unlink($file_path);
|
||||
}
|
||||
}
|
||||
$stmt = db()->prepare("DELETE FROM $table WHERE id = ?");
|
||||
$stmt->execute([$request_id]);
|
||||
header('Location: ../pages/admin.php?deleted=1');
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ── Status update ─────────────────────────────────────────────────── */
|
||||
if (!in_array($action, ['accepted', 'rejected'], true) || $request_id < 1) {
|
||||
header('Location: ../pages/admin.php?error=' . urlencode('Ungültige Aktion.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$table = 'requests_' . $type;
|
||||
$stmt = db()->prepare("SELECT id FROM $table WHERE id = ?");
|
||||
$stmt->execute([$request_id]);
|
||||
if (!$stmt->fetch()) {
|
||||
header('Location: ../pages/admin.php?error=' . urlencode('Antrag nicht gefunden.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("UPDATE $table SET status = ?, admin_note = ?, updated_at = ? WHERE id = ?");
|
||||
$stmt->execute([$action, $admin_note, date('c'), $request_id]);
|
||||
|
||||
header('Location: ../pages/admin.php?type=' . urlencode($type) . '&id=' . $request_id . '&updated=1');
|
||||
exit;
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/dokumentenarchiv.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int) ($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
http_response_code(400);
|
||||
echo 'Ungültige Anfrage.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare('SELECT * FROM dokumente WHERE id = ?');
|
||||
$stmt->execute([$id]);
|
||||
$doc = $stmt->fetch();
|
||||
|
||||
if (!$doc) {
|
||||
http_response_code(404);
|
||||
echo 'Dokument nicht gefunden.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$user = current_user();
|
||||
if ((int) $doc['user_id'] !== (int) $user['id'] && !is_admin()) {
|
||||
http_response_code(403);
|
||||
echo 'Keine Berechtigung.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$file_path = dirname(__DIR__) . '/uploads/' . $doc['filename'];
|
||||
if (is_file($file_path)) {
|
||||
unlink($file_path);
|
||||
}
|
||||
|
||||
db()->prepare('DELETE FROM dokumente WHERE id = ?')->execute([$id]);
|
||||
|
||||
header('Location: ../pages/dokumentenarchiv.php?deleted=1');
|
||||
exit;
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_admin();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/admin.php?tab=downloads');
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = $_POST['_action'] ?? '';
|
||||
|
||||
/* ── Add ──────────────────────────────────────────────────────────────── */
|
||||
if ($action === 'add') {
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$description = trim($_POST['description'] ?? '');
|
||||
|
||||
if ($title === '') {
|
||||
header('Location: ../pages/admin.php?tab=downloads&err=notitle');
|
||||
exit;
|
||||
}
|
||||
|
||||
$up = handle_upload($_FILES['file'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_OFFICE,
|
||||
'dir' => dirname(__DIR__) . '/downloads/',
|
||||
'naming' => 'hash',
|
||||
'max_bytes' => 20 * 1024 * 1024,
|
||||
'messages' => [
|
||||
'missing' => 'nofile', 'upload' => 'nofile',
|
||||
'ext' => 'badext', 'mime' => 'badmime',
|
||||
'size' => 'toobig', 'move' => 'upload',
|
||||
],
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
header('Location: ../pages/admin.php?tab=downloads&err=' . $up['error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$safe_name = $up['filename'];
|
||||
$original_name = $up['original_name'];
|
||||
|
||||
$sort_order = (int)db()->query('SELECT COALESCE(MAX(sort_order), 0) + 10 FROM downloads')->fetchColumn();
|
||||
$now = date('c');
|
||||
|
||||
$stmt = db()->prepare(
|
||||
'INSERT INTO downloads (title, description, filename, original_name, sort_order, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)'
|
||||
);
|
||||
$stmt->execute([$title, $description, $safe_name, $original_name, $sort_order, $now, $now]);
|
||||
|
||||
header('Location: ../pages/admin.php?tab=downloads&ok=added');
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ── Delete ───────────────────────────────────────────────────────────── */
|
||||
if ($action === 'delete') {
|
||||
$id = (int)($_POST['download_id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
header('Location: ../pages/admin.php?tab=downloads&err=invalid');
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare('SELECT filename FROM downloads WHERE id = ?');
|
||||
$stmt->execute([$id]);
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if ($row) {
|
||||
db()->prepare('DELETE FROM downloads WHERE id = ?')->execute([$id]);
|
||||
@unlink(dirname(__DIR__) . '/downloads/' . $row['filename']);
|
||||
}
|
||||
|
||||
header('Location: ../pages/admin.php?tab=downloads&ok=deleted');
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: ../pages/admin.php?tab=downloads');
|
||||
exit;
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_admin();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') !== 'XMLHttpRequest') {
|
||||
echo json_encode(['ok' => false, 'error' => 'forbidden']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['ok' => false, 'error' => 'method']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$body = file_get_contents('php://input');
|
||||
$data = json_decode($body, true);
|
||||
$order = $data['order'] ?? null;
|
||||
|
||||
if (!is_array($order)) {
|
||||
echo json_encode(['ok' => false, 'error' => 'invalid']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ids = array_values(array_filter(array_map('intval', $order), fn($v) => $v > 0));
|
||||
|
||||
if (empty($ids)) {
|
||||
echo json_encode(['ok' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$now = date('c');
|
||||
$pos = 10;
|
||||
$stmt = db()->prepare('UPDATE downloads SET sort_order = ?, updated_at = ? WHERE id = ?');
|
||||
|
||||
db()->beginTransaction();
|
||||
foreach ($ids as $id) {
|
||||
$stmt->execute([$pos, $now, $id]);
|
||||
$pos += 10;
|
||||
}
|
||||
db()->commit();
|
||||
|
||||
echo json_encode(['ok' => true]);
|
||||
exit;
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_admin();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/admin.php?tab=einsatzanweisung');
|
||||
exit;
|
||||
}
|
||||
|
||||
verify_csrf();
|
||||
|
||||
$back = '../pages/admin.php?tab=einsatzanweisung';
|
||||
$action = $_POST['_action'] ?? '';
|
||||
$user_id = (int)($_POST['target_user_id'] ?? 0);
|
||||
|
||||
if ($user_id <= 0) {
|
||||
header('Location: ' . $back . '&err=' . urlencode('Ungültiger Nutzer.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare('SELECT id FROM users WHERE id = ?');
|
||||
$stmt->execute([$user_id]);
|
||||
if (!$stmt->fetch()) {
|
||||
header('Location: ' . $back . '&err=' . urlencode('Nutzer nicht gefunden.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'update_ort') {
|
||||
$ort = trim($_POST['ort'] ?? '');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO einsatzanweisung (user_id, ort)
|
||||
VALUES (?, ?)
|
||||
ON CONFLICT(user_id) DO UPDATE SET ort = excluded.ort'
|
||||
)->execute([$user_id, $ort]);
|
||||
|
||||
header('Location: ' . $back . '&ok=' . urlencode('Einsatzort gespeichert.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'upload_pdf') {
|
||||
$stmt = db()->prepare('SELECT u.username, e.filename AS old_filename FROM users u LEFT JOIN einsatzanweisung e ON e.user_id = u.id WHERE u.id = ?');
|
||||
$stmt->execute([$user_id]);
|
||||
$row = $stmt->fetch();
|
||||
|
||||
$dir = dirname(__DIR__) . '/uploads/';
|
||||
$up = handle_upload($_FILES['pdf'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_PDF,
|
||||
'dir' => $dir,
|
||||
'prefix' => 'einsatzanweisung',
|
||||
'username' => $row['username'],
|
||||
'messages' => [
|
||||
'missing' => 'Bitte eine PDF-Datei auswählen.',
|
||||
'upload' => 'Fehler beim Hochladen.',
|
||||
'ext' => 'Nur PDF-Dateien erlaubt.',
|
||||
'mime' => 'Nur PDF-Dateien erlaubt.',
|
||||
'size' => 'Datei ist zu groß (max. 12 MB).',
|
||||
'move' => 'Fehler beim Speichern der Datei.',
|
||||
],
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
header('Location: ' . $back . '&err=' . urlencode($up['error']));
|
||||
exit;
|
||||
}
|
||||
|
||||
$original_name = $up['original_name'];
|
||||
$safe_name = $up['filename'];
|
||||
|
||||
if (!empty($row['old_filename'])) {
|
||||
$old_path = $dir . basename($row['old_filename']);
|
||||
if (is_file($old_path)) {
|
||||
unlink($old_path);
|
||||
}
|
||||
}
|
||||
|
||||
$now = date('c');
|
||||
db()->prepare(
|
||||
'INSERT INTO einsatzanweisung (user_id, filename, original_name, uploaded_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(user_id) DO UPDATE SET
|
||||
filename = excluded.filename,
|
||||
original_name = excluded.original_name,
|
||||
uploaded_at = excluded.uploaded_at'
|
||||
)->execute([$user_id, $safe_name, $original_name, $now]);
|
||||
|
||||
header('Location: ' . $back . '&ok=' . urlencode('PDF erfolgreich hochgeladen.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: ' . $back);
|
||||
exit;
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_admin();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/admin.php?tab=fortbildung');
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = $_POST['_action'] ?? '';
|
||||
|
||||
/* ── Add ──────────────────────────────────────────────────────────────── */
|
||||
if ($action === 'add') {
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$description = trim($_POST['description'] ?? '');
|
||||
|
||||
if ($title === '') {
|
||||
header('Location: ../pages/admin.php?tab=fortbildung&err=notitle');
|
||||
exit;
|
||||
}
|
||||
|
||||
$up = handle_upload($_FILES['file'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_OFFICE,
|
||||
'dir' => dirname(__DIR__) . '/fortbildung-materials/',
|
||||
'naming' => 'hash',
|
||||
'max_bytes' => 20 * 1024 * 1024,
|
||||
'messages' => [
|
||||
'missing' => 'nofile', 'upload' => 'nofile',
|
||||
'ext' => 'badext', 'mime' => 'badmime',
|
||||
'size' => 'toobig', 'move' => 'upload',
|
||||
],
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
header('Location: ../pages/admin.php?tab=fortbildung&err=' . $up['error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$safe_name = $up['filename'];
|
||||
$original_name = $up['original_name'];
|
||||
|
||||
$sort_order = (int)db()->query('SELECT COALESCE(MAX(sort_order), 0) + 10 FROM fortbildung_materials')->fetchColumn();
|
||||
$now = date('c');
|
||||
|
||||
$stmt = db()->prepare(
|
||||
'INSERT INTO fortbildung_materials (title, description, filename, original_name, sort_order, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)'
|
||||
);
|
||||
$stmt->execute([$title, $description, $safe_name, $original_name, $sort_order, $now, $now]);
|
||||
|
||||
header('Location: ../pages/admin.php?tab=fortbildung&ok=added');
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ── Delete ───────────────────────────────────────────────────────────── */
|
||||
if ($action === 'delete') {
|
||||
$id = (int)($_POST['material_id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
header('Location: ../pages/admin.php?tab=fortbildung&err=invalid');
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare('SELECT filename FROM fortbildung_materials WHERE id = ?');
|
||||
$stmt->execute([$id]);
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if ($row) {
|
||||
db()->prepare('DELETE FROM fortbildung_materials WHERE id = ?')->execute([$id]);
|
||||
@unlink(dirname(__DIR__) . '/fortbildung-materials/' . $row['filename']);
|
||||
}
|
||||
|
||||
header('Location: ../pages/admin.php?tab=fortbildung&ok=deleted');
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: ../pages/admin.php?tab=fortbildung');
|
||||
exit;
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_admin();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') !== 'XMLHttpRequest') {
|
||||
echo json_encode(['ok' => false, 'error' => 'forbidden']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['ok' => false, 'error' => 'method']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$body = file_get_contents('php://input');
|
||||
$data = json_decode($body, true);
|
||||
$order = $data['order'] ?? null;
|
||||
|
||||
if (!is_array($order)) {
|
||||
echo json_encode(['ok' => false, 'error' => 'invalid']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ids = array_values(array_filter(array_map('intval', $order), fn($v) => $v > 0));
|
||||
|
||||
if (empty($ids)) {
|
||||
echo json_encode(['ok' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$now = date('c');
|
||||
$pos = 10;
|
||||
$stmt = db()->prepare('UPDATE fortbildung_materials SET sort_order = ?, updated_at = ? WHERE id = ?');
|
||||
|
||||
db()->beginTransaction();
|
||||
foreach ($ids as $id) {
|
||||
$stmt->execute([$pos, $now, $id]);
|
||||
$pos += 10;
|
||||
}
|
||||
db()->commit();
|
||||
|
||||
echo json_encode(['ok' => true]);
|
||||
exit;
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
$_SESSION = [];
|
||||
if (ini_get('session.use_cookies')) {
|
||||
$p = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$p['path'], $p['domain'], $p['secure'], $p['httponly']);
|
||||
}
|
||||
session_destroy();
|
||||
header('Location: ../index.php');
|
||||
exit;
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/db.php';
|
||||
require_admin();
|
||||
|
||||
$action = $_POST['_action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$title = trim((string)($_POST['title'] ?? ''));
|
||||
$text = trim((string)($_POST['text'] ?? ''));
|
||||
$date = trim((string)($_POST['date'] ?? '')) ?: date('Y-m-d');
|
||||
if ($title === '' || $text === '') {
|
||||
header('Location: ../pages/admin.php?tab=news&err=empty');
|
||||
exit;
|
||||
}
|
||||
$stmt = db()->prepare(
|
||||
'INSERT INTO news (title, text, date, created_at) VALUES (?, ?, ?, ?)'
|
||||
);
|
||||
$stmt->execute([$title, $text, $date, date('c')]);
|
||||
header('Location: ../pages/admin.php?tab=news&ok=added');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'delete') {
|
||||
$id = (int)($_POST['news_id'] ?? 0);
|
||||
if ($id > 0) {
|
||||
db()->prepare('DELETE FROM news WHERE id = ?')->execute([$id]);
|
||||
}
|
||||
header('Location: ../pages/admin.php?tab=news&ok=deleted');
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: ../pages/admin.php?tab=news');
|
||||
exit;
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/db.php';
|
||||
require_login();
|
||||
|
||||
$ajax = !empty($_POST['_ajax']);
|
||||
|
||||
function ajax_error(string $msg): never {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['ok' => false, 'error' => $msg]);
|
||||
exit;
|
||||
}
|
||||
function ajax_ok(): never {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['ok' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
if ($ajax) ajax_error('Ungültige Anfrage.');
|
||||
header('Location: ../pages/dienstplan.php'); exit;
|
||||
}
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$year = (int)($_POST['year'] ?? 0);
|
||||
$month = (int)($_POST['month'] ?? 0);
|
||||
|
||||
if ($year < 2020 || $year > 2099 || $month < 1 || $month > 12) {
|
||||
if ($ajax) ajax_error('Ungültiger Monat.');
|
||||
header('Location: ../pages/dienstplan.php'); exit;
|
||||
}
|
||||
|
||||
$back = '../pages/dienstplan.php?year=' . $year . '&month=' . $month;
|
||||
$month_str = sprintf('%04d-%02d', $year, $month);
|
||||
$schicht_ok = ['frueh', 'spaet', 'nacht'];
|
||||
$submitted = $_POST['schicht'] ?? [];
|
||||
|
||||
if (!is_array($submitted)) {
|
||||
header('Location: ' . $back . '&saved=1'); exit;
|
||||
}
|
||||
|
||||
$now = date('c');
|
||||
db()->beginTransaction();
|
||||
try {
|
||||
foreach ($submitted as $date => $schicht) {
|
||||
if (!is_string($date) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue;
|
||||
if (substr($date, 0, 7) !== $month_str) continue;
|
||||
[$y, $m, $d] = array_map('intval', explode('-', $date));
|
||||
if (!checkdate($m, $d, $y)) continue;
|
||||
|
||||
if (in_array($schicht, $schicht_ok, true)) {
|
||||
db()->prepare(
|
||||
'INSERT INTO dienstplan (user_id, date, schicht, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE schicht=VALUES(schicht), updated_at=VALUES(updated_at)'
|
||||
)->execute([$user_id, $date, $schicht, $now, $now]);
|
||||
} else {
|
||||
db()->prepare(
|
||||
'DELETE FROM dienstplan WHERE user_id = ? AND date = ?'
|
||||
)->execute([$user_id, $date]);
|
||||
}
|
||||
}
|
||||
db()->commit();
|
||||
} catch (\PDOException $ex) {
|
||||
if (db()->inTransaction()) db()->rollBack();
|
||||
$msg = 'Datenbankfehler: ' . $ex->getMessage();
|
||||
if ($ajax) ajax_error($msg);
|
||||
header('Location: ' . $back . '&error=' . urlencode($msg));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($ajax) ajax_ok();
|
||||
header('Location: ' . $back . '&saved=1');
|
||||
exit;
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_login();
|
||||
|
||||
$config = _omsorgcore_config();
|
||||
$token = $_SESSION['omsorgcore_access_token'];
|
||||
$action = $_POST['action'] ?? '';
|
||||
$employeeId = $_SESSION['omsorgcore_profile']['employeeId'] ?? null;
|
||||
|
||||
if ($action === 'profile') {
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$telefon = trim($_POST['telefon'] ?? '');
|
||||
|
||||
if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
header('Location: ../pages/settings.php?error=' . urlencode('Ungültige E-Mail-Adresse.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$employeeId) {
|
||||
header('Location: ../pages/settings.php?error=' . urlencode('Kein verknüpfter Mitarbeiter-Datensatz gefunden.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$current = omsorgcore_employees_get($config, $token, $employeeId);
|
||||
if (!$current['ok']) {
|
||||
header('Location: ../pages/settings.php?error=' . urlencode('Profil konnte nicht geladen werden.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$payload = $current['data'];
|
||||
$payload['email'] = $email;
|
||||
$payload['phoneNumber'] = $telefon;
|
||||
unset($payload['id']);
|
||||
|
||||
$result = omsorgcore_employees_update($config, $token, $employeeId, $payload);
|
||||
if (!$result['ok']) {
|
||||
header('Location: ../pages/settings.php?error=' . urlencode('Profil konnte nicht gespeichert werden.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
_refresh_profile();
|
||||
header('Location: ../pages/settings.php?saved=1');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'password') {
|
||||
$old = $_POST['old_password'] ?? '';
|
||||
$new = $_POST['new_password'] ?? '';
|
||||
$repeat = $_POST['new_password_repeat'] ?? '';
|
||||
|
||||
if (mb_strlen($new) < 8) {
|
||||
header('Location: ../pages/settings.php?error=' . urlencode('Neues Passwort muss mindestens 8 Zeichen haben.'));
|
||||
exit;
|
||||
}
|
||||
if ($new !== $repeat) {
|
||||
header('Location: ../pages/settings.php?error=' . urlencode('Die neuen Passwörter stimmen nicht überein.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = omsorgcore_change_password($config, $token, $old, $new);
|
||||
if (!$result['ok']) {
|
||||
$message = $result['status'] === 401 ? 'Aktuelles Passwort ist falsch.' : 'Passwort konnte nicht geändert werden.';
|
||||
header('Location: ../pages/settings.php?error=' . urlencode($message));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Serverseitig wurden alle Sessions widerrufen - neuer Login mit dem neuen Passwort ist nötig.
|
||||
_clear_omsorgcore_session();
|
||||
header('Location: ../index.php?pwchanged=1');
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: ../pages/settings.php');
|
||||
exit;
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/mail.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/abwesenheitsantrag.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/abwesenheitsantrag.php';
|
||||
|
||||
$von = trim($_POST['von'] ?? '');
|
||||
$bis = trim($_POST['bis'] ?? '');
|
||||
$grund = trim($_POST['grund'] ?? '');
|
||||
$vertretung = trim($_POST['vertretung'] ?? '');
|
||||
$nachricht = trim($_POST['nachricht'] ?? '');
|
||||
|
||||
if ($von === '' || $bis === '' || $grund === '') {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Von, Bis und Grund sind Pflichtfelder.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$allowed_grund = ['krankheit', 'arztbesuch', 'behoerdengang', 'sonderurlaub', 'elternzeit_pflegezeit', 'sonstiges'];
|
||||
if (!in_array($grund, $allowed_grund, true)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Ungültiger Grund.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!strtotime($von) || !strtotime($bis)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Ungültiges Datum.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (strtotime($von) > strtotime($bis)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Das Startdatum muss vor dem Enddatum liegen.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO requests_abwesenheitsantrag (user_id, status, admin_note, created_at, updated_at, von, bis, grund, vertretung, nachricht)
|
||||
VALUES (?, \'pending\', \'\', ?, ?, ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $now, $now, $von, $bis, $grund, $vertretung, $nachricht]);
|
||||
|
||||
$grund_labels = [
|
||||
'krankheit' => 'Krankheit',
|
||||
'arztbesuch' => 'Arztbesuch',
|
||||
'behoerdengang' => 'Behördengang',
|
||||
'sonderurlaub' => 'Sonderurlaub',
|
||||
'elternzeit_pflegezeit' => 'Elternzeit / Pflegezeit',
|
||||
'sonstiges' => 'Sonstiges',
|
||||
];
|
||||
|
||||
$config = require __DIR__ . '/../lib/config.php';
|
||||
smtp_send(
|
||||
$config,
|
||||
$config['mail_sabrina'],
|
||||
'Neuer Abwesenheitsantrag: ' . current_name(),
|
||||
"Ein Abwesenheitsantrag wurde eingereicht.\n\n"
|
||||
. 'Mitarbeiter: ' . current_name() . "\n"
|
||||
. 'Von: ' . $von . "\n"
|
||||
. 'Bis: ' . $bis . "\n"
|
||||
. 'Grund: ' . ($grund_labels[$grund] ?? $grund) . "\n"
|
||||
. 'Vertretung: ' . ($vertretung ?: '—') . "\n"
|
||||
. 'Nachricht: ' . ($nachricht ?: '—') . "\n\n"
|
||||
. "---\nGesendet über OMSORG Connect"
|
||||
);
|
||||
|
||||
header('Location: ' . $back . '?success=1');
|
||||
exit;
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/mail.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/benefitsantrag.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/benefitsantrag.php';
|
||||
|
||||
$benefit = trim($_POST['benefit'] ?? '');
|
||||
$nachricht = trim($_POST['nachricht'] ?? '');
|
||||
|
||||
$allowed_benefits = ['yoga', 'autogenes_training', 'massage', 'tankgutschein', 'online_gutscheine'];
|
||||
if (!in_array($benefit, $allowed_benefits, true)) {
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
|
||||
header('Content-Type: application/json');
|
||||
http_response_code(400);
|
||||
echo json_encode(['ok' => false, 'error' => 'Bitte einen Benefit auswählen.']);
|
||||
exit;
|
||||
}
|
||||
header('Location: ' . $back . '?error=' . urlencode('Bitte einen Benefit auswählen.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO requests_benefitsantrag (user_id, status, admin_note, created_at, updated_at, benefit, nachricht)
|
||||
VALUES (?, \'pending\', \'\', ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $now, $now, $benefit, $nachricht]);
|
||||
|
||||
$benefit_labels = [
|
||||
'yoga' => 'Yoga',
|
||||
'autogenes_training' => 'Autogenes Training',
|
||||
'massage' => 'Massage',
|
||||
'tankgutschein' => 'Tankgutschein',
|
||||
'online_gutscheine' => 'Online-Gutscheine',
|
||||
];
|
||||
|
||||
$config = require __DIR__ . '/../lib/config.php';
|
||||
smtp_send(
|
||||
$config,
|
||||
$config['mail_info'],
|
||||
'Neuer Benefitsantrag: ' . current_name(),
|
||||
"Ein Benefitsantrag wurde eingereicht.\n\n"
|
||||
. 'Mitarbeiter: ' . current_name() . "\n"
|
||||
. 'Benefit: ' . ($benefit_labels[$benefit] ?? $benefit) . "\n"
|
||||
. 'Nachricht: ' . ($nachricht ?: '—') . "\n\n"
|
||||
. "---\nGesendet über OMSORG Connect"
|
||||
);
|
||||
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['ok' => true, 'benefit' => $benefit]);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: ' . $back . '?success=1');
|
||||
exit;
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/db.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/einsatzbewertung.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/einsatzbewertung.php';
|
||||
|
||||
$einsatzort = trim($_POST['einsatzort'] ?? '');
|
||||
$von = trim($_POST['von'] ?? '');
|
||||
$bis = trim($_POST['bis'] ?? '');
|
||||
$bewertung = (int)($_POST['bewertung'] ?? 0);
|
||||
$wieder = isset($_POST['wieder']) ? 1 : 0;
|
||||
$feedback = trim($_POST['feedback'] ?? '');
|
||||
|
||||
if ($einsatzort === '') {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Bitte den Einsatzort angeben.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($von === '' || $bis === '') {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Von und Bis sind Pflichtfelder.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!strtotime($von) || !strtotime($bis)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Ungültiges Datum.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (strtotime($von) > strtotime($bis)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Das Startdatum muss vor dem Enddatum liegen.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($bewertung < 1 || $bewertung > 5) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Bitte eine Bewertung von 1 bis 5 Sternen auswählen.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO einsatzbewertungen (user_id, einsatzort, von, bis, bewertung, wieder, feedback, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $einsatzort, $von, $bis, $bewertung, $wieder, $feedback, $now]);
|
||||
|
||||
header('Location: ' . $back . '?success=1');
|
||||
exit;
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_once __DIR__ . '/../lib/mail.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/fortbildungsantrag.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/fortbildungsantrag.php';
|
||||
|
||||
$anliegen = trim($_POST['anliegen'] ?? '');
|
||||
$thema = trim($_POST['thema'] ?? '');
|
||||
$nachricht = trim($_POST['nachricht'] ?? '');
|
||||
|
||||
$allowed_anliegen = ['wbl_pdl', 'fortbildung', 'pflichtschulung'];
|
||||
if (!in_array($anliegen, $allowed_anliegen, true)) {
|
||||
redirect_error($back, 'Bitte ein Anliegen auswählen.');
|
||||
}
|
||||
|
||||
if ($thema === '') {
|
||||
redirect_error($back, 'Bitte ein Thema angeben.');
|
||||
}
|
||||
|
||||
$up = handle_upload($_FILES['datei'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_DOCS,
|
||||
'dir' => dirname(__DIR__) . '/uploads/',
|
||||
'prefix' => 'fortbildung',
|
||||
'required' => false,
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
redirect_error($back, $up['error']);
|
||||
}
|
||||
|
||||
$filename = $up['filename'] ?? '';
|
||||
$original_name = $up['original_name'] ?? '';
|
||||
$mime = $up['mime'] ?? null;
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO requests_fortbildungsantrag
|
||||
(user_id, status, admin_note, anliegen, thema, nachricht, filename, original_name, created_at, updated_at)
|
||||
VALUES (?, \'pending\', \'\', ?, ?, ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $anliegen, $thema, $nachricht, $filename, $original_name, $now, $now]);
|
||||
|
||||
$anliegen_labels = [
|
||||
'wbl_pdl' => 'WBL / PDL',
|
||||
'fortbildung' => 'Fortbildung',
|
||||
'pflichtschulung' => 'Pflichtschulung',
|
||||
];
|
||||
|
||||
$config = require __DIR__ . '/../lib/config.php';
|
||||
$attach = ($filename !== '')
|
||||
? ['path' => dirname(__DIR__) . '/uploads/' . $filename, 'name' => $original_name, 'mime' => $mime]
|
||||
: [];
|
||||
smtp_send(
|
||||
$config,
|
||||
$config['mail_info'],
|
||||
'Neuer Fortbildungsantrag: ' . current_name(),
|
||||
"Ein Fortbildungsantrag wurde eingereicht.\n\n"
|
||||
. 'Mitarbeiter: ' . current_name() . "\n"
|
||||
. 'Anliegen: ' . ($anliegen_labels[$anliegen] ?? $anliegen) . "\n"
|
||||
. 'Thema: ' . $thema . "\n"
|
||||
. 'Nachricht: ' . ($nachricht ?: '—') . "\n\n"
|
||||
. "---\nGesendet über OMSORG Connect",
|
||||
$attach
|
||||
);
|
||||
|
||||
redirect_ok($back);
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_once __DIR__ . '/../lib/mail.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/stundennachweis.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/stundennachweis.php';
|
||||
$monat_m = trim($_POST['monat_m'] ?? '');
|
||||
$monat_j = trim($_POST['monat_j'] ?? '');
|
||||
|
||||
if (!preg_match('/^\d{2}$/', $monat_m) || !preg_match('/^\d{4}$/', $monat_j)
|
||||
|| (int)$monat_m < 1 || (int)$monat_m > 12
|
||||
|| (int)$monat_j < 2020 || (int)$monat_j > 2099) {
|
||||
redirect_error($back, 'Bitte einen gültigen Monat und ein gültiges Jahr auswählen.');
|
||||
}
|
||||
$monat = $monat_j . '-' . $monat_m;
|
||||
|
||||
$dir = dirname(__DIR__) . '/uploads/';
|
||||
$up = handle_upload($_FILES['datei'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_PDF_IMG,
|
||||
'dir' => $dir,
|
||||
'prefix' => 'stundennachweis',
|
||||
'messages' => [
|
||||
'missing' => 'Bitte eine Datei hochladen.',
|
||||
'ext' => 'Dateityp nicht erlaubt. Erlaubt: PDF, JPG, PNG.',
|
||||
],
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
redirect_error($back, $up['error']);
|
||||
}
|
||||
|
||||
$safe_name = $up['filename'];
|
||||
$original_name = $up['original_name'];
|
||||
$mime = $up['mime'];
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO requests_stundennachweis
|
||||
(user_id, status, admin_note, monat, filename, original_name, created_at, updated_at)
|
||||
VALUES (?, \'pending\', \'\', ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $monat, $safe_name, $original_name, $now, $now]);
|
||||
|
||||
$config = require __DIR__ . '/../lib/config.php';
|
||||
smtp_send(
|
||||
$config,
|
||||
$config['mail_sabrina'],
|
||||
'Neuer Stundennachweis: ' . current_name(),
|
||||
"Ein Stundennachweis wurde hochgeladen.\n\n"
|
||||
. 'Mitarbeiter: ' . current_name() . "\n"
|
||||
. 'Monat: ' . $monat . "\n"
|
||||
. 'Datei: ' . $original_name . "\n\n"
|
||||
. "---\nGesendet über OMSORG Connect",
|
||||
['path' => $dir . $safe_name, 'name' => $original_name, 'mime' => $mime]
|
||||
);
|
||||
|
||||
redirect_ok($back);
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_once __DIR__ . '/../lib/mail.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/urlaubsantrag.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/urlaubsantrag.php';
|
||||
|
||||
verify_csrf();
|
||||
|
||||
$von = trim($_POST['von'] ?? '');
|
||||
$bis = trim($_POST['bis'] ?? '');
|
||||
$vertretung = trim($_POST['vertretung'] ?? '');
|
||||
$nachricht = trim($_POST['nachricht'] ?? '');
|
||||
|
||||
if ($von === '' || $bis === '') {
|
||||
redirect_error($back, 'Von und Bis sind Pflichtfelder.');
|
||||
}
|
||||
|
||||
if (!strtotime($von) || !strtotime($bis)) {
|
||||
redirect_error($back, 'Ungültiges Datum.');
|
||||
}
|
||||
|
||||
if (strtotime($von) > strtotime($bis)) {
|
||||
redirect_error($back, 'Das Startdatum muss vor dem Enddatum liegen.');
|
||||
}
|
||||
|
||||
$up = handle_upload($_FILES['datei'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_DOCS,
|
||||
'dir' => dirname(__DIR__) . '/uploads/',
|
||||
'prefix' => 'urlaubsantrag',
|
||||
'required' => false,
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
redirect_error($back, $up['error']);
|
||||
}
|
||||
|
||||
$filename = $up['filename'] ?? '';
|
||||
$original_name = $up['original_name'] ?? '';
|
||||
$mime = $up['mime'] ?? null;
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO requests_urlaubsantrag (user_id, status, admin_note, created_at, updated_at, von, bis, vertretung, nachricht, filename, original_name)
|
||||
VALUES (?, \'pending\', \'\', ?, ?, ?, ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $now, $now, $von, $bis, $vertretung, $nachricht, $filename, $original_name]);
|
||||
|
||||
$config = require __DIR__ . '/../lib/config.php';
|
||||
$attach = ($filename !== '')
|
||||
? ['path' => dirname(__DIR__) . '/uploads/' . $filename, 'name' => $original_name, 'mime' => $mime]
|
||||
: [];
|
||||
smtp_send(
|
||||
$config,
|
||||
$config['mail_sabrina'],
|
||||
'Neuer Urlaubsantrag: ' . current_name(),
|
||||
"Ein Urlaubsantrag wurde eingereicht.\n\n"
|
||||
. 'Mitarbeiter: ' . current_name() . "\n"
|
||||
. 'Von: ' . $von . "\n"
|
||||
. 'Bis: ' . $bis . "\n"
|
||||
. 'Vertretung: ' . ($vertretung ?: '—') . "\n"
|
||||
. 'Nachricht: ' . ($nachricht ?: '—') . "\n\n"
|
||||
. "---\nGesendet über OMSORG Connect",
|
||||
$attach
|
||||
);
|
||||
|
||||
redirect_ok($back);
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/mail.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/werben.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/werben.php';
|
||||
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$qualifikation = trim($_POST['qualifikation'] ?? '');
|
||||
$nachricht = trim($_POST['nachricht'] ?? '');
|
||||
|
||||
if ($name === '' || $email === '' || $qualifikation === '') {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Name, E-Mail und Qualifikation sind Pflichtfelder.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Bitte eine gültige E-Mail-Adresse eingeben.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$allowed_qual = ['1jahr', '3jahr'];
|
||||
if (!in_array($qualifikation, $allowed_qual, true)) {
|
||||
header('Location: ' . $back . '?error=' . urlencode('Ungültige Qualifikation.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO requests_werben (user_id, status, admin_note, created_at, updated_at, name, email, qualifikation, nachricht)
|
||||
VALUES (?, \'pending\', \'\', ?, ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $now, $now, $name, $email, $qualifikation, $nachricht]);
|
||||
|
||||
$qual_labels = [
|
||||
'1jahr' => '1 Jährige Examinierte Pflegekraft',
|
||||
'3jahr' => '3 Jährige Examinierte Pflegekraft',
|
||||
];
|
||||
|
||||
$config = require __DIR__ . '/../lib/config.php';
|
||||
smtp_send(
|
||||
$config,
|
||||
$config['mail_info'],
|
||||
'Mitarbeiter werben: ' . current_name(),
|
||||
"Ein Mitarbeiter wurde empfohlen.\n\n"
|
||||
. 'Empfohlen von: ' . current_name() . "\n"
|
||||
. 'Name der empfohlenen Person: ' . $name . "\n"
|
||||
. 'E-Mail: ' . $email . "\n"
|
||||
. 'Art der Stelle: ' . ($qual_labels[$qualifikation] ?? $qualifikation) . "\n"
|
||||
. 'Nachricht: ' . ($nachricht ?: '—') . "\n\n"
|
||||
. "---\nGesendet über OMSORG Connect"
|
||||
);
|
||||
|
||||
header('Location: ' . $back . '?success=1');
|
||||
exit;
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/settings.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/settings.php';
|
||||
$user = current_user();
|
||||
$dir = dirname(__DIR__) . '/assets/avatars/';
|
||||
$config = _omsorgcore_config();
|
||||
$token = $_SESSION['omsorgcore_access_token'];
|
||||
$employeeId = $_SESSION['omsorgcore_profile']['employeeId'] ?? null;
|
||||
|
||||
function _set_avatar_file_name(array $config, string $token, string $employeeId, ?string $filename): bool {
|
||||
$current = omsorgcore_employees_get($config, $token, $employeeId);
|
||||
if (!$current['ok']) {
|
||||
return false;
|
||||
}
|
||||
$payload = $current['data'];
|
||||
$payload['avatarFileName'] = $filename;
|
||||
unset($payload['id']);
|
||||
|
||||
$result = omsorgcore_employees_update($config, $token, $employeeId, $payload);
|
||||
if ($result['ok']) {
|
||||
_refresh_profile();
|
||||
}
|
||||
return $result['ok'];
|
||||
}
|
||||
|
||||
if (!$employeeId) {
|
||||
redirect_error($back, 'Kein verknüpfter Mitarbeiter-Datensatz gefunden.');
|
||||
}
|
||||
|
||||
// Remove avatar
|
||||
if (!empty($_POST['remove_avatar'])) {
|
||||
if (!empty($user['avatar'])) {
|
||||
$old = $dir . basename($user['avatar']);
|
||||
if (is_file($old)) {
|
||||
unlink($old);
|
||||
}
|
||||
}
|
||||
_set_avatar_file_name($config, $token, $employeeId, null);
|
||||
redirect_ok($back, 'avatar_saved');
|
||||
}
|
||||
|
||||
$up = handle_upload($_FILES['avatar'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_IMAGES,
|
||||
'dir' => $dir,
|
||||
'naming' => 'plain',
|
||||
'max_bytes' => 3 * 1024 * 1024,
|
||||
'messages' => [
|
||||
'missing' => 'Bitte ein Bild auswählen.',
|
||||
'upload' => 'Fehler beim Hochladen des Bildes.',
|
||||
'ext' => 'Nur Bilder erlaubt (JPG, PNG, GIF, WebP).',
|
||||
'mime' => 'Nur Bilder erlaubt (JPG, PNG, GIF, WebP).',
|
||||
'size' => 'Bild ist zu groß (max. 3 MB).',
|
||||
'move' => 'Fehler beim Speichern des Bildes.',
|
||||
],
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
redirect_error($back, $up['error']);
|
||||
}
|
||||
|
||||
$safe_name = $up['filename'];
|
||||
|
||||
// Delete old avatar after successful upload
|
||||
if (!empty($user['avatar'])) {
|
||||
$old = $dir . basename($user['avatar']);
|
||||
if (is_file($old)) {
|
||||
unlink($old);
|
||||
}
|
||||
}
|
||||
|
||||
_set_avatar_file_name($config, $token, $employeeId, $safe_name);
|
||||
|
||||
redirect_ok($back, 'avatar_saved');
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/auth.php';
|
||||
require_once __DIR__ . '/../lib/upload.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: ../pages/dokumentenarchiv.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$back = '../pages/dokumentenarchiv.php';
|
||||
|
||||
$allowed_kategorien = ['Fortbildungsnachweis', 'Zeugnis', 'Bescheinigung', 'Sonstiges'];
|
||||
$kategorie = trim($_POST['kategorie'] ?? '');
|
||||
$beschreibung = trim($_POST['beschreibung'] ?? '');
|
||||
|
||||
if (!in_array($kategorie, $allowed_kategorien, true)) {
|
||||
redirect_error($back, 'Bitte eine Kategorie auswählen.');
|
||||
}
|
||||
|
||||
$filesize = $_FILES['datei']['size'] ?? 0;
|
||||
$up = handle_upload($_FILES['datei'] ?? [], [
|
||||
'allowed' => UPLOAD_TYPES_DOCS,
|
||||
'dir' => dirname(__DIR__) . '/uploads/',
|
||||
'prefix' => 'dokument',
|
||||
]);
|
||||
if (!$up['ok']) {
|
||||
redirect_error($back, $up['error']);
|
||||
}
|
||||
|
||||
$safe_name = $up['filename'];
|
||||
$original_name = $up['original_name'];
|
||||
|
||||
$user_id = current_user()['id'];
|
||||
$now = date('c');
|
||||
|
||||
db()->prepare(
|
||||
'INSERT INTO dokumente (user_id, kategorie, beschreibung, filename, original_name, filesize, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)'
|
||||
)->execute([$user_id, $kategorie, $beschreibung, $safe_name, $original_name, $filesize, $now]);
|
||||
|
||||
redirect_ok($back, 'ok');
|
||||
Reference in New Issue
Block a user