init
This commit is contained in:
@@ -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(['[', ']'], ['[', ']'], $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
|
||||
Reference in New Issue
Block a user