parentId map if needed. * * @param array $data Passed by reference; parentId modified in place. * @param array $parentMap Map of fieldIndex => newly created parent field id. */ public static function resolveParentId(array &$data, array $parentMap): void { if (!array_key_exists('parentId', $data)) { return; } $pid = $data['parentId']; $needsResolve = ($pid === 0 || $pid === '0' || $pid === null); if ($needsResolve && isset($data['fieldIndex']) && isset($parentMap[$data['fieldIndex']])) { $data['parentId'] = $parentMap[$data['fieldIndex']]; } } /** * Partition field options into new, update, and submitted IDs. * * @param array $fieldData * @param array $existingOptionIds * @return array{ * newOptions: array, * updateOptions: array, * submittedOptionIds: array * } * @throws ValidationException */ public static function partitionFieldOptions(array $fieldData, array $existingOptionIds): array { $newOptions = []; $updateOptions = []; $submittedOptionIds = []; foreach ($fieldData['fieldOptions'] as $optionData) { $option = FieldOptionsFactory::create($optionData); if ( isset($optionData['id']) && $optionData['id'] > 0 && in_array($optionData['id'], $existingOptionIds, true) ) { $updateOptions[] = $option; $submittedOptionIds[] = $optionData['id']; continue; } $newOptions[] = $option; } return [ 'newOptions' => $newOptions, 'updateOptions' => $updateOptions, 'submittedOptionIds' => $submittedOptionIds, ]; } /** * Batch process field options: add new, update existing, delete orphaned. * * @param int $fieldId * @param array $fieldData * @param object $fieldOptionsService * @param object $fieldOptionsRepository * @return void * @throws ValidationException */ public static function batchProcessFieldOptions( int $fieldId, array $fieldData, object $fieldOptionsService, object $fieldOptionsRepository ): void { $existingOptions = $fieldOptionsService->getByFieldId($fieldId); $existingOptionIds = array_map(fn($opt) => $opt->getId(), $existingOptions); $partition = self::partitionFieldOptions($fieldData, $existingOptionIds); $newOptionIds = $fieldOptionsService->addOptions($partition['newOptions']); $fieldOptionsService->updateOptions($partition['updateOptions']); $submittedOptionIds = array_merge($partition['submittedOptionIds'], $newOptionIds); $orphanedOptionIds = array_diff($existingOptionIds, $submittedOptionIds); if (!empty($orphanedOptionIds)) { $fieldOptionsRepository->deleteByOptionIds($orphanedOptionIds); } } }