Spaces:
No application file
No application file
| declare(strict_types=1); | |
| namespace Mautic\IntegrationsBundle\Helper; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeaturesInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormSyncInterface; | |
| use Mautic\IntegrationsBundle\Sync\Exception\ObjectNotFoundException; | |
| use Mautic\IntegrationsBundle\Sync\SyncDataExchange\Helper\FieldHelper; | |
| use Symfony\Component\Form\Form; | |
| use Symfony\Component\Form\FormError; | |
| use Symfony\Component\Form\FormInterface; | |
| use Symfony\Contracts\Translation\TranslatorInterface; | |
| class FieldValidationHelper | |
| { | |
| private ?ConfigFormSyncInterface $integrationObject = null; | |
| public function __construct( | |
| private FieldHelper $fieldHelper, | |
| private TranslatorInterface $translator | |
| ) { | |
| } | |
| /** | |
| * @param FormInterface<mixed> $form | |
| */ | |
| public function validateRequiredFields(FormInterface $form, ConfigFormSyncInterface $integrationObject, array $fieldMappings): void | |
| { | |
| $integrationConfiguration = $integrationObject->getIntegrationConfiguration(); | |
| if (!$integrationConfiguration->getIsPublished()) { | |
| // Don't bind form errors if the integration is not published | |
| return; | |
| } | |
| $features = $integrationConfiguration->getSupportedFeatures(); | |
| if (!in_array(ConfigFormFeaturesInterface::FEATURE_SYNC, $features)) { | |
| // Don't bind form errors if sync is not enabled | |
| return; | |
| } | |
| $this->integrationObject = $integrationObject; | |
| $settings = $integrationConfiguration->getFeatureSettings(); | |
| foreach ($settings['sync']['objects'] as $object) { | |
| $objectFieldMappings = $fieldMappings[$object] ?? []; | |
| $fieldMappingForm = $form['featureSettings']['sync']['fieldMappings'][$object]; | |
| try { | |
| $missingFields = $this->findMissingIntegrationRequiredFieldMappings($object, $objectFieldMappings); | |
| $this->validateIntegrationRequiredFields($fieldMappingForm, $missingFields); | |
| $this->validateMauticRequiredFields($fieldMappingForm, $object, $objectFieldMappings); | |
| } catch (\Throwable $exception) { | |
| $fieldMappingForm->addError(new FormError($exception->getMessage())); | |
| } | |
| } | |
| } | |
| private function validateIntegrationRequiredFields(Form $fieldMappingsForm, array $missingFields): void | |
| { | |
| $hasMissingFields = false; | |
| $errorsOnGivenPage = false; | |
| if (!$hasMissingFields && !empty($missingFields)) { | |
| $hasMissingFields = true; | |
| } | |
| foreach ($missingFields as $field) { | |
| if (!isset($fieldMappingsForm[$field])) { | |
| continue; | |
| } | |
| $errorsOnGivenPage = true; | |
| /** @var Form $formField */ | |
| $formField = $fieldMappingsForm[$field]['mappedField']; | |
| $formField->addError( | |
| new FormError( | |
| $this->translator->trans('mautic.core.value.required', [], 'validators') | |
| ) | |
| ); | |
| } | |
| if (!$errorsOnGivenPage && $hasMissingFields) { | |
| // A hidden page has required fields that are missing so we have to tell the form there is an error | |
| $fieldMappingsForm->addError( | |
| new FormError( | |
| $this->translator->trans('mautic.core.value.required', [], 'validators') | |
| ) | |
| ); | |
| } | |
| } | |
| private function findMissingIntegrationRequiredFieldMappings(string $object, array $mappedFields): array | |
| { | |
| $requiredFields = $this->integrationObject->getRequiredFieldsForMapping($object); | |
| $missingFields = []; | |
| foreach ($requiredFields as $field => $fieldObject) { | |
| if (empty($mappedFields[$field]['mappedField'])) { | |
| $missingFields[] = $field; | |
| } | |
| } | |
| return $missingFields; | |
| } | |
| /** | |
| * @throws ObjectNotFoundException | |
| */ | |
| private function validateMauticRequiredFields(Form $fieldMappingsForm, string $object, array $objectFieldMappings): void | |
| { | |
| $missingFields = $this->findMissingInternalRequiredFieldMappings($object, $objectFieldMappings); | |
| if (empty($missingFields)) { | |
| return; | |
| } | |
| $fieldMappingsForm->addError( | |
| new FormError( | |
| $this->translator->trans( | |
| 'mautic.integration.sync.missing_mautic_field_mappings', | |
| [ | |
| '%fields%' => implode(', ', $missingFields), | |
| ], | |
| 'validators' | |
| ) | |
| ) | |
| ); | |
| } | |
| /** | |
| * @throws ObjectNotFoundException | |
| */ | |
| private function findMissingInternalRequiredFieldMappings(string $object, array $objectFieldMappings): array | |
| { | |
| $mappedObjects = $this->integrationObject->getSyncMappedObjects(); | |
| if (!isset($mappedObjects[$object])) { | |
| throw new ObjectNotFoundException($object); | |
| } | |
| // Get Mautic mapped fields | |
| $mauticMappedFields = []; | |
| foreach ($objectFieldMappings as $mapping) { | |
| if (empty($mapping['mappedField'])) { | |
| continue; | |
| } | |
| $mauticMappedFields[$mapping['mappedField']] = true; | |
| } | |
| $requiredFields = $this->fieldHelper->getRequiredFields($mappedObjects[$object]); | |
| return array_diff_key($requiredFields, $mauticMappedFields); | |
| } | |
| } | |