true, 'cookie_secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'), 'use_strict_mode' => true, 'use_only_cookies' => true, 'cookie_samesite' => 'Strict' ]); ini_set('upload_max_filesize', '2G'); ini_set('post_max_size', '2G'); ini_set('memory_limit', '2G'); ini_set('max_execution_time', 0); error_reporting(E_ALL); ini_set('display_errors', 0); // set to 1 for debugging // Helper: get base URL dynamically function baseUrl() { $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST']; $script = $_SERVER['SCRIPT_NAME']; $dir = dirname($script); if ($dir == '\\' || $dir == '/') $dir = ''; return $protocol . $host . $dir; } $dbPath = __DIR__ . '/db.sqlite'; $db = new SQLite3($dbPath); $db->busyTimeout(30000); $db->exec("PRAGMA journal_mode=WAL"); $db->exec("PRAGMA synchronous=NORMAL"); // Create tables if not exist $db->exec("CREATE TABLE IF NOT EXISTS content ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT CHECK(type IN ('image','video','article')), title TEXT, description TEXT, content TEXT, filename TEXT, file_path TEXT, thumbnail TEXT, latitude REAL, longitude REAL, location_name TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, ip_address TEXT, fingerprint TEXT )"); $db->exec("CREATE INDEX IF NOT EXISTS idx_content_created ON content(created_at DESC)"); $db->exec("CREATE INDEX IF NOT EXISTS idx_content_type ON content(type)"); $db->exec("CREATE INDEX IF NOT EXISTS idx_content_location ON content(latitude, longitude) WHERE latitude IS NOT NULL AND longitude IS NOT NULL"); $db->exec("CREATE INDEX IF NOT EXISTS idx_content_search ON content(title, description, content)"); $db->exec("PRAGMA optimize"); // Ensure upload directories exist foreach (['uploads', 'uploads/images', 'uploads/videos', 'uploads/videos/thumbnails', 'uploads/chunks'] as $dir) { if (!is_dir(__DIR__ . '/' . $dir)) mkdir(__DIR__ . '/' . $dir, 0755, true); } // ------------------------------------------------------------------ if (!function_exists('haversineDistance')) { function haversineDistance($lat1, $lon1, $lat2, $lon2) { $earthRadiusKm = 6371; $dLat = deg2rad($lat2 - $lat1); $dLon = deg2rad($lon2 - $lon1); $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2) * sin($dLon/2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); return $earthRadiusKm * $c; } } function combineChunks($chunkDir, $totalChunks, $finalTempPath) { $out = fopen($finalTempPath, 'wb'); if (!$out) return false; for ($i = 0; $i < $totalChunks; $i++) { $partPath = $chunkDir . '/part_' . $i; if (!file_exists($partPath)) { fclose($out); return false; } $part = fopen($partPath, 'rb'); while (!feof($part)) { fwrite($out, fread($part, 8192)); } fclose($part); } fclose($out); return true; } function cleanupOldChunks() { $chunkBase = __DIR__ . '/uploads/chunks/'; if (!is_dir($chunkBase)) return; $now = time(); foreach (glob($chunkBase . '*', GLOB_ONLYDIR) as $dir) { if ($now - filemtime($dir) > 3600) { array_map('unlink', glob($dir . '/*')); rmdir($dir); } } } if (mt_rand(1, 100) === 1) cleanupOldChunks(); function getCachedGeoPoints($db, $cacheFile = __DIR__ . '/uploads/.geopoints.cache') { $ttl = 300; if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $ttl)) { $data = file_get_contents($cacheFile); if ($data !== false) { $cached = unserialize($data); if (is_array($cached)) return $cached; } } $geoQuery = "SELECT id, title, latitude, longitude, location_name, created_at FROM content WHERE latitude IS NOT NULL AND longitude IS NOT NULL ORDER BY created_at ASC"; $geoResult = $db->query($geoQuery); $points = []; while ($row = $geoResult->fetchArray(SQLITE3_ASSOC)) { $points[] = [ 'id' => $row['id'], 'title' => $row['title'], 'lat' => (float)$row['latitude'], 'lng' => (float)$row['longitude'], 'location_name' => $row['location_name'], 'created_at' => $row['created_at'] ]; } file_put_contents($cacheFile, serialize($points), LOCK_EX); return $points; } function invalidateGeoCache() { $cacheFile = __DIR__ . '/uploads/.geopoints.cache'; if (file_exists($cacheFile)) @unlink($cacheFile); } // Generate a filename and title from location and time function generateMediaTitleAndFilename($location_name, $timestamp = null) { if ($timestamp === null) $timestamp = time(); $dateTitle = date('n/j/Y, g:i:s A', $timestamp); $title = '@' . $dateTitle; if (!empty($location_name)) { $title .= ' - ' . $location_name; } $dateFile = date('m-d-Y_H-i-s', $timestamp); $filename = '@' . $dateFile; if (!empty($location_name)) { $slug = preg_replace('/[^a-z0-9]+/i', '_', trim($location_name)); $slug = trim($slug, '_'); if ($slug !== '') $filename .= '_' . $slug; } return ['title' => $title, 'filename' => $filename . '.jpg']; } // ------------------------------------------------------------------ // Handle POST requests (image, video chunked, article) if ($_SERVER['REQUEST_METHOD'] === 'POST') { $fingerprint = $_POST['fingerprint'] ?? session_id(); $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; // --- ARTICLE CREATION --- if (isset($_POST['article_title']) && isset($_POST['article_content'])) { $title = trim($_POST['article_title']); $content = trim($_POST['article_content']); $description = $_POST['article_description'] ?? ''; if ($title !== '' && $content !== '') { $stmt = $db->prepare("INSERT INTO content (type, title, description, content, ip_address, fingerprint) VALUES ('article', :title, :desc, :content, :ip, :fp)"); $stmt->bindValue(':title', $title); $stmt->bindValue(':desc', $description); $stmt->bindValue(':content', $content); $stmt->bindValue(':ip', $ip); $stmt->bindValue(':fp', $fingerprint); $stmt->execute(); header('Content-Type: application/json'); echo json_encode(['success' => true, 'post_id' => $db->lastInsertRowID()]); } else { http_response_code(400); echo json_encode(['error' => 'Title and content required']); } exit; } // --- IMAGE OR VIDEO UPLOAD --- if (!isset($_FILES['media'])) { http_response_code(400); echo json_encode(['error' => 'No file uploaded']); exit; } $title = $_POST['title'] ?? ''; $description = $_POST['description'] ?? ''; $latitude = isset($_POST['latitude']) && $_POST['latitude'] !== '' ? floatval($_POST['latitude']) : null; $longitude = isset($_POST['longitude']) && $_POST['longitude'] !== '' ? floatval($_POST['longitude']) : null; $location_name = $_POST['location_name'] ?? ''; $type = $_POST['type'] ?? ''; $isChunked = isset($_POST['chunk_index']) && isset($_POST['upload_id']) && isset($_POST['chunk_total']); // --- CHUNKED VIDEO UPLOAD --- if ($isChunked) { $chunkIndex = intval($_POST['chunk_index']); $chunkTotal = intval($_POST['chunk_total']); $uploadId = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['upload_id']); if (empty($uploadId) || $chunkTotal <= 0 || $chunkIndex < 0 || $chunkIndex >= $chunkTotal) { http_response_code(400); echo json_encode(['error' => 'Invalid chunk parameters']); exit; } $chunkBaseDir = __DIR__ . '/uploads/chunks/' . $uploadId; if (!is_dir($chunkBaseDir)) mkdir($chunkBaseDir, 0755, true); $chunkPath = $chunkBaseDir . '/part_' . $chunkIndex; if (!move_uploaded_file($_FILES['media']['tmp_name'], $chunkPath)) { http_response_code(500); echo json_encode(['error' => 'Failed to save chunk']); exit; } // Store metadata on first chunk if ($chunkIndex === 0) { $meta = [ 'title' => $title, 'description' => $description, 'type' => $type, 'latitude' => $latitude, 'longitude' => $longitude, 'location_name' => $location_name, 'fingerprint' => $fingerprint, 'ip' => $ip ]; file_put_contents($chunkBaseDir . '/meta.json', json_encode($meta)); } // On last chunk, reassemble and save if ($chunkIndex === $chunkTotal - 1) { $metaFile = $chunkBaseDir . '/meta.json'; if (!file_exists($metaFile)) { http_response_code(400); echo json_encode(['error' => 'Metadata missing']); exit; } $meta = json_decode(file_get_contents($metaFile), true); if (!$meta) { http_response_code(400); echo json_encode(['error' => 'Invalid metadata']); exit; } $title = $meta['title']; $description = $meta['description']; $latitude = $meta['latitude']; $longitude = $meta['longitude']; $location_name = $meta['location_name']; $fingerprint = $meta['fingerprint']; $ip = $meta['ip']; $tempFinal = $chunkBaseDir . '/final_temp'; if (!combineChunks($chunkBaseDir, $chunkTotal, $tempFinal)) { http_response_code(500); echo json_encode(['error' => 'Failed to combine chunks']); exit; } $upload_dir = __DIR__ . '/uploads/videos/'; $web_path = '/uploads/videos/'; $filename = uniqid('video_') . '.mp4'; $finalPath = $upload_dir . $filename; rename($tempFinal, $finalPath); $file_path = $web_path . $filename; // Generate thumbnail if ffmpeg available $thumbnail = null; if (function_exists('exec')) { $thumb_dir = __DIR__ . '/uploads/videos/thumbnails/'; if (!is_dir($thumb_dir)) mkdir($thumb_dir, 0755, true); $thumb_filename = uniqid() . '.jpg'; $thumbnail = '/uploads/videos/thumbnails/' . $thumb_filename; $cmd = "ffmpeg -i " . escapeshellarg($finalPath) . " -ss 00:00:01 -vframes 1 -vf scale=320:-1 " . escapeshellarg($thumb_dir . $thumb_filename) . " > /dev/null 2>&1 &"; exec($cmd); } $stmt = $db->prepare("INSERT INTO content (type, title, description, filename, file_path, thumbnail, latitude, longitude, location_name, ip_address, fingerprint) VALUES ('video', :title, :desc, :filename, :file_path, :thumb, :lat, :lng, :loc, :ip, :fp)"); $stmt->bindValue(':title', $title); $stmt->bindValue(':desc', $description); $stmt->bindValue(':filename', $filename); $stmt->bindValue(':file_path', $file_path); $stmt->bindValue(':thumb', $thumbnail); $stmt->bindValue(':lat', $latitude); $stmt->bindValue(':lng', $longitude); $stmt->bindValue(':loc', $location_name); $stmt->bindValue(':ip', $ip); $stmt->bindValue(':fp', $fingerprint); $stmt->execute(); if ($latitude && $longitude) invalidateGeoCache(); // Cleanup array_map('unlink', glob($chunkBaseDir . '/*')); rmdir($chunkBaseDir); header('Content-Type: application/json'); echo json_encode(['success' => true, 'post_id' => $db->lastInsertRowID()]); exit; } else { header('Content-Type: application/json'); echo json_encode(['success' => true, 'chunk' => $chunkIndex, 'total' => $chunkTotal]); exit; } } // --- SINGLE IMAGE UPLOAD (non-chunked) --- if ($type !== 'image') { http_response_code(400); echo json_encode(['error' => 'Only image uploads supported without chunking']); exit; } if ($_FILES['media']['error'] !== UPLOAD_ERR_OK) { http_response_code(400); echo json_encode(['error' => 'Upload failed']); exit; } $upload_dir = __DIR__ . '/uploads/images/'; $web_path = '/uploads/images/'; $serverTime = time(); $titleData = generateMediaTitleAndFilename($location_name, $serverTime); $title = $titleData['title']; $filename = $titleData['filename']; $finalPath = $upload_dir . $filename; $counter = 1; $originalFilename = $filename; while (file_exists($finalPath)) { $info = pathinfo($originalFilename); $filename = $info['filename'] . '_' . $counter . '.jpg'; $finalPath = $upload_dir . $filename; $counter++; } if (!move_uploaded_file($_FILES['media']['tmp_name'], $finalPath)) { http_response_code(500); echo json_encode(['error' => 'Failed to save image']); exit; } $file_path = $web_path . $filename; $stmt = $db->prepare("INSERT INTO content (type, title, description, filename, file_path, latitude, longitude, location_name, ip_address, fingerprint) VALUES ('image', :title, :desc, :filename, :file_path, :lat, :lng, :loc, :ip, :fp)"); $stmt->bindValue(':title', $title); $stmt->bindValue(':desc', $description); $stmt->bindValue(':filename', $filename); $stmt->bindValue(':file_path', $file_path); $stmt->bindValue(':lat', $latitude); $stmt->bindValue(':lng', $longitude); $stmt->bindValue(':loc', $location_name); $stmt->bindValue(':ip', $ip); $stmt->bindValue(':fp', $fingerprint); $stmt->execute(); if ($latitude && $longitude) invalidateGeoCache(); header('Content-Type: application/json'); echo json_encode(['success' => true, 'post_id' => $db->lastInsertRowID()]); exit; } // ------------------------------------------------------------------ // Handle article view (GET parameter article=ID) if (isset($_GET['article']) && is_numeric($_GET['article'])) { $articleId = intval($_GET['article']); $stmt = $db->prepare("SELECT * FROM content WHERE id = :id AND type = 'article'"); $stmt->bindValue(':id', $articleId, SQLITE3_INTEGER); $result = $stmt->execute(); $article = $result->fetchArray(SQLITE3_ASSOC); if (!$article) { header('Location: ' . baseUrl() . '/'); exit; } $geoPoints = getCachedGeoPoints($db); $totalDistanceKm = 0; $totalDistanceMiles = 0; if (count($geoPoints) >= 2) { for ($i = 0; $i < count($geoPoints) - 1; $i++) { $distKm = haversineDistance( $geoPoints[$i]['lat'], $geoPoints[$i]['lng'], $geoPoints[$i+1]['lat'], $geoPoints[$i+1]['lng'] ); $totalDistanceKm += $distKm; } $totalDistanceMiles = $totalDistanceKm * 0.621371; } ?> Fiveo1 - <?php echo htmlspecialchars($article['title']); ?>

