Skip to content

Commit 77e56e2

Browse files
authored
Merge pull request #171 from mailchimp/feat/form-templates
[Block] Add Form templates
2 parents e14f7b3 + 31ccd71 commit 77e56e2

File tree

15 files changed

+579
-52
lines changed

15 files changed

+579
-52
lines changed

includes/blocks/class-mailchimp-list-subscribe-form-blocks.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public function register_blocks() {
7878
'double_opt_in' => (bool) get_option( 'mc_double_optin', true ),
7979
'merge_fields_visibility' => $merge_fields_visibility,
8080
'interest_groups_visibility' => $interest_groups_visibility,
81+
'merge_fields' => $merge_fields,
82+
'interest_groups' => $interest_groups,
8183
);
8284
$data = 'window.mailchimp_sf_block_data = ' . wp_json_encode( $data );
8385
wp_add_inline_script( 'mailchimp-mailchimp-editor-script', $data, 'before' );
@@ -209,4 +211,51 @@ public function get_list_data( $request ) {
209211
public function get_list_data_permissions_check() {
210212
return current_user_can( 'edit_posts' );
211213
}
214+
215+
/**
216+
* Check if the merge validation should be skipped.
217+
*
218+
* @param array $inner_blocks The inner blocks of the block.
219+
* @param array $merge_fields The merge fields.
220+
* @param string $template The template of the block.
221+
* @return bool True if the merge validation should be skipped, false otherwise.
222+
*/
223+
public function should_skip_merge_validation( $inner_blocks = array(), $merge_fields = array(), $template = 'default' ) {
224+
if ( 'default' === $template ) {
225+
return false;
226+
}
227+
228+
// Get the tags of the visible inner blocks.
229+
$visible_inner_blocks = array_map(
230+
function ( $block ) {
231+
return $block['attrs']['tag'] ?? '';
232+
},
233+
array_filter(
234+
$inner_blocks,
235+
function ( $block ) {
236+
return 'mailchimp/mailchimp-form-field' === $block['blockName'] && isset( $block['attrs']['visible'] ) && $block['attrs']['visible'];
237+
}
238+
)
239+
);
240+
241+
// Get the tags of the required merge fields.
242+
$required_merge_fields = array_map(
243+
function ( $field ) {
244+
return $field['tag'] ?? '';
245+
},
246+
array_filter(
247+
$merge_fields,
248+
function ( $field ) {
249+
return $field['required'];
250+
}
251+
)
252+
);
253+
254+
$missing_required_fields = array_diff( $required_merge_fields, $visible_inner_blocks );
255+
if ( ! empty( $missing_required_fields ) ) {
256+
return true;
257+
}
258+
259+
return false;
260+
}
212261
}

includes/blocks/mailchimp-form-field/block.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"parent": [
3131
"mailchimp/mailchimp"
3232
],
33-
"usesContext": ["mailchimp/list_id","mailchimp/show_required_indicator"],
33+
"usesContext": ["mailchimp/list_id","mailchimp/show_required_indicator","mailchimp/template"],
3434
"editorScript": "file:./index.js",
3535
"render": "file:./field-markup.php"
3636
}

