![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/.cursor-server/data/User/History/21d84519/ |
<?php
/**
* The Commons - Social Connection & Dialogue
*/
require_once dirname(__DIR__) . '/private_html/config.php';
require_once __DIR__ . '/includes/auth.php';
$lang = $_GET['lang'] ?? (isset($_COOKIE['lang']) ? $_COOKIE['lang'] : 'en');
if (!in_array($lang, ['en', 'fr'])) $lang = 'en';
setcookie('lang', $lang, time() + (86400 * 365), '/');
$currentUser = getCurrentUser();
$db = getDBConnection();
// Handle post creation
$error = '';
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_post']) && isLoggedIn()) {
$content = trim($_POST['content'] ?? '');
$village_id = !empty($_POST['village_id']) ? (int)$_POST['village_id'] : null;
$visibility = $_POST['visibility'] ?? 'public';
if (empty($content)) {
$error = $lang === 'fr' ? 'Le contenu ne peut pas être vide' : 'Content cannot be empty';
} else {
$stmt = $db->prepare("
INSERT INTO posts (user_id, village_id, content, visibility, language)
VALUES (?, ?, ?, ?, ?)
");
$stmt->execute([$currentUser['id'], $village_id, $content, $visibility, $lang]);
$success = $lang === 'fr' ? 'Publication créée avec succès!' : 'Post created successfully!';
}
}
// Get posts
$village_filter = isset($_GET['village']) ? (int)$_GET['village'] : null;
$page = max(1, (int)($_GET['page'] ?? 1));
$per_page = 20;
$offset = ($page - 1) * $per_page;
$sql = "SELECT p.*, u.username, u.display_name, u.avatar_url, v.name as village_name, v.slug as village_slug,
(SELECT COUNT(*) FROM reactions WHERE target_type = 'post' AND target_id = p.id) as reaction_count,
(SELECT COUNT(*) FROM comments WHERE post_id = p.id AND deleted_at IS NULL) as comment_count
FROM posts p
JOIN users u ON p.user_id = u.id
LEFT JOIN villages v ON p.village_id = v.id
WHERE p.deleted_at IS NULL AND p.visibility = 'public'";
$params = [];
if ($village_filter) {
$sql .= " AND p.village_id = ?";
$params[] = $village_filter;
}
$sql .= " ORDER BY p.is_pinned DESC, p.created_at DESC LIMIT ? OFFSET ?";
$params[] = $per_page;
$params[] = $offset;
$stmt = $db->prepare($sql);
$stmt->execute($params);
$posts = $stmt->fetchAll();
// Get total count
$countSql = "SELECT COUNT(*) as total FROM posts WHERE deleted_at IS NULL AND visibility = 'public'";
if ($village_filter) {
$countSql .= " AND village_id = ?";
}
$countStmt = $db->prepare($countSql);
$countStmt->execute($village_filter ? [$village_filter] : []);
$total_posts = $countStmt->fetch()['total'];
$total_pages = ceil($total_posts / $per_page);
// Get user's villages for posting
$user_villages = [];
if (isLoggedIn()) {
$villageStmt = $db->prepare("
SELECT v.* FROM villages v
JOIN village_members vm ON v.id = vm.village_id
WHERE vm.user_id = ? AND v.status = 'active'
");
$villageStmt->execute([$currentUser['id']]);
$user_villages = $villageStmt->fetchAll();
}
// Get upcoming events
$eventsStmt = $db->prepare("
SELECT e.*, u.username, u.display_name, v.name as village_name,
(SELECT COUNT(*) FROM event_attendees WHERE event_id = e.id AND status = 'attending') as attendee_count
FROM events e
JOIN users u ON e.user_id = u.id
LEFT JOIN villages v ON e.village_id = v.id
WHERE e.is_public = 1 AND e.start_date >= NOW()
ORDER BY e.start_date ASC
LIMIT 10
");
$eventsStmt->execute();
$events = $eventsStmt->fetchAll();
$translations = [
'en' => [
'title' => 'The Commons',
'subtitle' => 'Social Connection & Dialogue',
'description' => 'A bilingual network of feeds, events, and stories',
'create_post' => 'Create Post',
'post_content' => 'What\'s on your mind?',
'post_btn' => 'Post',
'select_village' => 'Select Village (optional)',
'visibility' => 'Visibility',
'public' => 'Public',
'village' => 'Village Only',
'members' => 'Members Only',
'recent_posts' => 'Recent Posts',
'upcoming_events' => 'Upcoming Events',
'no_posts' => 'No posts yet. Be the first to share!',
'no_events' => 'No upcoming events.',
'comments' => 'Comments',
'reactions' => 'Reactions',
'view_post' => 'View Post',
'login_to_post' => 'Login to create posts',
'next' => 'Next',
'prev' => 'Previous',
],
'fr' => [
'title' => 'Les Communs',
'subtitle' => 'Connexion Sociale & Dialogue',
'description' => 'Un réseau bilingue de fils d\'actualité, d\'événements et d\'histoires',
'create_post' => 'Créer une Publication',
'post_content' => 'Qu\'avez-vous en tête?',
'post_btn' => 'Publier',
'select_village' => 'Sélectionner un Village (optionnel)',
'visibility' => 'Visibilité',
'public' => 'Public',
'village' => 'Village Seulement',
'members' => 'Membres Seulement',
'recent_posts' => 'Publications Récentes',
'upcoming_events' => 'Événements à Venir',
'no_posts' => 'Aucune publication pour le moment. Soyez le premier à partager!',
'no_events' => 'Aucun événement à venir.',
'comments' => 'Commentaires',
'reactions' => 'Réactions',
'view_post' => 'Voir la Publication',
'login_to_post' => 'Connectez-vous pour créer des publications',
'next' => 'Suivant',
'prev' => 'Précédent',
]
];
$t = $translations[$lang];
?>
<!DOCTYPE html>
<html lang="<?= $lang ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($t['title']) ?> - Free Village Network</title>
<link rel="stylesheet" href="/assets/css/main.css">
</head>
<body>
<nav class="navbar">
<div class="container">
<div class="nav-brand">
<a href="/">🌐 Free Village Network</a>
</div>
<div class="nav-links">
<a href="/commons" class="active"><?= htmlspecialchars($t['title']) ?></a>
<a href="/ledger">The Ledger</a>
<a href="/land">The Land</a>
<a href="/">Home</a>
</div>
</div>
</nav>
<section class="hero" style="min-height: 60vh; padding-top: 100px;">
<div class="container">
<div class="hero-content">
<h1 class="hero-title"><?= htmlspecialchars($t['title']) ?></h1>
<p class="hero-subtitle"><?= htmlspecialchars($t['subtitle']) ?></p>
<p class="hero-tagline"><?= htmlspecialchars($t['description']) ?></p>
</div>
</div>
</section>
<section class="activity">
<div class="container">
<p style="text-align: center; color: var(--color-text-secondary); padding: 4rem 0;">
The Commons interface is coming soon. This will be the social feed where members share posts, stories, and events.
</p>
</div>
</section>
<footer class="footer">
<div class="container">
<p style="text-align: center; color: var(--color-text-secondary);">© <?= date('Y') ?> The Free Village Network</p>
</div>
</footer>
</body>
</html>