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 {
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;
use Exception;
use MailPoet\Models\CustomField;
use MailPoet\Models\Form;
use MailPoet\WP\Functions as WPFunctions;
use MailPoet\CustomFields\CustomFieldsRepository;
use MailPoet\Entities\FormEntity;
class RequiredCustomFieldValidator {
/** @var CustomFieldsRepository */
private $customFieldRepository;
public function __construct(CustomFieldsRepository $customFieldRepository) {
$this->customFieldRepository = $customFieldRepository;
}
/**
* @param array $data
* @param Form|null $form
* @param FormEntity|null $form
*
* @throws Exception
*/
public function validate(array $data, Form $form = null) {
public function validate(array $data, FormEntity $form = null) {
$allCustomFields = $this->getCustomFields($form);
foreach ($allCustomFields as $customFieldId => $customFieldName) {
if ($this->isCustomFieldMissing($customFieldId, $data)) {
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)) {
return true;
}
@ -38,7 +44,7 @@ class RequiredCustomFieldValidator {
return false;
}
private function getCustomFields(Form $form = null) {
private function getCustomFields(FormEntity $form = null): array {
$result = [];
if ($form) {
@ -46,25 +52,23 @@ class RequiredCustomFieldValidator {
if (!$ids) {
return [];
}
$requiredCustomFields = CustomField::whereIn('id', $ids)->findMany();
$requiredCustomFields = $this->customFieldRepository->findBy(['id' => $ids]);
} else {
$requiredCustomFields = CustomField::findMany();
$requiredCustomFields = $this->customFieldRepository->findAll();
}
foreach ($requiredCustomFields as $customField) {
if (is_serialized($customField->params)) {
$params = unserialize($customField->params);
$params = $customField->getParams();
if (is_array($params) && isset($params['required']) && $params['required']) {
$result[$customField->id] = $customField->name;
}
$result[$customField->getId()] = $customField->getName();
}
}
return $result;
}
private function getFormCustomFieldIds(Form $form) {
$formFields = $form->getFieldList();
private function getFormCustomFieldIds(FormEntity $form): array {
$formFields = $form->getFields();
$customFieldIds = [];
foreach ($formFields as $fieldName) {
if (strpos($fieldName, 'cf_') === 0) {

View File

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