prepare(" SELECT bs.step_type, bs.bead_type, bs.attribution, cp.name, cp.leader_text, cp.all_text FROM builder_steps bs LEFT JOIN custom_prayers cp ON cp.id = bs.prayer_id WHERE bs.session_id = ? ORDER BY bs.step_order ASC "); $st->execute([$session_id]); return $st->fetchAll(); } /** * Returns the slide array for one decade of the Chaplet of Divine Mercy. * * Large bead : "Eternal Father…" * Small beads: "For the sake of His sorrowful Passion…" × 10 * No mystery announcement; no Glory Be between decades. * * @param int $decade_num 1–5 * @param int $of_bead_index bead_index for the large (Our Father) bead * @param int $hm_bead_start bead_index for the first small bead of this decade */ function build_chaplet_decade_slides(int $decade_num, int $of_bead_index, int $hm_bead_start): array { $slides = []; $slides[] = [ 'id' => 'dm_eternal_father_d' . $decade_num, 'type' => 'prayer', 'section' => 'dm_chaplet_decade_' . $decade_num, 'title' => 'Eternal Father', 'leader' => "Eternal Father, I offer You the Body and Blood,\nSoul and Divinity of Your dearly beloved Son,\nOur Lord Jesus Christ,", 'all' => "in atonement for our sins and those of the whole world.", 'bead' => 'large', 'bead_index' => $of_bead_index, ]; for ($i = 0; $i < 10; $i++) { $slides[] = [ 'id' => 'dm_for_sake_d' . $decade_num . '_' . ($i + 1), 'type' => 'prayer', 'section' => 'dm_chaplet_decade_' . $decade_num, 'title' => 'For the Sake of His Sorrowful Passion', 'leader' => 'For the sake of His sorrowful Passion,', 'all' => 'have mercy on us and on the whole world.', 'bead' => 'small', 'bead_index' => $hm_bead_start + $i, ]; } return $slides; } /** * Build the complete slide array for a session. * * @param array $session Row from the sessions table (keys match column names) * @return array Flat array of slide arrays */ function build_slides(array $session): array { global $opening, $mysteries, $hail_holy_queen, $rosary_closing_prayer, $litany_passion, $novena_prayers, $litany_departed, $closing, $divine_mercy_opening, $divine_mercy_novena_prayers, $divine_mercy_chaplet_opening, $divine_mercy_chaplet_close; $slides = []; // ----------------------------------------------------------------------- // Custom builder session — build directly from builder_steps // ----------------------------------------------------------------------- if ($session['occasion'] === 'custom') { $pdo = get_pdo(); $steps = get_builder_steps($pdo, (int)$session['id']); // Cover slide $cover_all = ''; if (!empty($session['subject_name'])) { $cover_all = "For {$session['subject_name']}"; } $slides[] = [ 'id' => 'cover', 'type' => 'cover', 'section' => 'cover', 'title' => $session['name'], 'leader' => '', 'all' => $cover_all, 'bead' => null, 'bead_index' => null, 'photo_path' => $session['photo_path'] ?? null, ]; $bead_idx = 0; // increments for each bead separator step foreach ($steps as $i => $step) { $type = $step['step_type'] ?? 'prayer'; if ($type === 'bead') { $slides[] = [ 'id' => 'bead_' . $i, 'type' => 'prayer', 'section' => 'bead', 'title' => '', 'leader' => '', 'all' => '', 'bead' => $step['bead_type'] ?? 'small', 'bead_index' => $bead_idx++, ]; continue; } $attr = $step['attribution'] ?? 'leader_all'; $leader = ''; $all = ''; if ($attr === 'leader_all' || $attr === 'leader_only') { $leader = $step['leader_text'] ?? ''; } if ($attr === 'leader_all' || $attr === 'all_only') { $all = $step['all_text'] ?? ''; } if ($attr === 'none') { $leader = ($step['leader_text'] ?: $step['all_text']) ?? ''; } $bead_type = $step['bead_type'] ?? null; $slides[] = [ 'id' => 'custom_' . $i, 'type' => 'prayer', 'section' => $step['name'], 'title' => $step['name'], 'leader' => $leader, 'all' => $all, 'bead' => $bead_type, 'bead_index' => $bead_type ? $bead_idx++ : null, ]; } // Closing slide $slides[] = [ 'id' => 'closing_custom', 'type' => 'closing', 'section' => 'closing', 'title' => '', 'leader' => '', 'all' => "May the souls of the faithful departed,\nthrough the mercy of God, rest in peace.", 'bead' => null, 'bead_index' => null, ]; // Apply variable substitution and return early $name = $session['subject_name'] ?? ''; $pronoun = $session['subject_pronoun'] ?? 'he'; $dates = $session['subject_dates'] ?? ''; $pronoun_obj = ($pronoun === 'she') ? 'her' : 'him'; $pronoun_poss = ($pronoun === 'she') ? 'her' : 'his'; $find = ['{name}', '{pronoun}', '{pronoun_obj}', '{pronoun_poss}', '{subject_dates}']; $replace = [$name, $pronoun, $pronoun_obj, $pronoun_poss, $dates]; foreach ($slides as &$slide) { $slide['title'] = str_replace($find, $replace, $slide['title'] ?? ''); $slide['leader'] = str_replace($find, $replace, $slide['leader'] ?? ''); $slide['all'] = str_replace($find, $replace, $slide['all'] ?? ''); } unset($slide); return $slides; } // ----------------------------------------------------------------------- // 1. Cover slide // ----------------------------------------------------------------------- $cover_title = ''; $cover_all = ''; switch ($session['occasion']) { case 'novena_deceased': $day = (int)($session['novena_day'] ?? 1); $cover_title = 'Nine-Day Novena Rosary'; $cover_all = "In Loving Memory of\n{name}\n{subject_dates}\n\nDay {$day} of 9"; break; case 'memorial': $cover_title = 'Memorial Rosary'; $cover_all = "In Loving Memory of\n{name}\n{subject_dates}"; break; case 'divine_mercy_novena': $day = (int)($session['novena_day'] ?? 1); $cover_title = 'Divine Mercy Novena'; $cover_all = "Chaplet of Divine Mercy\n\nDay {$day} of 9"; break; case 'general_rosary': default: $cover_title = 'The Holy Rosary'; $cover_all = ucfirst($session['mystery_set']) . ' Mysteries'; break; } $slides[] = [ 'id' => 'cover', 'type' => 'cover', 'section' => 'cover', 'title' => $cover_title, 'leader' => '', 'all' => $cover_all, 'bead' => null, 'bead_index' => null, 'photo_path' => $session['photo_path'] ?? null, ]; // ----------------------------------------------------------------------- // 2. Opening prayers // ----------------------------------------------------------------------- if ($session['occasion'] === 'divine_mercy_novena') { // Pre-chaplet devotion: opening prayer + O Blood and Water × 3 foreach ($divine_mercy_opening as $slide) { $slides[] = $slide; } // Day-specific intention and prayer $day = (int)($session['novena_day'] ?? 1); if (isset($divine_mercy_novena_prayers[$day])) { foreach ($divine_mercy_novena_prayers[$day] as $slide) { $slides[] = $slide; } } // Chaplet opening on stem beads (Sign of Cross, Our Father, Hail Mary, Creed) foreach ($divine_mercy_chaplet_opening as $slide) { $slides[] = $slide; } } else { foreach ($opening as $slide) { $slides[] = $slide; } } // ----------------------------------------------------------------------- // 3. Five decades // // Bead layout: // Bead 0: Crucifix (Sign of Cross / Creed) // Bead 1: large (Our Father, stem) // Beads 2–4: small (3 Hail Marys / Creed for chaplet, stem) // Bead 5: large (Our Father, Decade 1) // Beads 6–15: small (Decade 1, 10 HMs / For the sake…) // Bead 16: large (Our Father, Decade 2) // Beads 17–26: small (Decade 2) // Bead 27: large (Our Father, Decade 3) // Beads 28–37: small (Decade 3) // Bead 38: large (Our Father, Decade 4) // Beads 39–48: small (Decade 4) // Bead 49: large (Our Father, Decade 5) // Beads 50–59: small (Decade 5) // ----------------------------------------------------------------------- $decade_bead_map = [ // decade => [our_father_index, first_hm_index] 1 => [5, 6], 2 => [16, 17], 3 => [27, 28], 4 => [38, 39], 5 => [49, 50], ]; if ($session['occasion'] === 'divine_mercy_novena') { for ($d = 1; $d <= 5; $d++) { [$of_idx, $hm_idx] = $decade_bead_map[$d]; foreach (build_chaplet_decade_slides($d, $of_idx, $hm_idx) as $slide) { $slides[] = $slide; } } } else { $mystery_set = $mysteries[$session['mystery_set']] ?? $mysteries['sorrowful']; for ($d = 1; $d <= 5; $d++) { [$of_idx, $hm_idx] = $decade_bead_map[$d]; $mystery_slide = $mystery_set[$d - 1]; $decade_slides = build_decade_slides($d, $mystery_slide, $of_idx, $hm_idx); foreach ($decade_slides as $slide) { $slides[] = $slide; } } } // ----------------------------------------------------------------------- // 4. Post-decade prayers by occasion // ----------------------------------------------------------------------- switch ($session['occasion']) { case 'novena_deceased': // Hail Holy Queen foreach ($hail_holy_queen as $slide) { $slides[] = $slide; } // Day-specific novena prayer $day = (int)($session['novena_day'] ?? 1); if (isset($novena_prayers[$day])) { $slides[] = $novena_prayers[$day]; } // Litany of the Passion foreach ($litany_passion as $slide) { $slides[] = $slide; } // Litany for the Departed foreach ($litany_departed as $slide) { $slides[] = $slide; } break; case 'divine_mercy_novena': // Holy God, Holy Mighty One, Holy Immortal One × 3 foreach ($divine_mercy_chaplet_close as $slide) { $slides[] = $slide; } break; case 'memorial': case 'general_rosary': default: foreach ($hail_holy_queen as $slide) { $slides[] = $slide; } $slides[] = $rosary_closing_prayer; break; } // ----------------------------------------------------------------------- // 5. Closing slide — inject photo for personal occasions // ----------------------------------------------------------------------- $occasion_key = $session['occasion']; if (!isset($closing[$occasion_key])) { $occasion_key = 'general_rosary'; } $closing_slide = $closing[$occasion_key]; if (in_array($occasion_key, ['novena_deceased', 'memorial'])) { $closing_slide['photo_path'] = $session['photo_path'] ?? null; } $slides[] = $closing_slide; // ----------------------------------------------------------------------- // 6. Variable substitution // ----------------------------------------------------------------------- $name = $session['subject_name'] ?? ''; $pronoun = $session['subject_pronoun'] ?? 'he'; // 'he' or 'she' $dates = $session['subject_dates'] ?? ''; $pronoun_obj = ($pronoun === 'she') ? 'her' : 'him'; $pronoun_poss = ($pronoun === 'she') ? 'her' : 'his'; $pronoun_cap = ucfirst($pronoun); $find = ['{name}', '{pronoun}', '{pronoun_obj}', '{pronoun_poss}', '{subject_dates}']; $replace = [$name, $pronoun, $pronoun_obj, $pronoun_poss, $dates]; foreach ($slides as &$slide) { $slide['title'] = str_replace($find, $replace, $slide['title'] ?? ''); $slide['leader'] = str_replace($find, $replace, $slide['leader'] ?? ''); $slide['all'] = str_replace($find, $replace, $slide['all'] ?? ''); if (isset($slide['subtitle'])) { $slide['subtitle'] = str_replace($find, $replace, $slide['subtitle']); } } unset($slide); return $slides; }