setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (\PDOException $e) { die("Błąd połączenia z bazą danych: " . $e->getMessage()); } // [ZABEZPIECZENIE CSRF] Generowanie tokenu jeśli nie istnieje if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } // 3. Obsługa dodawania nowego komentarza (Formularz POST) if ($_SERVER['REQUEST_METHOD'] === 'POST') { $autor = trim($_POST['username']); $tresc_komentarza = trim($_POST['comment']); // Pobranie danych z zabezpieczeń $user_csrf = $_POST['csrf_token'] ?? ''; $user_captcha = isset($_POST['captcha_answer']) ? (int)$_POST['captcha_answer'] : 0; $correct_captcha = isset($_SESSION['captcha_result']) ? (int)$_SESSION['captcha_result'] : -1; // Walidacja CSRF if (!hash_equals($_SESSION['csrf_token'], $user_csrf)) { $_SESSION['komunikat'] = '
Błąd walidacji formularza (CSRF). Spróbuj ponownie.
'; } // Walidacja CAPTCHA elseif ($user_captcha !== $correct_captcha) { $_SESSION['komunikat'] = 'Niepoprawny wynik działania matematycznego!
'; } // Standardowa walidacja pól formularza elseif (!empty($autor) && !empty($tresc_komentarza)) { $sql = "INSERT INTO komentarze (nazwa_uzytkownika, tresc) VALUES (:autor, :tresc)"; $stmt = $pdo->prepare($sql); try { $stmt->execute([ ':autor' => $autor, ':tresc' => $tresc_komentarza ]); $_SESSION['komunikat'] = 'Komentarz został dodany!
'; // Po sukcesie resetujemy token CSRF i CAPTCHA unset($_SESSION['csrf_token']); unset($_SESSION['captcha_result']); } catch (\PDOException $e) { $_SESSION['komunikat'] = 'Wystąpił błąd podczas zapisu: ' . $e->getMessage() . '
'; } } else { $_SESSION['komunikat'] = 'Wszystkie pola są wymagane!
'; } // Przekierowanie na tę samą stronę metodą GET header("Location: komentarze4.html"); exit(); } // 4. Odczytanie komunikatu z sesji (jeśli istnieje) i natychmiastowe usunięcie go $komunikat = ''; if (isset($_SESSION['komunikat'])) { $komunikat = $_SESSION['komunikat']; unset($_SESSION['komunikat']); } // [ZABEZPIECZENIE CAPTCHA] Losowanie nowego działania matematycznego do wyświetlenia $num1 = rand(1, 9); $num2 = rand(1, 9); $_SESSION['captcha_result'] = $num1 + $num2; // [WYSZUKIWANIE] Pobranie frazy szukanej z adresu URL $search = isset($_GET['search']) ? trim($_GET['search']) : ''; // [PAGINACJA] Obliczanie parametrów stronicowania $limit = 10; $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; if ($page < 1) { $page = 1; } $offset = ($page - 1) * $limit; // [PAGINACJA & WYSZUKIWANIE] Pobranie łącznej liczby komentarzy (z uwzględnieniem filtra wyszukiwania) if ($search !== '') { $total_stmt = $pdo->prepare("SELECT COUNT(*) FROM komentarze WHERE tresc LIKE :search OR nazwa_uzytkownika LIKE :search"); $total_stmt->execute([':search' => '%' . $search . '%']); } else { $total_stmt = $pdo->query("SELECT COUNT(*) FROM komentarze"); } $total_komentarzy = $total_stmt->fetchColumn(); // [PAGINACJA] Obliczanie łącznej liczby stron $total_pages = ceil($total_komentarzy / $limit); // Zabezpieczenie przed wpisaniem zbyt dużego numeru strony w URL if ($page > $total_pages && $total_pages > 0) { $page = $total_pages; $offset = ($page - 1) * $limit; } // 5. Pobranie komentarzy z bazy z uwzględnieniem wyszukiwania, LIMIT i OFFSET if ($search !== '') { $stmt = $pdo->prepare("SELECT nazwa_uzytkownika, tresc, data_dodania FROM komentarze WHERE tresc LIKE :search OR nazwa_uzytkownika LIKE :search ORDER BY data_dodania ASC LIMIT :limit OFFSET :offset"); $stmt->bindValue(':search', '%' . $search . '%', PDO::PARAM_STR); } else { $stmt = $pdo->prepare("SELECT nazwa_uzytkownika, tresc, data_dodania FROM komentarze ORDER BY data_dodania ASC LIMIT :limit OFFSET :offset"); } $stmt->bindValue(':limit', $limit, PDO::PARAM_INT); $stmt->bindValue(':offset', $offset, PDO::PARAM_INT); $stmt->execute(); $lista_komentarzy = $stmt->fetchAll(PDO::FETCH_ASSOC); // Pomocniczy ciąg znaków do linków paginacji zachowujący filtr wyszukiwania $search_query = $search !== '' ? '&search=' . urlencode($search) : ''; ?>Brak komentarzy spełniających kryteria wyszukiwania.