getMembershipBindings() as $binding) { $program_id = intval($binding['program_id'] ?? 0); $discount = floatval($binding['discount'] ?? 0.0); $field = strval($binding['field'] ?? ''); if ($program_id <= 0 || $field === '') { continue; } $raw = $data->getValue($field, ''); $value = is_scalar($raw) ? trim((string) $raw) : ''; if ($value === '') { continue; } if ($repo->key_exists($program_id, $value)) { $program = $repo->get($program_id); if ($program) { $matched_programs[] = $program['name']; } $matched_discounts[] = $discount; } } if (empty($matched_discounts)) { return ['percent' => 0.0, 'reason' => '']; } if ($def->getMembershipCombine() === 'sum') { $reason = implode(', ', $matched_programs); return ['percent' => min(100.0, array_sum($matched_discounts)), 'reason' => $reason]; } $max_idx = array_search(max($matched_discounts), $matched_discounts, true); $reason = $matched_programs[$max_idx] ?? ''; return ['percent' => max($matched_discounts), 'reason' => $reason]; } /** * Total membership discount for a submission. * * Each binding names a form field whose submitted value must match a key * in the bound program. Matching bindings' discounts are combined per the * definition's combine mode: the best single discount, or all summed and * capped at 100%. */ public function discount_for(RsvFormDefinition $def, RsvFormData $data): float { return $this->discount_detail_for($def, $data)['percent']; } }