Use Doctrine in RequiredCustomFieldValidator

[MAILPOET-3032]
This commit is contained in:
Jan Lysý
2021-03-30 17:36:53 +02:00
committed by Veljko V
parent 5ceb084c64
commit 69d5eb42f7
3 changed files with 91 additions and 47 deletions

View File

@ -194,4 +194,37 @@ class FormEntity {
public function getSettingsSegmentIds(): array { public function getSettingsSegmentIds(): array {
return $this->settings['segments'] ?? []; return $this->settings['segments'] ?? [];
} }
public function getFields(array $body = null): array {
$body = $body ?? $this->getBody();
if (empty($body)) {
return [];
}
$skippedTypes = ['html', 'divider', 'submit'];
$nestedTypes = ['column', 'columns'];
$fields = [];
foreach ($body as $field) {
if (!empty($field['type']) && in_array($field['type'], $nestedTypes) && !empty($field['body'])) {
$nestedFields = $this->getFields($field['body']);
if ($nestedFields) {
$fields = array_merge($fields, $nestedFields);
}
continue;
}
if (empty($field['id']) || empty($field['type']) || in_array($field['type'], $skippedTypes)) {
continue;
}
if ((int)$field['id'] > 0) {
$fields[] = 'cf_' . $field['id'];
} else {
$fields[] = $field['id'];
}
}
return $fields;
}
} }

View File

