HEX
Server: LiteSpeed
System:
User: ()
PHP: 7.4.33
Disabled: sendmail,mail,exec,shell_exec,dl,system,passthru,pclose,proc_open,proc_nice,proc_terminate,proc_get_status,proc_close,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,escapeshellcmd,escapeshellarg shell-exec,fpassthru,crack_check,crack_closedict,crack_getlastmessage,crack_opendict,psockopen,php_uname,symlink,ini_restore,posix_getpwuid,posix_getegid,posix_getcwd,posix_geteuid,posix_getgroups,posix_uname,posix_setuid,eval,show_source,passthru,popen,allow_url_fopen,get_current_user,getmyuid,getmygid,entre2v2,index_changer_wp,index_changer_joomla,exec_mode_1,exec_mode_2,exec_mode_3,wsoFooter,wsoEx,wsoViewSize,wsoPerms,wsoPermsColor,ukuran,tulis,ambil,tukar,entre2v2,rapih,magicboom,goaction,scookie,showstat,index_changer
Upload Files
File: /home/muratemr/theotto.tr/includes/functions.php
<?php
/**
 * includes/functions.php
 * Genel yardımcı fonksiyonlar
 */

declare(strict_types=1);

/**
 * WhatsApp numarasını normalleştirir
 * "0532 111 22 33" → "905321112233"
 */
function normalize_whatsapp_number(string $number): string
{
    // Boşluk, parantez, +, - ve diğer gereksiz karakterleri temizle
    $clean = preg_replace('/[\s\(\)\+\-]/', '', $number);

    // Başındaki 0'ı kaldır
    $clean = ltrim($clean, '0');

    // 90 ile başlamıyorsa ekle
    if (!str_starts_with($clean, '90')) {
        $clean = '90' . $clean;
    }

    return $clean;
}

/**
 * WhatsApp linki oluşturur
 */
function whatsapp_link(string $number, string $message = ''): string
{
    $normalized = normalize_whatsapp_number($number);
    if ($message !== '') {
        return 'https://wa.me/' . $normalized . '?text=' . rawurlencode($message);
    }
    return 'https://wa.me/' . $normalized;
}

/**
 * Güvenli HTML çıktısı
 */
function e(mixed $value): string
{
    return htmlspecialchars((string)$value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}

/**
 * Tarihi Türkçe formatlar (2024-01-15 → 15.01.2024)
 */
function format_date(string $date): string
{
    if (!$date) return '-';
    return date('d.m.Y', strtotime($date));
}

/**
 * Tarih + saati formatlar
 */
function format_datetime(string $dt): string
{
    if (!$dt) return '-';
    return date('d.m.Y H:i', strtotime($dt));
}

/**
 * Saati formatlar (09:00:00 → 09:00)
 */
function format_time(string $time): string
{
    if (!$time) return '-';
    return substr($time, 0, 5);
}

/**
 * Dakikayı saat:dakika formatına çevirir
 */
function minutes_to_hm(int $minutes): string
{
    $h = intdiv($minutes, 60);
    $m = $minutes % 60;
    return sprintf('%02d:%02d', $h, $m);
}

/**
 * JSON API cevabı döner ve çıkar
 */
function json_response(bool $success, string $message = '', array $data = []): never
{
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array_merge(['success' => $success, 'message' => $message], $data));
    exit;
}

/**
 * Sayfalama verisi hesaplar
 * @return array ['offset'=>int, 'limit'=>int, 'total_pages'=>int, 'current_page'=>int]
 */
function paginate(int $total, int $page = 1, int $per_page = 25): array
{
    $page       = max(1, $page);
    $total_pages = (int)ceil($total / $per_page);
    $page       = min($page, max(1, $total_pages));
    return [
        'offset'      => ($page - 1) * $per_page,
        'limit'       => $per_page,
        'total_pages' => $total_pages,
        'current_page'=> $page,
        'total'       => $total,
        'per_page'    => $per_page,
    ];
}

/**
 * Rezervasyon durumuna göre Bootstrap badge sınıfı
 */
