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); | |
} | |
} | |