![]() 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/domains/soundstudiopro.com/private_html/ |
<?php
session_start();
require_once 'config/database.php';
// Ensure UTF-8 encoding for proper handling of emojis and Unicode characters
header('Content-Type: application/json; charset=utf-8');
if (function_exists('mb_internal_encoding')) {
mb_internal_encoding('UTF-8');
}
$pdo = getDBConnection();
$user_id = $_SESSION['user_id'] ?? null;
$is_admin = $_SESSION['is_admin'] ?? false;
if (!$user_id) {
echo json_encode(['success' => false, 'message' => 'User not logged in']);
exit;
}
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
$isMultipart = stripos($contentType, 'multipart/form-data') !== false;
if ($isMultipart) {
$input = $_POST;
$files = $_FILES;
} else {
$raw = file_get_contents('php://input');
$input = $raw ? json_decode($raw, true) : [];
$files = [];
}
$action = $input['action'] ?? '';
try {
switch ($action) {
case 'create':
createEvent($pdo, $user_id, $input, $files);
break;
case 'rsvp':
rsvpEvent($pdo, $user_id, $input);
break;
case 'like':
likeEvent($pdo, $user_id, $input);
break;
case 'comment':
commentEvent($pdo, $user_id, $input, $files);
break;
case 'update':
updateEvent($pdo, $user_id, $input, $is_admin, $files);
break;
case 'delete':
deleteEvent($pdo, $user_id, $input, $is_admin);
break;
case 'share':
shareEvent($pdo, $user_id, $input);
break;
case 'toggle_private_party':
togglePrivateParty($pdo, $user_id, $input);
break;
case 'change_party_password':
changePartyPassword($pdo, $user_id, $input);
break;
default:
echo json_encode(['success' => false, 'message' => 'Invalid action']);
}
} catch (Exception $e) {
error_log("Events API Error: " . $e->getMessage());
echo json_encode(['success' => false, 'message' => 'Server error: ' . $e->getMessage()]);
}
function createEvent($pdo, $user_id, $data, $files = []) {
$required_fields = ['title', 'event_type', 'description', 'start_date', 'end_date'];
foreach ($required_fields as $field) {
if (empty($data[$field])) {
echo json_encode(['success' => false, 'message' => "Missing required field: $field"]);
return;
}
}
$coverImagePath = null;
if (!empty($files['cover_image']) && $files['cover_image']['error'] === UPLOAD_ERR_OK) {
$coverImagePath = uploadEventCoverImage($files['cover_image'], $user_id, 'cover');
}
$bannerImagePath = null;
if (!empty($files['banner_image']) && $files['banner_image']['error'] === UPLOAD_ERR_OK) {
$bannerImagePath = uploadEventCoverImage($files['banner_image'], $user_id, 'banner');
}
// Check if organizer_absorbs_fees column exists
$columns = $pdo->query("SHOW COLUMNS FROM events LIKE 'organizer_absorbs_fees'");
$has_organizer_absorbs_column = $columns->rowCount() > 0;
if ($has_organizer_absorbs_column) {
$stmt = $pdo->prepare("
INSERT INTO events (
creator_id, title, description, event_type, location, venue_name,
address, start_date, end_date, max_attendees, ticket_price, is_free, organizer_absorbs_fees, cover_image, banner_image, status
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
} else {
$stmt = $pdo->prepare("
INSERT INTO events (
creator_id, title, description, event_type, location, venue_name,
address, start_date, end_date, max_attendees, ticket_price, is_free, cover_image, banner_image, status
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
}
// Handle ticket price and is_free logic
$ticket_price = isset($data['ticket_price']) && $data['ticket_price'] !== '' ? (float)$data['ticket_price'] : 0.00;
$is_free = $ticket_price == 0;
// Handle max attendees
$max_attendees = isset($data['max_attendees']) && $data['max_attendees'] !== '' ? (int)$data['max_attendees'] : null;
// Handle organizer_absorbs_fees (default to false/0 if not set)
$organizer_absorbs_fees = isset($data['organizer_absorbs_fees']) && $data['organizer_absorbs_fees'] == '1' ? 1 : 0;
// Log the values being inserted for debugging
error_log("Creating event with values: ticket_price=$ticket_price, is_free=" . ($is_free ? 'true' : 'false') . ", max_attendees=" . ($max_attendees ?? 'null') . ", organizer_absorbs_fees=$organizer_absorbs_fees");
if ($has_organizer_absorbs_column) {
$stmt->execute([
$user_id,
$data['title'],
$data['description'],
$data['event_type'],
$data['location'] ?? '',
$data['venue_name'] ?? '',
$data['address'] ?? '',
$data['start_date'],
$data['end_date'],
$max_attendees,
$ticket_price,
$is_free ? 1 : 0,
$organizer_absorbs_fees,
$coverImagePath,
$bannerImagePath,
'published'
]);
} else {
$stmt->execute([
$user_id,
$data['title'],
$data['description'],
$data['event_type'],
$data['location'] ?? '',
$data['venue_name'] ?? '',
$data['address'] ?? '',
$data['start_date'],
$data['end_date'],
$max_attendees,
$ticket_price,
$is_free ? 1 : 0,
$coverImagePath,
$bannerImagePath,
'published'
]);
}
$event_id = $pdo->lastInsertId();
echo json_encode([
'success' => true,
'message' => 'Event created successfully',
'event_id' => $event_id
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
function rsvpEvent($pdo, $user_id, $data) {
if (empty($data['event_id']) || empty($data['status'])) {
echo json_encode(['success' => false, 'message' => 'Missing event_id or status']);
return;
}
$event_id = $data['event_id'];
$status = $data['status'];
// Check if event exists
$stmt = $pdo->prepare("SELECT id FROM events WHERE id = ?");
$stmt->execute([$event_id]);
if (!$stmt->fetch()) {
echo json_encode(['success' => false, 'message' => 'Event not found']);
return;
}
// Check if RSVP already exists
$stmt = $pdo->prepare("SELECT id FROM event_attendees WHERE event_id = ? AND user_id = ?");
$stmt->execute([$event_id, $user_id]);
if ($stmt->fetch()) {
// Update existing RSVP
$stmt = $pdo->prepare("UPDATE event_attendees SET status = ?, rsvp_date = NOW() WHERE event_id = ? AND user_id = ?");
$stmt->execute([$status, $event_id, $user_id]);
} else {
// Create new RSVP
$stmt = $pdo->prepare("INSERT INTO event_attendees (event_id, user_id, status) VALUES (?, ?, ?)");
$stmt->execute([$event_id, $user_id, $status]);
}
// Update event attendee count
$stmt = $pdo->prepare("
UPDATE events
SET current_attendees = (
SELECT COUNT(*)
FROM event_attendees
WHERE event_id = ? AND status = 'attending'
)
WHERE id = ?
");
$stmt->execute([$event_id, $event_id]);
echo json_encode(['success' => true, 'message' => 'RSVP updated successfully']);
}
function likeEvent($pdo, $user_id, $data) {
if (empty($data['event_id'])) {
echo json_encode(['success' => false, 'message' => 'Missing event_id']);
return;
}
$event_id = $data['event_id'];
// Check if already liked
$stmt = $pdo->prepare("SELECT id FROM event_likes WHERE event_id = ? AND user_id = ?");
$stmt->execute([$event_id, $user_id]);
$is_liked = $stmt->fetch() !== false;
if ($is_liked) {
// Unlike
$stmt = $pdo->prepare("DELETE FROM event_likes WHERE event_id = ? AND user_id = ?");
$stmt->execute([$event_id, $user_id]);
$liked = false;
} else {
// Like
$stmt = $pdo->prepare("INSERT INTO event_likes (event_id, user_id) VALUES (?, ?)");
$stmt->execute([$event_id, $user_id]);
$liked = true;
}
// Get updated like count
$stmt = $pdo->prepare("SELECT COUNT(*) FROM event_likes WHERE event_id = ?");
$stmt->execute([$event_id]);
$like_count = $stmt->fetchColumn();
echo json_encode([
'success' => true,
'message' => $liked ? 'Event liked' : 'Event unliked',
'liked' => $liked,
'like_count' => (int)$like_count
]);
}
function commentEvent($pdo, $user_id, $data, $files = []) {
if (empty($data['event_id'])) {
echo json_encode(['success' => false, 'message' => 'Missing event_id'], JSON_UNESCAPED_UNICODE);
return;
}
// Get comment text and ensure proper UTF-8 encoding
$comment = trim($data['comment'] ?? '');
// Ensure the comment is properly encoded as UTF-8
if (function_exists('mb_check_encoding') && !mb_check_encoding($comment, 'UTF-8')) {
$comment = mb_convert_encoding($comment, 'UTF-8', 'auto');
}
$hasImage = !empty($files['comment_image']) && $files['comment_image']['error'] === UPLOAD_ERR_OK;
if ($comment === '' && !$hasImage) {
echo json_encode(['success' => false, 'message' => 'Please provide a comment or an image'], JSON_UNESCAPED_UNICODE);
return;
}
ensureEventCommentImageColumn($pdo);
$imagePath = null;
if ($hasImage) {
$imagePath = uploadCommentImage($files['comment_image'], $user_id);
}
$stmt = $pdo->prepare("INSERT INTO event_comments (event_id, user_id, comment, comment_image) VALUES (?, ?, ?, ?)");
$stmt->execute([$data['event_id'], $user_id, $comment, $imagePath]);
echo json_encode(['success' => true, 'message' => 'Comment added successfully'], JSON_UNESCAPED_UNICODE);
}
function shareEvent($pdo, $user_id, $data) {
if (empty($data['event_id'])) {
echo json_encode(['success' => false, 'message' => 'Missing event_id']);
return;
}
$platform = $data['platform'] ?? 'internal';
$stmt = $pdo->prepare("INSERT INTO event_shares (event_id, user_id, platform) VALUES (?, ?, ?)");
$stmt->execute([$data['event_id'], $user_id, $platform]);
echo json_encode(['success' => true, 'message' => 'Event shared successfully']);
}
function updateEvent($pdo, $user_id, $data, $is_admin = false, $files = []) {
$required_fields = ['event_id', 'title', 'event_type', 'description', 'start_date', 'end_date'];
foreach ($required_fields as $field) {
if (empty($data[$field]) && $data[$field] !== '0') {
echo json_encode(['success' => false, 'message' => "Missing required field: $field"]);
return;
}
}
$event_id = (int)$data['event_id'];
$stmt = $pdo->prepare("SELECT creator_id FROM events WHERE id = ?");
$stmt->execute([$event_id]);
$event = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$event) {
echo json_encode(['success' => false, 'message' => 'Event not found']);
return;
}
if ($event['creator_id'] != $user_id && !$is_admin) {
echo json_encode(['success' => false, 'message' => 'You do not have permission to edit this event']);
return;
}
$ticket_price = isset($data['ticket_price']) && $data['ticket_price'] !== '' ? (float)$data['ticket_price'] : 0.00;
$is_free = $ticket_price == 0;
$max_attendees = isset($data['max_attendees']) && $data['max_attendees'] !== '' ? (int)$data['max_attendees'] : null;
$cover_image = $data['existing_cover_image'] ?? null;
$banner_image = $data['existing_banner_image'] ?? null;
if (!empty($files['cover_image']) && $files['cover_image']['error'] === UPLOAD_ERR_OK) {
$cover_image = uploadEventCoverImage($files['cover_image'], $user_id, 'cover');
}
if (!empty($files['banner_image']) && $files['banner_image']['error'] === UPLOAD_ERR_OK) {
$banner_image = uploadEventCoverImage($files['banner_image'], $user_id, 'banner');
}
$stmt = $pdo->prepare("
UPDATE events
SET
title = ?,
description = ?,
event_type = ?,
location = ?,
venue_name = ?,
address = ?,
start_date = ?,
end_date = ?,
max_attendees = ?,
ticket_price = ?,
is_free = ?,
cover_image = ?,
banner_image = ?
WHERE id = ?
");
$stmt->execute([
$data['title'],
$data['description'],
$data['event_type'],
$data['location'] ?? '',
$data['venue_name'] ?? '',
$data['address'] ?? '',
$data['start_date'],
$data['end_date'],
$max_attendees,
$ticket_price,
$is_free ? 1 : 0,
$cover_image,
$banner_image,
$event_id
]);
echo json_encode(['success' => true, 'message' => 'Event updated successfully', 'event_id' => $event_id], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
function deleteEvent($pdo, $user_id, $data, $is_admin = false) {
$event_id = isset($data['event_id']) ? (int)$data['event_id'] : 0;
if (!$event_id) {
echo json_encode(['success' => false, 'message' => 'Event ID is required']);
return;
}
// Check if event exists
$stmt = $pdo->prepare("SELECT creator_id, title FROM events WHERE id = ?");
$stmt->execute([$event_id]);
$event = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$event) {
echo json_encode(['success' => false, 'message' => 'Event not found']);
return;
}
// Check permissions - only creator or admin can delete
if ($event['creator_id'] != $user_id && !$is_admin) {
echo json_encode(['success' => false, 'message' => 'You do not have permission to delete this event']);
return;
}
// Delete related records first (due to foreign key constraints)
// Delete event tickets
$pdo->prepare("DELETE FROM event_tickets WHERE event_id = ?")->execute([$event_id]);
// Delete event attendees
$pdo->prepare("DELETE FROM event_attendees WHERE event_id = ?")->execute([$event_id]);
// Delete event likes
$pdo->prepare("DELETE FROM event_likes WHERE event_id = ?")->execute([$event_id]);
// Delete event comments
$pdo->prepare("DELETE FROM event_comments WHERE event_id = ?")->execute([$event_id]);
// Delete event managers
$pdo->prepare("DELETE FROM event_managers WHERE event_id = ?")->execute([$event_id]);
// Delete the event itself
$stmt = $pdo->prepare("DELETE FROM events WHERE id = ?");
$stmt->execute([$event_id]);
echo json_encode(['success' => true, 'message' => 'Event deleted successfully']);
}
function uploadEventCoverImage($file, $user_id, $type = 'cover') {
// SECURITY: Enhanced file upload validation
require_once __DIR__ . '/includes/security.php';
$validation = validateFileUpload($file, ['jpg', 'jpeg', 'png', 'gif', 'webp'], 6 * 1024 * 1024); // 6MB max
if (!$validation['valid']) {
error_log("SECURITY: Invalid event cover image upload attempt from user $user_id: " . ($validation['error'] ?? 'unknown error'));
throw new Exception('Invalid cover image. ' . ($validation['error'] ?? 'Please upload a valid image file.'));
}
$subdir = $type === 'banner' ? 'event_banners' : 'event_covers';
$prefix = $type === 'banner' ? 'event_banner' : 'event_cover';
$upload_dir = __DIR__ . '/uploads/' . $subdir . '/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Use sanitized filename from validation
$filename = $prefix . '_' . $user_id . '_' . time() . '_' . $validation['filename'];
$filepath = $upload_dir . $filename;
if (!move_uploaded_file($file['tmp_name'], $filepath)) {
error_log("SECURITY: Failed to move uploaded event cover image for user $user_id");
throw new Exception('Failed to save cover image.');
}
return '/uploads/' . $subdir . '/' . $filename;
}
function ensureEventCommentImageColumn($pdo) {
static $checked = false;
if ($checked) {
return;
}
$result = $pdo->query("SHOW COLUMNS FROM event_comments LIKE 'comment_image'")->fetch(PDO::FETCH_ASSOC);
if (!$result) {
$pdo->exec("ALTER TABLE event_comments ADD COLUMN comment_image VARCHAR(255) NULL AFTER comment");
}
$checked = true;
}
function uploadCommentImage($file, $user_id) {
// SECURITY: Enhanced file upload validation
require_once __DIR__ . '/includes/security.php';
$validation = validateFileUpload($file, ['jpg', 'jpeg', 'png', 'gif', 'webp'], 5 * 1024 * 1024); // 5MB max
if (!$validation['valid']) {
error_log("SECURITY: Invalid event comment image upload attempt from user $user_id: " . ($validation['error'] ?? 'unknown error'));
throw new Exception('Invalid image type. ' . ($validation['error'] ?? 'Please upload a valid image file.'));
}
$upload_dir = __DIR__ . '/uploads/event_comment_images/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Use sanitized filename from validation, add random component for uniqueness
$random = bin2hex(random_bytes(4));
$filename = 'event_comment_' . $user_id . '_' . time() . '_' . $random . '_' . $validation['filename'];
$filepath = $upload_dir . $filename;
if (!move_uploaded_file($file['tmp_name'], $filepath)) {
error_log("SECURITY: Failed to move uploaded event comment image for user $user_id");
throw new Exception('Failed to save comment image.');
}
return '/uploads/event_comment_images/' . $filename;
}
function togglePrivateParty($pdo, $user_id, $data) {
if (empty($data['event_id'])) {
echo json_encode(['success' => false, 'message' => 'Missing event_id']);
return;
}
$event_id = (int)$data['event_id'];
$is_private = isset($data['is_private']) ? (bool)$data['is_private'] : false;
// Check if event exists and user is creator
$stmt = $pdo->prepare("SELECT creator_id FROM events WHERE id = ?");
$stmt->execute([$event_id]);
$event = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$event) {
echo json_encode(['success' => false, 'message' => 'Event not found']);
return;
}
if ($event['creator_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'You do not have permission to modify this event']);
return;
}
// Check if columns exist, if not add them
try {
$columns = $pdo->query("SHOW COLUMNS FROM events LIKE 'is_private_party'")->fetch();
if (!$columns) {
$pdo->exec("ALTER TABLE events ADD COLUMN is_private_party BOOLEAN DEFAULT FALSE");
}
$columns = $pdo->query("SHOW COLUMNS FROM events LIKE 'party_password'")->fetch();
if (!$columns) {
$pdo->exec("ALTER TABLE events ADD COLUMN party_password VARCHAR(255) NULL");
}
} catch (Exception $e) {
// Columns might already exist, continue
}
if ($is_private) {
$party_password = $data['party_password'] ?? '';
if (empty($party_password)) {
echo json_encode(['success' => false, 'message' => 'Password is required for private party']);
return;
}
// Hash the password before storing (using password_hash for security)
$hashed_password = password_hash($party_password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE events SET is_private_party = 1, party_password = ? WHERE id = ?");
$stmt->execute([$hashed_password, $event_id]);
} else {
$stmt = $pdo->prepare("UPDATE events SET is_private_party = 0, party_password = NULL WHERE id = ?");
$stmt->execute([$event_id]);
}
echo json_encode([
'success' => true,
'message' => $is_private ? 'Private Password Party enabled' : 'Private Password Party disabled',
'is_private' => $is_private
]);
}
function changePartyPassword($pdo, $user_id, $data) {
if (empty($data['event_id'])) {
echo json_encode(['success' => false, 'message' => 'Missing event_id']);
return;
}
$event_id = (int)$data['event_id'];
$new_password = $data['party_password'] ?? '';
if (empty($new_password)) {
echo json_encode(['success' => false, 'message' => 'Password is required']);
return;
}
// Check if event exists and user is creator
$stmt = $pdo->prepare("SELECT creator_id, is_private_party FROM events WHERE id = ?");
$stmt->execute([$event_id]);
$event = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$event) {
echo json_encode(['success' => false, 'message' => 'Event not found']);
return;
}
if ($event['creator_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'You do not have permission to modify this event']);
return;
}
if (!((int)$event['is_private_party'] === 1 || $event['is_private_party'] === true)) {
echo json_encode(['success' => false, 'message' => 'This event is not a private password party']);
return;
}
// Hash the new password before storing
$hashed_password = password_hash($new_password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE events SET party_password = ? WHERE id = ?");
$stmt->execute([$hashed_password, $event_id]);
echo json_encode([
'success' => true,
'message' => 'Password changed successfully'
]);
}
?>