This commit is contained in:
emmymayo
2025-02-05 23:15:46 +01:00
commit 7269c99357
16995 changed files with 3389680 additions and 0 deletions
@@ -0,0 +1,307 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\Util\FieldNameObfuscator;
use MailPoet\Services\Validator;
use MailPoet\WP\Functions as WPFunctions;
/**
* This class still covers several responsibilities and could be further refactored
* @package MailPoet\Form\Block
*/
class BlockRendererHelper {
/** @var FieldNameObfuscator */
private $fieldNameObfuscator;
/** @var WPFunctions */
protected $wp;
public function __construct(
FieldNameObfuscator $fieldNameObfuscator,
WPFunctions $wp
) {
$this->fieldNameObfuscator = $fieldNameObfuscator;
$this->wp = $wp;
}
public function getInputValidation(array $block, array $extraRules = [], ?int $formId = null): string {
$rules = [
'errors-container' => '.' . $this->getErrorsContainerClass($block, $formId),
];
$blockId = $this->wp->escAttr($block['id']);
if ($blockId === 'email') {
$rules['required'] = true;
$rules['minlength'] = Validator::EMAIL_MIN_LENGTH;
$rules['maxlength'] = Validator::EMAIL_MAX_LENGTH;
$rules['type-message'] = __('This value should be a valid email.', 'mailpoet');
}
if (($blockId === 'first_name') || ($blockId === 'last_name')) {
$errorMessages = [
__('Please specify a valid name.', 'mailpoet'),
__('Addresses in names are not permitted, please add your name instead.', 'mailpoet'),
];
$rules['names'] = '[' . implode(',', array_map(function (string $errorMessage): string {
return $this->wp->escAttr('"' . $errorMessage . '"');
}, $errorMessages)) . ']';
}
// Segments should be required only when form ID is not empty. That allows save form on subscription management site when any segment is not checked.
if ($blockId === 'segments' && $formId) {
$rules['required'] = true;
$rules['mincheck'] = 1;
$rules['group'] = $blockId;
$rules['required-message'] = __('Please select a list.', 'mailpoet');
}
if (static::getFieldIsRequired($block)) {
$rules['required'] = true;
$rules['required-message'] = __('This field is required.', 'mailpoet');
}
if (!empty($block['params']['validate'])) {
if ($block['params']['validate'] === 'phone') {
$rules['pattern'] = "^[\d\+\-\.\(\)\/\s]*$";
$rules['error-message'] = __('Please specify a valid phone number.', 'mailpoet');
} else {
$rules['type'] = $this->wp->escAttr($block['params']['validate']);
$rules['error-message'] = $this->translateValidationErrorMessage($block['params']['validate']);
}
}
if (in_array($block['type'], ['radio', 'checkbox', 'date'])) {
$rules['group'] = 'custom_field_' . $blockId;
}
$rules = array_merge($rules, $extraRules);
if (empty($rules)) {
return '';
}
$validation = [];
$rules = array_unique($rules);
foreach ($rules as $rule => $value) {
if (is_bool($value)) {
$value = ($value) ? 'true' : 'false';
}
// We need to use single quotes because we need to pass array of strings as a parameter for custom validation
if ($rule === 'names') {
$validation[] = 'data-parsley-' . $rule . '=\'' . $this->wp->wpKsesPost($value) . '\''; // The value has been escaped above.
} else {
$validation[] = 'data-parsley-' . $this->wp->escAttr($rule) . '="' . $this->wp->escAttr($this->wp->wpKsesPost($value)) . '"';
if ($rule === 'required') {
$validation[] = 'required aria-required="true"';
}
}
}
return join(' ', $validation);
}
public function renderLabel(array $block, array $formSettings): string {
$html = '';
$forId = '';
if (
isset($block['params']['hide_label'])
&& $block['params']['hide_label']
) {
return $html;
}
// If the label is displayed within the field,
// we'll use aria-label instead of a label element
if (
isset($block['params']['label_within'])
&& $block['params']['label_within']
) {
return $html;
}
$automationId = null;
if (in_array($block['id'], ['email', 'last_name', 'first_name'], true)) {
$automationId = 'data-automation-id="form_' . $block['id'] . '_label" ';
}
if (isset($formSettings['id'])) {
$forId = 'for="form_' . $block['id'] . '_' . $formSettings['id'] . '" ';
}
if (
isset($block['params']['label'])
&& strlen(trim($block['params']['label'])) > 0
) {
$labelClass = 'class="mailpoet_' . $block['type'] . '_label" ';
$html .= '<label '
. $forId
. $labelClass
. $this->renderFontStyle($formSettings, $block['styles'] ?? [])
. ($automationId ? " $automationId" : '')
. '>';
$html .= static::getFieldLabel($block);
if (static::getFieldIsRequired($block)) {
$html .= ' <span class="mailpoet_required" aria-hidden="true">*</span>';
}
$html .= '</label>';
}
return $html;
}
public function renderLegend(array $block, array $formSettings): string {
$html = '';
if (
isset($block['params']['hide_label'])
&& $block['params']['hide_label']
) {
return $html;
}
if (
isset($block['params']['label'])
&& strlen(trim($block['params']['label'])) > 0
) {
// Use _label suffix for backward compatibility
$labelClass = 'class="mailpoet_' . $block['type'] . '_label" ';
$html .= '<legend '
. $labelClass
. $this->renderFontStyle($formSettings, $block['styles'] ?? [])
. '>';
$html .= static::getFieldLabel($block);
if (static::getFieldIsRequired($block)) {
$html .= ' <span class="mailpoet_required" aria-hidden="true">*</span>';
}
$html .= '</legend>';
}
return $html;
}
public function renderFontStyle(array $formSettings, array $styles = []) {
$rules = [];
if (isset($formSettings['fontSize'])) {
$rules[] = 'font-size: ' . $formSettings['fontSize'] . (is_numeric($formSettings['fontSize']) ? "px;" : ";");
$rules[] = 'line-height: 1.2;';
}
if (isset($styles['bold']) && $styles['bold']) {
$rules[] = 'font-weight: bold;';
}
return $rules ? 'style="' . $this->wp->escAttr(implode("", $rules)) . '"' : '';
}
public function renderInputPlaceholder(array $block): string {
$html = '';
// if the label is displayed as a placeholder,
if (
isset($block['params']['label_within'])
&& $block['params']['label_within']
) {
$label = $this->wp->escAttr(static::getFieldLabel($block));
if (static::getFieldIsRequired($block)) {
$label .= ' *';
}
// Some screen readers don't read placeholders, so we need to add aria-label
// but to prevent reading it twice, they need to be the same (including *)
$html .= ' placeholder="' . $label . '"';
$html .= ' aria-label="' . $label . '" ';
}
return $html;
}
// return field name depending on block data
public function getFieldName(array $block = []): string {
$blockId = $this->wp->escAttr($block['id']);
if ((int)$blockId > 0) {
return 'cf_' . $blockId;
} elseif (isset($block['params']['obfuscate']) && !$block['params']['obfuscate']) {
return $blockId;
} else {
return $this->fieldNameObfuscator->obfuscate($block['id']);//obfuscate field name for spambots
}
}
public function getFieldLabel(array $block = []): string {
return (isset($block['params']['label'])
&& strlen(trim($block['params']['label'])) > 0)
? $this->wp->escHtml(trim($block['params']['label'])) : '';
}
public function getFieldValue($block = []) {
return (isset($block['params']['value'])
&& strlen(trim($block['params']['value'])) > 0)
? $this->wp->escAttr(trim($block['params']['value'])) : '';
}
public function getFieldIsRequired($block = []): bool {
return (isset($block['params']['required'])
&& strlen(trim($block['params']['required'])) > 0)
? !empty($block['params']['required']) : false;
}
public function getInputModifiers(array $block = []): string {
$modifiers = [];
if (isset($block['params']['readonly']) && $block['params']['readonly']) {
$modifiers[] = 'readonly';
}
if (isset($block['params']['disabled']) && $block['params']['disabled']) {
$modifiers[] = 'disabled';
}
return join(' ', $modifiers);
}
public function escapeShortCodes(?string $value): ?string {
if ($value === null) {
return null;
}
return preg_replace_callback('/' . $this->wp->getShortcodeRegex() . '/s', function ($matches) {
return str_replace(['[', ']'], ['&#91;', '&#93;'], $matches[0]);
}, $value);
}
public function renderErrorsContainer(array $block = [], ?int $formId = null): string {
$errorContainerClass = $this->getErrorsContainerClass($block, $formId);
return '<span class="' . $errorContainerClass . '"></span>';
}
private function getErrorsContainerClass(array $block = [], ?int $formId = null): string {
$validationId = $block['validation_id'] ?? null;
if (!$validationId) {
$validationId = $this->wp->escAttr($block['id']);
if ($formId) {
$validationId .= '_' . $formId;
}
}
return 'mailpoet_error_' . $validationId;
}
private function translateValidationErrorMessage(string $validate): string {
switch ($validate) {
case 'email':
return __('This value should be a valid email.', 'mailpoet');
case 'url':
return __('This value should be a valid url.', 'mailpoet');
case 'number':
return __('This value should be a valid number.', 'mailpoet');
case 'integer':
return __('This value should be a valid integer.', 'mailpoet');
case 'digits':
return __('This value should be digits.', 'mailpoet');
case 'alphanum':
return __('This value should be alphanumeric.', 'mailpoet');
default:
return __('This value seems to be invalid.', 'mailpoet');
}
}
}
@@ -0,0 +1,84 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\Form\FormHtmlSanitizer;
use MailPoet\WP\Functions as WPFunctions;
class Checkbox {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var WPFunctions */
private $wp;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockWrapperRenderer $wrapper,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->wrapper = $wrapper;
$this->wp = $wp;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$html = '';
$fieldName = 'data[' . $this->rendererHelper->getFieldName($block) . ']';
$fieldValidation = $this->rendererHelper->getInputValidation($block, [], $formId);
$html .= '<fieldset>';
$html .= $this->rendererHelper->renderLegend($block, $formSettings);
$options = (!empty($block['params']['values'])
? $block['params']['values']
: []
);
$selectedValue = $this->rendererHelper->getFieldValue($block);
$isFieldRequired = $this->rendererHelper->getFieldIsRequired($block);
foreach ($options as $option) {
$hiddenValue = $isFieldRequired ? '1' : '0'; // Mandatory Fields can not be Empty
$html .= '<input type="hidden" value="' . $hiddenValue . '" name="' . $fieldName . '" />';
$id = $this->wp->wpUniqueId('mailpoet_checkbox_');
$html .= '<label class="mailpoet_checkbox_label" for="' . $id . '" '
. $this->rendererHelper->renderFontStyle($formSettings) . '>';
$html .= '<input type="checkbox" class="mailpoet_checkbox" ';
$html .= 'id="' . $id . '" ';
$html .= 'name="' . $fieldName . '" ';
$html .= 'value="1" ';
$html .= (
(
$selectedValue === ''
&& isset($option['is_checked'])
&& $option['is_checked']
) || ($selectedValue)
) ? 'checked="checked"' : '';
$html .= $fieldValidation;
$html .= ' /> ' . $this->wp->wpKses($option['value'], FormHtmlSanitizer::ALLOWED_HTML);
$html .= '</label>';
}
$html .= '</fieldset>';
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
return $this->wrapper->render($block, $html);
}
}
@@ -0,0 +1,66 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class Column {
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
public function render(array $block, string $content): string {
return "<div {$this->getClass($block['params'])}{$this->getStyles($block['params'])}>$content</div>";
}
private function getStyles(array $params): string {
$styles = [];
if (
!empty($params['width']) &&
(strlen($params['width']) > 0 && ctype_digit(substr($params['width'], 0, 1)))
) {
$widthValue = $params['width'] . (is_numeric($params['width']) ? '%' : '');
$styles[] = "flex-basis:{$widthValue}";
}
if (!empty($params['padding']) && is_array($params['padding'])) {
$top = $params['padding']['top'] ?? 0;
$right = $params['padding']['right'] ?? 0;
$bottom = $params['padding']['bottom'] ?? 0;
$left = $params['padding']['left'] ?? 0;
$styles[] = "padding:{$top} {$right} {$bottom} {$left};";
}
if (!empty($params['text_color'])) {
$styles[] = "color:{$params['text_color']};";
}
if (!empty($params['background_color'])) {
$styles[] = "background-color:{$params['background_color']};";
}
if (!empty($params['gradient'])) {
$styles[] = "background:{$params['gradient']};";
}
if (!count($styles)) {
return '';
}
return ' style="' . $this->wp->escAttr(implode(';', $styles)) . ';"';
}
private function getClass(array $params): string {
$classes = ['mailpoet_form_column'];
if (!empty($params['vertical_alignment'])) {
$classes[] = "mailpoet_vertically_align_{$params['vertical_alignment']}";
}
if (!empty($params['class_name'])) {
$classes[] = $params['class_name'];
}
$classes = implode(' ', $classes);
return "class=\"{$this->wp->escAttr($classes)}\"";
}
}
@@ -0,0 +1,69 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class Columns {
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
public function render(array $block, string $content): string {
return "<div class='mailpoet_form_columns_container'><div {$this->getClass($block['params'] ?? [])}{$this->getStyles($block['params'] ?? [])}>$content</div></div>";
}
private function getStyles(array $params): string {
$styles = [];
if (!empty($params['text_color'])) {
$styles[] = "color:{$params['text_color']};";
}
if (!empty($params['background_color'])) {
$styles[] = "background-color:{$params['background_color']};";
}
if (!empty($params['gradient'])) {
$styles[] = "background:{$params['gradient']};";
}
if (!empty($params['padding']) && is_array($params['padding'])) {
$top = $params['padding']['top'] ?? 0;
$right = $params['padding']['right'] ?? 0;
$bottom = $params['padding']['bottom'] ?? 0;
$left = $params['padding']['left'] ?? 0;
$styles[] = "padding:{$top} {$right} {$bottom} {$left};";
}
if (count($styles)) {
return ' style="' . $this->wp->escAttr(implode('', $styles)) . '"';
}
return '';
}
private function getClass(array $params): string {
$classes = ['mailpoet_form_columns mailpoet_paragraph'];
if (!empty($params['vertical_alignment'])) {
$classes[] = "mailpoet_vertically_align_{$params['vertical_alignment']}";
}
if (!empty($params['background_color']) || !empty($params['gradient'])) {
$classes[] = "mailpoet_column_with_background";
}
if (!empty($params['text_color'])) {
$classes[] = "has-{$params['text_color']}-color";
}
// BC !isset for older forms that were saved without the flag
if (!isset($params['is_stacked_on_mobile']) || $params['is_stacked_on_mobile'] === '1') {
$classes[] = "mailpoet_stack_on_mobile";
}
if (!empty($params['class_name'])) {
$classes[] = $params['class_name'];
}
$classes = implode(' ', $classes);
return "class=\"{$this->wp->escAttr($classes)}\"";
}
}
@@ -0,0 +1,226 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockStylesRenderer;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\WP\Functions as WPFunctions;
use MailPoetVendor\Carbon\CarbonImmutable;
class Date {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var BlockStylesRenderer */
private $blockStylesRenderer;
/** @var WPFunctions */
private $wp;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockStylesRenderer $blockStylesRenderer,
BlockWrapperRenderer $wrapper,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->wrapper = $wrapper;
$this->blockStylesRenderer = $blockStylesRenderer;
$this->wp = $wp;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$html = '';
$html .= $this->rendererHelper->renderLabel($block, $formSettings);
$html .= $this->renderDateSelect($formId, $block, $formSettings);
return $this->wrapper->render($block, $html);
}
private function renderDateSelect(?int $formId, array $block = [], $formSettings = []): string {
$html = '';
$fieldName = 'data[' . $this->rendererHelper->getFieldName($block) . ']';
$dateFormats = $this->getDateFormats();
// automatically select first date format
$dateFormat = $dateFormats[$block['params']['date_type']][0];
// set date format if specified
if (
isset($block['params']['date_format'])
&& strlen(trim($block['params']['date_format'])) > 0
) {
$dateFormat = $block['params']['date_format'];
}
// generate an array of selectors based on date format
$dateSelectors = explode('/', $dateFormat);
foreach ($dateSelectors as $dateSelector) {
if ($dateSelector === 'DD') {
$html .= '<select class="mailpoet_date_day" ';
$html .= ' style="' . $this->wp->escAttr($this->blockStylesRenderer->renderForSelect([], $formSettings)) . '"';
$html .= $this->rendererHelper->getInputValidation($block, [
'required-message' => $this->wp->escAttr(__('Please select a day', 'mailpoet')),
], $formId);
$html .= 'name="' . $fieldName . '[day]" placeholder="' . $this->wp->escAttr(__('Day', 'mailpoet')) . '">';
$html .= $this->getDays($block);
$html .= '</select>';
} else if ($dateSelector === 'MM') {
$html .= '<select class="mailpoet_select mailpoet_date_month" data-automation-id="form_date_month" ';
$html .= ' style="' . $this->wp->escAttr($this->blockStylesRenderer->renderForSelect([], $formSettings)) . '"';
$html .= $this->rendererHelper->getInputValidation($block, [
'required-message' => $this->wp->escAttr(__('Please select a month', 'mailpoet')),
], $formId);
$html .= 'name="' . $fieldName . '[month]" placeholder="' . $this->wp->escAttr(__('Month', 'mailpoet')) . '">';
$html .= $this->getMonths($block);
$html .= '</select>';
} else if ($dateSelector === 'YYYY') {
$html .= '<select class="mailpoet_date_year" data-automation-id="form_date_year" ';
$html .= ' style="' . $this->wp->escAttr($this->blockStylesRenderer->renderForSelect([], $formSettings)) . '"';
$html .= $this->rendererHelper->getInputValidation($block, [
'required-message' => $this->wp->escAttr(__('Please select a year', 'mailpoet')),
], $formId);
$html .= 'name="' . $fieldName . '[year]" placeholder="' . $this->wp->escAttr(__('Year', 'mailpoet')) . '">';
$html .= $this->getYears($block);
$html .= '</select>';
}
}
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
return $html;
}
public function getDateTypes(): array {
return [
'year_month_day' => $this->wp->escHtml(__('Year, month, day', 'mailpoet')),
'year_month' => $this->wp->escHtml(__('Year, month', 'mailpoet')),
'month' => $this->wp->escHtml(__('Month (January, February,...)', 'mailpoet')),
'year' => $this->wp->escHtml(__('Year', 'mailpoet')),
];
}
public function getDateFormats(): array {
return [
'year_month_day' => ['MM/DD/YYYY', 'DD/MM/YYYY', 'YYYY/MM/DD'],
'year_month' => ['MM/YYYY', 'YYYY/MM'],
'year' => ['YYYY'],
'month' => ['MM'],
];
}
public function getMonthNames(): array {
return [__('January', 'mailpoet'), __('February', 'mailpoet'), __('March', 'mailpoet'), __('April', 'mailpoet'),
__('May', 'mailpoet'), __('June', 'mailpoet'), __('July', 'mailpoet'), __('August', 'mailpoet'), __('September', 'mailpoet'),
__('October', 'mailpoet'), __('November', 'mailpoet'), __('December', 'mailpoet'),
];
}
private function getMonths(array $block = []): string {
$defaults = [
'selected' => null,
];
if (!empty($block['params']['value'])) {
$date = CarbonImmutable::createFromFormat('Y-m-d H:i:s', $block['params']['value']);
if ($date instanceof CarbonImmutable) {
$defaults['selected'] = (int)date('m', $date->getTimestamp());
}
} elseif (!empty($block['params']['is_default_today'])) {
// is default today
$defaults['selected'] = (int)date('m');
}
// merge block with defaults
$block = array_merge($defaults, $block);
$monthNames = $this->getMonthNames();
$html = '';
// empty value label
$html .= '<option value="">' . $this->wp->escHtml(__('Month', 'mailpoet')) . '</option>';
for ($i = 1; $i < 13; $i++) {
$isSelected = ($i === $block['selected']) ? 'selected="selected"' : '';
$html .= '<option value="' . $i . '" ' . $isSelected . '>';
$html .= $this->wp->escHtml($monthNames[$i - 1]);
$html .= '</option>';
}
return $html;
}
private function getYears(array $block = []): string {
$defaults = [
'selected' => null,
'from' => (int)date('Y') - 100,
'to' => (int)date('Y'),
];
if (!empty($block['params']['value'])) {
$date = CarbonImmutable::createFromFormat('Y-m-d H:i:s', $block['params']['value']);
if ($date instanceof CarbonImmutable) {
$defaults['selected'] = (int)date('Y', $date->getTimestamp());
}
} elseif (!empty($block['params']['is_default_today'])) {
// is default today
$defaults['selected'] = (int)date('Y');
}
// merge block with defaults
$block = array_merge($defaults, $block);
$html = '';
// empty value label
$html .= '<option value="">' . $this->wp->escHtml(__('Year', 'mailpoet')) . '</option>';
// return years as an array
for ($i = (int)$block['to']; $i > (int)($block['from'] - 1); $i--) {
$isSelected = ($i === $block['selected']) ? 'selected="selected"' : '';
$html .= '<option value="' . $i . '" ' . $isSelected . '>' . $i . '</option>';
}
return $html;
}
private function getDays(array $block = []): string {
$defaults = [
'selected' => null,
];
if (!empty($block['params']['value'])) {
$date = CarbonImmutable::createFromFormat('Y-m-d H:i:s', $block['params']['value']);
if ($date instanceof CarbonImmutable) {
$defaults['selected'] = (int)date('d', $date->getTimestamp());
}
} elseif (!empty($block['params']['is_default_today'])) {
// is default today
$defaults['selected'] = (int)date('d');
}
// merge block with defaults
$block = array_merge($defaults, $block);
$html = '';
// empty value label
$html .= '<option value="">' . $this->wp->escHtml(__('Day', 'mailpoet')) . '</option>';
// return days as an array
for ($i = 1; $i < 32; $i++) {
$isSelected = ($i === $block['selected']) ? 'selected="selected"' : '';
$html .= '<option value="' . $i . '" ' . $isSelected . '>' . $i . '</option>';
}
return $html;
}
}
@@ -0,0 +1,63 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class Divider {
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
const DEFAULT_ATTRIBUTES = [
'height' => 1,
'type' => 'divider',
'style' => 'solid',
'dividerHeight' => 1,
'dividerWidth' => 100,
'color' => 'black',
];
public function render($block): string {
$classes = ['mailpoet_spacer'];
if (isset($block['params']['type']) && $block['params']['type'] === 'divider') {
$classes[] = 'mailpoet_has_divider';
}
if (!empty($block['params']['class_name'])) {
$classes[] = $block['params']['class_name'];
}
$classAttr = $this->wp->escAttr(join(' ', $classes));
$height = $this->wp->escAttr($block['params']['height'] ?? self::DEFAULT_ATTRIBUTES['height']);
return "<div class='{$classAttr}' style='height: {$height}px;'>"
. $this->renderDivider($block)
. '</div>';
}
private function renderDivider(array $block): string {
if (isset($block['params']['type']) && $block['params']['type'] === 'spacer') {
return '';
}
$width = $block['params']['divider_width'] ?? self::DEFAULT_ATTRIBUTES['dividerWidth'];
$style = $block['params']['style'] ?? self::DEFAULT_ATTRIBUTES['style'];
$dividerHeight = $block['params']['divider_height'] ?? self::DEFAULT_ATTRIBUTES['dividerHeight'];
$color = $block['params']['color'] ?? self::DEFAULT_ATTRIBUTES['color'];
$dividerStyles = [
"border-top-style: $style",
"border-top-width: {$dividerHeight}px",
"border-top-color: $color",
"height: {$dividerHeight}px",
"width: $width%",
];
$style = $this->wp->escAttr(implode(";", $dividerStyles));
return "<div class='mailpoet_divider' data-automation-id='form_divider' style='$style'></div>";
}
}
@@ -0,0 +1,121 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class Heading {
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
public function render(array $block): string {
$content = ($block['params']['content'] ?? '');
return $this->wrapContent($content, $block);
}
private function wrapContent(string $content, array $block): string {
$tag = $this->renderTag($block);
$attributes = $this->renderAttributes($block);
$openTag = $this->getOpenTag($tag, $attributes);
return $openTag
. $content
. "</$tag>";
}
private function renderTag(array $block): string {
$level = isset($block['params']['level']) ? (int)$block['params']['level'] : 2;
return ($level < 1 || $level > 6) ? 'h2' : 'h' . $level;
}
private function renderAttributes(array $block): array {
$result = [];
$classes = $this->renderClass($block);
if ($classes) {
$result[] = $classes;
}
if (!empty($block['params']['anchor'])) {
$result[] = $this->renderAnchor($block);
}
$styles = $this->renderStyle($block);
if ($styles) {
$result[] = $styles;
}
return $result;
}
private function getOpenTag(string $tag, array $attributes): string {
if (empty($attributes)) {
return "<$tag>";
}
return "<$tag " . join(' ', $attributes) . ">";
}
private function renderClass(array $block): string {
$classes = ['mailpoet-heading'];
if (isset($block['params']['class_name'])) {
$classes[] = $block['params']['class_name'];
}
if (!empty($block['params']['background_color']) || !empty($block['params']['gradient'])) {
$classes[] = 'mailpoet-has-background-color';
}
if (!empty($block['params']['font_size'])) {
$classes[] = 'mailpoet-has-font-size';
}
return 'class="'
. $this->wp->escAttr(join(' ', $classes))
. '"';
}
private function renderAnchor(array $block): string {
return 'id="'
. $this->wp->escAttr($block['params']['anchor'])
. '"';
}
private function renderStyle(array $block): string {
$styles = [];
if (!empty($block['params']['align'])) {
$styles[] = 'text-align: ' . $block['params']['align'];
}
if (!empty($block['params']['text_color'])) {
$styles[] = 'color: ' . $block['params']['text_color'];
}
if (!empty($block['params']['font_size'])) {
$styles[] = 'font-size: ' . $block['params']['font_size'] . (is_numeric($block['params']['font_size']) ? 'px' : '');
}
if (!empty($block['params']['line_height'])) {
$styles[] = 'line-height: ' . $block['params']['line_height'];
}
if (!empty($block['params']['background_color'])) {
$styles[] = 'background-color: ' . $block['params']['background_color'];
}
if (!empty($block['params']['gradient'])) {
$styles[] = "background: {$block['params']['gradient']};";
}
if (!empty($block['params']['padding']) && is_array($block['params']['padding'])) {
$top = $block['params']['padding']['top'] ?? 0;
$right = $block['params']['padding']['right'] ?? 0;
$bottom = $block['params']['padding']['bottom'] ?? 0;
$left = $block['params']['padding']['left'] ?? 0;
$styles[] = "padding:{$top} {$right} {$bottom} {$left};";
}
if (empty($styles)) {
return '';
}
return 'style="'
. $this->wp->escAttr(join('; ', $styles))
. '"';
}
}
@@ -0,0 +1,43 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class Html {
/** @var BlockRendererHelper */
private $rendererHelper;
private WPFunctions $wp;
public function __construct(
BlockRendererHelper $rendererHelper,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->wp = $wp;
}
public function render(array $block, array $formSettings): string {
$html = '';
$text = '';
if (isset($block['params']['text']) && $block['params']['text']) {
$text = html_entity_decode($block['params']['text'], ENT_QUOTES);
}
if (isset($block['params']['nl2br']) && $block['params']['nl2br']) {
$text = nl2br($text);
}
$classes = isset($block['params']['class_name']) ? " " . $block['params']['class_name'] : '';
$html .= '<div class="mailpoet_paragraph' . $this->wp->escAttr($classes) . '" ' . $this->rendererHelper->renderFontStyle($formSettings) . '>';
$html .= $this->wp->wpKsesPost($text);
$html .= '</div>';
return $html;
}
}
@@ -0,0 +1,92 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\FormHtmlSanitizer;
use MailPoet\WP\Functions as WPFunctions;
class Image {
/** @var WPFunctions */
private $wp;
/** @var FormHtmlSanitizer */
private $htmlSanitizer;
public function __construct(
WPFunctions $wp,
FormHtmlSanitizer $htmlSanitizer
) {
$this->wp = $wp;
$this->htmlSanitizer = $htmlSanitizer;
}
public function render(array $block): string {
if (empty($block['params']['url'])) {
return '';
}
return $this->wrapImage($block['params'], $this->renderImage($block['params']));
}
private function renderImage(array $params): string {
$attributes = [];
$styles = [];
$attributes[] = 'src="' . $this->wp->escAttr($params['url']) . '"';
$attributes[] = $params['alt'] ? 'alt="' . $this->wp->escAttr($params['alt']) . '"' : 'alt';
if ($params['title']) {
$attributes[] = 'title="' . $this->wp->escAttr($params['title']) . '"';
}
if ($params['id']) {
$attributes[] = 'class="wp-image-' . $this->wp->escAttr($params['id']) . '"';
$attributes[] = 'srcset="' . $this->wp->wpGetAttachmentImageSrcset(intval($params['id']), $params['size_slug']) . '"';
}
if ($params['width']) {
$attributes[] = 'width=' . intval($params['width']);
$styles[] = 'width: ' . intval($params['width']) . 'px';
}
if ($params['height']) {
$attributes[] = 'height=' . intval($params['height']);
$styles[] = 'height: ' . intval($params['height']) . 'px';
}
if ($styles) {
$attributes[] = 'style="' . $this->wp->escAttr(implode(';', $styles)) . '"';
}
return '<img ' . implode(' ', $attributes) . '>';
}
private function wrapImage(array $params, string $img): string {
// Figure
$figureClasses = ['size-' . $params['size_slug']];
if ($params['align']) {
$figureClasses[] = 'align' . $params['align'];
}
// Link
if ($params['href']) {
$img = $this->wrapToLink($params, $img);
}
$caption = isset($params['caption']) && $params['caption'] ? "<figcaption>{$this->htmlSanitizer->sanitize($params['caption'])}</figcaption>" : '';
$figure = '<figure class="' . $this->wp->escAttr(implode(' ', $figureClasses)) . '">' . $img . $caption . '</figure>';
// Main wrapper
$divClasses = ['mailpoet_form_image'];
if (trim($params['class_name'])) {
$divClasses[] = trim($params['class_name']);
}
return '<div class="' . $this->wp->escAttr(implode(' ', $divClasses)) . '">' . $figure . '</div>';
}
private function wrapToLink(array $params, string $img): string {
$attributes = ['href="' . $this->wp->escAttr($params['href']) . '"'];
if ($params['link_class']) {
$attributes[] = 'class="' . $this->wp->escAttr($params['link_class']) . '"';
}
if ($params['link_target']) {
$attributes[] = 'target="' . $this->wp->escAttr($params['link_target']) . '"';
}
if ($params['rel']) {
$attributes[] = 'rel="' . $this->wp->escAttr($params['rel']) . '"';
}
return '<a ' . implode(' ', $attributes) . ' >' . $img . '</a>';
}
}
@@ -0,0 +1,106 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class Paragraph {
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
public function render(array $block): string {
$content = ($block['params']['content'] ?? '');
return $this->wrapContent($content, $block);
}
private function wrapContent(string $content, array $block): string {
$attributes = $this->renderAttributes($block);
$openTag = $this->getOpenTag($attributes);
return $openTag
. $content
. "</p>";
}
private function getOpenTag(array $attributes): string {
if (empty($attributes)) {
return "<p>";
}
return "<p " . join(' ', $attributes) . ">";
}
private function renderAttributes(array $block): array {
$result = [];
$result[] = $this->renderClass($block);
$result[] = $this->renderStyle($block);
$result = array_filter($result, function ($attribute) {
return $attribute !== null;
});
return $result;
}
private function renderClass(array $block) {
$classes = ['mailpoet_form_paragraph'];
if (isset($block['params']['class_name'])) {
$classes[] = $block['params']['class_name'];
}
if (isset($block['params']['drop_cap']) && $block['params']['drop_cap'] === '1') {
$classes[] = 'has-drop-cap';
}
if (!empty($block['params']['background_color']) || !empty($block['params']['gradient'])) {
$classes[] = 'mailpoet-has-background-color';
}
if (!empty($block['params']['font_size'])) {
$classes[] = 'mailpoet-has-font-size';
}
if (empty($classes)) {
return null;
}
return 'class="'
. $this->wp->escAttr(join(' ', $classes))
. '"';
}
private function renderStyle(array $block) {
$styles = [];
if (!empty($block['params']['background_color'])) {
$styles[] = 'background-color: ' . $block['params']['background_color'];
}
if (!empty($block['params']['gradient'])) {
$styles[] = "background: {$block['params']['gradient']};";
}
if (!empty($block['params']['align'])) {
$styles[] = 'text-align: ' . $block['params']['align'];
}
if (!empty($block['params']['text_color'])) {
$styles[] = 'color: ' . $block['params']['text_color'];
}
if (!empty($block['params']['font_size'])) {
$styles[] = 'font-size: ' . $block['params']['font_size'] . (is_numeric($block['params']['font_size']) ? 'px' : '');
}
if (!empty($block['params']['line_height'])) {
$styles[] = 'line-height: ' . $block['params']['line_height'];
}
if (!empty($block['params']['padding']) && is_array($block['params']['padding'])) {
$top = $block['params']['padding']['top'] ?? 0;
$right = $block['params']['padding']['right'] ?? 0;
$bottom = $block['params']['padding']['bottom'] ?? 0;
$left = $block['params']['padding']['left'] ?? 0;
$styles[] = "padding:{$top} {$right} {$bottom} {$left};";
}
if (empty($styles)) {
return null;
}
return 'style="'
. $this->wp->escAttr(join('; ', $styles))
. '"';
}
}
@@ -0,0 +1,87 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\WP\Functions as WPFunctions;
class Radio {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var WPFunctions */
private $wp;
/** @var BlockWrapperRenderer */
private $wrapper;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockWrapperRenderer $wrapper,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->wrapper = $wrapper;
$this->wp = $wp;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$html = '';
$fieldName = 'data[' . $this->rendererHelper->getFieldName($block) . ']';
$fieldValidation = $this->rendererHelper->getInputValidation($block, [], $formId);
$html .= '<fieldset>';
$html .= $this->rendererHelper->renderLegend($block, $formSettings);
$options = (!empty($block['params']['values'])
? $block['params']['values']
: []
);
$selectedValue = $this->rendererHelper->getFieldValue($block);
foreach ($options as $option) {
$id = $this->wp->wpUniqueId('mailpoet_radio_');
$html .= '<label class="mailpoet_radio_label" for="' . $id . '" '
. $this->rendererHelper->renderFontStyle($formSettings)
. '>';
$html .= '<input type="radio" class="mailpoet_radio" ';
$html .= 'id="' . $id . '" ';
$html .= 'name="' . $fieldName . '" ';
if (is_array($option['value'])) {
$value = key($option['value']);
$label = reset($option['value']);
} else {
$value = $option['value'];
$label = $option['value'];
}
$html .= 'value="' . $this->wp->escAttr($value) . '" ';
$html .= (
(
$selectedValue === ''
&& isset($option['is_checked'])
&& $option['is_checked']
) || ($selectedValue === $value)
) ? 'checked="checked"' : '';
$html .= $fieldValidation;
$html .= ' /> ' . $this->wp->escAttr($label);
$html .= '</label>';
}
$html .= '</fieldset>';
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
return $this->wrapper->render($block, $html);
}
}
@@ -0,0 +1,94 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\Segments\SegmentsRepository;
use MailPoet\WP\Functions as WPFunctions;
class Segment {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var WPFunctions */
private $wp;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var SegmentsRepository */
private $segmentsRepository;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockWrapperRenderer $wrapper,
WPFunctions $wp,
SegmentsRepository $segmentsRepository
) {
$this->rendererHelper = $rendererHelper;
$this->wrapper = $wrapper;
$this->wp = $wp;
$this->segmentsRepository = $segmentsRepository;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$html = '';
$fieldName = 'data[' . $this->rendererHelper->getFieldName($block) . ']';
$fieldValidation = $this->rendererHelper->getInputValidation($block, [], $formId);
// Add fieldset around the checkboxes
$html .= '<fieldset>';
$html .= $this->rendererHelper->renderLegend($block, $formSettings);
$options = (!empty($block['params']['values'])
? $block['params']['values']
: []
);
$options = array_map(function ($option) {
$option['id'] = intval($option['id']);
return $option;
}, $options);
$segmentsNamesMap = $this->getSegmentsNames($options);
foreach ($options as $option) {
if (!isset($option['id']) || !isset($segmentsNamesMap[$option['id']])) continue;
$id = $this->wp->wpUniqueId('mailpoet_segment_');
$isChecked = (isset($option['is_checked']) && $option['is_checked']) ? 'checked="checked"' : '';
$html .= '<label class="mailpoet_checkbox_label" for="' . $id . '" '
. $this->rendererHelper->renderFontStyle($formSettings)
. '>';
$html .= '<input type="checkbox" class="mailpoet_checkbox" ';
$html .= 'id="' . $id . '" ';
$html .= 'name="' . $fieldName . '[]" ';
$html .= 'value="' . $option['id'] . '" ' . $isChecked . ' ';
$html .= $fieldValidation;
$html .= ' /> ' . $this->wp->escAttr($segmentsNamesMap[$option['id']]);
$html .= '</label>';
}
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
// End fieldset around checkboxes
$html .= '</fieldset>';
return $this->wrapper->render($block, $html);
}
private function getSegmentsNames($values): array {
$ids = array_column($values, 'id');
$segments = $this->segmentsRepository->findBy(['id' => $ids]);
$namesMap = [];
foreach ($segments as $segment) {
$namesMap[$segment->getId()] = $segment->getName();
}
return $namesMap;
}
}
@@ -0,0 +1,104 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockStylesRenderer;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\WP\Functions as WPFunctions;
class Select {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var WPFunctions */
private $wp;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var BlockStylesRenderer */
private $blockStylesRenderer;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockWrapperRenderer $wrapper,
BlockStylesRenderer $blockStylesRenderer,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->wrapper = $wrapper;
$this->wp = $wp;
$this->blockStylesRenderer = $blockStylesRenderer;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$html = '';
$fieldName = 'data[' . $this->rendererHelper->getFieldName($block) . ']';
$automationId = ($block['id'] == 'status') ? 'data-automation-id="form_status"' : '';
$html .= $this->rendererHelper->renderLabel($block, $formSettings);
$html .= '<select
class="mailpoet_select"
name="' . $fieldName . '" '
. $automationId
. 'style="' . $this->wp->escAttr($this->blockStylesRenderer->renderForSelect([], $formSettings)) . '"'
. '>';
if (isset($block['params']['label_within']) && $block['params']['label_within']) {
$label = $this->rendererHelper->getFieldLabel($block);
if (!empty($block['params']['required'])) {
$label .= ' *';
}
$html .= '<option value="" disabled selected hidden>' . $this->wp->escHtml($label) . '</option>';
} else {
if (empty($block['params']['required'])) {
$html .= '<option value="">-</option>';
}
}
$options = (!empty($block['params']['values'])
? $block['params']['values']
: []
);
foreach ($options as $option) {
if (!empty($option['is_hidden'])) {
continue;
}
$isSelected = '';
if ($this->rendererHelper->getFieldValue($block) === $option['value']) {
// use selected value if it exist
$isSelected = ' selected="selected"';
} elseif ((isset($option['is_checked']) && $option['is_checked']) && !($this->rendererHelper->getFieldValue($block))) {
// use default value otherwise
$isSelected = ' selected="selected"';
}
$isDisabled = (!empty($option['is_disabled'])) ? ' disabled="disabled"' : '';
if (is_array($option['value'])) {
$value = key($option['value']);
$label = reset($option['value']);
} else {
$value = $option['value'];
$label = $option['value'];
}
$html .= '<option value="' . $this->wp->escAttr($value) . '"' . $isSelected . $isDisabled . '>';
$html .= $this->wp->escAttr($label);
$html .= '</option>';
}
$html .= '</select>';
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
return $this->wrapper->render($block, $html);
}
}
@@ -0,0 +1,63 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockStylesRenderer;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\WP\Functions as WPFunctions;
class Submit {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var BlockStylesRenderer */
private $stylesRenderer;
/** @var WPFunctions */
private $wp;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockWrapperRenderer $wrapper,
BlockStylesRenderer $stylesRenderer,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->wrapper = $wrapper;
$this->stylesRenderer = $stylesRenderer;
$this->wp = $wp;
}
public function render(array $block, array $formSettings): string {
$html = '';
$html .= '<input type="submit" class="mailpoet_submit" ';
$html .= 'value="' . $this->wp->escAttr($this->rendererHelper->getFieldLabel($block)) . '" ';
$html .= 'data-automation-id="subscribe-submit-button" ';
if (isset($block['styles']['font_family'])) {
$html .= "data-font-family='{$this->wp->escAttr($block['styles']['font_family'])}' " ;
}
$styles = $this->stylesRenderer->renderForButton($block['styles'] ?? [], $formSettings);
if ($styles) {
$html .= 'style="' . $this->wp->escAttr($styles) . '" ';
}
$html .= '/>';
$html .= '<span class="mailpoet_form_loading"><span class="mailpoet_bounce1"></span><span class="mailpoet_bounce2"></span><span class="mailpoet_bounce3"></span></span>';
return $this->wrapper->render($block, $html);
}
}
@@ -0,0 +1,96 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockStylesRenderer;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\WP\Functions as WPFunctions;
class Text {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var BlockStylesRenderer */
private $inputStylesRenderer;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var WPFunctions */
private $wp;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockStylesRenderer $inputStylesRenderer,
BlockWrapperRenderer $wrapper,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->inputStylesRenderer = $inputStylesRenderer;
$this->wrapper = $wrapper;
$this->wp = $wp;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$type = 'text';
$automationId = ' ';
$id = '';
if ($block['id'] === 'email') {
$type = 'email';
$autocomplete = 'email';
} else if ($block['id'] === 'first_name') {
$autocomplete = 'given-name';
} else if ($block['id'] === 'last_name') {
$autocomplete = 'family-name';
} else {
$autocomplete = 'on';
}
if (in_array($block['id'], ['email', 'last_name', 'first_name'], true)) {
$automationId = 'data-automation-id="form_' . $this->wp->escAttr($block['id']) . '" ';
}
if (isset($formSettings['id'])) {
$id = 'id="form_' . $this->wp->escAttr($block['id']) . '_' . $this->wp->escAttr($formSettings['id']) . '" ';
}
$styles = $this->inputStylesRenderer->renderForTextInput($block['styles'] ?? [], $formSettings);
$name = $this->rendererHelper->getFieldName($block);
$html = $this->inputStylesRenderer->renderPlaceholderStyles($block, 'input[name="data[' . $name . ']"]');
$html .= $this->rendererHelper->renderLabel($block, $formSettings);
$html .= '<input type="' . $type . '" autocomplete="' . $autocomplete . '" class="mailpoet_text" ';
$html .= $id;
$html .= 'name="data[' . $name . ']" ';
$html .= 'title="' . $this->wp->escAttr($this->rendererHelper->getFieldLabel($block)) . '" ';
$html .= 'value="' . $this->rendererHelper->getFieldValue($block) . '" ';
if ($styles) {
$html .= 'style="' . $this->wp->escAttr($styles) . '" ';
}
$html .= $automationId;
$html .= $this->rendererHelper->renderInputPlaceholder($block);
$html .= $this->rendererHelper->getInputValidation($block);
$html .= $this->rendererHelper->getInputModifiers($block);
$html .= '/>';
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
return $this->wrapper->render($block, $html);
}
}
@@ -0,0 +1,67 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Form\Block;
if (!defined('ABSPATH')) exit;
use MailPoet\Form\BlockStylesRenderer;
use MailPoet\Form\BlockWrapperRenderer;
use MailPoet\WP\Functions as WPFunctions;
class Textarea {
/** @var BlockRendererHelper */
private $rendererHelper;
/** @var BlockStylesRenderer */
private $inputStylesRenderer;
/** @var BlockWrapperRenderer */
private $wrapper;
/** @var WPFunctions */
private $wp;
public function __construct(
BlockRendererHelper $rendererHelper,
BlockStylesRenderer $inputStylesRenderer,
BlockWrapperRenderer $wrapper,
WPFunctions $wp
) {
$this->rendererHelper = $rendererHelper;
$this->inputStylesRenderer = $inputStylesRenderer;
$this->wrapper = $wrapper;
$this->wp = $wp;
}
public function render(array $block, array $formSettings, ?int $formId = null): string {
$html = '';
$name = $this->rendererHelper->getFieldName($block);
$styles = $this->inputStylesRenderer->renderForTextInput($block['styles'] ?? [], $formSettings);
$html .= $this->rendererHelper->renderLabel($block, $formSettings);
$lines = (isset($block['params']['lines']) ? (int)$block['params']['lines'] : 1);
$html .= $this->inputStylesRenderer->renderPlaceholderStyles($block, 'textarea[name="data[' . $name . ']"]');
$html .= '<textarea class="mailpoet_textarea" data-automation-id="form_custom_text_area" rows="' . $lines . '" ';
$html .= 'name="data[' . $name . ']"';
$html .= $this->rendererHelper->renderInputPlaceholder($block);
$html .= $this->rendererHelper->getInputValidation($block);
$html .= $this->rendererHelper->getInputModifiers($block);
if ($styles) {
$html .= 'style="' . $this->wp->escAttr($styles) . '" ';
}
$html .= '>' . $this->rendererHelper->escapeShortCodes($this->rendererHelper->getFieldValue($block)) . '</textarea>';
$html .= $this->rendererHelper->renderErrorsContainer($block, $formId);
return $this->wrapper->render($block, $html);
}
}
@@ -0,0 +1 @@
<?php