From 69d5eb42f7275c07ccc2e9403c36ba1ddf4ff8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lys=C3=BD?= Date: Tue, 30 Mar 2021 17:36:53 +0200 Subject: [PATCH] Use Doctrine in RequiredCustomFieldValidator [MAILPOET-3032] --- lib/Entities/FormEntity.php | 33 +++++++++ .../RequiredCustomFieldValidator.php | 38 ++++++----- .../RequiredCustomFieldValidatorTest.php | 67 ++++++++++--------- 3 files changed, 91 insertions(+), 47 deletions(-) diff --git a/lib/Entities/FormEntity.php b/lib/Entities/FormEntity.php index 2a6309b6ed..7a252ff79d 100644 --- a/lib/Entities/FormEntity.php +++ b/lib/Entities/FormEntity.php @@ -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; + } } diff --git a/lib/Subscribers/RequiredCustomFieldValidator.php b/lib/Subscribers/RequiredCustomFieldValidator.php index 51ee115b2b..8e264ba82f 100644 --- a/lib/Subscribers/RequiredCustomFieldValidator.php +++ b/lib/Subscribers/RequiredCustomFieldValidator.php @@ -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); - if (is_array($params) && isset($params['required']) && $params['required']) { - $result[$customField->id] = $customField->name; - } + $params = $customField->getParams(); + if (is_array($params) && isset($params['required']) && $params['required']) { + $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) { diff --git a/tests/integration/Subscribers/RequiredCustomFieldValidatorTest.php b/tests/integration/Subscribers/RequiredCustomFieldValidatorTest.php index ce4fc5bbd7..237f204c3c 100644 --- a/tests/integration/Subscribers/RequiredCustomFieldValidatorTest.php +++ b/tests/integration/Subscribers/RequiredCustomFieldValidatorTest.php @@ -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' => [[ - 'type' => 'text', - 'name' => 'mandatory', - 'id' => $this->customField->id(), - 'unique' => '1', - 'static' => '0', - 'params' => ['required' => '1'], - 'position' => '0', - ]], + $form = new FormEntity('form'); + $form->setBody([ + 'type' => 'text', + 'name' => 'mandatory', + '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); } }