prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
$startup_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$stmt = db()->prepare("SELECT * FROM startups WHERE id = ?");
$stmt->execute([$startup_id]);
$startup = $stmt->fetch();
if (!$startup) {
header('Location: startups.php');
exit;
}
// Check if current user is following
$stmt = db()->prepare("SELECT 1 FROM startup_followers WHERE startup_id = ? AND user_id = ?");
$stmt->execute([$startup_id, $user_id]);
$isFollowing = (bool)$stmt->fetchColumn();
// Check for active funding round
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? AND status = 'Active' LIMIT 1");
$stmt->execute([$startup_id]);
$activeRound = $stmt->fetch();
// Handle Actions
$error = '';
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
// Follow/Unfollow Actions (Available to all logged in users except the founder of this startup)
if ($action === 'follow' && $startup['founder_id'] != $user_id) {
$stmt = db()->prepare("INSERT IGNORE INTO startup_followers (startup_id, user_id) VALUES (?, ?)");
$stmt->execute([$startup_id, $user_id]);
$success = "You are now following " . $startup['name'] . "!";
$isFollowing = true;
} elseif ($action === 'unfollow' && $startup['founder_id'] != $user_id) {
$stmt = db()->prepare("DELETE FROM startup_followers WHERE startup_id = ? AND user_id = ?");
$stmt->execute([$startup_id, $user_id]);
$success = "You have unfollowed " . $startup['name'] . ".";
$isFollowing = false;
}
// Founder Actions
if ($user['role'] === 'founder' && $startup['founder_id'] == $user_id) {
$round_id = isset($_POST['round_id']) ? (int)$_POST['round_id'] : 0;
if ($action === 'finish_round' && $activeRound && $activeRound['id'] == $round_id) {
$stmt = db()->prepare("UPDATE funding_rounds SET status = 'Closed' WHERE id = ?");
$stmt->execute([$round_id]);
$success = "Funding round finished early. No new investments allowed.";
$activeRound = null; // Refresh for UI
} elseif ($action === 'cancel_round' && $activeRound && $activeRound['id'] == $round_id) {
db()->beginTransaction();
try {
// 1. Cancel round
$stmt = db()->prepare("UPDATE funding_rounds SET status = 'Cancelled' WHERE id = ?");
$stmt->execute([$round_id]);
// 2. Refund all investors for this round
$stmt = db()->prepare("SELECT * FROM investments WHERE funding_round_id = ? AND status = 'approved'");
$stmt->execute([$round_id]);
$investmentsToRefund = $stmt->fetchAll();
foreach ($investmentsToRefund as $inv) {
// Mark investment as refunded
$upd = db()->prepare("UPDATE investments SET status = 'Refunded' WHERE id = ?");
$upd->execute([$inv['id']]);
// Notify investor
$notif = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$notif->execute([$inv['investor_id'], "The funding round for " . $startup['name'] . " has been cancelled. Your investment of £" . number_format($inv['amount']) . " has been refunded."]);
}
db()->commit();
$success = "Funding round cancelled and investors refunded.";
$activeRound = null; // Refresh for UI
} catch (Exception $e) {
db()->rollBack();
$error = "Cancellation failed: " . $e->getMessage();
}
} elseif ($action === 'start_new_round') {
$newTarget = (float)($_POST['new_target'] ?? 0);
if ($newTarget < 50) {
$error = "Minimum target for a new round is £50.";
} elseif ($activeRound) {
$error = "An active round already exists.";
} else {
$stmt = db()->prepare("INSERT INTO funding_rounds (startup_id, funding_goal, status) VALUES (?, ?, 'Active')");
$stmt->execute([$startup_id, $newTarget]);
$success = "New funding round launched!";
// Refresh active round
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? AND status = 'Active' LIMIT 1");
$stmt->execute([$startup_id]);
$activeRound = $stmt->fetch();
}
} elseif ($action === 'post_update') {
$title = trim($_POST['update_title'] ?? '');
$content = trim($_POST['update_content'] ?? '');
if (empty($title) || empty($content)) {
$error = "Update title and content are required.";
} else {
db()->beginTransaction();
try {
// 1. Insert Update
$stmt = db()->prepare("INSERT INTO startup_updates (startup_id, founder_id, title, content) VALUES (?, ?, ?, ?)");
$stmt->execute([$startup_id, $user_id, $title, $content]);
// 2. Identify All Unique Investors AND Followers for this startup
$stmt = db()->prepare("
SELECT DISTINCT u.id, u.email, u.full_name
FROM users u
LEFT JOIN investments i ON i.investor_id = u.id AND i.startup_id = ? AND i.status = 'approved'
LEFT JOIN startup_followers f ON f.user_id = u.id AND f.startup_id = ?
WHERE i.investor_id IS NOT NULL OR f.user_id IS NOT NULL
");
$stmt->execute([$startup_id, $startup_id]);
$peopleToNotify = $stmt->fetchAll();
// 3. Notify them
foreach ($peopleToNotify as $targetUser) {
// DB Notification
$notif = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$notif->execute([$targetUser['id'], "New progress update from " . $startup['name'] . ": " . $title]);
// Email Notification
$subject = "New Update: " . $startup['name'];
$emailHtml = "
New Update: " . htmlspecialchars($title) . "
Hi " . htmlspecialchars($targetUser['full_name']) . ", " . htmlspecialchars($startup['name']) . " has posted a new progress update:
" . nl2br(htmlspecialchars($content)) . "
";
$emailText = "New Update: " . $title . "\n\nHi " . $targetUser['full_name'] . ", " . $startup['name'] . " has posted a new progress update: " . $content;
MailService::sendMail($targetUser['email'], $subject, $emailHtml, $emailText);
}
db()->commit();
$success = "Update posted and " . count($peopleToNotify) . " backers/followers notified.";
} catch (Exception $e) {
db()->rollBack();
$error = "Failed to post update: " . $e->getMessage();
}
}
}
}
// Investor Actions
if ($action === 'invest') {
if ($user['role'] !== 'investor') {
$error = "Founders cannot make investments.";
} elseif (!$activeRound) {
$error = "There is no active funding round for this startup.";
} else {
$amount = (float)($_POST['amount'] ?? 0);
if ($amount < 50) {
$error = "Minimum investment is £50.";
} else {
db()->beginTransaction();
try {
// Use funding_round_id for the investment
$stmt = db()->prepare("INSERT INTO investments (investor_id, startup_id, funding_round_id, amount, status) VALUES (?, ?, ?, ?, 'approved')");
$stmt->execute([$_SESSION['user_id'], $startup_id, $activeRound['id'], $amount]);
// Update funding_raised in funding_rounds (the dedicated pot)
$stmt = db()->prepare("UPDATE funding_rounds SET funding_raised = funding_raised + ? WHERE id = ?");
$stmt->execute([$amount, $activeRound['id']]);
// Update legacy field for backward compatibility in listing pages if needed
$stmt = db()->prepare("UPDATE startups SET funding_raised = funding_raised + ? WHERE id = ?");
$stmt->execute([$amount, $startup_id]);
$stmt = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$stmt->execute([$startup['founder_id'], "New investment of £" . number_format($amount) . " in " . $startup['name'] . "!"]);
// Check if goal reached for automated notification system
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE id = ?");
$stmt->execute([$activeRound['id']]);
$updatedRound = $stmt->fetch();
if ($updatedRound['funding_raised'] >= $updatedRound['funding_goal']) {
// Update status to 'Closed'
$stmt = db()->prepare("UPDATE funding_rounds SET status = 'Closed' WHERE id = ?");
$stmt->execute([$updatedRound['id']]);
// Notify Founder (DB)
$stmt = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$stmt->execute([$startup['founder_id'], "Congratulations! The funding round for " . $startup['name'] . " has reached its goal of £" . number_format($updatedRound['funding_goal']) . "!"]);
// Notify All Investors for this round (DB + Email)
$stmt = db()->prepare("SELECT DISTINCT u.id, u.email, u.full_name FROM investments i JOIN users u ON i.investor_id = u.id WHERE i.funding_round_id = ? AND i.status = 'approved'");
$stmt->execute([$updatedRound['id']]);
$investorsToNotify = $stmt->fetchAll();
foreach ($investorsToNotify as $invUser) {
// DB Notification
$stmt = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$stmt->execute([$invUser['id'], "Great news! The funding round for " . $startup['name'] . " that you invested in has reached its goal!"]);
// Email Notification
$subject = "Funding Goal Reached for " . $startup['name'];
$html = "
Goal Reached!
Hi " . htmlspecialchars($invUser['full_name']) . ", the funding round for " . htmlspecialchars($startup['name']) . " has successfully reached its goal. Thank you for being a part of this journey!
";
$text = "Goal Reached! Hi " . $invUser['full_name'] . ", the funding round for " . $startup['name'] . " has successfully reached its goal. Thank you for being a part of this journey!";
MailService::sendMail($invUser['email'], $subject, $html, $text);
}
// Email Founder
$stmt = db()->prepare("SELECT email, full_name FROM users WHERE id = ?");
$stmt->execute([$startup['founder_id']]);
$founderUser = $stmt->fetch();
if ($founderUser) {
$subject = "Funding Goal Reached: " . $startup['name'];
$html = "
Congratulations!
Your funding round for " . htmlspecialchars($startup['name']) . " has reached its goal of £" . number_format($updatedRound['funding_goal']) . ".
";
$text = "Congratulations! Your funding round for " . $startup['name'] . " has reached its goal of £" . number_format($updatedRound['funding_goal']) . ".";
MailService::sendMail($founderUser['email'], $subject, $html, $text);
}
}
db()->commit();
$success = "Investment successful! You've backed the current round.";
// Refresh active round data
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE id = ?");
$stmt->execute([$activeRound['id']]);
$activeRound = $stmt->fetch();
} catch (Exception $e) {
db()->rollBack();
$error = "Investment failed: " . $e->getMessage();
}
}
}
}
}
$platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
?>
= htmlspecialchars($startup['name']) ?> — = htmlspecialchars($platformName) ?>
Founded = date('M Y', strtotime($startup['created_at'])) ?>= ucfirst($startup['status']) ?>
About the Venture
= htmlspecialchars($startup['description']) ?>
Public Updates
New Progress Report
prepare("SELECT * FROM startup_updates WHERE startup_id = ? ORDER BY created_at DESC");
$stmt->execute([$startup_id]);
$updates = $stmt->fetchAll();
?>
No updates have been posted yet.
= htmlspecialchars($upd['title']) ?>
Posted on = date('M d, Y', strtotime($upd['created_at'])) ?>
This startup is not currently raising funds, or the previous round has closed.
Round Details
Venture Stats
Backers
prepare("SELECT COUNT(DISTINCT investor_id) FROM investments WHERE startup_id = ? AND status = 'approved'");
$stmt->execute([$startup_id]);
$backerCount = $stmt->fetchColumn();
?>
= $backerCount ?>
Followers
prepare("SELECT COUNT(*) FROM startup_followers WHERE startup_id = ?");
$stmt->execute([$startup_id]);
$followerCount = $stmt->fetchColumn();
?>
= $followerCount ?>
Founder
prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$startup['founder_id']]);
$founder = $stmt->fetch();
?>