| 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/doskocil_jservices_cz/ |
Upload File : |
<?php
/**
* GPS Instalace — Maintenance mode middleware
* Includuj na začátku každého veřejného PHP souboru:
* require_once __DIR__ . '/maintenance.php';
*
* Admin rozhraní (/admin/) tento soubor neincluduje vůbec.
*/
// Pokud je soubor includován z admin složky, nic nedělej
if (defined('GPS_ADMIN_CONTEXT')) return;
// DB připojení (pokud ještě neexistuje)
if (!isset($pdo)) {
require_once __DIR__ . '/config.php';
}
// Načti nastavení maintenance modu z DB
try {
$stmt = $pdo->query("
SELECT klic, hodnota FROM nastaveni
WHERE klic IN ('maintenance_mode','maintenance_heslo','maintenance_zprava')
");
$settings = [];
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
$settings[$row['klic']] = $row['hodnota'];
}
} catch (Exception $e) {
// Pokud DB selže, nezablokuj přístup
return;
}
// Je maintenance mode vypnutý?
if (empty($settings['maintenance_mode']) || $settings['maintenance_mode'] === '0') {
return;
}
// Je uživatel přihlášen jako admin/majitel? → propusť
session_start();
if (!empty($_SESSION['uzivatel_id']) && !empty($_SESSION['role'])
&& in_array($_SESSION['role'], ['admin', 'majitel'])) {
return;
}
// Má uživatel platnou maintenance cookie?
$cookie_name = 'gps_maintenance_access';
if (!empty($_COOKIE[$cookie_name])) {
$stored_hash = $settings['maintenance_heslo'] ?? '';
if ($stored_hash && password_verify($_COOKIE[$cookie_name] . '_verified', $stored_hash . '_verified')) {
// Cookie odpovídá — propusť (porovnáváme token, ne heslo přímo)
return;
}
// Neplatná cookie — smažeme ji
setcookie($cookie_name, '', time() - 3600, '/', '', false, true);
}
// Zpracování odeslaného hesla
$chyba = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['maintenance_heslo'])) {
$zadane = trim($_POST['maintenance_heslo']);
$ulozeny = $settings['maintenance_heslo'] ?? '';
if ($ulozeny && password_verify($zadane, $ulozeny)) {
// Správné heslo — nastav cookie na 24 hodin
$token = base64_encode($zadane . '_verified');
setcookie($cookie_name, $token, time() + 86400, '/', '', false, true);
// Přesměruj na aktuální URL (GET)
header('Location: ' . $_SERVER['REQUEST_URI']);
exit;
} else {
$chyba = 'Nesprávné heslo. Zkuste to prosím znovu.';
}
}
// Zobraz maintenance stránku
$zprava = htmlspecialchars($settings['maintenance_zprava'] ?? 'Stránky jsou dočasně nedostupné.');
$rok = date('Y');
http_response_code(503);
header('Retry-After: 3600');
?>
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow">
<title>Stránky v rekonstrukci</title>
<style>
:root {
--nav: #1E3A5F;
--accent: #3B82F6;
--bg: #F8FAFC;
--card: #FFFFFF;
--text1: #0F172A;
--text2: #64748B;
--border: #E2E8F0;
--danger: #EF4444;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg);
color: var(--text1);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 1.5rem;
}
/* Animovaný background */
body::before {
content: '';
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 80% 60% at 20% 20%, rgba(59,130,246,.06) 0%, transparent 70%),
radial-gradient(ellipse 60% 80% at 80% 80%, rgba(30,58,95,.07) 0%, transparent 70%);
pointer-events: none;
z-index: 0;
}
.card {
position: relative;
z-index: 1;
background: var(--card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2.5rem 2rem;
max-width: 440px;
width: 100%;
text-align: center;
}
/* Logo / ikona */
.icon-wrap {
width: 64px;
height: 64px;
background: var(--nav);
border-radius: 14px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1.5rem;
}
.icon-wrap svg {
width: 32px;
height: 32px;
fill: none;
stroke: #7DD3FC;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
/* Blikající tečka — "pracujeme na tom" */
.status-dot {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--text2);
margin-bottom: 1rem;
}
.dot {
width: 8px;
height: 8px;
background: #F59E0B;
border-radius: 50%;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: .5; transform: scale(.8); }
}
h1 { font-size: 22px; font-weight: 600; margin-bottom: .5rem; }
.zprava { font-size: 15px; color: var(--text2); line-height: 1.6; margin-bottom: 2rem; }
/* Oddělovač */
.divider {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 1.5rem;
}
.divider::before, .divider::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.divider span { font-size: 12px; color: var(--text2); white-space: nowrap; }
/* Formulář */
.form-group { text-align: left; margin-bottom: 1rem; }
label { display: block; font-size: 13px; font-weight: 500; color: var(--text2); margin-bottom: 5px; }
input[type="password"] {
width: 100%;
padding: 11px 14px;
border: 1.5px solid var(--border);
border-radius: 8px;
font-size: 15px;
background: var(--bg);
color: var(--text1);
transition: border-color .15s;
-webkit-appearance: none;
}
input[type="password"]:focus {
outline: none;
border-color: var(--accent);
}
input[type="password"].chyba { border-color: var(--danger); }
.chyba-text {
font-size: 12px;
color: var(--danger);
margin-top: 5px;
display: flex;
align-items: center;
gap: 4px;
}
button[type="submit"] {
width: 100%;
padding: 12px;
background: var(--nav);
color: #fff;
border: none;
border-radius: 8px;
font-size: 15px;
font-weight: 500;
cursor: pointer;
transition: opacity .15s, transform .1s;
}
button[type="submit"]:active { transform: scale(.98); opacity: .9; }
.footer {
position: relative;
z-index: 1;
margin-top: 1.5rem;
font-size: 12px;
color: var(--text2);
}
.footer a { color: var(--text2); text-decoration: none; }
</style>
</head>
<body>
<div class="card">
<div class="icon-wrap">
<!-- GPS pin ikona -->
<svg viewBox="0 0 24 24">
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/>
<circle cx="12" cy="9" r="2.5"/>
</svg>
</div>
<div class="status-dot">
<div class="dot"></div>
Pracujeme na vylepšeních
</div>
<h1>Stránky v rekonstrukci</h1>
<p class="zprava"><?= $zprava ?></p>
<div class="divider">
<span>Máte přístupové heslo?</span>
</div>
<form method="POST" action="" novalidate>
<div class="form-group">
<label for="maintenance_heslo">Přístupové heslo</label>
<input
type="password"
id="maintenance_heslo"
name="maintenance_heslo"
placeholder="Zadejte heslo pro přístup"
autocomplete="current-password"
<?= $chyba ? 'class="chyba"' : '' ?>
autofocus
>
<?php if ($chyba): ?>
<div class="chyba-text">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
<?= htmlspecialchars($chyba) ?>
</div>
<?php endif; ?>
</div>
<button type="submit">Vstoupit →</button>
</form>
</div>
<div class="footer">
© <?= $rok ?> GPS Instalace ·
<a href="/admin.html">Administrace</a>
</div>
</body>
</html>
<?php
exit;