includes/blocks/mailchimp-form-field/edit.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,13 @@ export const BlockEdit = (props) => {
312312
const {
313313
attributes,
314314
setAttributes,
315-
context: { 'mailchimp/list_id': listId },
315+
context: { 'mailchimp/list_id': listId, 'mailchimp/template': template },
316316
} = props;
317317
const { visible, tag } = attributes;
318318
const { mailchimpListData } = window;
319-
const isRequired = mailchimpListData?.[listId]?.mergeFields?.[tag]?.required || false;
319+
const isRequired =
320+
(template === 'default' && mailchimpListData?.[listId]?.mergeFields?.[tag]?.required) ||
321+
tag === 'EMAIL';
320322

321323
return (
322324
<div {...blockProps} style={{ color: 'inherit' }}>

includes/blocks/mailchimp-form-field/field-markup.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
$list_id = $block->context['mailchimp/list_id'] ?? '';
99
$show_required_indicator = $block->context['mailchimp/show_required_indicator'] ?? true;
10+
$template = $block->context['mailchimp/template'] ?? 'default';
1011
$field_tag = $attributes['tag'] ?? '';
1112
$label = $attributes['label'] ?? '';
1213
$is_visible = $attributes['visible'] ?? false;
@@ -32,6 +33,11 @@ function ( $field ) use ( $field_tag ) {
3233
return;
3334
}
3435

36+
// If the template is not default and the field is marked as hidden, don't render the field.
37+
if ( 'default' !== $template && ! $is_visible && 'EMAIL' !== $field_tag ) {
38+
return;
39+
}
40+
3541
?>
3642
<div <?php echo get_block_wrapper_attributes(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
3743
<?php

includes/blocks/mailchimp/block.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
"required_indicator_text": {
3939
"type": "string",
4040
"default": "* = required field"
41+
},
42+
"template": {
43+
"type": "string",
44+
"default": "default"
4145
}
4246
},
4347
"supports": {
@@ -76,10 +80,11 @@
7680
],
7781
"providesContext": {
7882
"mailchimp/list_id": "list_id",
79-
"mailchimp/show_required_indicator": "show_required_indicator"
83+
"mailchimp/show_required_indicator": "show_required_indicator",
84+
"mailchimp/template": "template"
8085
},
8186
"textdomain": "mailchimp",
8287
"editorScript": "file:./index.js",
8388
"render": "file:./markup.php",
84-
"editorStyle": "file:./editor.css"
89+
"editorStyle": ["file:./editor.css", "dashicons"]
8590
}

includes/blocks/mailchimp/edit.js

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import apiFetch from '@wordpress/api-fetch';
1818
import { useDispatch, useSelect } from '@wordpress/data';
1919
import { createBlock } from '@wordpress/blocks';
2020
import Icon from './icon';
21+
import { VariationPicker } from './variation-picker';
2122

2223
const SelectListPlaceholder = () => {
2324
return (
@@ -59,6 +60,7 @@ export const BlockEdit = (props) => {
5960
unsubscribe_link_text,
6061
show_required_indicator = true,
6162
required_indicator_text,
63+
template = 'default',
6264
} = attributes;
6365

6466
const [listData, setListData] = useState({});
@@ -74,7 +76,10 @@ export const BlockEdit = (props) => {
7476
);
7577
const exisingTags = innerBlocks.map((block) => block?.attributes?.tag).filter(Boolean);
7678
const exisingGroups = innerBlocks.map((block) => block?.attributes?.id).filter(Boolean);
77-
const visibleFieldsCount = innerBlocks.filter((block) => block?.attributes?.visible).length;
79+
const visibleFields = innerBlocks
80+
.filter((block) => block?.attributes?.visible)
81+
.map((block) => block?.attributes?.tag);
82+
const visibleFieldsCount = visibleFields.length;
7883

7984
const listOptions = [];
8085
// Check if selected list is not in the list of available lists.
@@ -116,20 +121,27 @@ export const BlockEdit = (props) => {
116121
tag: field.tag,
117122
label: field.name,
118123
type: field.type,
124+
/**
125+
* Visibility logic:
126+
* 1. If there are visible fields from the previous list, make the field visible if it's visible in the previous list form (Try to keep the same visibility as the previous list form) for the default template also make the field visible if it's required.
127+
* 2. If there are no visible fields from the previous list, make the field visible if it's required or it's public and the visibility setting is on in the global settings.
128+
*/
119129
visible:
120-
(field.required ||
121-
merge_fields_visibility?.[field.tag] === 'on') &&
122-
field.public,
130+
(template === 'default' && field.required) ||
131+
(visibleFields.length > 0 &&
132+
visibleFields.includes(field.tag)) ||
133+
(visibleFields.length === 0 &&
134+
(field.required ||
135+
(merge_fields_visibility?.[field.tag] === 'on' &&
136+
field.public))),
123137
}),
124138
) || [];
125139
const listGroupsBlocks =
126140
data?.interest_groups?.map((group) =>
127141
createBlock('mailchimp/mailchimp-audience-group', {
128142
id: group.id,
129143
label: group.title,
130-
visible:
131-
interest_groups_visibility?.[group.id] === 'on' &&
132-
group.type !== 'hidden',
144+
visible: false, // Keep the groups hidden by default.
133145
}),
134146
) || [];
135147
replaceInnerBlocks(clientId, [...listFieldsBlocks, ...listGroupsBlocks], false);
@@ -161,19 +173,14 @@ export const BlockEdit = (props) => {
161173
tag: field.tag,
162174
label: field.name,
163175
type: field.type,
164-
visible:
165-
(field.required ||
166-
merge_fields_visibility?.[field.tag] === 'on') &&
167-
field.public,
176+
visible: template === 'default' && field.required, // Keep newly added fields hidden by default, except for required fields.
168177
}),
169178
);
170179
const newGroupBlocks = newFormGroups.map((group) =>
171180
createBlock('mailchimp/mailchimp-audience-group', {
172181
id: group.id,
173182
label: group.title,
174-
visible:
175-
interest_groups_visibility?.[group.id] === 'on' &&
176-
group.type !== 'hidden',
183+
visible: false, // Keep newly added groups hidden by default.
177184
}),
178185
);
179186