function reservation_status_badge(string $status): string
{
    return match ($status) {
        'bekliyor'   => '<span class="badge bg-warning text-dark">Bekliyor</span>',
        'onaylandi'  => '<span class="badge bg-success">Onaylandı</span>',
        'reddedildi' => '<span class="badge bg-danger">Reddedildi</span>',
        'iptal'      => '<span class="badge bg-secondary">İptal</span>',
        'arsiv'      => '<span class="badge bg-info text-dark">Arşiv</span>',
        default      => '<span class="badge bg-dark">' . e($status) . '</span>',
    };
}

/**
 * Devam durumuna göre badge
 */
function attendance_status_badge(string $status): string
{
    return match ($status) {
        'pending'     => '<span class="badge bg-secondary">Bekliyor</span>',
        'present'     => '<span class="badge bg-success">Geldi</span>',
        'absent'      => '<span class="badge bg-danger">Gelmedi</span>',
        'late'        => '<span class="badge bg-warning text-dark">Geç Kaldı</span>',
        'early_leave' => '<span class="badge bg-warning text-dark">Erken Çıktı</span>',
        'incomplete'  => '<span class="badge bg-orange text-dark">Eksik</span>',
        default       => '<span class="badge bg-dark">' . e($status) . '</span>',
    };
}

/**
 * İzin türü Türkçe adı
 */
function leave_type_label(string $type): string
{
    return match ($type) {
        'none'    => '-',
        'annual'  => 'Yıllık İzin',
        'sick'    => 'Raporlu',
        'unpaid'  => 'Ücretsiz İzin',
        'excuse'  => 'Mazeret İzni',
        default   => $type,
    };
}

/**
 * Rezervasyon için WhatsApp onay mesajı
 */
function reservation_whatsapp_message(array $r, string $type = 'confirm'): string
{
    $date = format_date($r['date']);
    $time = format_time($r['time']);

    return match ($type) {
        'confirm' => "Sayın {$r['full_name']},\n\nRezervasyonunuz onaylanmıştır. ✅\n\nTarih: $date\nSaat: $time\nKişi: {$r['guest_count']}\nMasa No: " . ($r['table_no'] ?? '-') . "\n\nSizi bekliyoruz! 🌟",
        'reject'  => "Sayın {$r['full_name']},\n\nÜzgünüz, rezervasyon talebiniz onaylanamadı. ❌\n\nTarih: $date\nSaat: $time\n\nBaşka bir tarih için rezervasyon yapabilirsiniz.",
        default   => '',
    };
}

/**
 * Günlük sipariş WhatsApp mesajı oluşturur
 */
function order_whatsapp_message(array $order, array $items, string $supplier_name): string
{
    $date = format_date($order['order_date']);
    $lines = ["Merhaba, aşağıdaki siparişi oluşturmak istiyoruz.\n"];
    $lines[] = "Tarih: $date";
    $lines[] = "Tedarikçi: $supplier_name\n";
    $lines[] = "Sipariş Listesi:";

    foreach ($items as $i => $item) {
        $no   = $i + 1;
        $line = "$no. {$item['product_name']} - {$item['quantity']} {$item['unit']}";
        if (!empty($item['approx_price'])) {
            $line .= " (~{$item['approx_price']} ₺)";
        }
        $lines[] = $line;
    }

    if (!empty($order['general_note'])) {
        $lines[] = "\nNot: {$order['general_note']}";
    }

    $lines[] = "\nTeşekkürler.";

    return implode("\n", $lines);
}

/**
 * İki zaman arasındaki dakika farkı (gece vardiyası desteği)
 */
function time_diff_minutes(string $start, string $end, bool $next_day = false): int
{
    $base = new DateTime('2000-01-01 ' . $start);
    $endDt = new DateTime('2000-01-01 ' . $end);
    if ($next_day || $endDt <= $base) {
        $endDt->modify('+1 day');
    }
    return (int)(($endDt->getTimestamp() - $base->getTimestamp()) / 60);
}

/**
 * Devam kaydı istatistiklerini hesaplar
 */
