index.php

Colombo
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); $db = new SQLite3(__DIR__ . '/db.sqlite'); $db->busyTimeout(30000); $cols = $db->query("PRAGMA table_info(content)"); $existing = []; while ($c = $cols->fetchArray(SQLITE3_ASSOC)) $existing[] = $c['name']; foreach (['content', 'thumbnail', 'ip_address', 'fingerprint'] as $col) { if (!in_array($col, $existing)) $db->exec("ALTER TABLE content ADD COLUMN $col TEXT"); } 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; } // ------------------------------------------------------------------ // HANDLE UPLOADS (single image from PHOTO, chunked video from GO LIVE) // ------------------------------------------------------------------ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['media'])) { $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'] ?? ''; $fingerprint = $_POST['fingerprint'] ?? ''; $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $type = $_POST['type'] ?? ''; $isChunked = isset($_POST['chunk_index']) && isset($_POST['upload_id']) && isset($_POST['chunk_total']); 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; } 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)); } 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']; $type = $meta['type']; $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 = ''; $web_path = ''; $thumbnail = null; $filename = ''; if ($type === 'video') { $upload_dir = __DIR__ . '/uploads/videos/'; $web_path = '/uploads/videos/'; if (!is_dir($upload_dir)) mkdir($upload_dir, 0755, true); $ext = 'mp4'; $filename = uniqid('live_') . '.' . $ext; $finalPath = $upload_dir . $filename; rename($tempFinal, $finalPath); $file_path = $web_path . $filename; 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) . " 2>&1"; exec($cmd); } } else { http_response_code(400); echo json_encode(['error' => 'Invalid media type for chunked upload']); exit; } $stmt = $db->prepare("INSERT INTO content (type, title, description, filename, file_path, thumbnail, latitude, longitude, location_name, created_at, ip_address, fingerprint) VALUES (:type, :title, :description, :filename, :file_path, :thumbnail, :lat, :lng, :loc, datetime('now'), :ip, :fp)"); $stmt->bindValue(':type', $type); $stmt->bindValue(':title', $title); $stmt->bindValue(':description', $description); $stmt->bindValue(':filename', $filename); $stmt->bindValue(':file_path', $file_path); $stmt->bindValue(':thumbnail', $thumbnail); $stmt->bindValue(':lat', $latitude); $stmt->bindValue(':lng', $longitude); $stmt->bindValue(':loc', $location_name); $stmt->bindValue(':ip', $ip); $stmt->bindValue(':fp', $fingerprint); $stmt->execute(); 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; } } if ($_FILES['media']['error'] !== UPLOAD_ERR_OK) { http_response_code(400); exit('Upload failed'); } if ($type !== 'image') { http_response_code(400); exit('Invalid media type for single upload'); } $upload_dir = __DIR__ . '/uploads/images/'; $web_path = '/uploads/images/'; if (!is_dir($upload_dir)) mkdir($upload_dir, 0755, true); $ext = 'jpg'; $filename = uniqid('photo_') . '.' . $ext; $file_path = $web_path . $filename; move_uploaded_file($_FILES['media']['tmp_name'], $upload_dir . $filename); $stmt = $db->prepare("INSERT INTO content (type, title, description, filename, file_path, thumbnail, latitude, longitude, location_name, created_at, ip_address, fingerprint) VALUES (:type, :title, :description, :filename, :file_path, :thumbnail, :lat, :lng, :loc, datetime('now'), :ip, :fp)"); $stmt->bindValue(':type', $type); $stmt->bindValue(':title', $title); $stmt->bindValue(':description', $description); $stmt->bindValue(':filename', $filename); $stmt->bindValue(':file_path', $file_path); $stmt->bindValue(':thumbnail', null); $stmt->bindValue(':lat', $latitude); $stmt->bindValue(':lng', $longitude); $stmt->bindValue(':loc', $location_name); $stmt->bindValue(':ip', $ip); $stmt->bindValue(':fp', $fingerprint); $stmt->execute(); header('Content-Type: application/json'); echo json_encode(['success' => true, 'post_id' => $db->lastInsertRowID()]); exit; } // ------------------------------------------------------------------ // MAIN FEED WITH PAGINATION // ------------------------------------------------------------------ $search = isset($_GET['q']) ? trim($_GET['q']) : ''; $type = isset($_GET['type']) ? $_GET['type'] : 'all'; $page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1; $limit = 60; $offset = ($page - 1) * $limit; // Count total matching records $countSql = "SELECT COUNT(*) as total FROM content WHERE 1=1"; $params = []; if (!empty($search)) { $countSql .= " AND (title LIKE :search OR description LIKE :search OR content LIKE :search)"; $params[':search'] = "%$search%"; } if ($type !== 'all') { $countSql .= " AND type = :type"; $params[':type'] = $type; } $countStmt = $db->prepare($countSql); foreach ($params as $key => $val) $countStmt->bindValue($key, $val); $total = $countStmt->execute()->fetchArray(SQLITE3_ASSOC)['total']; $totalPages = ceil($total / $limit); // Fetch current page $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; // ------------------------------------------------------------------ // FOOTER MAP & JOURNEY STATS (standalone) // ------------------------------------------------------------------ $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); $geoPoints = []; $totalDistanceKm = 0; $totalDistanceMiles = 0; while ($row = $geoResult->fetchArray(SQLITE3_ASSOC)) { $geoPoints[] = [ 'id' => $row['id'], 'title' => $row['title'], 'lat' => (float)$row['latitude'], 'lng' => (float)$row['longitude'], 'location_name' => $row['location_name'], 'created_at' => $row['created_at'] ]; } 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; } 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 · Evan Winter = 1): ?>

No content found.

<?php echo htmlspecialchars($item['title']); ?>
180) ? '...' : ''; ?>
📍
1): ?>
Recording...
= 1): ?>
← Back to Fiveo1
▼
▲