← Back to feed
= 1): ?>
prepare($countSql); foreach ($params as $key => $val) $countStmt->bindValue($key, $val); $total = $countStmt->execute()->fetchArray(SQLITE3_ASSOC)['total']; $totalPages = ceil($total / $limit); $sql = "SELECT * FROM content WHERE 1=1"; if (!empty($search)) $sql .= " AND (title LIKE :search OR description LIKE :search OR content LIKE :search)"; if ($type !== 'all') $sql .= " AND type = :type"; $sql .= " ORDER BY created_at DESC LIMIT $limit OFFSET $offset"; $stmt = $db->prepare($sql); foreach ($params as $key => $val) $stmt->bindValue($key, $val); $result = $stmt->execute(); $contents = []; while ($row = $result->fetchArray(SQLITE3_ASSOC)) $contents[] = $row; $geoPoints = getCachedGeoPoints($db); $totalDistanceKm = 0; $totalDistanceMiles = 0; if (count($geoPoints) >= 2) { for ($i = 0; $i < count($geoPoints) - 1; $i++) { $distKm = haversineDistance( $geoPoints[$i]['lat'], $geoPoints[$i]['lng'], $geoPoints[$i+1]['lat'], $geoPoints[$i+1]['lng'] ); $totalDistanceKm += $distKm; } $totalDistanceMiles = $totalDistanceKm * 0.621371; } // Generate a session-based fingerprint if (!isset($_SESSION['fp'])) { $_SESSION['fp'] = 'fp_' . bin2hex(random_bytes(16)); } $fingerprint = $_SESSION['fp']; ?> Fiveo1 Social

No content found.

1): ?>
🔴 Recording...