Leave on-save email validation only in SubscriberSaveController

[MAILPOET-5878]
This commit is contained in:
alex-mpoet
2024-03-10 19:09:59 +03:00
committed by Veljko V
parent 5d781f3f7f
commit 15b0846f34
8 changed files with 87 additions and 5 deletions

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types = 1);
namespace MailPoet\Doctrine\EntityTraits;
trait ValidationGroupsTrait {
/**
* @var array|null
*/
private $validationGroups;
public function getValidationGroups(): ?array {
return $this->validationGroups;
}
public function setValidationGroups(?array $validationGroups): void {
$this->validationGroups = $validationGroups;
}
}

View File

@@ -29,9 +29,17 @@ class ValidationListener {
} }
private function validate($entity) { private function validate($entity) {
$violations = $this->validator->validate($entity); $groups = $this->getValidationGroups($entity);
$violations = $this->validator->validate($entity, null, $groups);
if ($violations->count() > 0) { if ($violations->count() > 0) {
throw new ValidationException(get_class($entity), $violations); throw new ValidationException(get_class($entity), $violations);
} }
} }
private function getValidationGroups($entity) {
if (is_object($entity) && method_exists($entity, 'getValidationGroups')) {
return $entity->getValidationGroups();
}
return null;
}
} }

View File

