403Webshell
Server IP : 193.86.120.172  /  Your IP : 216.73.216.215
Web Server : Apache/2.4.63 (Unix)
System : Linux JServices 3.10.108 #86003 SMP Wed Oct 22 13:20:46 CST 2025 x86_64
User : kubec ( 1026)
PHP Version : 8.2.28
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /volume1/web/kadernictvidenisa_cz/includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /volume1/web/kadernictvidenisa_cz/includes/calendar.php
<?php
// ============================================
//  includes/calendar.php
//  Microsoft Graph Calendar API
// ============================================

require_once __DIR__ . '/mailer.php';

function ms_get_graph_token(): string {
    static $cache = null;
    if ($cache !== null) return $cache;

    $stmt = db()->prepare(
        "SELECT access_token, expires_at, refresh_token FROM oauth_tokeny
         WHERE provider = 'microsoft_graph' ORDER BY id DESC LIMIT 1"
    );
    $stmt->execute();
    $row = $stmt->fetch();

    if ($row && new DateTime() < new DateTime($row['expires_at'])) {
        return $cache = $row['access_token'];
    }

    if ($row) {
        $body = http_build_query([
            'client_id'     => MS_CLIENT_ID,
            'client_secret' => MS_CLIENT_SECRET,
            'grant_type'    => 'refresh_token',
            'refresh_token' => $row['refresh_token'],
            'scope'         => 'https://graph.microsoft.com/Calendars.ReadWrite offline_access',
        ]);
        $ctx = stream_context_create(['http' => [
            'method'  => 'POST',
            'header'  => "Content-Type: application/x-www-form-urlencoded
",
            'content' => $body,
            'timeout' => 10,
        ]]);
        $resp = file_get_contents(
            'https://login.microsoftonline.com/' . MS_TENANT_ID . '/oauth2/v2.0/token',
            false, $ctx
        );
        $data = json_decode($resp, true);
        if (isset($data['access_token'])) {
            $expires_at = date('Y-m-d H:i:s', time() + (int)$data['expires_in'] - 60);
            db()->prepare("UPDATE oauth_tokeny SET access_token=?, refresh_token=?, expires_at=? WHERE provider='microsoft_graph'")
               ->execute([$data['access_token'], $data['refresh_token'] ?? $row['refresh_token'], $expires_at]);
            return $cache = $data['access_token'];
        }
    }

    throw new RuntimeException('Graph token není k dispozici. Spusťte znovu oauth-setup.php.');
}

function graph_vytvor_udalost(array $rez, string $sluzba_nazev): ?string {
    try {
        $access_token = ms_get_graph_token();
    } catch (Exception $e) {
        error_log('[Calendar] Token error: ' . $e->getMessage());
        return null;
    }

    $salon   = salon_nazev();
    $adresa  = nastaveni('salon_adresa', '');
    $telefon = nastaveni('salon_telefon', '');

    // Sestavení datetime v ISO 8601
    $start = $rez['datum'] . 'T' . $rez['cas_od'] . ':00';
    $end   = $rez['datum'] . 'T' . $rez['cas_do'] . ':00';

    $body_text = "Zákazník: {$rez['jmeno']} {$rez['prijmeni']}\n"
               . "E-mail: {$rez['email']}\n"
               . ($rez['telefon'] ? "Telefon: {$rez['telefon']}\n" : '')
               . ($rez['poznamka'] ? "Poznámka: {$rez['poznamka']}\n" : '')
               . (isset($rez["cena"]) && $rez["cena"] !== null ? "Cena: {$rez['cena']} Kč" : "Cena: Individuální");

    $event = [
        'subject' => $sluzba_nazev . ' – ' . $rez['jmeno'] . ' ' . $rez['prijmeni'],
        'body' => [
            'contentType' => 'text',
            'content'     => $body_text,
        ],
        'start' => [
            'dateTime' => $start,
            'timeZone' => 'Europe/Prague',
        ],
        'end' => [
            'dateTime' => $end,
            'timeZone' => 'Europe/Prague',
        ],
        'location' => $adresa ? ['displayName' => $adresa] : null,
        'reminderMinutesBeforeStart' => 30,
        'isReminderOn' => true,
        'showAs' => 'busy',
        'categories' => ['Kadeřnictví'],
    ];

    // Odstraň null hodnoty
    $event = array_filter($event, function($v){ return $v !== null; });

    $url = 'https://graph.microsoft.com/v1.0/me/events';
    $response = graph_request('POST', $url, $access_token, $event);

    if (isset($response['id'])) {
        return $response['id'];
    }

    error_log('[Calendar] Vytvoření události selhalo: ' . json_encode($response));
    return null;
}

