⚝
One Hat Cyber Team
⚝
Your IP:
216.73.217.70
Server IP:
209.74.65.82
Server:
Linux 209-74-65-82.cprapid.com 5.14.0-427.42.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Nov 1 14:58:02 EDT 2024 x86_64
PHP Version:
8.1.34
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
home
/
ivsoxidh
/
system.ivsoftdesign.mk
/
Edit File: functions.php
<?php if (session_status() === PHP_SESSION_NONE) session_start(); require_once __DIR__ . '/db.php'; function find_user_by_email($email) { global $pdo; $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?"); $stmt->execute([$email]); return $stmt->fetch(); } function find_user($id) { global $pdo; $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$id]); return $stmt->fetch(); } function is_admin() { return !empty($_SESSION['user']) && $_SESSION['user']['role'] === 'admin'; } function all_employees() { global $pdo; return $pdo->query("SELECT id, name, email, team_id FROM users WHERE role = 'employee' ORDER BY name")->fetchAll(); } function team_name($team_id) { if (!$team_id) return ''; global $pdo; $stmt = $pdo->prepare("SELECT name FROM teams WHERE id=?"); $stmt->execute([$team_id]); $r = $stmt->fetch(); return $r['name'] ?? ''; } function leave_count_in_year($user_id, $year) { global $pdo; $stmt = $pdo->prepare("SELECT COUNT(*) AS c FROM leave_days WHERE user_id = ? AND YEAR(date) = ?"); $stmt->execute([$user_id, $year]); $row = $stmt->fetch(); return (int)($row['c'] ?? 0); } function leave_days_between($user_id, $start, $end) { global $pdo; $stmt = $pdo->prepare("SELECT * FROM leave_days WHERE user_id = ? AND date BETWEEN ? AND ? ORDER BY date"); $stmt->execute([$user_id, $start, $end]); return $stmt->fetchAll(); } function is_weekend($date) { $n = (int)date('N', strtotime($date)); return $n >= 6; } function is_holiday($date, $country) { global $pdo; $stmt = $pdo->prepare("SELECT 1 FROM holidays WHERE country = ? AND date = ?"); $stmt->execute([$country, $date]); return (bool)$stmt->fetchColumn(); } function business_days_in_range($start, $end, $country) { $days = []; $cur = new DateTime($start); $to = new DateTime($end); while ($cur <= $to) { $d = $cur->format('Y-m-d'); if (!is_weekend($d) && !is_holiday($d, $country)) $days[] = $d; $cur->modify('+1 day'); } return $days; } function add_leave_request($user_id, $start_date, $end_date, $reason) { global $pdo; $user = find_user($user_id); if (!$user) return ['ok'=>false, 'msg'=>'Корисникот не постои.']; if (!$start_date || !$end_date) return ['ok'=>false, 'msg'=>'Изберете период.']; if ($end_date < $start_date) return ['ok'=>false, 'msg'=>'Крајниот датум мора да е по почетниот.']; $biz = business_days_in_range($start_date, $end_date, $user['country']); if (empty($biz)) return ['ok'=>false, 'msg'=>'Нема работни денови во периодот (викенд/празници).']; // Soft cap check vs existing taken $year = (int)date('Y', strtotime($start_date)); $taken = leave_count_in_year($user_id, $year); if ($taken + count($biz) > MAX_LEAVE_DAYS_PER_YEAR) { return ['ok'=>false, 'msg'=>"Периодот надминува вкупно ".MAX_LEAVE_DAYS_PER_YEAR." денови за $year (вклучувајќи постоечки)."]; } $stmt = $pdo->prepare("INSERT INTO leave_requests (user_id, start_date, end_date, reason) VALUES (?,?,?,?)"); $stmt->execute([$user_id, $start_date, $end_date, $reason ?: null]); // Notify admin (simple) $subject = "Ново барање за слободни денови"; $body = "<p><strong>{$user['name']}</strong> побара од <strong>{$start_date}</strong> до <strong>{$end_date}</strong>.<br>Причина: ".htmlspecialchars($reason)."</p>"; $admins = $pdo->query("SELECT email FROM users WHERE role='admin'")->fetchAll(); foreach ($admins as $a) send_email($a['email'], $subject, $body); return ['ok'=>true, 'msg'=>'Барањето е испратено на одобрување.']; } function approve_request($request_id, $reviewer_id) { global $pdo; $stmt = $pdo->prepare("SELECT * FROM leave_requests WHERE id=? FOR UPDATE"); $pdo->beginTransaction(); $stmt->execute([$request_id]); $req = $stmt->fetch(); if (!$req) { $pdo->rollBack(); return ['ok'=>false, 'msg'=>'Барањето не постои.']; } if ($req['status'] !== 'pending') { $pdo->rollBack(); return ['ok'=>false, 'msg'=>'Веќе обработено.']; } $user = find_user($req['user_id']); $biz = business_days_in_range($req['start_date'], $req['end_date'], $user['country']); // Enforce cap at approval time $year = (int)date('Y', strtotime($req['start_date'])); $taken = leave_count_in_year($user['id'], $year); if ($taken + count($biz) > MAX_LEAVE_DAYS_PER_YEAR) { $pdo->rollBack(); return ['ok'=>false, 'msg'=>"Одбивано: надминува ".MAX_LEAVE_DAYS_PER_YEAR." денови за $year."]; } // Insert leave_days $ins = $pdo->prepare("INSERT IGNORE INTO leave_days (user_id, date, reason) VALUES (?,?,?)"); foreach ($biz as $d) { $ins->execute([$user['id'], $d, $req['reason']]); } // Mark request approved $upd = $pdo->prepare("UPDATE leave_requests SET status='approved', reviewed_by=?, reviewed_at=NOW() WHERE id=?"); $upd->execute([$reviewer_id, $request_id]); $pdo->commit(); // Notify employee send_email($user['email'], 'Вашето барање е одобрено', "<p>Барањето од {$req['start_date']} до {$req['end_date']} е <strong>одобрено</strong>.</p>"); return ['ok'=>true, 'msg'=>'Одобрено и додадени деновите.']; } function reject_request($request_id, $reviewer_id, $note='') { global $pdo; $stmt = $pdo->prepare("UPDATE leave_requests SET status='rejected', reviewed_by=?, reviewed_at=NOW() WHERE id=? AND status='pending'"); $stmt->execute([$reviewer_id, $request_id]); if ($stmt->rowCount() === 0) return ['ok'=>false, 'msg'=>'Барањето не може да се одбие (веројатно не е pending).']; // Email $r = $pdo->prepare("SELECT lr.*, u.email, u.name FROM leave_requests lr JOIN users u ON u.id=lr.user_id WHERE lr.id=?"); $r->execute([$request_id]); $row = $r->fetch(); send_email($row['email'], 'Вашето барање е одбиено', "<p>Барањето од {$row['start_date']} до {$row['end_date']} е <strong>одбиено</strong>. {$note}</p>"); return ['ok'=>true, 'msg'=>'Одбиено.']; } function render_calendar($month, $year, $user_id) { global $pdo; $firstDay = new DateTimeImmutable("$year-$month-01"); $daysInMonth = (int)$firstDay->format('t'); $startDow = (int)$firstDay->format('N'); // 1..7 $stmt = $pdo->prepare("SELECT date, reason FROM leave_days WHERE user_id = ? AND date BETWEEN ? AND ?"); $stmt->execute([$user_id, "$year-$month-01", "$year-$month-$daysInMonth"]); $leaves = []; foreach ($stmt->fetchAll() as $r) $leaves[$r['date']] = $r['reason'] ?? ''; $today = date('Y-m-d'); echo '<table class="table table-bordered calendar">'; echo '<thead><tr class="table-light"><th>Пон</th><th>Вто</th><th>Сре</th><th>Чет</th><th>Пет</th><th class="text-muted">Саб</th><th class="text-muted">Нед</th></tr></thead>'; echo '<tbody><tr>'; for ($i=1; $i<$startDow; $i++) echo '<td class="bg-body-tertiary"></td>'; $dow = $startDow; for ($d=1; $d<=$daysInMonth; $d++, $dow++) { $dateStr = sprintf('%04d-%02d-%02d', $year, $month, $d); $classes = []; if ($dateStr === $today) $classes[] = 'today'; $isWeekend = (int)date('N', strtotime($dateStr)) >= 6; if ($isWeekend) $classes[] = 'text-muted'; $content = "<div class='fw-semibold'>$d</div>"; if (isset($leaves[$dateStr])) { $content .= "<span class='badge bg-success mt-1'>Слободно</span>"; if ($leaves[$dateStr]) $content .= "<div class='small text-secondary mt-1'>".htmlspecialchars($leaves[$dateStr])."</div>"; } echo '<td class="'.implode(' ', $classes).'">'.$content.'</td>'; if ($dow % 7 == 0 && $d < $daysInMonth) echo '</tr><tr>'; } while ($dow % 7 != 1) { echo '<td class="bg-body-tertiary"></td>'; $dow++; } echo '</tr></tbody></table>'; } ?>
Simpan