function calculate_attendance(array $shift, array $attendance): array
{
    $result = [
        'late_minutes'        => 0,
        'early_leave_minutes' => 0,
        'missing_minutes'     => 0,
        'status'              => 'pending',
        'auto_note'           => '',
    ];

    if (empty($attendance['actual_start_time'])) {
        return $result;
    }

    $is_next_day = (bool)($shift['is_next_day'] ?? false);

    // Geç kalma
    if (!empty($shift['planned_start_time']) && $attendance['actual_start_time'] > $shift['planned_start_time']) {
        $result['late_minutes'] = time_diff_minutes($shift['planned_start_time'], $attendance['actual_start_time']);
    }

    // Erken çıkış
    if (!empty($shift['planned_end_time']) && !empty($attendance['actual_end_time'])) {
        $plannedEnd   = $shift['planned_end_time'];
        $actualEnd    = $attendance['actual_end_time'];

        // Gece vardiyası hesabı
        if ($is_next_day || $actualEnd < $shift['planned_start_time']) {
            // planlanan bitiş ertesi gün
        }

        if ($actualEnd < $plannedEnd && !$is_next_day) {
            $result['early_leave_minutes'] = time_diff_minutes($actualEnd, $plannedEnd);
        }
    }

    // Toplam eksik
    $result['missing_minutes'] = $result['late_minutes'] + $result['early_leave_minutes'];

    // Durum belirleme
    if (empty($attendance['actual_start_time'])) {
        $result['status'] = 'absent';
    } elseif ($result['late_minutes'] > 0 && $result['early_leave_minutes'] > 0) {
        $result['status'] = 'incomplete';
    } elseif ($result['late_minutes'] > 0) {
        $result['status'] = 'late';
    } elseif ($result['early_leave_minutes'] > 0) {
        $result['status'] = 'early_leave';
    } else {
        $result['status'] = 'present';
    }

    return $result;
}

/**
 * Site ayarını döner
 */
function get_setting(string $key, string $default = ''): string
{
    static $settings = null;
    if ($settings === null) {
        try {
            $rows = db_rows('SELECT `key`, `value` FROM site_settings');
            $settings = array_column($rows, 'value', 'key');
        } catch (\Throwable $e) {
            return $default;
        }
    }
    return $settings[$key] ?? $default;
}

/**
 * Türkçe gün adları
 */
function day_names_tr(): array
{
    return ['Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt', 'Paz'];
}

/**
 * Türkçe ay adları
 */
function month_names_tr(): array
{
    return [
        1=>'Ocak',2=>'Şubat',3=>'Mart',4=>'Nisan',5=>'Mayıs',6=>'Haziran',
        7=>'Temmuz',8=>'Ağustos',9=>'Eylül',10=>'Ekim',11=>'Kasım',12=>'Aralık'
    ];
}

/**
 * POST string değerini temizler
 */
function post_str(string $key, string $default = ''): string
{
    return trim((string)($_POST[$key] ?? $default));
}

/**
 * POST int değerini döner
 */
function post_int(string $key, int $default = 0): int
{
    return (int)($_POST[$key] ?? $default);
}

/**
 * GET int değerini döner
 */
function get_int(string $key, int $default = 0): int
{
    return (int)($_GET[$key] ?? $default);
}

/**
 * GET string değerini döner
 */
function get_str(string $key, string $default = ''): string
{
    return trim((string)($_GET[$key] ?? $default));
}

/**
 * Telefon numarasını standart forma dönüştürür (müşteri eşleştirme için)
 * 905312440567, 05312440567, 5312440567 → 5312440567 (10 haneli TR formatı)
 */
function normalize_phone(string $number): string
{
    // Sadece rakam bırak
    $clean = preg_replace('/\D/', '', $number);

    // Başındaki 90'ı kaldır (uluslararası TR kodu)
    if (str_starts_with($clean, '90') && strlen($clean) === 12) {
        $clean = substr($clean, 2);
    }

    // Başındaki tek 0'ı kaldır → 10 haneli format
    if (str_starts_with($clean, '0') && strlen($clean) === 11) {
        $clean = substr($clean, 1);
    }

    return $clean;
}