@ -3,29 +3,35 @@
namespace MailPoet\Subscribers; namespace MailPoet\Subscribers;
use Exception; use Exception;
use MailPoet\Models\CustomField; use MailPoet\CustomFields\CustomFieldsRepository;
use MailPoet\Models\Form; use MailPoet\Entities\FormEntity;
use MailPoet\WP\Functions as WPFunctions;
class RequiredCustomFieldValidator { class RequiredCustomFieldValidator {
/** @var CustomFieldsRepository */
private $customFieldRepository;
public function __construct(CustomFieldsRepository $customFieldRepository) {
$this->customFieldRepository = $customFieldRepository;
}
/** /**
* @param array $data * @param array $data
* @param Form|null $form * @param FormEntity|null $form
* *
* @throws Exception * @throws Exception
*/ */
public function validate(array $data, Form $form = null) { public function validate(array $data, FormEntity $form = null) {
$allCustomFields = $this->getCustomFields($form); $allCustomFields = $this->getCustomFields($form);
foreach ($allCustomFields as $customFieldId => $customFieldName) { foreach ($allCustomFields as $customFieldId => $customFieldName) {
if ($this->isCustomFieldMissing($customFieldId, $data)) { if ($this->isCustomFieldMissing($customFieldId, $data)) {
throw new Exception( throw new Exception(
WPFunctions::get()->__(sprintf('Missing value for custom field "%s"', $customFieldName), 'mailpoet') __(sprintf('Missing value for custom field "%s"', $customFieldName), 'mailpoet')
); );
} }
} }
} }
private function isCustomFieldMissing($customFieldId, $data) { private function isCustomFieldMissing(int $customFieldId, array $data): bool {
if (!array_key_exists($customFieldId, $data) && !array_key_exists('cf_' . $customFieldId, $data)) { if (!array_key_exists($customFieldId, $data) && !array_key_exists('cf_' . $customFieldId, $data)) {
return true; return true;
} }
@ -38,7 +44,7 @@ class RequiredCustomFieldValidator {
return false; return false;
} }
private function getCustomFields(Form $form = null) { private function getCustomFields(FormEntity $form = null): array {
$result = []; $result = [];
if ($form) { if ($form) {
@ -46,25 +52,23 @@ class RequiredCustomFieldValidator {
if (!$ids) { if (!$ids) {
return []; return [];
} }
$requiredCustomFields = CustomField::whereIn('id', $ids)->findMany(); $requiredCustomFields = $this->customFieldRepository->findBy(['id' => $ids]);
} else { } else {
$requiredCustomFields = CustomField::findMany(); $requiredCustomFields = $this->customFieldRepository->findAll();
} }
foreach ($requiredCustomFields as $customField) { foreach ($requiredCustomFields as $customField) {
if (is_serialized($customField->params)) { $params = $customField->getParams();
$params = unserialize($customField->params);
if (is_array($params) && isset($params['required']) && $params['required']) { if (is_array($params) && isset($params['required']) && $params['required']) {
$result[$customField->id] = $customField->name; $result[$customField->getId()] = $customField->getName();
}
} }
} }
return $result; return $result;
} }
private function getFormCustomFieldIds(Form $form) { private function getFormCustomFieldIds(FormEntity $form): array {
$formFields = $form->getFieldList(); $formFields = $form->getFields();
$customFieldIds = []; $customFieldIds = [];
foreach ($formFields as $fieldName) { foreach ($formFields as $fieldName) {
if (strpos($fieldName, 'cf_') === 0) { if (strpos($fieldName, 'cf_') === 0) {

View File

@ -2,18 +2,26 @@
namespace MailPoet\Subscribers; namespace MailPoet\Subscribers;
use MailPoet\Models\CustomField; use MailPoet\CustomFields\CustomFieldsRepository;
use MailPoet\Models\Form; use MailPoet\Entities\CustomFieldEntity;
use MailPoetVendor\Idiorm\ORM; use MailPoet\Entities\FormEntity;
class RequiredCustomFieldValidatorTest extends \MailPoetTest { class RequiredCustomFieldValidatorTest extends \MailPoetTest {
/** @var CustomFieldEntity */
private $customField; private $customField;
/** @var CustomFieldsRepository */
private $customFieldRepository;
/** @var RequiredCustomFieldValidator */
private $validator;
public function _before() { public function _before() {
parent::_before(); parent::_before();
ORM::raw_execute('TRUNCATE ' . CustomField::$_table); $this->cleanup();
$this->customField = CustomField::createOrUpdate([ $this->customFieldRepository = $this->diContainer->get(CustomFieldsRepository::class);
$this->validator = new RequiredCustomFieldValidator($this->customFieldRepository);
$this->customField = $this->customFieldRepository->createOrUpdate([
'name' => 'custom field', 'name' => 'custom field',
'type' => 'text', 'type' => 'text',
'params' => ['required' => '1'], 'params' => ['required' => '1'],
@ -21,52 +29,51 @@ class RequiredCustomFieldValidatorTest extends \MailPoetTest {
} }
public function testItValidatesDataWithoutCustomField() { public function testItValidatesDataWithoutCustomField() {
$validator = new RequiredCustomFieldValidator();
$this->expectException('Exception'); $this->expectException('Exception');
$validator->validate([]); $this->validator->validate([]);
} }
public function testItValidatesDataWithCustomFieldPassedAsId() { public function testItValidatesDataWithCustomFieldPassedAsId() {
$validator = new RequiredCustomFieldValidator(); $this->validator->validate([$this->customField->getId() => 'value']);
$validator->validate([$this->customField->id() => 'value']);
} }
public function testItValidatesDataWithCustomFieldPassedAsCFId() { public function testItValidatesDataWithCustomFieldPassedAsCFId() {
$validator = new RequiredCustomFieldValidator(); $this->validator->validate(['cf_' . $this->customField->getId() => 'custom field']);
$validator->validate(['cf_' . $this->customField->id() => 'custom field']);
} }
public function testItValidatesDataWithEmptyCustomField() { public function testItValidatesDataWithEmptyCustomField() {
$validator = new RequiredCustomFieldValidator();
$this->expectException('Exception'); $this->expectException('Exception');
$validator->validate([$this->customField->id() => '']); $this->validator->validate([$this->customField->getId() => '']);
} }
public function testItValidatesDataWithEmptyCustomFieldAsCFId() { public function testItValidatesDataWithEmptyCustomFieldAsCFId() {
$validator = new RequiredCustomFieldValidator();
$this->expectException('Exception'); $this->expectException('Exception');
$validator->validate(['cf_' . $this->customField->id() => '']); $this->validator->validate(['cf_' . $this->customField->getId() => '']);
} }
public function testItValidatesOnlyFieldPresentInForm() { public function testItValidatesOnlyFieldPresentInForm() {
CustomField::createOrUpdate([ $this->customFieldRepository->createOrUpdate([
'name' => 'custom field 2', 'name' => 'custom field 2',
'type' => 'text', 'type' => 'text',
'params' => ['required' => '1'], 'params' => ['required' => '1'],
]); ]);
$form = Form::createOrUpdate([ $form = new FormEntity('form');
'name' => 'form', $form->setBody([
'body' => [[
'type' => 'text', 'type' => 'text',
'name' => 'mandatory', 'name' => 'mandatory',
'id' => $this->customField->id(), 'id' => $this->customField->getId(),
'unique' => '1', 'unique' => '1',
'static' => '0', 'static' => '0',
'params' => ['required' => '1'], 'params' => ['required' => '1'],
'position' => '0', 'position' => '0',
]],
]); ]);
$validator = new RequiredCustomFieldValidator(); $this->entityManager->persist($form);
$validator->validate(['cf_' . $this->customField->id() => 'value'], $form); $this->entityManager->flush();
$this->validator->validate(['cf_' . $this->customField->getId() => 'value'], $form);
}
private function cleanup() {
$this->truncateEntity(CustomFieldEntity::class);
$this->truncateEntity(FormEntity::class);
} }
} }