| Server IP : 193.86.120.172 / Your IP : 216.73.216.67 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/jservices_cz/ |
Upload File : |
<?php
declare(strict_types=1);
/**
* J Services - odesílání emailů přes Microsoft Graph API (OAuth2)
*/
require_once __DIR__ . '/smtp_config.php';
function ziskat_m365_token(PDO $pdo): string
{
$cachedToken = nacti_nastaveni($pdo, 'm365_token_cache', '');
$cachedExpires = (int) nacti_nastaveni($pdo, 'm365_token_expires', '0');
if ($cachedToken !== '' && $cachedExpires > time() + 60) {
return $cachedToken;
}
$url = 'https://login.microsoftonline.com/' . M365_TENANT_ID . '/oauth2/v2.0/token';
$data = http_build_query([
'grant_type' => 'client_credentials',
'client_id' => M365_CLIENT_ID,
'client_secret' => M365_CLIENT_SECRET,
'scope' => 'https://graph.microsoft.com/.default',
]);
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $data,
]]);
$response = @file_get_contents($url, false, $context);
if ($response === false) { error_log('M365 token request failed'); return ''; }
$json = json_decode($response, true);
if (empty($json['access_token'])) { error_log('M365 token error: ' . ($json['error_description'] ?? 'unknown')); return ''; }
$token = $json['access_token'];
$expires = time() + (int) ($json['expires_in'] ?? 3600);
ulozit_nastaveni($pdo, 'm365_token_cache', $token);
ulozit_nastaveni($pdo, 'm365_token_expires', (string) $expires);
return $token;
}
function odeslat_graph_email(string $token, string $predmet, string $htmlTelo, string $toEmail, string $toJmeno, string $replyToEmail = '', string $replyToJmeno = ''): bool
{
$payload = [
'message' => [
'subject' => $predmet,
'body' => ['contentType' => 'HTML', 'content' => $htmlTelo],
'toRecipients' => [[
'emailAddress' => ['name' => $toJmeno, 'address' => $toEmail],
]],
],
'saveToSentItems' => true,
];
if ($replyToEmail !== '') {
$payload['message']['replyTo'] = [[
'emailAddress' => ['name' => $replyToJmeno, 'address' => $replyToEmail],
]];
}
$json = json_encode($payload);
$url = 'https://graph.microsoft.com/v1.0/users/' . urlencode(M365_FROM_EMAIL) . '/sendMail';
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Content-Length: ' . strlen($json),
]),
'content' => $json,
'ignore_errors' => true,
]]);
@file_get_contents($url, false, $context);
foreach ($http_response_header ?? [] as $h) {
if (str_starts_with($h, 'HTTP/') && str_contains($h, ' 202')) return true;
}
return false;
}
function email_sablona(string $nadpis, string $obsah, string $paticka = ''): string
{
$rok = date('Y');
$logo = 'https://jservices.cz/assets/img/logo_pruhledne.png';
return <<<HTML
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$nadpis}</title>
</head>
<body style="margin:0;padding:0;background:#F5F4EF;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#F5F4EF;padding:32px 0;">
<tr><td align="center">
<table width="560" cellpadding="0" cellspacing="0" style="max-width:560px;width:100%;">
<tr><td style="padding-bottom:20px;" align="center">
<img src="{$logo}" alt="J Services" style="height:48px;width:auto;display:block;">
</td></tr>
<tr><td style="background:#FFFFFF;border-radius:12px;border:1px solid #E5E7EB;padding:32px 36px;">
<h1 style="font-size:20px;font-weight:600;color:#2A2A2A;margin:0 0 20px;">{$nadpis}</h1>
{$obsah}
</td></tr>
<tr><td style="padding:20px 0;text-align:center;font-size:12px;color:#9A9A98;">
{$paticka}
© {$rok} J Services · <a href="https://jservices.cz" style="color:#1C75BC;text-decoration:none;">jservices.cz</a>
</td></tr>
</table>
</td></tr>
</table>
</body>
</html>
HTML;
}
function poslat_email_poptavka(string $jmeno, string $email, string $telefon, string $zprava): bool
{
global $pdo;
if (M365_TENANT_ID === '' || M365_CLIENT_ID === '' || M365_CLIENT_SECRET === '' || M365_FROM_EMAIL === '') return false;
$token = ziskat_m365_token($pdo);
if ($token === '') return false;
$jmenoEsc = htmlspecialchars($jmeno, ENT_QUOTES, 'UTF-8');
$emailEsc = htmlspecialchars($email, ENT_QUOTES, 'UTF-8');
$telefonEsc = htmlspecialchars($telefon, ENT_QUOTES, 'UTF-8');
$zpravaEsc = nl2br(htmlspecialchars($zprava, ENT_QUOTES, 'UTF-8'));
$datum = date('j. n. Y H:i');
// --- Email pro vás: notifikace o nové poptávce ---
$obsahNotifikace = <<<HTML
<p style="font-size:14px;color:#6B6B6B;margin:0 0 20px;">Přišla nová poptávka z webu jservices.cz.</p>
<table cellpadding="0" cellspacing="0" width="100%" style="border:1px solid #E5E7EB;border-radius:8px;overflow:hidden;margin-bottom:20px;">
<tr style="background:#F7F8FA;">
<td style="padding:10px 14px;font-size:12px;color:#9A9A98;font-weight:500;text-transform:uppercase;letter-spacing:0.05em;width:120px;">Jméno</td>
<td style="padding:10px 14px;font-size:14px;color:#2A2A2A;">{$jmenoEsc}</td>
</tr>
<tr>
<td style="padding:10px 14px;font-size:12px;color:#9A9A98;font-weight:500;text-transform:uppercase;letter-spacing:0.05em;border-top:1px solid #E5E7EB;">E-mail</td>
<td style="padding:10px 14px;font-size:14px;border-top:1px solid #E5E7EB;"><a href="mailto:{$emailEsc}" style="color:#1C75BC;text-decoration:none;">{$emailEsc}</a></td>
</tr>
<tr style="background:#F7F8FA;">
<td style="padding:10px 14px;font-size:12px;color:#9A9A98;font-weight:500;text-transform:uppercase;letter-spacing:0.05em;border-top:1px solid #E5E7EB;">Telefon</td>
<td style="padding:10px 14px;font-size:14px;color:#2A2A2A;border-top:1px solid #E5E7EB;"><a href="tel:{$telefonEsc}" style="color:#1C75BC;text-decoration:none;">{$telefonEsc}</a></td>
</tr>
<tr>
<td style="padding:10px 14px;font-size:12px;color:#9A9A98;font-weight:500;text-transform:uppercase;letter-spacing:0.05em;border-top:1px solid #E5E7EB;vertical-align:top;">Zpráva</td>
<td style="padding:10px 14px;font-size:14px;color:#2A2A2A;border-top:1px solid #E5E7EB;">{$zpravaEsc}</td>
</tr>
</table>
<p style="font-size:12px;color:#9A9A98;margin:0;">Přijato: {$datum}</p>
HTML;
$htmlNotifikace = email_sablona('Nová poptávka z webu', $obsahNotifikace);
odeslat_graph_email($token, 'Nová poptávka – ' . $jmeno, $htmlNotifikace, M365_TO_EMAIL, 'J Services', $email, $jmeno);
// --- Email pro odesílatele: potvrzení přijetí ---
$obsahPotvrzeni = <<<HTML
<p style="font-size:15px;color:#2A2A2A;margin:0 0 16px;">Dobrý den, <strong>{$jmenoEsc}</strong>,</p>
<p style="font-size:14px;color:#6B6B6B;line-height:1.7;margin:0 0 20px;">
děkujeme za vaši zprávu. Přijali jsme vaši poptávku a ozveme se vám co nejdříve, obvykle do druhého pracovního dne.
</p>
<div style="background:#F7F8FA;border-radius:8px;border:1px solid #E5E7EB;padding:16px 20px;margin-bottom:24px;">
<p style="font-size:12px;color:#9A9A98;font-weight:500;text-transform:uppercase;letter-spacing:0.05em;margin:0 0 8px;">Vaše zpráva</p>
<p style="font-size:14px;color:#2A2A2A;line-height:1.7;margin:0;">{$zpravaEsc}</p>
</div>
HTML;
$patickaPotvrzeni = 'Tento email byl odeslán automaticky jako potvrzení vaší poptávky.<br>';
$htmlPotvrzeni = email_sablona('Přijali jsme vaši poptávku', $obsahPotvrzeni, $patickaPotvrzeni);
odeslat_graph_email($token, 'Potvrzení přijetí poptávky – J Services', $htmlPotvrzeni, $email, $jmeno);
return true;
}