Right now the analytics table has a form_id column but we never fill it in, so all forms on a list get together. This phase gives each form a stable ID, wires it through tracking, and adds a forms table for titles and lifecycle.
What we already have
wp_mailchimp_sf_form_analytics has form_id.
increment_views() / increment_submissions() take $form_id - callers pass nothing.
The block is rendered on server, so a new attribute won't trigger block validation errors.
Form IDs
Block forms: a UUID stored as a form_id block attribute. edit.js generates it on mount when empty (heal every empty block, not just the clicked one).
Shortcode and widget forms, legacy. Aggregate together
No render time fallback. Legacy blocks with no UUID keep writing to the shared bucket until the post is re-saved and gets a UUID.
Forms table wp_mailchimp_sf_forms
form_id PK, list_id, title, post_id, status (active|removed), created_at, updated_at
Title: a form_title block attribute edited in the block sidebar, capped at 50 chars, upserted on save_post.
Removed: on save_post, diff form_ids in content vs table and mark missing ones removed. Re-adding the same UUID flips back to active. Guard against autosaves, revisions, and partial saves.
Copy-paste: copies share the UUID and merge into one form / one title (last save wins). Accepted as known behavior, no regeneration.
Page-source (blog vs footer breakdown): out of scope here, needs separate discussion.
Code changes
block.json: add form_id and form_title attributes.
edit.js: generate UUID on mount when empty. Add the form name sidebar field.
markup.php: output data-form-id and a hidden mailchimp_sf_form_id field from the attribute.
mailchimp_widget.php: same, hardcoded to legacy.
assets/js/mailchimp.js: include form_id from data-form-id in the view ping.
class-mailchimp-analytics-data.php: handle_form_view() reads/validates form_id (^[A-Za-z0-9_-]{1,50}$) and passes to increment_views(), track_submission() passes form_id to increment_submissions().
class-mailchimp-form-submission.php: read the hidden field, validate, do_action( 'mailchimp_sf_form_submission_success', $list_id, $form_id )
New: forms table create/update + the save_post sync/diff.
Right now the analytics table has a
form_idcolumn but we never fill it in, so all forms on a list get together. This phase gives each form a stable ID, wires it through tracking, and adds a forms table for titles and lifecycle.What we already have
wp_mailchimp_sf_form_analyticshasform_id.increment_views()/increment_submissions()take$form_id- callers pass nothing.The block is rendered on server, so a new attribute won't trigger block validation errors.
Form IDs
Block forms: a UUID stored as a
form_idblock attribute.edit.jsgenerates it on mount when empty (heal every empty block, not just the clicked one).Shortcode and widget forms, legacy. Aggregate together
No render time fallback. Legacy blocks with no UUID keep writing to the shared bucket until the post is re-saved and gets a UUID.
Forms table
wp_mailchimp_sf_formsform_id PK, list_id, title, post_id, status (active|removed), created_at, updated_atTitle: a
form_titleblock attribute edited in the block sidebar, capped at 50 chars, upserted onsave_post.Removed: on
save_post, diffform_idsin content vs table and mark missing ones removed. Re-adding the same UUID flips back to active. Guard against autosaves, revisions, and partial saves.Copy-paste: copies share the UUID and merge into one form / one title (last save wins). Accepted as known behavior, no regeneration.
Page-source (blog vs footer breakdown): out of scope here, needs separate discussion.
Code changes
block.json: addform_idandform_titleattributes.edit.js: generate UUID on mount when empty. Add the form name sidebar field.markup.php:outputdata-form-idand a hiddenmailchimp_sf_form_idfield from the attribute.mailchimp_widget.php: same, hardcoded to legacy.assets/js/mailchimp.js:includeform_idfromdata-form-idin the view ping.class-mailchimp-analytics-data.php:handle_form_view()reads/validatesform_id(^[A-Za-z0-9_-]{1,50}$)and passes toincrement_views(),track_submission()passesform_idtoincrement_submissions().class-mailchimp-form-submission.php:read the hidden field, validate,do_action( 'mailchimp_sf_form_submission_success', $list_id, $form_id )New: forms table create/update + the save_post sync/diff.