]*>.*?<\s*\/\s*\1\s*>/is', '', $value) ?? $value; $value = strip_tags($value); $value = str_replace(["\r\n", "\r"], "\n", $value); $value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $value) ?? ''; $value = preg_replace('/[ \t]+/u', ' ', $value) ?? $value; $value = preg_replace("/\n{3,}/", "\n\n", $value) ?? $value; $value = trim($value); if (strlen($value) > $maxLength) { $value = substr($value, 0, $maxLength); } return $value; } function visitor_ideas_recently_submitted(int $seconds = 45): bool { if (!visitor_ideas_ensure_dir()) { return true; } $file = visitor_ideas_rate_file(); $key = hash('sha256', $_SERVER['REMOTE_ADDR'] ?? 'unknown'); $now = time(); $handle = fopen($file, 'c+'); if (!$handle) { return true; } flock($handle, LOCK_EX); $raw = stream_get_contents($handle); $rates = json_decode($raw ?: '{}', true); if (!is_array($rates)) { $rates = []; } foreach ($rates as $rateKey => $timestamp) { if (!is_int($timestamp) && !ctype_digit((string) $timestamp)) { unset($rates[$rateKey]); continue; } if ($now - (int) $timestamp > 86400) { unset($rates[$rateKey]); } } $last = (int) ($rates[$key] ?? 0); $blocked = $now - $last < $seconds; if (!$blocked) { $rates[$key] = $now; rewind($handle); ftruncate($handle, 0); fwrite($handle, json_encode($rates, JSON_UNESCAPED_SLASHES)); } fflush($handle); flock($handle, LOCK_UN); fclose($handle); return $blocked; } function visitor_ideas_append(string $name, string $idea): bool { if (!visitor_ideas_ensure_dir()) { return false; } $entry = [ 'name' => $name !== '' ? $name : 'Anonymous visitor', 'idea' => $idea, 'created_at' => gmdate('c'), ]; return file_put_contents( visitor_ideas_file(), json_encode($entry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND | LOCK_EX ) !== false; } function visitor_ideas_read(int $limit = 6): array { $file = visitor_ideas_file(); if (!is_readable($file)) { return []; } $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines) { return []; } $ideas = []; foreach (array_reverse($lines) as $line) { $entry = json_decode($line, true); if (!is_array($entry) || !isset($entry['idea'], $entry['name'], $entry['created_at'])) { continue; } $ideas[] = [ 'name' => visitor_idea_clean((string) $entry['name'], 80), 'idea' => visitor_idea_clean((string) $entry['idea'], 600), 'created_at' => visitor_idea_clean((string) $entry['created_at'], 40), ]; if (count($ideas) >= $limit) { break; } } return $ideas; }