@@ -279,6 +286,11 @@ export const BlockEdit = (props) => {
279286
);
280287
}
281288

289+
// Display the variation picker if there are no innerBlocks.
290+
if (innerBlocks.length === 0) {
291+
return <VariationPicker {...props} />;
292+
}
293+
282294
// Create a template for innerBlocks based on list data and visibility settings.
283295
const templateFields =
284296
listData?.merge_fields?.map((field) => [
@@ -301,7 +313,7 @@ export const BlockEdit = (props) => {
301313
visible: interest_groups_visibility?.[group.id] === 'on' && group.type !== 'hidden',
302314
},
303315
]) || [];
304-
const template = [...templateFields, ...templateGroups];
316+
const templateBlocks = [...templateFields, ...templateGroups];
305317

306318
return (
307319
<>
@@ -343,7 +355,7 @@ export const BlockEdit = (props) => {
343355
<InnerBlocks
344356
allowedBlocks={['mailchimp/mailchimp-form-field']}
345357
orientation="vertical"
346-
template={template}
358+
template={templateBlocks}
347359
templateLock="insert"
348360
/>
349361
{show_required_indicator && (

includes/blocks/mailchimp/editor.css

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,38 @@ select.mc_select {
151151
width:100%;
152152
margin-top: 1em;
153153
}
154+
155+
.wp-block-mailchimp-mailchimp .block-editor-block-variation-picker .components-placeholder__fieldset .block-editor-block-variation-picker__variations {
156+
gap: 20px 0;
157+
justify-content: center;
158+
margin: 16px auto;
159+
max-width: 560px;
160+
}
161+
162+
.wp-block-mailchimp-mailchimp .block-editor-block-variation-picker .components-placeholder__fieldset .block-editor-block-variation-picker__variations>li {
163+
flex: 0;
164+
margin: 0;
165+
max-width: none;
166+
padding: 0 4px;
167+
text-align: center;
168+
width: unset
169+
}
170+
171+
.wp-block-mailchimp-mailchimp .block-editor-block-variation-picker .components-placeholder__fieldset .block-editor-block-variation-picker__variations .block-editor-block-variation-picker__variation {
172+
margin-left: 4px;
173+
margin-right: 4px;
174+
padding: 22px
175+
}
176+
177+
.wp-block-mailchimp-mailchimp .block-editor-block-variation-picker .components-placeholder__fieldset .block-editor-block-variation-picker__variations .block-editor-block-variation-picker__variation span.dashicon::before {
178+
font-size: 24px;
179+
}
180+
181+
.wp-block-mailchimp-mailchimp .block-editor-block-variation-picker .components-placeholder__fieldset .block-editor-block-variation-picker__variations .block-editor-block-variation-picker__variation svg {
182+
height: auto;
183+
width: 24px
184+
}
185+
186+
.wp-block-mailchimp-mailchimp .block-editor-block-variation-picker .components-placeholder__fieldset .block-editor-block-variation-picker__variations .block-editor-block-variation-picker__variation-label {
187+
margin-right: 0
188+
}

includes/blocks/mailchimp/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { InnerBlocks } from '@wordpress/block-editor';
44
import { BlockEdit } from './edit';
55
import metadata from './block.json';
66
import Icon from './icon';
7+
import { variations } from './variations';
78

89
registerBlockType(metadata, {
910
icon: Icon,
11+
variations,
1012
transforms: {
1113
from: [
1214
{

includes/blocks/mailchimp/markup.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,22 @@ function ( $single_list ) {
4242
$header = $attributes['header'] ?? '';
4343
$sub_heading = $attributes['sub_header'] ?? '';
4444
$submit_text = $attributes['submit_text'] ?? __( 'Subscribe', 'mailchimp' );
45-
$merge_fields = get_option( 'mailchimp_sf_merge_fields_' . $list_id );
45+
$merge_fields = get_option( 'mailchimp_sf_merge_fields_' . $list_id, array() );
4646
$show_unsubscribe_link = $attributes['show_unsubscribe_link'] ?? get_option( 'mc_use_unsub_link' ) === 'on';
4747
$unsubscribe_link_text = $attributes['unsubscribe_link_text'] ?? __( 'unsubscribe from list', 'mailchimp' );
4848
$update_existing_subscribers = ( $attributes['update_existing_subscribers'] ?? get_option( 'mc_update_existing' ) === 'on' ) ? 'yes' : 'no';
4949
$double_opt_in = ( $attributes['double_opt_in'] ?? get_option( 'mc_double_optin' ) === 'on' ) ? 'yes' : 'no';
5050
$show_required_indicator = $attributes['show_required_indicator'] ?? true;
5151
$required_indicator_text = $attributes['required_indicator_text'] ?? __( '* = required field', 'mailchimp' );
52+
$template = $attributes['template'] ?? 'default';
53+
$skip_merge_validation = ( new Mailchimp_List_Subscribe_Form_Blocks() )->should_skip_merge_validation( $inner_blocks, $merge_fields, $template ) ? 'yes' : 'no';
5254
$hash = wp_hash(
5355
serialize( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
5456
array(
55-
'list_id' => $list_id,
56-
'update_existing' => $update_existing_subscribers,
57-
'double_opt_in' => $double_opt_in,
57+
'list_id' => $list_id,
58+
'update_existing' => $update_existing_subscribers,
59+
'double_opt_in' => $double_opt_in,
60+
'skip_merge_validation' => $skip_merge_validation,
5861
)
5962
)
6063
);
@@ -108,6 +111,7 @@ function ( $single_list ) {
108111
<input type="hidden" name="mailchimp_sf_list_id" value="<?php echo esc_attr( $list_id ); ?>" />
109112
<input type="hidden" name="mailchimp_sf_update_existing_subscribers" value="<?php echo esc_attr( $update_existing_subscribers ); ?>" />
110113
<input type="hidden" name="mailchimp_sf_double_opt_in" value="<?php echo esc_attr( $double_opt_in ); ?>" />
114+
<input type="hidden" name="mailchimp_sf_skip_merge_validation" value="<?php echo esc_attr( $skip_merge_validation ); ?>" />
111115
<input type="hidden" name="mailchimp_sf_hash" value="<?php echo esc_attr( $hash ); ?>" />
112116
<?php
113117
wp_nonce_field( 'mc_submit_signup_form', '_mc_submit_signup_form_nonce', false );

0 commit comments

Comments
 (0)