diff --git a/Api/BrevoClient.php b/Api/BrevoClient.php index 90381db..165ba54 100644 --- a/Api/BrevoClient.php +++ b/Api/BrevoClient.php @@ -32,6 +32,7 @@ use Propel\Runtime\Propel; use Thelia\Core\Event\Newsletter\NewsletterEvent; use Thelia\Exception\TheliaProcessException; +use Thelia\Log\Tlog; use Thelia\Model\ConfigQuery; use Thelia\Model\Customer; @@ -142,10 +143,16 @@ public function unsubscribe(NewsletterEvent $event) public function getCustomerAttribute($customerId) { try { - $mapping = json_decode(ConfigQuery::read(Brevo::BREVO_ATTRIBUTES_MAPPING), true, 512, \JSON_THROW_ON_ERROR); + if (null === $mapping = json_decode(ConfigQuery::read(Brevo::BREVO_ATTRIBUTES_MAPPING), true, 512, \JSON_THROW_ON_ERROR)) { + throw new TheliaProcessException("Customer attribute mapping error: JSON data seems invalid, pleas echeck syntax."); + } + + if (empty($mapping)) { + return []; + } if (!\array_key_exists('customer_query', $mapping)) { - throw new \Exception("Customer attribute mapping error : the configuration file is incorrect, 'customer_query' element is missing"); + throw new TheliaProcessException("Customer attribute mapping error : 'customer_query' element is missing in JSON data"); } $attributes = []; @@ -155,32 +162,37 @@ public function getCustomerAttribute($customerId) foreach ($mapping['customer_query'] as $key => $customerDataQuery) { if (!\array_key_exists('select', $customerDataQuery)) { - throw new \Exception("Customer attribute mapping error : 'select' element missing in " . $key . ' query'); + throw new \Exception("Customer attribute mapping error : 'select' element missing in ".$key.' query'); } - $sql = 'SELECT ' . $customerDataQuery['select'] . ' AS ' . $key . ' FROM customer'; + try { + $sql = 'SELECT '.$customerDataQuery['select'].' AS '.$key.' FROM customer'; - if (\array_key_exists('join', $customerDataQuery)) { - foreach ($customerDataQuery['join'] as $join) { - $sql .= ' LEFT JOIN ' . $join; + if (\array_key_exists('join', $customerDataQuery)) { + foreach ($customerDataQuery['join'] as $join) { + $sql .= ' LEFT JOIN '.$join; + } } - } - $sql .= ' WHERE customer.id = :customerId'; + $sql .= ' WHERE customer.id = :customerId'; - if (\array_key_exists('groupBy', $customerDataQuery)) { - $sql .= ' GROUP BY ' . $customerDataQuery['groupBy']; - } + if (\array_key_exists('groupBy', $customerDataQuery)) { + $sql .= ' GROUP BY '.$customerDataQuery['groupBy']; + } - $stmt = $con->prepare($sql); - $stmt->bindValue(':customerId', $customerId, \PDO::PARAM_INT); - $stmt->execute(); + $stmt = $con->prepare($sql); + $stmt->bindValue(':customerId', $customerId, \PDO::PARAM_INT); + $stmt->execute(); - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $attributes[$key] = $row[$key]; - if (\array_key_exists($key, $mapping) && \array_key_exists($row[$key], $mapping[$key])) { - $attributes[$key] = $mapping[$key][$row[$key]]; + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + $attributes[$key] = $row[$key]; + if (\array_key_exists($key, $mapping) && \array_key_exists($row[$key], $mapping[$key])) { + $attributes[$key] = $mapping[$key][$row[$key]]; + } } + } catch (\Exception $ex) { + Tlog::getInstance()->error( + 'Failed to execute SQL request to map Brevo attribute. Error is '.$ex->getMessage().", request is : $sql"); } } diff --git a/Config/module.xml b/Config/module.xml index bea6a6e..6a8c559 100644 --- a/Config/module.xml +++ b/Config/module.xml @@ -13,7 +13,7 @@ en_US fr_FR - 1.1.5 + 1.1.6 Chabreuil Antoine diff --git a/Form/BrevoConfigurationForm.php b/Form/BrevoConfigurationForm.php index af400f6..6a7c0f2 100644 --- a/Form/BrevoConfigurationForm.php +++ b/Form/BrevoConfigurationForm.php @@ -23,7 +23,9 @@ use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Context\ExecutionContextInterface; use Thelia\Core\Translation\Translator; use Thelia\Form\BaseForm; use Thelia\Model\ConfigQuery; @@ -127,6 +129,10 @@ protected function buildForm(): void ) ], 'required' => false, + 'constraints' => [ + new NotBlank(), + new Callback([$this, 'checkJsonValidity']), + ], 'data' => ConfigQuery::read(Brevo::BREVO_ATTRIBUTES_MAPPING, $defaultMapping), ]) ->add('exception_on_errors', CheckboxType::class, [ @@ -143,6 +149,32 @@ protected function buildForm(): void ]) ; } + public function checkJsonValidity($value, ExecutionContextInterface $context): void + { + if (empty($value)) { + return; + } + + if (null === $jsonData = json_decode($value, true)) { + $context->addViolation( + Translator::getInstance()->trans( + "The customer attributes mapping JSON seems invalid, please check syntax.", + [], + Brevo::MESSAGE_DOMAIN + ) + ); + } + + if (! isset($jsonData['customer_query'])) { + $context->addViolation( + Translator::getInstance()->trans( + "The customer attributes mapping JSON should contain a 'customer_query' field.", + [], + Brevo::MESSAGE_DOMAIN + ) + ); + } + } /** * @return string the name of you form. This name must be unique