function graph_aktualizuj_udalost(string $event_id, array $rez, string $sluzba_nazev): bool {
    try {
        $access_token = ms_get_graph_token();
    } catch (Exception $e) {
        error_log('[Calendar] Token error: ' . $e->getMessage());
        return false;
    }

    $start = $rez['datum'] . 'T' . $rez['cas_od'] . ':00';
    $end   = $rez['datum'] . 'T' . $rez['cas_do'] . ':00';

    $body_text = "Zákazník: {$rez['jmeno']} {$rez['prijmeni']}\n"
               . "E-mail: {$rez['email']}\n"
               . ($rez['telefon'] ? "Telefon: {$rez['telefon']}\n" : '')
               . ($rez['poznamka'] ? "Poznámka: {$rez['poznamka']}\n" : '')
               . (isset($rez["cena"]) && $rez["cena"] !== null ? "Cena: {$rez['cena']} Kč" : "Cena: Individuální");

    $event = [
        'subject' => $sluzba_nazev . ' – ' . $rez['jmeno'] . ' ' . $rez['prijmeni'],
        'body' => [
            'contentType' => 'text',
            'content'     => $body_text,
        ],
        'start' => [
            'dateTime' => $start,
            'timeZone' => 'Europe/Prague',
        ],
        'end' => [
            'dateTime' => $end,
            'timeZone' => 'Europe/Prague',
        ],
    ];

    $url = 'https://graph.microsoft.com/v1.0/me/events/' . urlencode($event_id);
    $response = graph_request('PATCH', $url, $access_token, $event);

    return isset($response['id']);
}

function graph_zrus_udalost(string $event_id): bool {
    try {
        $access_token = ms_get_graph_token();
    } catch (Exception $e) {
        error_log('[Calendar] Token error: ' . $e->getMessage());
        return false;
    }

    $url = 'https://graph.microsoft.com/v1.0/me/events/' . urlencode($event_id);
    $response = graph_request('DELETE', $url, $access_token);

    return $response === null; // DELETE vrací 204 No Content = null
}

function graph_request(string $method, string $url, string $token, ?array $body = null): ?array {
    $opts = [
        'http' => [
            'method'  => $method,
            'header'  => "Authorization: Bearer {$token}\r\n"
                       . "Content-Type: application/json\r\n"
                       . "Accept: application/json\r\n",
            'timeout' => 15,
            'ignore_errors' => true,
        ]
    ];

    if ($body !== null) {
        $opts['http']['content'] = json_encode($body);
    }

    $ctx      = stream_context_create($opts);
    $result   = file_get_contents($url, false, $ctx);
    $headers  = $http_response_header ?? [];
    $status   = 200;

    foreach ($headers as $h) {
        if (preg_match('/HTTP\/\d\.\d\s+(\d+)/', $h, $m)) {
            $status = (int) $m[1];
        }
    }

    if ($status === 204) return null; // No Content (DELETE úspěch)
    if ($result === false || $result === '') return [];

    return json_decode($result, true) ?? [];
}

Youez - 2016 - github.com/yon3zu
LinuXploit