'Method not allowed']); exit; } // Collect and sanitize input $id = isset($_POST['id']) && $_POST['id'] !== '' ? (int)$_POST['id'] : null; $name = trim($_POST['name'] ?? ''); $occasion = trim($_POST['occasion'] ?? ''); $mystery_set = trim($_POST['mystery_set'] ?? ''); $novena_mystery_mode = trim($_POST['novena_mystery_mode'] ?? ''); $novena_day = isset($_POST['novena_day']) && $_POST['novena_day'] !== '' ? (int)$_POST['novena_day'] : null; $subject_name = trim($_POST['subject_name'] ?? '') ?: null; $subject_pronoun = trim($_POST['subject_pronoun'] ?? '') ?: null; $subject_dates = trim($_POST['subject_dates'] ?? '') ?: null; $photo_path = trim($_POST['photo_path'] ?? '') ?: null; $is_public = isset($_POST['is_public']) ? 1 : 0; // For novena sessions, mystery_set is determined by novena_mystery_mode if ($occasion === 'novena_deceased') { $mystery_set = ($novena_mystery_mode === 'by_day_of_week') ? 'by_day_of_week' : 'sorrowful'; } // Divine Mercy Novena uses the chaplet — no mystery set if ($occasion === 'divine_mercy_novena') { $mystery_set = 'chaplet'; } // Validate required fields $valid_occasions = ['novena_deceased', 'divine_mercy_novena', 'general_rosary', 'memorial']; $valid_mysteries = ['sorrowful', 'joyful', 'glorious', 'luminous', 'by_day_of_week', 'chaplet']; if ($name === '') { http_response_code(400); echo json_encode(['error' => 'Session name is required']); exit; } if (!in_array($occasion, $valid_occasions, true)) { http_response_code(400); echo json_encode(['error' => 'Invalid occasion']); exit; } if (!in_array($mystery_set, $valid_mysteries, true)) { http_response_code(400); echo json_encode(['error' => 'Invalid mystery set']); exit; } try { $pdo = get_pdo(); // ------------------------------------------------------------------ // EDIT: update single existing session // ------------------------------------------------------------------ if ($id !== null) { // Verify ownership or admin $chk = $pdo->prepare('SELECT user_id FROM sessions WHERE id = ?'); $chk->execute([$id]); $row = $chk->fetch(); if (!$row) { http_response_code(404); echo json_encode(['error' => 'Session not found']); exit; } if (!has_role('admin') && (int)$row['user_id'] !== $uid) { http_response_code(403); echo json_encode(['error' => 'Permission denied']); exit; } // Update slug if name changed and user owns it $new_slug = null; if (!has_role('admin') || (int)$row['user_id'] === $uid) { $owner_id = (int)$row['user_id']; $new_slug = unique_slug($name, $owner_id, 'sessions', $id); } $stmt = $pdo->prepare(' UPDATE sessions SET name = ?, occasion = ?, mystery_set = ?, subject_name = ?, subject_pronoun = ?, subject_dates = ?, photo_path = COALESCE(?, photo_path), is_public = ?' . ($new_slug !== null ? ', slug = ?' : '') . ' WHERE id = ? '); $params = [ $name, $occasion, $mystery_set, $subject_name, $subject_pronoun, $subject_dates, $photo_path, $is_public, ]; if ($new_slug !== null) $params[] = $new_slug; $params[] = $id; $stmt->execute($params); echo json_encode(['id' => $id]); exit; } // ------------------------------------------------------------------ // Creating new: check rosary limit // ------------------------------------------------------------------ if (!can_create_rosary($uid, $user['rosary_limit'])) { http_response_code(429); echo json_encode(['error' => 'Rosary limit reached. Contact an administrator to increase your limit.']); exit; } // ------------------------------------------------------------------ // CREATE NEW NOVENA: create a group record, then 9 day sessions // ------------------------------------------------------------------ if ($occasion === 'divine_mercy_novena') { $grp_slug = unique_slug($name, $uid, 'novena_groups'); $grp = $pdo->prepare(' INSERT INTO novena_groups (name, mystery_set, subject_name, subject_pronoun, subject_dates, photo_path, user_id, is_public, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) '); $grp->execute([$name, $mystery_set, null, null, null, $photo_path, $uid, $is_public, $grp_slug]); $group_id = (int)$pdo->lastInsertId(); $insert = $pdo->prepare(' INSERT INTO sessions (name, occasion, mystery_set, novena_day, subject_name, subject_pronoun, subject_dates, photo_path, novena_group_id, user_id, is_public, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '); $created_ids = []; for ($day = 1; $day <= 9; $day++) { $day_name = $name . ' — Day ' . $day; $day_slug = unique_slug($day_name, $uid, 'sessions'); $insert->execute([ $day_name, $occasion, $mystery_set, $day, null, null, null, $photo_path, $group_id, $uid, $is_public, $day_slug, ]); $created_ids[] = (int)$pdo->lastInsertId(); } echo json_encode(['novena' => true, 'group_id' => $group_id, 'ids' => $created_ids]); exit; } if ($occasion === 'novena_deceased') { $grp_slug = unique_slug($name, $uid, 'novena_groups'); $grp = $pdo->prepare(' INSERT INTO novena_groups (name, mystery_set, subject_name, subject_pronoun, subject_dates, photo_path, user_id, is_public, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) '); $grp->execute([$name, $mystery_set, $subject_name, $subject_pronoun, $subject_dates, $photo_path, $uid, $is_public, $grp_slug]); $group_id = (int)$pdo->lastInsertId(); $insert = $pdo->prepare(' INSERT INTO sessions (name, occasion, mystery_set, novena_day, subject_name, subject_pronoun, subject_dates, photo_path, novena_group_id, user_id, is_public, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '); $created_ids = []; for ($day = 1; $day <= 9; $day++) { $day_name = $name . ' — Day ' . $day; $day_slug = unique_slug($day_name, $uid, 'sessions'); $insert->execute([ $day_name, $occasion, $mystery_set, $day, $subject_name, $subject_pronoun, $subject_dates, $photo_path, $group_id, $uid, $is_public, $day_slug, ]); $created_ids[] = (int)$pdo->lastInsertId(); } echo json_encode(['novena' => true, 'group_id' => $group_id, 'ids' => $created_ids]); exit; } // ------------------------------------------------------------------ // CREATE NEW: single session (general_rosary or memorial) // ------------------------------------------------------------------ $slug = unique_slug($name, $uid, 'sessions'); $stmt = $pdo->prepare(' INSERT INTO sessions (name, occasion, mystery_set, novena_day, subject_name, subject_pronoun, subject_dates, photo_path, user_id, is_public, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '); $stmt->execute([ $name, $occasion, $mystery_set, $novena_day, $subject_name, $subject_pronoun, $subject_dates, $photo_path, $uid, $is_public, $slug, ]); echo json_encode(['id' => (int)$pdo->lastInsertId()]); } catch (PDOException $e) { http_response_code(500); echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); }