customFieldsRepository = $customFieldsRepository; $this->wordPress = $wordPress; } /** @return Field[] */ public function getFields(): array { return array_map(function (CustomFieldEntity $customField) { return $this->getField($customField); }, $this->customFieldsRepository->findAll()); } private function getField(CustomFieldEntity $customField): Field { switch ($customField->getType()) { case CustomFieldEntity::TYPE_TEXT: case CustomFieldEntity::TYPE_TEXTAREA: $validate = $customField->getParams()['validate'] ?? null; return $validate === 'number' ? $this->createNumberField($customField) : $this->createStringField($customField); case CustomFieldEntity::TYPE_CHECKBOX: return $this->createBooleanField($customField); case CustomFieldEntity::TYPE_RADIO: case CustomFieldEntity::TYPE_SELECT: return $this->createEnumField($customField); case CustomFieldEntity::TYPE_DATE: $type = $customField->getParams()['date_type'] ?? null; if ($type === 'year_month_day' || $type === 'year_month') { return $this->createDateTimeField($customField); } elseif ($type === 'year') { return $this->createYearField($customField); } elseif ($type === 'month') { return $this->createMonthField($customField); } elseif ($type === 'day') { return $this->createDayField($customField); } else { throw new InvalidStateException(sprintf('Unknown date type "%s"', $type)); } default: throw new InvalidStateException(sprintf('Unknown custom field type "%s"', $customField->getType())); } } private function createStringField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { return $this->getCustomFieldValue($payload, $customField); }; return $this->createField($customField, Field::TYPE_STRING, $factory); } private function createNumberField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { $value = $this->getCustomFieldValue($payload, $customField); return is_numeric($value) ? (float)$value : null; }; return $this->createField($customField, Field::TYPE_NUMBER, $factory); } private function createBooleanField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { $value = $this->getCustomFieldValue($payload, $customField); return $value === null ? null : (bool)$value; }; return $this->createField($customField, Field::TYPE_BOOLEAN, $factory); } private function createEnumField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { $value = $this->getCustomFieldValue($payload, $customField); return $value === null ? null : $value; }; return $this->createField($customField, Field::TYPE_ENUM, $factory, [ 'options' => array_map(function (array $value) { return ['id' => $value['value'], 'name' => $value['value']]; }, $customField->getParams()['values'] ?? []), ]); } private function createDateTimeField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { return $this->getDateTimeValue($customField, $this->getCustomFieldValue($payload, $customField) ?? ''); }; return $this->createField($customField, Field::TYPE_DATETIME, $factory); } private function createYearField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { $value = $this->getDateTimeValue($customField, $this->getCustomFieldValue($payload, $customField) ?? ''); return $value ? (int)$value->format('Y') : null; }; return $this->createField($customField, Field::TYPE_INTEGER, $factory); } private function createMonthField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { $value = $this->getDateTimeValue($customField, $this->getCustomFieldValue($payload, $customField) ?? ''); return $value ? (int)$value->format('n') : null; }; return $this->createField($customField, Field::TYPE_ENUM, $factory, [ 'options' => array_map(function (int $value) { return ['id' => $value, 'name' => $this->wordPress->getWpLocale()->get_month($value)]; }, range(1, 12)), ]); } private function createDayField(CustomFieldEntity $customField): Field { $factory = function (SubscriberPayload $payload) use ($customField) { $value = $this->getDateTimeValue($customField, $this->getCustomFieldValue($payload, $customField) ?? ''); return $value ? (int)$value->format('j') : null; }; return $this->createField($customField, Field::TYPE_ENUM, $factory, [ 'options' => array_map(function (int $value) { return ['id' => $value, 'name' => "$value"]; }, range(1, 31)), ]); } private function getCustomFieldValue(SubscriberPayload $payload, CustomFieldEntity $customField): ?string { $subscriberCustomField = $payload->getSubscriber()->getSubscriberCustomFields()->filter( function (SubscriberCustomFieldEntity $subscriberCustomField = null) use ($customField) { return $subscriberCustomField && $subscriberCustomField->getCustomField() === $customField; } )->first() ?: null; return $subscriberCustomField ? $subscriberCustomField->getValue() : null; } private function createField(CustomFieldEntity $customField, string $type, callable $factory, array $args = []): Field { $key = 'mailpoet:subscriber:custom-field:' . $customField->getName(); $name = sprintf( // translators: %s is the name of the custom field __('Custom field: %s', 'mailpoet'), $customField->getParams()['label'] ?? $customField->getName() ); return new Field($key, $type, $name, $factory, $args); } private function getDateTimeValue(CustomFieldEntity $customField, ?string $value): ?DateTimeImmutable { $dateFormat = $customField->getParams()['date_format'] ?? null; if (!$dateFormat || !$value) { return null; } $dateString = (new DateConverter())->convertDateToDatetime($value, $dateFormat) ?: null; return $dateString ? new DateTimeImmutable($dateString, $this->wordPress->wpTimezone()) : null; } }