@@ -7,6 +7,7 @@ use MailPoet\Doctrine\EntityTraits\AutoincrementedIdTrait;
use MailPoet\Doctrine\EntityTraits\CreatedAtTrait; use MailPoet\Doctrine\EntityTraits\CreatedAtTrait;
use MailPoet\Doctrine\EntityTraits\DeletedAtTrait; use MailPoet\Doctrine\EntityTraits\DeletedAtTrait;
use MailPoet\Doctrine\EntityTraits\UpdatedAtTrait; use MailPoet\Doctrine\EntityTraits\UpdatedAtTrait;
use MailPoet\Doctrine\EntityTraits\ValidationGroupsTrait;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection; use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection;
use MailPoetVendor\Doctrine\Common\Collections\Collection; use MailPoetVendor\Doctrine\Common\Collections\Collection;
@@ -44,6 +45,7 @@ class SubscriberEntity {
use CreatedAtTrait; use CreatedAtTrait;
use UpdatedAtTrait; use UpdatedAtTrait;
use DeletedAtTrait; use DeletedAtTrait;
use ValidationGroupsTrait;
/** /**
* @ORM\Column(type="bigint", nullable=true) * @ORM\Column(type="bigint", nullable=true)
@@ -71,7 +73,7 @@ class SubscriberEntity {
/** /**
* @ORM\Column(type="string") * @ORM\Column(type="string")
* @Assert\Email() * @Assert\Email(groups={"Saving"})
* @Assert\NotBlank() * @Assert\NotBlank()
* @var string * @var string
*/ */

View File

@@ -229,6 +229,9 @@ class SubscriberSaveController {
// wipe any unconfirmed data at this point // wipe any unconfirmed data at this point
$subscriber->setUnconfirmedData(null); $subscriber->setUnconfirmedData(null);
// Validate the email (Saving group) + everything else (Default group)
$subscriber->setValidationGroups(['Saving', 'Default']);
try { try {
$this->subscribersRepository->persist($subscriber); $this->subscribersRepository->persist($subscriber);
$this->subscribersRepository->flush(); $this->subscribersRepository->flush();

View File

@@ -772,7 +772,7 @@ parameters:
- -
message: "#^Dead catch \\- MailPoet\\\\Doctrine\\\\Validator\\\\ValidationException is never thrown in the try block\\.$#" message: "#^Dead catch \\- MailPoet\\\\Doctrine\\\\Validator\\\\ValidationException is never thrown in the try block\\.$#"
count: 2 count: 4
path: ../../tests/integration/Doctrine/EventListeners/ValidationTest.php path: ../../tests/integration/Doctrine/EventListeners/ValidationTest.php
- -

View File

@@ -767,7 +767,7 @@ parameters:
- -
message: "#^Dead catch \\- MailPoet\\\\Doctrine\\\\Validator\\\\ValidationException is never thrown in the try block\\.$#" message: "#^Dead catch \\- MailPoet\\\\Doctrine\\\\Validator\\\\ValidationException is never thrown in the try block\\.$#"
count: 2 count: 4
path: ../../tests/integration/Doctrine/EventListeners/ValidationTest.php path: ../../tests/integration/Doctrine/EventListeners/ValidationTest.php
- -

View File

@@ -2,6 +2,7 @@
namespace MailPoet\Test\Doctrine\EventListeners; namespace MailPoet\Test\Doctrine\EventListeners;
use MailPoet\Doctrine\EntityTraits\ValidationGroupsTrait;
use MailPoetVendor\Doctrine\ORM\Mapping as ORM; use MailPoetVendor\Doctrine\ORM\Mapping as ORM;
use MailPoetVendor\Symfony\Component\Validator\Constraints as Assert; use MailPoetVendor\Symfony\Component\Validator\Constraints as Assert;
@@ -10,6 +11,8 @@ use MailPoetVendor\Symfony\Component\Validator\Constraints as Assert;
* @ORM\Table(name="test_validated_entity") * @ORM\Table(name="test_validated_entity")
*/ */
class ValidatedEntity { class ValidatedEntity {
use ValidationGroupsTrait;
/** /**
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
* @ORM\Id * @ORM\Id
@@ -26,6 +29,13 @@ class ValidatedEntity {
*/ */
private $name; private $name;
/**
* @ORM\Column(type="string")
* @Assert\Email(groups={"Saving"})
* @var string
*/
private $email;
/** @return int|null */ /** @return int|null */
public function getId() { public function getId() {
return $this->id; return $this->id;
@@ -40,4 +50,14 @@ class ValidatedEntity {
public function setName($name) { public function setName($name) {
$this->name = $name; $this->name = $name;
} }
/** @return string */
public function getEmail() {
return $this->email;
}
/** @param string $email */
public function setEmail($email) {
$this->email = $email;
}
} }

View File

@@ -35,7 +35,8 @@ class ValidationTest extends \MailPoetTest {
$this->connection->executeStatement(" $this->connection->executeStatement("
CREATE TABLE $this->tableName ( CREATE TABLE $this->tableName (
id int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, id int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(255) NOT NULL name varchar(255) NOT NULL,
email varchar(255)
) )
"); ");
} }
@@ -69,6 +70,36 @@ class ValidationTest extends \MailPoetTest {
} }
} }
public function testItSupportsValidationGroups() {
$id = 1;
$name = 'Test name';
$email = 'test@example.com';
$this->connection->executeStatement("INSERT INTO $this->tableName (id, name, email) VALUES (?, ?, ?)", [$id, $name, $email]);
/** @var ValidatedEntity $entity */
$entity = $this->entityManager->find(ValidatedEntity::class, $id);
$entity->setEmail('example');
// Validation group is Default, no email validation
try {
$this->entityManager->flush();
} catch (ValidationException $e) {
$this->fail('Validation exception was thrown.');
}
// Validation group is Default + Saving, with email validation
$entity->setValidationGroups(['Saving', 'Default']);
$entity->setEmail('example2');
try {
$this->entityManager->flush();
$this->fail('Validation exception was not thrown.');
} catch (ValidationException $e) {
$entityClass = get_class($entity);
verify($e->getMessage())->same("Validation failed for '$entityClass'.\nDetails:\n [email] This value is not a valid email address.");
}
}
private function createEntityManager() { private function createEntityManager() {
$annotationReaderProvider = new AnnotationReaderProvider(); $annotationReaderProvider = new AnnotationReaderProvider();
$configurationFactory = new ConfigurationFactory($annotationReaderProvider, false); $configurationFactory = new ConfigurationFactory($annotationReaderProvider, false);