$submittedIds keys are preserved, grouped radios submit under their group name * @param array $previousIds * * @return array */ public function resolve(array $availableServices, array $submittedIds, array $previousIds): array { $rules = $this->buildRules($availableServices); if ([] === $rules) { return $submittedIds; } $added = array_values(array_diff($submittedIds, $previousIds)); foreach ($added as $addedId) { if (!isset($rules[$addedId])) { continue; } $submittedIds = array_filter( $submittedIds, fn (int $id) => !$this->conflicts($rules, $addedId, $id), ); } return $submittedIds; } /** * @param array $rules */ private function conflicts(array $rules, int $a, int $b): bool { if ($a === $b || !isset($rules[$b])) { return false; } if ($rules[$a]['group'] !== $rules[$b]['group']) { return false; } return $rules[$a]['exclusive'] || $rules[$b]['exclusive']; } /** * @param AdditionalService[] $availableServices * * @return array */ private function buildRules(array $availableServices): array { $rules = []; foreach ($availableServices as $service) { $group = $service->getExclusionGroup(); $id = $service->getId(); if (null === $id || null === $group || '' === $group) { continue; } $rules[$id] = ['group' => $group, 'exclusive' => $service->isExclusive()]; } return $rules; } }