{"id":24360,"date":"2013-07-25T16:57:41","date_gmt":"2013-07-25T16:57:41","guid":{"rendered":"https:\/\/wordpress.org\/plugins-wp\/contact-forms\/"},"modified":"2026-08-05T09:38:42","modified_gmt":"2026-08-05T09:38:42","slug":"contact-forms","status":"publish","type":"plugin","link":"https:\/\/ko.wordpress.org\/plugins\/contact-forms\/","author":12579273,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.3.0","stable_tag":"2.3.0","tested":"7.0.4","requires":"5.9","requires_php":"7.4","requires_plugins":null,"header_name":"Contact Forms by Cimatti","header_author":"Cimatti","header_description":"","assets_banners_color":"f7f7f7","last_updated":"2026-08-05 09:38:42","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/www.cimatti.it\/en\/wordpress-plugins\/contact-forms\/","header_author_uri":"https:\/\/www.cimatti.it","rating":4.4,"author_block_rating":0,"active_installs":600,"downloads":83612,"num_ratings":16,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0":{"tag":"1.0","author":"cimatti","date":"2013-07-25 17:06:35"},"1.1":{"tag":"1.1","author":"cimatti","date":"2013-08-20 19:38:44"},"1.2":{"tag":"1.2","author":"cimatti","date":"2013-10-31 19:21:06"},"1.2.1":{"tag":"1.2.1","author":"cimatti","date":"2013-11-13 09:52:16"},"1.3":{"tag":"1.3","author":"cimatti","date":"2014-01-09 14:50:26"},"1.3.1":{"tag":"1.3.1","author":"cimatti","date":"2014-01-24 18:28:31"},"1.3.2":{"tag":"1.3.2","author":"cimatti","date":"2014-02-01 04:20:16"},"1.3.3":{"tag":"1.3.3","author":"cimatti","date":"2014-04-10 12:34:36"},"1.3.4":{"tag":"1.3.4","author":"cimatti","date":"2015-02-06 21:48:13"},"1.3.5":{"tag":"1.3.5","author":"cimatti","date":"2015-10-06 13:19:03"},"1.3.6":{"tag":"1.3.6","author":"cimatti","date":"2015-10-23 19:24:25"},"1.3.7":{"tag":"1.3.7","author":"cimatti","date":"2015-12-10 23:16:32"},"1.3.8":{"tag":"1.3.8","author":"cimatti","date":"2015-12-17 13:19:32"},"1.3.9":{"tag":"1.3.9","author":"cimatti","date":"2015-12-24 20:47:12"},"1.4.0":{"tag":"1.4.0","author":"cimatti","date":"2016-03-15 21:53:59"},"1.4.1":{"tag":"1.4.1","author":"cimatti","date":"2016-03-16 20:11:10"},"1.4.10":{"tag":"1.4.10","author":"cimatti","date":"2020-07-08 20:06:52"},"1.4.11":{"tag":"1.4.11","author":"cimatti","date":"2020-11-04 11:23:28"},"1.4.12":{"tag":"1.4.12","author":"cimatti","date":"2023-05-29 12:37:20"},"1.4.13":{"tag":"1.4.13","author":"cimatti","date":"2023-05-29 12:37:20"},"1.4.14":{"tag":"1.4.14","author":"cimatti","date":"2023-05-29 12:37:20"},"1.4.2":{"tag":"1.4.2","author":"cimatti","date":"2016-03-29 15:13:42"},"1.4.3":{"tag":"1.4.3","author":"cimatti","date":"2016-03-29 18:43:06"},"1.4.4":{"tag":"1.4.4","author":"cimatti","date":"2016-04-21 15:15:16"},"1.4.5":{"tag":"1.4.5","author":"cimatti","date":"2017-01-18 11:52:47"},"1.4.6":{"tag":"1.4.6","author":"cimatti","date":"2017-02-14 11:36:47"},"1.4.7":{"tag":"1.4.7","author":"cimatti","date":"2017-06-13 14:29:54"},"1.4.8":{"tag":"1.4.8","author":"cimatti","date":"2019-03-11 14:27:11"},"1.4.9":{"tag":"1.4.9","author":"cimatti","date":"2019-07-24 15:16:08"},"1.5.1":{"tag":"1.5.1","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.10":{"tag":"1.5.10","author":"cimatti","date":"2023-07-26 06:59:35"},"1.5.2":{"tag":"1.5.2","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.3":{"tag":"1.5.3","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.4":{"tag":"1.5.4","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.5":{"tag":"1.5.5","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.6":{"tag":"1.5.6","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.7":{"tag":"1.5.7","author":"cimatti","date":"2023-05-29 12:37:20"},"1.5.8":{"tag":"1.5.8","author":"cimatti","date":"2023-06-12 07:53:19"},"1.5.9":{"tag":"1.5.9","author":"cimatti","date":"2023-07-26 06:54:15"},"1.6.0":{"tag":"1.6.0","author":"cimatti","date":"2023-08-03 11:06:27"},"1.6.1":{"tag":"1.6.1","author":"cimatti","date":"2023-11-03 16:28:07"},"1.7.0":{"tag":"1.7.0","author":"cimatti","date":"2023-12-14 08:31:49"},"1.8.0":{"tag":"1.8.0","author":"cimatti","date":"2023-12-19 13:31:45"},"1.9.0":{"tag":"1.9.0","author":"cimatti","date":"2024-04-22 13:12:00"},"1.9.1":{"tag":"1.9.1","author":"cimatti","date":"2024-04-30 12:16:17"},"1.9.2":{"tag":"1.9.2","author":"cimatti","date":"2024-04-30 14:26:56"},"1.9.3":{"tag":"1.9.3","author":"cimatti","date":"2024-11-25 17:15:35"},"1.9.4":{"tag":"1.9.4","author":"cimatti","date":"2025-01-30 16:10:24"},"1.9.5":{"tag":"1.9.5","author":"cimatti","date":"2025-01-30 16:10:24"},"1.9.6":{"tag":"1.9.6","author":"cimatti","date":"2025-05-13 06:56:06"},"1.9.7":{"tag":"1.9.7","author":"cimatti","date":"2025-05-13 06:56:06"},"2.0.0":{"tag":"2.0.0","author":"cimatti","date":"2026-04-08 09:49:57"},"2.1.0":{"tag":"2.1.0","author":"cimatti","date":"2026-04-21 16:05:25"},"2.1.1":{"tag":"2.1.1","author":"cimatti","date":"2026-04-22 08:07:22"},"2.1.2":{"tag":"2.1.2","author":"cimatti","date":"2026-05-07 08:32:01"},"2.2.0":{"tag":"2.2.0","author":"cimatti","date":"2026-05-18 15:14:51"},"2.2.32":{"tag":"2.2.32","author":"cimatti","date":"2026-07-13 12:55:41"},"2.2.4":{"tag":"2.2.4","author":"cimatti","date":"2026-05-25 14:50:52"},"2.3.0":{"tag":"2.3.0","author":"cimatti","date":"2026-08-05 09:38:42"}},"upgrade_notice":{"2.3.0":"<p>Recommended. Fixes two cases where submitted values were silently discarded: field slugs differing only in upper\/lower case, and forms carried over from a pre-2.0 install. Adds reCAPTCHA v3 and Cap captcha fields, a Spam view, live field preview, and an optional delete-data-on-uninstall setting.<\/p>","2.2.32":"<p>Large maintenance release: admin UI improvements, post field fixes, faster dashboard, Plugin Check compliance. Note: fieldset borders are now opt-in. If your forms use fieldset groups, re-enable the border via the field&#039;s new &quot;Border and Title&quot; option.<\/p>","2.0.0":"<p>Major rewrite: accessibility (WCAG 2.2 AA), GDPR tools, new layouts, spam protection, and modern admin UI. CSS changes may affect custom theme styling -- use Theme Helper to review. All existing forms continue to work.<\/p>"},"ratings":{"1":2,"2":0,"3":0,"4":2,"5":12},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3006878,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3006878,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":2947119,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":2947115,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":2947115,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3635159,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/\",\"login\":true,\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"steps\":[{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"contact-forms\"},\"options\":{\"activate\":true}},{\"step\":\"mkdir\",\"path\":\"\\\/wordpress\\\/wp-content\\\/mu-plugins\"},{\"step\":\"writeFile\",\"path\":\"\\\/wordpress\\\/wp-content\\\/mu-plugins\\\/playground-demo-mail.php\",\"data\":\"<?php\\n\\\/**\\n * Playground demo helper: report emails as sent.\\n *\\n * WordPress Playground has no mail transport, so wp_mail() always fails.\\n * Contact Forms shows the form's error message when the notification email\\n * cannot be sent, which would make every demo submission look broken even\\n * though it is saved. Short-circuiting wp_mail() keeps the demo honest:\\n * submissions succeed and the success message is shown.\\n *\\\/\\nadd_filter( 'pre_wp_mail', '__return_true' );\\n\"},{\"step\":\"setSiteOptions\",\"options\":{\"permalink_structure\":\"\\\/%postname%\\\/\",\"blogname\":\"Contact Forms Demo\"}},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $avail_fields = get_option('accua_forms_avail_fields', array()); $avail_fields['start_date'] = array('version' => 2, 'id' => 'start_date', 'name' => 'Preferred Start Date', 'type' => 'date', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['resume'] = array('version' => 2, 'id' => 'resume', 'name' => 'Resume \\\/ CV', 'type' => 'file', 'description' => 'PDF, DOC or DOCX. Drag and drop the file or click to choose it.', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => 'pdf,doc,docx', 'min_date' => '', 'max_date' => ''); $avail_fields['department'] = array('version' => 2, 'id' => 'department', 'name' => 'Department', 'type' => 'select', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Sales\\\\r\\\\nMarketing\\\\r\\\\nEngineering\\\\r\\\\nSupport\\\\r\\\\nHuman Resources\\\\r\\\\nOther\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['contact_reason'] = array('version' => 2, 'id' => 'contact_reason', 'name' => 'Reason for Contact', 'type' => 'radio', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"General Inquiry\\\\r\\\\nSupport Request\\\\r\\\\nPartnership\\\\r\\\\nFeedback\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['sessions'] = array('version' => 2, 'id' => 'sessions', 'name' => 'Sessions of Interest', 'type' => 'multiselect', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Keynote\\\\r\\\\nWorkshop A: Frontend Dev\\\\r\\\\nWorkshop B: Backend Dev\\\\r\\\\nNetworking Lunch\\\\r\\\\nPanel Discussion\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['dietary'] = array('version' => 2, 'id' => 'dietary', 'name' => 'Dietary Requirements', 'type' => 'multicheckbox', 'description' => 'Select all that apply.', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Vegetarian\\\\r\\\\nVegan\\\\r\\\\nGluten-free\\\\r\\\\nHalal\\\\r\\\\nNo restrictions\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['agree_terms'] = array('version' => 2, 'id' => 'agree_terms', 'name' => 'I agree to the Terms and Conditions', 'type' => 'checkbox', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['related_article'] = array('version' => 2, 'id' => 'related_article', 'name' => 'Related Article', 'type' => 'post-select', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['related_pages'] = array('version' => 2, 'id' => 'related_pages', 'name' => 'Related Pages', 'type' => 'post-multicheckbox', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['source_page'] = array('version' => 2, 'id' => 'source_page', 'name' => 'Source Page', 'type' => 'hidden', 'description' => '', 'default_value' => 'wordpress-playground-demo', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['satisfaction'] = array('version' => 2, 'id' => 'satisfaction', 'name' => 'Overall, how satisfied are you with our service?', 'type' => 'radio', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Very satisfied\\\\r\\\\nSatisfied\\\\r\\\\nNeutral\\\\r\\\\nDissatisfied\\\\r\\\\nVery dissatisfied\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['recommend'] = array('version' => 2, 'id' => 'recommend', 'name' => 'How likely are you to recommend us to a colleague?', 'type' => 'radio', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Definitely\\\\r\\\\nProbably\\\\r\\\\nNot sure\\\\r\\\\nProbably not\\\\r\\\\nDefinitely not\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['used_features'] = array('version' => 2, 'id' => 'used_features', 'name' => 'Which features do you use?', 'type' => 'multicheckbox', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Contact forms\\\\r\\\\nFile uploads\\\\r\\\\nEmail notifications\\\\r\\\\nSpam protection\\\\r\\\\nSubmission archive\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['poll_comments'] = array('version' => 2, 'id' => 'poll_comments', 'name' => 'Anything else you would like to tell us?', 'type' => 'textarea', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['service'] = array('version' => 2, 'id' => 'service', 'name' => 'Service Needed', 'type' => 'select', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Website Design\\\\r\\\\nE-commerce Development\\\\r\\\\nSEO Optimization\\\\r\\\\nMaintenance and Support\\\\r\\\\nOther\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['budget'] = array('version' => 2, 'id' => 'budget', 'name' => 'Estimated Budget', 'type' => 'select', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => \\\"Under 1,000\\\\r\\\\n1,000 - 5,000\\\\r\\\\n5,000 - 10,000\\\\r\\\\nOver 10,000\\\", 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['deadline'] = array('version' => 2, 'id' => 'deadline', 'name' => 'Desired Completion Date', 'type' => 'date', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['privacy_notice'] = array('version' => 2, 'id' => 'privacy_notice', 'name' => 'Privacy Notice', 'type' => 'html', 'description' => 'Reusable HTML block: a short privacy note shown near the submit button. Edit the content here to update every form that uses it.', 'default_value' => '<p class=\\\"privacy-notice\\\" style=\\\"font-size:0.9em;color:#50575e;background:#f6f7f7;border-left:4px solid #003974;padding:8px 12px;\\\">We use your details only to answer your request and never share them with third parties.<\\\/p>', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['brand_color'] = array('version' => 2, 'id' => 'brand_color', 'name' => 'Preferred Primary Color', 'type' => 'colorpicker', 'description' => 'Pick the color your new design should be built around.', 'default_value' => '#003974', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['choose_password'] = array('version' => 2, 'id' => 'choose_password', 'name' => 'Choose a Password', 'type' => 'password-and-confirm', 'description' => 'You will use it to access the member area.', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); $avail_fields['send_brief'] = array('version' => 2, 'id' => 'send_brief', 'name' => 'Send My Brief', 'type' => 'submit', 'description' => '', 'default_value' => '', 'default_date_value' => '', 'allowed_values' => '', 'allowed_extensions' => '', 'min_date' => '', 'max_date' => ''); update_option('accua_forms_avail_fields', $avail_fields); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); if (!is_array($forms)) $forms = array(); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $variants = array('toplabel' => 'Contact Us (Top Labels)', 'sidebyside' => 'Contact Us (Side by Side Labels)', 'inlinelabel' => 'Contact Us (Inline Labels)'); foreach ($variants as $layout => $title) { $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => $title, 'layout' => $layout, 'success_message' => '<div><h2>Thank you {first_name}!<\\\/h2><p>We received your message and will get back to you shortly.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Something went wrong.<\\\/h2><p>Please try again or contact us directly.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New contact request from {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'We received your message', 'confirmation_emails_message' => '<div><p>Dear {first_name}, thank you for contacting us. We will reply as soon as possible.<\\\/p><\\\/div>', 'fields' => array('first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'telephone' => array('version' => 2, 'istance_id' => 'telephone', 'widget_number' => '', 'ref' => 'telephone', 'required' => false, 'country_code' => 'US', 'css_class' => '', 'css_id' => ''), 'contact_reason' => array('version' => 2, 'istance_id' => 'contact_reason', 'widget_number' => '', 'ref' => 'contact_reason', 'required' => true, 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'required' => true, 'css_class' => '', 'css_id' => ''))); } update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $styles = array('border-on-title-inline' => 'Workshop Registration (Inline Legend)', 'border-on-title-outside' => 'Workshop Registration (Title Above)', 'border-on-title-inside' => 'Workshop Registration (Title Inside)', 'border-off-title-on' => 'Workshop Registration (Title Without Border)'); foreach ($styles as $style => $title) { $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => $title, 'layout' => 'toplabel', 'success_message' => '<div><h2>Registration complete!<\\\/h2><p>Thank you {first_name}, we saved your seat. Check your email for the confirmation.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Registration failed.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New workshop registration: {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'Workshop registration confirmed', 'confirmation_emails_message' => '<div><p>Dear {first_name}, your registration has been confirmed. See you at the workshop!<\\\/p><\\\/div>', 'fields' => array('__fieldset-begin-1' => array('version' => 2, 'istance_id' => '__fieldset-begin-1', 'widget_number' => 1, 'ref' => '__fieldset-begin', 'label' => 'Personal Information', 'fieldset_style' => $style, 'required' => false, 'css_class' => '', 'css_id' => ''), 'first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), '__fieldset-end-1' => array('version' => 2, 'istance_id' => '__fieldset-end-1', 'widget_number' => 1, 'ref' => '__fieldset-end', 'required' => false, 'css_class' => '', 'css_id' => ''), '__fieldset-begin-2' => array('version' => 2, 'istance_id' => '__fieldset-begin-2', 'widget_number' => 2, 'ref' => '__fieldset-begin', 'label' => 'Workshop Preferences', 'fieldset_style' => $style, 'required' => false, 'css_class' => '', 'css_id' => ''), 'sessions' => array('version' => 2, 'istance_id' => 'sessions', 'widget_number' => '', 'ref' => 'sessions', 'required' => true, 'css_class' => '', 'css_id' => ''), 'dietary' => array('version' => 2, 'istance_id' => 'dietary', 'widget_number' => '', 'ref' => 'dietary', 'required' => false, 'css_class' => '', 'css_id' => ''), '__fieldset-end-2' => array('version' => 2, 'istance_id' => '__fieldset-end-2', 'widget_number' => 2, 'ref' => '__fieldset-end', 'required' => false, 'css_class' => '', 'css_id' => ''), 'agree_terms' => array('version' => 2, 'istance_id' => 'agree_terms', 'widget_number' => '', 'ref' => 'agree_terms', 'required' => true, 'custom_required_message' => 'You must accept the Terms and Conditions to complete your registration.', 'css_class' => '', 'css_id' => ''))); } update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => 'Job Application', 'layout' => 'toplabel', 'success_message' => '<div><h2>Application received.<\\\/h2><p>Thank you {first_name}! We will review your application and get back to you within 5 business days.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Submission error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New job application: {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'Application received', 'confirmation_emails_message' => '<div><p>Dear {first_name}, your application has been received.<\\\/p><\\\/div>', 'fields' => array('first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'telephone' => array('version' => 2, 'istance_id' => 'telephone', 'widget_number' => '', 'ref' => 'telephone', 'required' => true, 'country_code' => 'US', 'css_class' => '', 'css_id' => ''), 'department' => array('version' => 2, 'istance_id' => 'department', 'widget_number' => '', 'ref' => 'department', 'required' => true, 'css_class' => '', 'css_id' => ''), 'start_date' => array('version' => 2, 'istance_id' => 'start_date', 'widget_number' => '', 'ref' => 'start_date', 'required' => false, 'css_class' => '', 'css_id' => ''), 'resume' => array('version' => 2, 'istance_id' => 'resume', 'widget_number' => '', 'ref' => 'resume', 'required' => true, 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'required' => false, 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => 'Request a Quote', 'layout' => 'toplabel', 'success_message' => '<div><h2>Quote request received.<\\\/h2><p>Thank you {first_name}! We will prepare your quote and get back to you within 2 business days.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Something went wrong.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New quote request: {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'We received your quote request', 'confirmation_emails_message' => '<div><p>Dear {first_name}, we received your request and will reply with a quote shortly.<\\\/p><\\\/div>', 'fields' => array('__fieldset-begin-1' => array('version' => 2, 'istance_id' => '__fieldset-begin-1', 'widget_number' => 1, 'ref' => '__fieldset-begin', 'label' => 'Your Details', 'fieldset_style' => 'border-on-title-inline', 'required' => false, 'css_class' => '', 'css_id' => ''), 'first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'telephone' => array('version' => 2, 'istance_id' => 'telephone', 'widget_number' => '', 'ref' => 'telephone', 'required' => false, 'country_code' => 'US', 'css_class' => '', 'css_id' => ''), '__fieldset-end-1' => array('version' => 2, 'istance_id' => '__fieldset-end-1', 'widget_number' => 1, 'ref' => '__fieldset-end', 'required' => false, 'css_class' => '', 'css_id' => ''), '__fieldset-begin-2' => array('version' => 2, 'istance_id' => '__fieldset-begin-2', 'widget_number' => 2, 'ref' => '__fieldset-begin', 'label' => 'Address', 'fieldset_style' => 'border-on-title-inline', 'required' => false, 'css_class' => '', 'css_id' => ''), 'address' => array('version' => 2, 'istance_id' => 'address', 'widget_number' => '', 'ref' => 'address', 'required' => false, 'css_class' => '', 'css_id' => ''), 'city' => array('version' => 2, 'istance_id' => 'city', 'widget_number' => '', 'ref' => 'city', 'required' => false, 'css_class' => '', 'css_id' => ''), 'country' => array('version' => 2, 'istance_id' => 'country', 'widget_number' => '', 'ref' => 'country', 'required' => false, 'css_class' => '', 'css_id' => ''), '__fieldset-end-2' => array('version' => 2, 'istance_id' => '__fieldset-end-2', 'widget_number' => 2, 'ref' => '__fieldset-end', 'required' => false, 'css_class' => '', 'css_id' => ''), '__fieldset-begin-3' => array('version' => 2, 'istance_id' => '__fieldset-begin-3', 'widget_number' => 3, 'ref' => '__fieldset-begin', 'label' => 'Project Information', 'fieldset_style' => 'border-on-title-inline', 'required' => false, 'css_class' => '', 'css_id' => ''), 'service' => array('version' => 2, 'istance_id' => 'service', 'widget_number' => '', 'ref' => 'service', 'required' => true, 'css_class' => '', 'css_id' => ''), 'budget' => array('version' => 2, 'istance_id' => 'budget', 'widget_number' => '', 'ref' => 'budget', 'required' => false, 'css_class' => '', 'css_id' => ''), 'deadline' => array('version' => 2, 'istance_id' => 'deadline', 'widget_number' => '', 'ref' => 'deadline', 'required' => false, 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'required' => false, 'css_class' => '', 'css_id' => ''), '__fieldset-end-3' => array('version' => 2, 'istance_id' => '__fieldset-end-3', 'widget_number' => 3, 'ref' => '__fieldset-end', 'required' => false, 'css_class' => '', 'css_id' => ''), 'agree_terms' => array('version' => 2, 'istance_id' => 'agree_terms', 'widget_number' => '', 'ref' => 'agree_terms', 'required' => true, 'custom_required_message' => 'You must accept the Terms and Conditions to request a quote.', 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => 'Quick Feedback (Custom Validation Messages)', 'layout' => 'toplabel', 'success_message' => '<div><h2>Thanks for your feedback!<\\\/h2><p>We appreciate you taking the time to write to us.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New feedback received', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => '', 'confirmation_emails_message' => '', 'fields' => array('first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'custom_required_message' => 'Please tell us your name, so we know who we are talking to.', 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'custom_format_message' => 'Please enter a valid email address like name@example.com so we can reply to you.', 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'required' => true, 'custom_required_message' => 'Please write at least a short message before sending.', 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => 'Content Feedback (Post Select)', 'layout' => 'toplabel', 'success_message' => '<div><h2>Feedback received.<\\\/h2><p>Thank you for your feedback on our content!<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'Content feedback received', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => '', 'confirmation_emails_message' => '', 'fields' => array('__html-1' => array('version' => 2, 'istance_id' => '__html-1', 'widget_number' => 1, 'ref' => '__html', 'default_value' => '<div style=\\\"background:#f0f7ff;border:1px solid #c0d8f0;border-radius:4px;padding:12px 16px;margin-bottom:1em;\\\"><strong>Help us improve!<\\\/strong> Select the article you are providing feedback about, then tell us what you think.<\\\/div>', 'required' => false, 'css_class' => '', 'css_id' => ''), 'related_article' => array('version' => 2, 'istance_id' => 'related_article', 'widget_number' => '', 'ref' => 'related_article', 'required' => true, 'post_type' => 'post', 'css_class' => '', 'css_id' => ''), 'related_pages' => array('version' => 2, 'istance_id' => 'related_pages', 'widget_number' => '', 'ref' => 'related_pages', 'required' => false, 'post_type' => 'page', 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'required' => true, 'css_class' => '', 'css_id' => ''), 'source_page' => array('version' => 2, 'istance_id' => 'source_page', 'widget_number' => '', 'ref' => 'source_page', 'required' => false, 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $lastid++; $forms[$lastid] = array('use_ajax' => true, 'title' => 'Customer Satisfaction Poll', 'layout' => 'toplabel', 'success_message' => '<div><h2>Thanks for taking part!<\\\/h2><p>Your anonymous answers have been recorded.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => '', 'emails_bcc' => '', 'admin_emails_subject' => '', 'admin_emails_message' => '', 'confirmation_emails_subject' => '', 'confirmation_emails_message' => '', 'fields' => array('satisfaction' => array('version' => 2, 'istance_id' => 'satisfaction', 'widget_number' => '', 'ref' => 'satisfaction', 'required' => true, 'css_class' => '', 'css_id' => ''), 'recommend' => array('version' => 2, 'istance_id' => 'recommend', 'widget_number' => '', 'ref' => 'recommend', 'required' => true, 'css_class' => '', 'css_id' => ''), 'used_features' => array('version' => 2, 'istance_id' => 'used_features', 'widget_number' => '', 'ref' => 'used_features', 'required' => false, 'css_class' => '', 'css_id' => ''), 'poll_comments' => array('version' => 2, 'istance_id' => 'poll_comments', 'widget_number' => '', 'ref' => 'poll_comments', 'required' => false, 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $lastid++; $reg_fid = $lastid; $forms[$reg_fid] = array('use_ajax' => true, 'title' => 'Conference Registration (Custom HTML)', 'layout' => 'toplabel', 'success_message' => '<div><h2>You are in, {first_name}!<\\\/h2><p>Your seat is reserved. Check your inbox for the confirmation.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New conference registration: {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'Your conference seat is reserved', 'confirmation_emails_message' => '<div><p>Dear {first_name}, your registration has been confirmed. See you at the conference!<\\\/p><\\\/div>', 'fields' => array('__html-1' => array('version' => 2, 'istance_id' => '__html-1', 'widget_number' => 1, 'ref' => '__html', 'default_value' => '<div style=\\\"background:linear-gradient(135deg,#003974,#0a5cad);color:#fff;border-radius:6px;padding:18px 22px;margin-bottom:1em;\\\"><h3 style=\\\"margin:0 0 6px;color:#fff;\\\">Annual Web Conference<\\\/h3><p style=\\\"margin:0;\\\">June 12, 2027 - Milan Convention Center. Free admission, limited seats.<\\\/p><\\\/div>', 'required' => false, 'css_class' => '', 'css_id' => ''), 'first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'privacy_notice' => array('version' => 2, 'istance_id' => 'privacy_notice', 'widget_number' => '', 'ref' => 'privacy_notice', 'required' => false, 'css_class' => '', 'css_id' => ''))); $lastid++; $press_fid = $lastid; $forms[$press_fid] = array('use_ajax' => true, 'title' => 'Press Pass Request (Custom HTML override)', 'layout' => 'toplabel', 'success_message' => '<div><h2>Request received.<\\\/h2><p>Thank you {first_name}, our press office will verify your accreditation and reply by email.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New press pass request: {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'We received your press pass request', 'confirmation_emails_message' => '<div><p>Dear {first_name}, we received your request and will get back to you after verifying your accreditation.<\\\/p><\\\/div>', 'fields' => array('__html-1' => array('version' => 2, 'istance_id' => '__html-1', 'widget_number' => 1, 'ref' => '__html', 'default_value' => '<div style=\\\"background:#1d2327;color:#fff;border-radius:6px;padding:14px 20px;margin-bottom:1em;\\\"><strong>Media accreditation<\\\/strong> - Annual Web Conference, June 12, 2027.<\\\/div>', 'required' => false, 'css_class' => '', 'css_id' => ''), 'first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'label' => 'Outlet and coverage plans', 'required' => true, 'css_class' => '', 'css_id' => ''), 'privacy_notice' => array('version' => 2, 'istance_id' => 'privacy_notice', 'widget_number' => '', 'ref' => 'privacy_notice', 'default_value' => '<p class=\\\"privacy-notice\\\" style=\\\"font-size:0.9em;color:#50575e;background:#fdf5e6;border-left:4px solid #b26200;padding:8px 12px;\\\">Press requests: your details are also forwarded to our press office to verify your accreditation. We never share them with anyone else.<\\\/p>', 'required' => false, 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); $notice = '<!-- wp:paragraph --><p><em>Note: this is a live demo running in WordPress Playground. Form submissions are saved to the database but email notifications are not delivered.<\\\/em><\\\/p><!-- \\\/wp:paragraph -->'; $body = '<!-- wp:heading --><h2>Custom HTML Content in Forms<\\\/h2><!-- \\\/wp:heading --><!-- wp:paragraph --><p>HTML content can be mixed into a form in three ways. A one-off block: drag the special Custom HTML content widget into a form and write the markup for that form only (the banners at the top of both forms below). A reusable block: define an HTML field in the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_fields\\\">Fields page<\\\/a> with its content as the default value, then add the field to any number of forms - edit the definition once and every form updates (the grey privacy note in the first form). A per-form variation: tick the override checkbox on the field inside one form and replace the content just there, without touching the definition or the other forms (the amber press note in the second form, same field as the grey one).<\\\/p><!-- \\\/wp:paragraph -->' . $notice . '<!-- wp:heading {\\\"level\\\":3} --><h3>Conference Registration<\\\/h3><!-- \\\/wp:heading --><!-- wp:paragraph --><p>The blue banner is a one-off Custom HTML block. The grey note above the submit button is the reusable Privacy Notice field, rendered with the default content from its definition.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:shortcode -->[accua-form fid=\\\"' . $reg_fid . '\\\"]<!-- \\\/wp:shortcode --><!-- wp:heading {\\\"level\\\":3} --><h3>Press Pass Request<\\\/h3><!-- \\\/wp:heading --><!-- wp:paragraph --><p>The same Privacy Notice field, but this form ticks the override checkbox in the form editor and shows a press-specific note instead. Open the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_list\\\">form editor<\\\/a> to compare the two field instances.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:shortcode -->[accua-form fid=\\\"' . $press_fid . '\\\"]<!-- \\\/wp:shortcode -->'; wp_insert_post(array('post_title' => 'Custom HTML Content', 'post_name' => 'custom-html-content', 'post_content' => $body, 'post_status' => 'publish', 'post_type' => 'page')); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $lastid = (int) get_option('accua_forms_lastid', 0); $admin_email = get_option('admin_email'); $lastid++; $brief_fid = $lastid; $forms[$brief_fid] = array('use_ajax' => true, 'title' => 'Website Restyling Brief (Color Picker)', 'layout' => 'toplabel', 'success_message' => '<div><h2>Brief received, {first_name}!<\\\/h2><p>We will study your current site and get back to you with a proposal.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New restyling brief from {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'We received your restyling brief', 'confirmation_emails_message' => '<div><p>Dear {first_name}, thank you for the details. We will reply with a proposal shortly.<\\\/p><\\\/div>', 'fields' => array('first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => false, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'brand_color' => array('version' => 2, 'istance_id' => 'brand_color', 'widget_number' => '', 'ref' => 'brand_color', 'required' => false, 'css_class' => '', 'css_id' => ''), 'message' => array('version' => 2, 'istance_id' => 'message', 'widget_number' => '', 'ref' => 'message', 'label' => 'What should change in the new design?', 'required' => true, 'css_class' => '', 'css_id' => ''), 'send_brief' => array('version' => 2, 'istance_id' => 'send_brief', 'widget_number' => '', 'ref' => 'send_brief', 'required' => false, 'css_class' => '', 'css_id' => ''))); $lastid++; $member_fid = $lastid; $forms[$member_fid] = array('use_ajax' => false, 'title' => 'Member Registration (Non-AJAX)', 'layout' => 'toplabel', 'success_message' => '<div><h2>Welcome aboard, {first_name}!<\\\/h2><p>Your registration has been recorded. This confirmation was rendered by a full page load, no AJAX involved.<\\\/p><\\\/div>', 'error_message' => '<div><h2>Error.<\\\/h2><p>Please try again.<\\\/p><\\\/div>', 'emails_from_name' => '', 'emails_from' => '', 'admin_emails_to' => $admin_email, 'emails_bcc' => '', 'admin_emails_subject' => 'New member registration: {first_name} {last_name}', 'admin_emails_message' => '{__submitted_html}', 'confirmation_emails_subject' => 'Your membership registration', 'confirmation_emails_message' => '<div><p>Dear {first_name}, welcome! Your registration has been recorded.<\\\/p><\\\/div>', 'fields' => array('first_name' => array('version' => 2, 'istance_id' => 'first_name', 'widget_number' => '', 'ref' => 'first_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'last_name' => array('version' => 2, 'istance_id' => 'last_name', 'widget_number' => '', 'ref' => 'last_name', 'required' => true, 'css_class' => '', 'css_id' => ''), 'email' => array('version' => 2, 'istance_id' => 'email', 'widget_number' => '', 'ref' => 'email', 'required' => true, 'css_class' => '', 'css_id' => ''), 'choose_password' => array('version' => 2, 'istance_id' => 'choose_password', 'widget_number' => '', 'ref' => 'choose_password', 'required' => true, 'css_class' => '', 'css_id' => ''), 'agree_terms' => array('version' => 2, 'istance_id' => 'agree_terms', 'widget_number' => '', 'ref' => 'agree_terms', 'required' => true, 'custom_required_message' => 'You must accept the Terms and Conditions to register.', 'css_class' => '', 'css_id' => ''))); update_option('accua_forms_saved_forms', $forms); update_option('accua_forms_lastid', $lastid); $notice = '<!-- wp:paragraph --><p><em>Note: this is a live demo running in WordPress Playground. Form submissions are saved to the database but email notifications are not delivered.<\\\/em><\\\/p><!-- \\\/wp:paragraph -->'; $mkpage = function($title, $slug, $heading, $body, $fid) use ($notice) { return wp_insert_post(array('post_title' => $title, 'post_name' => $slug, 'post_content' => '<!-- wp:heading --><h2>' . $heading . '<\\\/h2><!-- \\\/wp:heading -->' . $body . $notice . '<!-- wp:shortcode -->[accua-form fid=\\\"' . $fid . '\\\"]<!-- \\\/wp:shortcode -->', 'post_status' => 'publish', 'post_type' => 'page')); }; $mkpage('Website Restyling Brief', 'website-restyling-brief', 'Color Picker and Custom Submit Button', '<!-- wp:paragraph --><p>The color field is a Color Picker: it renders as the browser\\\\'s native color input, so visitors choose the color visually and the form receives a hex value like #003974, shown as a color swatch in the notification email. The submit button is not the automatic one: this form contains a Submit button field with its own label, which replaces the auto-added button and can be placed anywhere in the form.<\\\/p><!-- \\\/wp:paragraph -->', $brief_fid); $mkpage('Member Registration', 'member-registration', 'Password Fields and Non-AJAX Submission', '<!-- wp:paragraph --><p>The password field is a Password and confirmation field: two masked inputs that must match before the form is accepted. The password is never stored in plain text: the submissions archive keeps only a secure hash.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>This form also has the Use AJAX option turned off, so submitting performs a classic full page reload instead of an in-page update. Validation runs on the server: submit the form empty and the page re-renders with the error messages; on success the confirmation message replaces the form.<\\\/p><!-- \\\/wp:paragraph -->', $member_fid); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; wp_insert_post(array('post_title' => 'Getting Started with Our Platform', 'post_content' => '<!-- wp:paragraph --><p>Welcome to our platform! This guide covers the basics.<\\\/p><!-- \\\/wp:paragraph -->', 'post_status' => 'publish', 'post_type' => 'post')); wp_insert_post(array('post_title' => 'Tips for Better Productivity', 'post_content' => '<!-- wp:paragraph --><p>Here are our top tips for getting the most out of your workflow.<\\\/p><!-- \\\/wp:paragraph -->', 'post_status' => 'publish', 'post_type' => 'post')); wp_insert_post(array('post_title' => 'Frequently Asked Questions', 'post_content' => '<!-- wp:paragraph --><p>Answers to the questions we hear most often.<\\\/p><!-- \\\/wp:paragraph -->', 'post_status' => 'publish', 'post_type' => 'post')); wp_insert_post(array('post_title' => 'Company News and Updates', 'post_content' => '<!-- wp:paragraph --><p>The latest news from our team.<\\\/p><!-- \\\/wp:paragraph -->', 'post_status' => 'publish', 'post_type' => 'post')); wp_insert_post(array('post_title' => 'Feature Spotlight: Contact Forms', 'post_content' => '<!-- wp:paragraph --><p>A deep dive into our contact forms plugin features.<\\\/p><!-- \\\/wp:paragraph -->', 'post_status' => 'publish', 'post_type' => 'post')); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $forms = get_option('accua_forms_saved_forms', array()); $fids = array_keys($forms); $notice = '<!-- wp:paragraph --><p><em>Note: this is a live demo running in WordPress Playground. Form submissions are saved to the database but email notifications are not delivered. You are already logged in: explore the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_submissions_list\\\">submissions archive<\\\/a> and the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms\\\">dashboard statistics<\\\/a>.<\\\/em><\\\/p><!-- \\\/wp:paragraph -->'; $mkpage = function($title, $slug, $heading, $body, $fid) use ($notice) { return wp_insert_post(array('post_title' => $title, 'post_name' => $slug, 'post_content' => '<!-- wp:heading --><h2>' . $heading . '<\\\/h2><!-- \\\/wp:heading -->' . $body . $notice . '<!-- wp:shortcode -->[accua-form fid=\\\"' . $fid . '\\\"]<!-- \\\/wp:shortcode -->', 'post_status' => 'publish', 'post_type' => 'page')); }; $mkpage('Contact Us: Top Labels', 'contact-top-labels', 'Label Layout: Top Labels', '<!-- wp:paragraph --><p>Labels are placed above their fields. This is the default and most versatile layout: a single column that reads naturally on any screen width and leaves room for long labels.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>The layout is selected per form in the form editor. This is the same contact form shown on the <a href=\\\"\\\/contact-side-labels\\\/\\\">Side by Side Labels<\\\/a> and <a href=\\\"\\\/contact-inline-labels\\\/\\\">Inline Labels<\\\/a> pages, so you can compare the three variants directly.<\\\/p><!-- \\\/wp:paragraph -->', $fids[0]); $mkpage('Contact Us: Side by Side Labels', 'contact-side-labels', 'Label Layout: Side by Side', '<!-- wp:paragraph --><p>Labels sit on the left, next to their fields. Long forms become visually shorter and easier to scan on wide screens; on narrow screens the fields stack automatically.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>This is the same contact form shown on the <a href=\\\"\\\/contact-top-labels\\\/\\\">Top Labels<\\\/a> and <a href=\\\"\\\/contact-inline-labels\\\/\\\">Inline Labels<\\\/a> pages, so you can compare the three variants directly.<\\\/p><!-- \\\/wp:paragraph -->', $fids[1]); $mkpage('Contact Us: Inline Labels', 'contact-inline-labels', 'Label Layout: Inline Labels', '<!-- wp:paragraph --><p>Labels appear inside the fields as floating labels: while you type, the label moves above the value, so the hint never disappears. A compact and modern look, great for short forms.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>This is the same contact form shown on the <a href=\\\"\\\/contact-top-labels\\\/\\\">Top Labels<\\\/a> and <a href=\\\"\\\/contact-side-labels\\\/\\\">Side by Side Labels<\\\/a> pages, so you can compare the three variants directly.<\\\/p><!-- \\\/wp:paragraph -->', $fids[2]); $mkpage('Field Groups: Inline Legend', 'groups-inline-legend', 'Field Groups: Inline Legend', '<!-- wp:paragraph --><p>Related fields can be grouped with the special Group field. Both groups in this registration form use the classic style: a border around the group with the title rendered as an inline legend on the border edge.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>The style is chosen per group with the Border and Title dropdown in the form editor. Compare the same form with the <a href=\\\"\\\/groups-title-above\\\/\\\">Title Above<\\\/a>, <a href=\\\"\\\/groups-title-inside\\\/\\\">Title Inside<\\\/a> and <a href=\\\"\\\/groups-title-no-border\\\/\\\">Title Without Border<\\\/a> variants. Two more options exist for purely structural grouping: border only, and no border with no title.<\\\/p><!-- \\\/wp:paragraph -->', $fids[3]); $mkpage('Field Groups: Title Above', 'groups-title-above', 'Field Groups: Title Above the Border', '<!-- wp:paragraph --><p>In this variant the group title is rendered above the bordered box, like a section heading standing on top of the group.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>This is the same registration form shown on the <a href=\\\"\\\/groups-inline-legend\\\/\\\">Inline Legend<\\\/a>, <a href=\\\"\\\/groups-title-inside\\\/\\\">Title Inside<\\\/a> and <a href=\\\"\\\/groups-title-no-border\\\/\\\">Title Without Border<\\\/a> pages: only the Border and Title setting of the two groups changes.<\\\/p><!-- \\\/wp:paragraph -->', $fids[4]); $mkpage('Field Groups: Title Inside', 'groups-title-inside', 'Field Groups: Title Inside the Border', '<!-- wp:paragraph --><p>In this variant the group title is rendered inside the bordered box, above the first field of the group.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>This is the same registration form shown on the <a href=\\\"\\\/groups-inline-legend\\\/\\\">Inline Legend<\\\/a>, <a href=\\\"\\\/groups-title-above\\\/\\\">Title Above<\\\/a> and <a href=\\\"\\\/groups-title-no-border\\\/\\\">Title Without Border<\\\/a> pages: only the Border and Title setting of the two groups changes.<\\\/p><!-- \\\/wp:paragraph -->', $fids[5]); $mkpage('Field Groups: Title Without Border', 'groups-title-no-border', 'Field Groups: Title Without Border', '<!-- wp:paragraph --><p>In this variant the group title is rendered without any border, giving a light section heading that separates the form without drawing boxes.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>This is the same registration form shown on the <a href=\\\"\\\/groups-inline-legend\\\/\\\">Inline Legend<\\\/a>, <a href=\\\"\\\/groups-title-above\\\/\\\">Title Above<\\\/a> and <a href=\\\"\\\/groups-title-inside\\\/\\\">Title Inside<\\\/a> pages: only the Border and Title setting of the two groups changes.<\\\/p><!-- \\\/wp:paragraph -->', $fids[6]); $mkpage('Job Application', 'job-application', 'Job Application: File Upload and Date Picker', '<!-- wp:paragraph --><p>A focused hiring form. The resume field accepts only pdf, doc and docx files and supports drag and drop; invalid files are rejected immediately, before the form is even submitted. The preferred start date uses a date picker, and the phone number is validated with United States number rules.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>Submissions of this form are preloaded with the Job Candidate lead status: open the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_submissions_list\\\">submissions archive<\\\/a> to see how leads can be classified.<\\\/p><!-- \\\/wp:paragraph -->', $fids[7]); $mkpage('Request a Quote', 'request-a-quote', 'Request a Quote: a Long Real World Form', '<!-- wp:paragraph --><p>A complete quote request split into three groups (contact details, address and project information), all using the same inline legend style so the form stays visually consistent. It includes select fields for service and budget, a date picker for the desired deadline, and address fields.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>The Terms and Conditions checkbox is the last field before the submit button, where users expect it.<\\\/p><!-- \\\/wp:paragraph -->', $fids[8]); $mkpage('Custom Validation Messages', 'custom-validation-messages', 'Custom Validation Messages', '<!-- wp:paragraph --><p>Every field can override the default validation texts: both the required field message and the wrong format message, either globally in the field definition or per single form. Submit this form empty, or type an invalid email address, and read the resulting errors.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>In this form the name and the message fields use custom required messages, and the email field uses a custom format message.<\\\/p><!-- \\\/wp:paragraph -->', $fids[9]); $mkpage('Content Feedback', 'content-feedback', 'Content Feedback: Fields Populated from Posts', '<!-- wp:paragraph --><p>The article dropdown is a Post Select field: it loads published posts lazily via AJAX, with search and pagination, so it stays fast even with thousands of posts. The related pages below it are a Post Checkboxes field, populated from pages.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>The form also contains a custom HTML block (the blue box) and a hidden field that silently records where the submission came from.<\\\/p><!-- \\\/wp:paragraph -->', $fids[10]); $mkpage('Customer Poll', 'customer-poll', 'Customer Poll: Anonymous Survey', '<!-- wp:paragraph --><p>A poll built with radio scales, a multiple choice checkbox question and an optional comment box. No name or email is collected and no notification emails are sent: answers only go to the submissions archive.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p>30 sample responses are preloaded: open the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_submissions_list\\\">archive<\\\/a> and filter by this form to browse them.<\\\/p><!-- \\\/wp:paragraph -->', $fids[11]); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $welcome_body = '<!-- wp:paragraph --><p>This site is a live demo of the Contact Forms by Cimatti plugin for WordPress. Every page shows one focused example, so you can evaluate each capability on its own. The forms submit via AJAX (one example also demonstrates the classic full page reload), store their submissions in the archive and support notification and confirmation emails.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:heading {\\\"level\\\":3} --><h3>Label layouts<\\\/h3><!-- \\\/wp:heading --><!-- wp:paragraph --><p>The same contact form rendered with the three available label layouts:<\\\/p><!-- \\\/wp:paragraph --><!-- wp:list --><ul class=\\\"wp-block-list\\\"><!-- wp:list-item --><li><a href=\\\"\\\/contact-top-labels\\\/\\\">Top Labels<\\\/a>: the default layout, labels above the fields<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/contact-side-labels\\\/\\\">Side by Side Labels<\\\/a>: labels on the left, compact on wide screens<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/contact-inline-labels\\\/\\\">Inline Labels<\\\/a>: floating labels inside the fields<\\\/li><!-- \\\/wp:list-item --><\\\/ul><!-- \\\/wp:list --><!-- wp:heading {\\\"level\\\":3} --><h3>Field group styles<\\\/h3><!-- \\\/wp:heading --><!-- wp:paragraph --><p>The same workshop registration form rendered with four different group title styles (the Border and Title setting of the Group field):<\\\/p><!-- \\\/wp:paragraph --><!-- wp:list --><ul class=\\\"wp-block-list\\\"><!-- wp:list-item --><li><a href=\\\"\\\/groups-inline-legend\\\/\\\">Inline Legend<\\\/a>: classic legend on the border edge<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/groups-title-above\\\/\\\">Title Above<\\\/a>: heading on top of the bordered box<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/groups-title-inside\\\/\\\">Title Inside<\\\/a>: heading inside the bordered box<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/groups-title-no-border\\\/\\\">Title Without Border<\\\/a>: light section heading, no box<\\\/li><!-- \\\/wp:list-item --><\\\/ul><!-- \\\/wp:list --><!-- wp:heading {\\\"level\\\":3} --><h3>Real world examples<\\\/h3><!-- \\\/wp:heading --><!-- wp:paragraph --><p>Focused forms for common scenarios:<\\\/p><!-- \\\/wp:paragraph --><!-- wp:list --><ul class=\\\"wp-block-list\\\"><!-- wp:list-item --><li><a href=\\\"\\\/job-application\\\/\\\">Job Application<\\\/a>: file upload with allowed extensions, date picker, phone validation<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/request-a-quote\\\/\\\">Request a Quote<\\\/a>: a long form with field groups, selects and address fields<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/custom-validation-messages\\\/\\\">Custom Validation Messages<\\\/a>: per field error texts<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/content-feedback\\\/\\\">Content Feedback<\\\/a>: fields populated from posts and pages, hidden tracking field<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/customer-poll\\\/\\\">Customer Poll<\\\/a>: anonymous survey with no email notifications<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/custom-html-content\\\/\\\">Custom HTML Content<\\\/a>: one-off HTML blocks, a reusable HTML field and a per-form content override<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/website-restyling-brief\\\/\\\">Website Restyling Brief<\\\/a>: color picker field and a custom submit button<\\\/li><!-- \\\/wp:list-item --><!-- wp:list-item --><li><a href=\\\"\\\/member-registration\\\/\\\">Member Registration<\\\/a>: password with confirmation, submitting without AJAX<\\\/li><!-- \\\/wp:list-item --><\\\/ul><!-- \\\/wp:list --><!-- wp:heading {\\\"level\\\":3} --><h3>Explore the admin area<\\\/h3><!-- \\\/wp:heading --><!-- wp:paragraph --><p>You are already logged in as admin. Open the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_submissions_list\\\">submissions archive<\\\/a> (preloaded with more than 120 sample submissions, including GDPR anonymized entries, spam and trashed items), the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms\\\">statistics dashboard<\\\/a> and the <a href=\\\"\\\/wp-admin\\\/admin.php?page=accua_forms_list\\\">form editor<\\\/a> to see how each demo form is built.<\\\/p><!-- \\\/wp:paragraph --><!-- wp:paragraph --><p><em>Note: this is a live demo running in WordPress Playground. Form submissions are saved to the database but email notifications are not delivered.<\\\/em><\\\/p><!-- \\\/wp:paragraph -->'; $wp_page = get_page_by_path('welcome'); if ($wp_page) { wp_update_post(array('ID' => $wp_page->ID, 'post_content' => $welcome_body)); $welcome_id = $wp_page->ID; } else { $welcome_id = wp_insert_post(array('post_title' => 'Welcome', 'post_name' => 'welcome', 'post_content' => $welcome_body, 'post_status' => 'publish', 'post_type' => 'page')); } update_option('show_on_front', 'page'); update_option('page_on_front', $welcome_id); ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; $mk = function($slug, $label) { $p = get_page_by_path($slug); if (!$p) return ''; return '<!-- wp:navigation-link {\\\"label\\\":\\\"' . $label . '\\\",\\\"type\\\":\\\"page\\\",\\\"id\\\":' . $p->ID . ',\\\"url\\\":\\\"' . esc_url(get_permalink($p)) . '\\\",\\\"kind\\\":\\\"post-type\\\"} \\\/-->'; }; $nav = '<!-- wp:navigation-link {\\\"label\\\":\\\"Home\\\",\\\"url\\\":\\\"' . esc_url(home_url('\\\/')) . '\\\",\\\"kind\\\":\\\"custom\\\"} \\\/-->'; $nav .= '<!-- wp:navigation-submenu {\\\"label\\\":\\\"Label Layouts\\\",\\\"url\\\":\\\"\\\/contact-top-labels\\\/\\\",\\\"kind\\\":\\\"custom\\\"} -->' . $mk('contact-top-labels', 'Top Labels') . $mk('contact-side-labels', 'Side by Side Labels') . $mk('contact-inline-labels', 'Inline Labels') . '<!-- \\\/wp:navigation-submenu -->'; $nav .= '<!-- wp:navigation-submenu {\\\"label\\\":\\\"Field Groups\\\",\\\"url\\\":\\\"\\\/groups-inline-legend\\\/\\\",\\\"kind\\\":\\\"custom\\\"} -->' . $mk('groups-inline-legend', 'Inline Legend') . $mk('groups-title-above', 'Title Above') . $mk('groups-title-inside', 'Title Inside') . $mk('groups-title-no-border', 'Title Without Border') . '<!-- \\\/wp:navigation-submenu -->'; $nav .= '<!-- wp:navigation-submenu {\\\"label\\\":\\\"Examples\\\",\\\"url\\\":\\\"\\\/job-application\\\/\\\",\\\"kind\\\":\\\"custom\\\"} -->' . $mk('job-application', 'Job Application') . $mk('request-a-quote', 'Request a Quote') . $mk('custom-validation-messages', 'Custom Messages') . $mk('content-feedback', 'Content Feedback') . $mk('customer-poll', 'Customer Poll') . $mk('custom-html-content', 'Custom HTML') . $mk('website-restyling-brief', 'Restyling Brief') . $mk('member-registration', 'Member Registration') . '<!-- \\\/wp:navigation-submenu -->'; $nav_posts = get_posts(array('post_type' => 'wp_navigation', 'title' => 'Demo Pages', 'post_status' => 'publish', 'numberposts' => 1)); if ($nav_posts) { wp_update_post(array('ID' => $nav_posts[0]->ID, 'post_content' => $nav)); } else { wp_insert_post(array('post_title' => 'Demo Pages', 'post_type' => 'wp_navigation', 'post_status' => 'publish', 'post_content' => $nav)); } ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; global $wpdb; $forms = get_option('accua_forms_saved_forms', array()); $fids = array_keys($forms); $ts = $wpdb->prefix . 'accua_forms_submissions'; $tv = $wpdb->prefix . 'accua_forms_submissions_values'; $fn = array('Alice','Bob','Carol','David','Eva','Frank','Grace','Henry','Iris','Jack','Karen','Leo','Marta','Nick','Olga','Paul','Rita','Sam','Tina','Hugo','Vera','Walter','Nadia','Yuri'); $ln = array('Johnson','Smith','Williams','Brown','Martinez','Garcia','Lee','Wilson','Taylor','Anderson','Thomas','Moore','Rossi','Bianchi','Kim','Novak','Weber','Silva','Costa','Meyer','Olsen','Dubois','Fischer','Marino'); $msgs = array('I would like to learn more about your services.','Can you help me with a new project?','Great plugin, I just wanted to say thanks!','I have a question about pricing.','Please contact me regarding a partnership.','We are interested in your enterprise plan.','How do I integrate this with my existing site?','Looking forward to hearing from you.'); $reasons = array('General Inquiry','Support Request','Partnership','Feedback'); $ins = function($fid, $uri, $vals, $lead, $days) use ($wpdb, $ts, $tv) { $now = time(); $submitted = $now - ($days * 86400) - rand(0, 70000); $created = $submitted - rand(60, 900); $pid = 0; $pg = get_page_by_path(trim($uri, '\\\/')); if ($pg) { $pid = $pg->ID; } $wpdb->insert($ts, array('afs_form_id' => (string) $fid, 'afs_post_id' => $pid, 'afs_ip' => '192.168.1.' . rand(10, 250), 'afs_uri' => $uri, 'afs_referrer' => '', 'afs_lang' => 'en_US', 'afs_created' => gmdate('Y-m-d H:i:s', $created), 'afs_submitted' => gmdate('Y-m-d H:i:s', $submitted), 'afs_status' => 0, 'afs_stats' => json_encode(array('user_agent' => 'Mozilla\\\/5.0 (Windows NT 10.0; Win64; x64)', 'platform' => rand(0, 3) ? 'desktop' : 'mobile', 'tentatives' => 1, 'submit_method' => 'ajax')), 'afs_lead_status' => $lead)); $sid = $wpdb->insert_id; foreach ($vals as $k => $v) { if ($v[1] === '') continue; $wpdb->insert($tv, array('afsv_sub_id' => $sid, 'afsv_field_id' => $k, 'afsv_type' => $v[0], 'afsv_value' => $v[1])); } return $sid; }; $contact_leads = array(2, 0, 3, 5, 0, 2, 0, -1, 0, 3, 2, 0, 5, 0, 2, 0); $contact = array(array($fids[0], '\\\/contact-top-labels\\\/', 16), array($fids[1], '\\\/contact-side-labels\\\/', 12), array($fids[2], '\\\/contact-inline-labels\\\/', 12)); $n = 0; foreach ($contact as $cf) { for ($i = 0; $i < $cf[2]; $i++) { $f = $fn[$n % 24]; $l = $ln[($n * 5 + 3) % 24]; $ins($cf[0], $cf[1], array('first_name' => array('textfield', $f), 'last_name' => array('textfield', $l), 'email' => array('autoreply_email', strtolower($f) . '.' . strtolower($l) . '@example.com'), 'telephone' => array('telephone', ($i % 3 === 0) ? '+1 202 555 01' . sprintf('%02d', $i) : ''), 'contact_reason' => array('radio', $reasons[$n % 4]), 'message' => array('textarea', $msgs[$n % 8])), $contact_leads[$i % 16], rand(0, 59)); $n++; } } $sess = array('Keynote', 'Workshop A: Frontend Dev', 'Workshop B: Backend Dev', 'Networking Lunch', 'Panel Discussion'); $diet = array('Vegetarian', 'Vegan', 'Gluten-free', '', 'No restrictions', ''); $wuris = array('\\\/groups-inline-legend\\\/', '\\\/groups-title-above\\\/', '\\\/groups-title-inside\\\/', '\\\/groups-title-no-border\\\/'); for ($v = 0; $v < 4; $v++) { for ($i = 0; $i < 6; $i++) { $f = $fn[($n + $i) % 24]; $l = $ln[($n + $i * 7) % 24]; $ins($fids[3 + $v], $wuris[$v], array('first_name' => array('textfield', $f), 'last_name' => array('textfield', $l), 'email' => array('autoreply_email', strtolower($f) . '.' . strtolower($l) . '@example.com'), 'sessions' => array('multiselect', $sess[$i % 5] . ($i % 2 ? ', ' . $sess[($i + 2) % 5] : '')), 'dietary' => array('multicheckbox', $diet[$i % 6])), 0, rand(0, 45)); } $n += 6; } $deps = array('Engineering', 'Sales', 'Marketing', 'Support', 'Human Resources'); for ($i = 0; $i < 10; $i++) { $f = $fn[($i * 3 + 1) % 24]; $l = $ln[($i * 11 + 2) % 24]; $ins($fids[7], '\\\/job-application\\\/', array('first_name' => array('textfield', $f), 'last_name' => array('textfield', $l), 'email' => array('autoreply_email', strtolower($f) . '.' . strtolower($l) . '@example.com'), 'telephone' => array('telephone', '+1 202 555 02' . sprintf('%02d', $i)), 'department' => array('select', $deps[$i % 5]), 'message' => array('textarea', 'I am excited to apply for a position in your team.')), ($i < 8) ? 1 : 0, rand(0, 59)); } $services = array('Website Design', 'E-commerce Development', 'SEO Optimization', 'Maintenance and Support'); $budgets = array('Under 1,000', '1,000 - 5,000', '5,000 - 10,000', 'Over 10,000'); $cities = array('New York', 'Milan', 'Berlin', 'Madrid', 'Lyon', 'Austin', 'Toronto', 'Oslo'); $countries = array('United States', 'Italy', 'Germany', 'Spain', 'France', 'United States', 'Canada', 'Norway'); $quote_leads = array(2, 4, 2, 0, 4, 2, 3, 0, 2, 4); for ($i = 0; $i < 10; $i++) { $f = $fn[($i * 7 + 4) % 24]; $l = $ln[($i * 13 + 5) % 24]; $ins($fids[8], '\\\/request-a-quote\\\/', array('first_name' => array('textfield', $f), 'last_name' => array('textfield', $l), 'email' => array('autoreply_email', strtolower($f) . '.' . strtolower($l) . '@example.com'), 'service' => array('select', $services[$i % 4]), 'budget' => array('select', $budgets[$i % 4]), 'city' => array('textfield', $cities[$i % 8]), 'country' => array('select', $countries[$i % 8])), $quote_leads[$i], rand(0, 59)); } for ($i = 0; $i < 8; $i++) { $f = $fn[($i * 5 + 9) % 24]; $ins($fids[9], '\\\/custom-validation-messages\\\/', array('first_name' => array('textfield', $f), 'email' => array('autoreply_email', strtolower($f) . '.feedback@example.com'), 'message' => array('textarea', $msgs[($i + 3) % 8])), 0, rand(0, 40)); } for ($i = 0; $i < 5; $i++) { $f = $fn[($i * 9 + 6) % 24]; $ins($fids[10], '\\\/content-feedback\\\/', array('email' => array('autoreply_email', strtolower($f) . '.reader@example.com'), 'message' => array('textarea', 'Very useful article, thanks for publishing it.'), 'source_page' => array('hidden', 'wordpress-playground-demo')), 0, rand(0, 30)); } $sat = array('Very satisfied', 'Satisfied', 'Satisfied', 'Neutral', 'Very satisfied', 'Dissatisfied', 'Satisfied', 'Very satisfied', 'Neutral', 'Satisfied'); $rec = array('Definitely', 'Probably', 'Definitely', 'Not sure', 'Probably', 'Probably not', 'Definitely', 'Probably', 'Definitely', 'Not sure'); $feat = array('Contact forms', 'Contact forms, File uploads', 'Email notifications', 'Contact forms, Spam protection', 'Spam protection', 'Contact forms, Submission archive', 'File uploads, Email notifications', 'Contact forms'); for ($i = 0; $i < 30; $i++) { $ins($fids[11], '\\\/customer-poll\\\/', array('satisfaction' => array('radio', $sat[$i % 10]), 'recommend' => array('radio', $rec[($i + 2) % 10]), 'used_features' => array('multicheckbox', $feat[$i % 8])), 0, rand(0, 59)); } $anon = $wpdb->get_col(\\\"SELECT afs_id FROM $ts WHERE afs_form_id = '{$fids[0]}' ORDER BY afs_id ASC LIMIT 3\\\"); $anon2 = $wpdb->get_col(\\\"SELECT afs_id FROM $ts WHERE afs_form_id = '{$fids[1]}' ORDER BY afs_id ASC LIMIT 1\\\"); foreach (array_merge($anon, $anon2) as $aid) { $wpdb->update($ts, array('afs_anonymized' => 1, 'afs_ip' => '0.0.0.0'), array('afs_id' => $aid)); $wpdb->update($tv, array('afsv_value' => 'deleted@site.invalid'), array('afsv_sub_id' => $aid, 'afsv_field_id' => 'email')); $wpdb->query($wpdb->prepare(\\\"UPDATE $tv SET afsv_value = '[Anonymized]' WHERE afsv_sub_id = %d AND afsv_field_id != 'email'\\\", $aid)); } $trash = $wpdb->get_col(\\\"SELECT afs_id FROM $ts WHERE afs_form_id = '{$fids[1]}' AND afs_anonymized = 0 ORDER BY afs_id DESC LIMIT 3\\\"); foreach ($trash as $tid) { $wpdb->update($ts, array('afs_status' => -1), array('afs_id' => $tid)); } ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; global $wpdb; $ts = $wpdb->prefix . 'accua_forms_submissions'; $tv = $wpdb->prefix . 'accua_forms_submissions_values'; $forms = get_option('accua_forms_saved_forms', array()); $by_title = array(); foreach ($forms as $bfid => $bf) { $by_title[$bf['title']] = (string) $bfid; } $refs = array('https:\\\/\\\/www.search-engine.example\\\/search?q=contact+forms+wordpress+plugin+accessible+wcag+drag+and+drop&client=desktop&session=demo1234567890abcdef&token=AbCdEfGhIjKlMnOp&result=17', 'https:\\\/\\\/www.search-hub.example\\\/search?q=wordpress+contact+form+plugin+gdpr+submissions+archive&form=WEBSRCH&pq=wordpress+contact+form+plugin&session=DEMO1234567890ABCDEF', 'https:\\\/\\\/www.privacy-search.example\\\/?q=accessible+wordpress+contact+form+plugin+file+upload&t=web&region=eu'); if (isset($by_title['Contact Us (Top Labels)'])) { $cids = $wpdb->get_col($wpdb->prepare(\\\"SELECT afs_id FROM $ts WHERE afs_form_id = %s AND afs_referrer = '' ORDER BY afs_id ASC\\\", $by_title['Contact Us (Top Labels)'])); $ri = 0; foreach ($cids as $ci => $cid) { if ($ci % 4 === 1) { $wpdb->update($ts, array('afs_referrer' => $refs[$ri % 3]), array('afs_id' => $cid)); $ri++; } } } if (isset($by_title['Website Restyling Brief (Color Picker)'])) { $brief_fid = $by_title['Website Restyling Brief (Color Picker)']; $brief_pg = get_page_by_path('website-restyling-brief'); $brief_pid = $brief_pg ? $brief_pg->ID : 0; $people = array(array('Elena', 'Ferrari', '#8e44ad', 'We sell handmade jewellery; the new site should feel elegant and warm.'), array('Marco', 'Conti', '#0a5cad', 'Our corporate site looks dated, we want a cleaner and faster layout.'), array('Julia', 'Weber', '#1e8449', 'An organic food shop: fresh, natural feeling, easier navigation.'), array('Tom', 'Olsen', '#c0392b', 'Sports club website: bold colors, upcoming matches on the homepage.')); foreach ($people as $pi => $p) { $submitted = time() - rand(0, 40) * 86400 - rand(0, 70000); $created = $submitted - rand(60, 900); $wpdb->insert($ts, array('afs_form_id' => $brief_fid, 'afs_post_id' => $brief_pid, 'afs_ip' => '192.168.1.' . rand(10, 250), 'afs_uri' => '\\\/website-restyling-brief\\\/', 'afs_referrer' => ($pi === 0) ? $refs[0] : '', 'afs_lang' => 'en_US', 'afs_created' => gmdate('Y-m-d H:i:s', $created), 'afs_submitted' => gmdate('Y-m-d H:i:s', $submitted), 'afs_status' => 0, 'afs_stats' => json_encode(array('user_agent' => 'Mozilla\\\/5.0 (Windows NT 10.0; Win64; x64)', 'platform' => ($pi % 2) ? 'desktop' : 'mobile', 'tentatives' => 1, 'submit_method' => 'ajax')), 'afs_lead_status' => ($pi % 2) ? 2 : 0)); $sid = $wpdb->insert_id; foreach (array('first_name' => array('textfield', $p[0]), 'last_name' => array('textfield', $p[1]), 'email' => array('autoreply_email', strtolower($p[0]) . '.' . strtolower($p[1]) . '@example.com'), 'brand_color' => array('colorpicker', $p[2]), 'message' => array('textarea', $p[3])) as $k => $v) { $wpdb->insert($tv, array('afsv_sub_id' => $sid, 'afsv_field_id' => $k, 'afsv_type' => $v[0], 'afsv_value' => $v[1])); } } } ?>\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; global $wpdb; $ts = $wpdb->prefix . 'accua_forms_submissions'; $tv = $wpdb->prefix . 'accua_forms_submissions_values'; $forms = get_option('accua_forms_saved_forms', array()); $by_title = array(); foreach ($forms as $bfid => $bf) { $by_title[$bf['title']] = (string) $bfid; } $more_refs = array('https:\\\/\\\/www.social-network.example\\\/feed\\\/update\\\/activity:7210987654321098765\\\/?utm_source=share&utm_medium=member_desktop&tracking=ACoAAB1234567890abcdefghijklmnop', 'https:\\\/\\\/www.social-hub.example\\\/redirect?u=https%3A%2F%2Fportfolio.example.com%2Fweb-design%2F&h=AT1234567890abcdefghijklmnopqrstuvwxyz1234&source=timeline', 'https:\\\/\\\/www.newsletter-platform.example\\\/example-agency\\\/spring-newsletter-2026?e=1234567890abcdef&utm_source=newsletter&utm_medium=email&utm_campaign=spring_2026_portfolio', 'https:\\\/\\\/www.search-engine.example\\\/search?q=quanto+costa+rifare+un+sito+web+aziendale+preventivo&client=mobile&session=demo0987654321fedcba&token=ZyXwVuTsRqPoNmLk'); $ref_targets = array('Workshop Registration (Inline Legend)', 'Job Application', 'Request a Quote', 'Customer Satisfaction Poll'); foreach ($ref_targets as $ti => $t) { if (!isset($by_title[$t])) { continue; } $ids = $wpdb->get_col($wpdb->prepare(\\\"SELECT afs_id FROM $ts WHERE afs_form_id = %s AND afs_referrer = '' ORDER BY afs_id ASC LIMIT 2\\\", $by_title[$t])); foreach ($ids as $j => $id) { $wpdb->update($ts, array('afs_referrer' => $more_refs[($ti + $j) % 4]), array('afs_id' => $id)); } } $long_uris = array('Job Application' => '\\\/job-application\\\/?utm_source=social_network&utm_medium=social&utm_campaign=hiring_campaign_q3_2026&utm_content=backend_developer_post&click_id=abcdef12-3456-7890-abcd-ef1234567890', 'Request a Quote' => '\\\/request-a-quote\\\/?utm_source=search_ads&utm_medium=cpc&utm_campaign=web_design_services&utm_term=website+redesign+quote&click_id=DEMO1234567890abcdefghijklmnopqrstuv'); foreach ($long_uris as $t => $u) { if (!isset($by_title[$t])) { continue; } $ids = $wpdb->get_col($wpdb->prepare(\\\"SELECT afs_id FROM $ts WHERE afs_form_id = %s ORDER BY afs_id DESC LIMIT 2\\\", $by_title[$t])); foreach ($ids as $id) { $wpdb->update($ts, array('afs_uri' => $u), array('afs_id' => $id)); } } if (isset($by_title['Contact Us (Top Labels)'])) { $cfid = $by_title['Contact Us (Top Labels)']; $cpg = get_page_by_path('contact-top-labels'); $cpid = $cpg ? $cpg->ID : 0; $long_people = array(array('Sofia', 'Lombardi', 'General Inquiry', \\\"We are a family-run manufacturing company founded in 1987, and over the years our website has grown into a collection of more than two hundred pages, spread across three different content management systems that no longer talk to each other. The oldest section still runs on a discontinued CMS that our previous agency customized so heavily that nobody dares to update it anymore, the product area lives in a second system that was added in 2015, and the corporate news are published through a third one that only our marketing intern really understands. We would like to consolidate everything into a single WordPress installation, migrate the product catalog (roughly 1,400 items with technical data sheets in PDF format, organized in four levels of categories with several cross-references between related products), keep the German and French translations aligned with the Italian original, and introduce a proper quotation workflow so that our sales team stops copying requests from email into the CRM by hand. The quotation form should ask different questions depending on the product family, attach the relevant data sheet automatically, and notify the right area manager based on the country of the visitor. On top of that we have a list of smaller wishes: a searchable archive of our old newsletters, a private area where our forty distributors can download price lists and marketing material in their own language, automatic generation of the product PDF from the same data that feeds the web page so the two can never diverge again, and some form of integration with the ERP we use for stock levels, even if it is only a nightly import. Ideally the new site should keep the current URL structure where possible, redirect the legacy addresses that cannot be preserved, and reach a good performance score on mobile devices even from the trade fair pavilions where the connection is notoriously bad. Our budget is flexible but we need the first milestone online before the autumn trade fair in October, because we already printed the QR codes for the new catalog pages on all the brochures. Could you tell us whether you handle projects of this size, what a realistic timeline would look like considering the summer holidays, which parts you would suggest to postpone to a second phase, and which information you need from us to prepare a detailed proposal? If it helps we can share the export of the current page tree and the database schema of the product catalog.\\\", 2, ''), array('Peter', 'Novak', 'Support Request', \\\"Our current site is https:\\\/\\\/www.corporate-group.example\\\/departments\\\/sales\\\/legacy-catalog\\\/product-archive-2019?category=industrial-fasteners&subcategory=self-tapping-screws&page=17&sort=alphabetical&session=abcdef1234567890 and it takes more than eight seconds to load on a phone. The product pages are even slower, and our colleagues at the trade fair booth gave up opening them in front of customers, which is embarrassing. We already changed hosting provider once and it did not help at all. Can you help us understand where the bottleneck actually is and how much a serious performance overhaul would cost?\\\", 0, 'https:\\\/\\\/www.search-engine.example\\\/search?q=website+performance+audit+wordpress+agency&client=desktop&session=demoabcdef0123456789&token=PqRsTuVwXyZaBcDe'), array('Anna', 'Keller', 'Partnership', \\\"Good morning,\\\\n\\\\nwe met at the Web Conference in Milan last month and I promised to write to you about our association. It took me a while, but here we are.\\\\n\\\\nFirst: we need a members area where people can renew their yearly subscription and download their receipts. At the moment everything is handled by two volunteers with a spreadsheet, and the renewal period is a nightmare for them.\\\\n\\\\nSecond: the events calendar must sync with the one our volunteers already keep in their own calendars. We organize around sixty events per year, from small reading groups to the yearly festival, and double bookings of the rooms happen every month.\\\\n\\\\nThird: everything has to be accessible, many of our members use screen readers. This is not negotiable for us: if we have to choose between a nice animation and a page that works with assistive technology, we choose the second without hesitation.\\\\n\\\\nFourth: we publish a printed bulletin four times a year and we would love to generate it from the articles already published on the site instead of recomposing everything by hand in a desktop publishing program.\\\\n\\\\nAnd finally: our current hosting contract expires in November, so if a migration is needed that would be the natural moment to do it.\\\\n\\\\nWhen could we schedule a call? We are usually available in the late afternoon, after office hours, because all of us follow the association as volunteers.\\\\n\\\\nWith kind regards,\\\\nAnna\\\", 3, '')); foreach ($long_people as $pi => $p) { $submitted = time() - rand(0, 20) * 86400 - rand(0, 70000); $created = $submitted - rand(120, 1200); $wpdb->insert($ts, array('afs_form_id' => $cfid, 'afs_post_id' => $cpid, 'afs_ip' => '192.168.1.' . rand(10, 250), 'afs_uri' => '\\\/contact-top-labels\\\/', 'afs_referrer' => $p[5], 'afs_lang' => 'en_US', 'afs_created' => gmdate('Y-m-d H:i:s', $created), 'afs_submitted' => gmdate('Y-m-d H:i:s', $submitted), 'afs_status' => 0, 'afs_stats' => json_encode(array('user_agent' => 'Mozilla\\\/5.0 (Windows NT 10.0; Win64; x64)', 'platform' => ($pi % 2) ? 'desktop' : 'mobile', 'tentatives' => 1, 'submit_method' => 'ajax')), 'afs_lead_status' => $p[4])); $sid = $wpdb->insert_id; foreach (array('first_name' => array('textfield', $p[0]), 'last_name' => array('textfield', $p[1]), 'email' => array('autoreply_email', strtolower($p[0]) . '.' . strtolower($p[1]) . '@example.com'), 'contact_reason' => array('radio', $p[2]), 'message' => array('textarea', $p[3])) as $k => $v) { $wpdb->insert($tv, array('afsv_sub_id' => $sid, 'afsv_field_id' => $k, 'afsv_type' => $v[0], 'afsv_value' => $v[1])); } } } ?>\"}]}"}},"all_blocks":{"contact-forms\/form-selector":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"contact-forms\/form-selector","title":"Contact Form","category":"widgets","icon":"email-alt","description":"Display a contact form created with Contact Forms by Cimatti.","keywords":["form","contact","email","cimatti"],"textdomain":"contact-forms","attributes":{"formId":{"type":"integer","default":0}},"supports":{"html":false,"multiple":true},"editorScript":"contact-forms-block-editor","render":"file:.\/render.php"}},"tagged_versions":["1.0","1.1","1.2","1.2.1","1.3","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.3.6","1.3.7","1.3.8","1.3.9","1.4.0","1.4.1","1.4.10","1.4.11","1.4.12","1.4.13","1.4.14","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.4.8","1.4.9","1.5.1","1.5.10","1.5.2","1.5.3","1.5.4","1.5.5","1.5.6","1.5.7","1.5.8","1.5.9","1.6.0","1.6.1","1.7.0","1.8.0","1.9.0","1.9.1","1.9.2","1.9.3","1.9.4","1.9.5","1.9.6","1.9.7","2.0.0","2.1.0","2.1.1","2.1.2","2.2.0","2.2.32","2.2.4","2.3.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3606071,"resolution":"1","location":"assets","locale":"","width":2000,"height":2000},"screenshot-10.png":{"filename":"screenshot-10.png","revision":3606071,"resolution":"10","location":"assets","locale":"","width":2880,"height":1800},"screenshot-11.png":{"filename":"screenshot-11.png","revision":3606071,"resolution":"11","location":"assets","locale":"","width":2880,"height":1800},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3606071,"resolution":"2","location":"assets","locale":"","width":2880,"height":2136},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3606071,"resolution":"3","location":"assets","locale":"","width":2000,"height":2000},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3606071,"resolution":"4","location":"assets","locale":"","width":2000,"height":2000},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3606071,"resolution":"5","location":"assets","locale":"","width":2000,"height":2000},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3606071,"resolution":"6","location":"assets","locale":"","width":2000,"height":2000},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3606071,"resolution":"7","location":"assets","locale":"","width":2880,"height":1800},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3606071,"resolution":"8","location":"assets","locale":"","width":2880,"height":1800},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3606071,"resolution":"9","location":"assets","locale":"","width":2880,"height":1800}},"screenshots":{"1":"Accessible contact form with the Top Labels layout. WCAG 2.2 AA compliant.","2":"Create forms with drag and drop and see the result immediately in the live preview.","3":"Three label layouts per form: top, side by side, or inline floating labels.","4":"Drag and drop file upload with allowed extensions, date picker, and phone validation.","5":"Group related fields with six border and title styles for long forms.","6":"Clear error messages with a clickable validation summary and custom texts per field.","7":"Track form performance over time, for all forms or each form individually.","8":"Search, filter, classify by lead status, and export submissions to Excel.","9":"Review each submission with details, lead status, notes, and GDPR anonymization.","10":"Build your own fields once and reuse them in any form.","11":"Set default messages, styling, and integrations once for all forms."}},"plugin_section":[262246],"plugin_tags":[358,1203,260727,2253,337],"plugin_category":[41,42,59],"plugin_contributors":[80387],"plugin_business_model":[],"class_list":["post-24360","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-contact-form","plugin_tags-email-notifications","plugin_tags-form-api","plugin_tags-form-builder","plugin_tags-lead-generation","plugin_category-communication","plugin_category-contact-forms","plugin_category-utilities-and-tools","plugin_contributors-cimatti","plugin_committers-cimatti"],"banners":{"banner":"https:\/\/ps.w.org\/contact-forms\/assets\/banner-772x250.png?rev=2947115","banner_2x":"https:\/\/ps.w.org\/contact-forms\/assets\/banner-1544x500.png?rev=2947115","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/contact-forms\/assets\/icon.svg?rev=2947119","icon":"https:\/\/ps.w.org\/contact-forms\/assets\/icon.svg?rev=2947119","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-1.png?rev=3606071","caption":"Accessible contact form with the Top Labels layout. WCAG 2.2 AA compliant."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-2.png?rev=3606071","caption":"Create forms with drag and drop and see the result immediately in the live preview."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-3.png?rev=3606071","caption":"Three label layouts per form: top, side by side, or inline floating labels."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-4.png?rev=3606071","caption":"Drag and drop file upload with allowed extensions, date picker, and phone validation."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-5.png?rev=3606071","caption":"Group related fields with six border and title styles for long forms."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-6.png?rev=3606071","caption":"Clear error messages with a clickable validation summary and custom texts per field."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-7.png?rev=3606071","caption":"Track form performance over time, for all forms or each form individually."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-8.png?rev=3606071","caption":"Search, filter, classify by lead status, and export submissions to Excel."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-9.png?rev=3606071","caption":"Review each submission with details, lead status, notes, and GDPR anonymization."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-10.png?rev=3606071","caption":"Build your own fields once and reuse them in any form."},{"src":"https:\/\/ps.w.org\/contact-forms\/assets\/screenshot-11.png?rev=3606071","caption":"Set default messages, styling, and integrations once for all forms."}],"raw_content":"<!--section=description-->\n<p><a href=\"https:\/\/wordpress.org\/plugins\/contact-forms\/?preview=1\"><strong>Live Preview - Try it in WordPress Playground<\/strong><\/a> (form submission is not available in the live preview)<\/p>\n\n<p>Forms are an essential component of any website. Contact Forms by Cimatti is the culmination of years of experience building and developing business websites of all types. Our plugin focuses on simplicity, power, and <strong>accessibility<\/strong>, helping you capture, store, and classify contacts according to their lead status. It's ideal for single-language and multilingual sites, simple blogs, or complex WordPress-powered Content Management Systems.<\/p>\n\n<h4>Accessibility First<\/h4>\n\n<p>Contact Forms is built with accessibility at its core, designed to meet <strong>WCAG 2.2 AA<\/strong> standards and comply with the <strong>European Accessibility Act<\/strong>:<\/p>\n\n<ul>\n<li><strong>Screen Reader Support<\/strong>: All form elements are properly labelled and wired with <code>aria-describedby<\/code> and <code>aria-invalid<\/code>, with live regions for dynamic updates and meaningful error announcements<\/li>\n<li><strong>Keyboard Navigation<\/strong>: Full keyboard accessibility for all interactions, including drag-and-drop file uploads<\/li>\n<li><strong>Clear Error Messages<\/strong>: Validation summary with clickable links to problematic fields, smooth scroll and focus management<\/li>\n<li><strong>Accessible Loading States<\/strong>: Visual and screen reader feedback during form submission<\/li>\n<li><strong>Reduced Motion Support<\/strong>: Respects <code>prefers-reduced-motion<\/code> user preference<\/li>\n<li><strong>High Contrast<\/strong>: Error and success states designed for visibility<\/li>\n<\/ul>\n\n<h4>Select, Configure, and Embed Forms<\/h4>\n\n<p>Choose the fields you require, customize on-screen messages and email responses, preview, and effortlessly embed forms into your posts, pages, or custom content types using the Contact Form block, a shortcode, or the button in the classic visual editor.<\/p>\n\n<h4>Create Forms for Any Purpose<\/h4>\n\n<p>Create as many forms as you need. Design landing pages, contact pages, invitations, job application forms with curriculum upload, customer request forms, spare part requests, and more. Utilize the \"Clone\" feature to avoid \"reinventing the wheel\" when creating new forms.<\/p>\n\n<h4>Ready-to-Use Features<\/h4>\n\n<p>Contact Forms by Cimatti has commonly used fields like First Name, Last Name, Address, Province, Country, Telephone, Email, Captcha, and default success messages and email notifications. Simply create a drag-and-drop form, save it, go to a post or page, and insert it with the Contact Form block \u2014 or, in the classic visual editor, with the Contact Forms button in the toolbar.<\/p>\n\n<h4>Easy to Use for Beginners<\/h4>\n\n<p>These features make it effortless for first-time users, but the plugin's fast learning curve will soon entice you to explore its advanced features.<\/p>\n\n<h4>Craft Superior Forms<\/h4>\n\n<p>Don't leave anything to chance; fine-tune the entire form submission process.<\/p>\n\n<h4>Spam Protection<\/h4>\n\n<p>Stop spam with Google reCAPTCHA v2 (checkbox), the invisible score-based Google reCAPTCHA v3, Cap (the open-source proof-of-work captcha you host yourself), or Cloudflare Turnstile (which needs the free Simple Cloudflare Turnstile plugin). Captcha fields are added per form with drag and drop, so you protect only the forms that need it. With reCAPTCHA v2 and v3 you can also choose, per form, what happens when the check fails: accept the submission silently \u2014 the sender sees the normal success message while it is stored with the Spam status and no notification emails are sent \u2014 move it to Trash, delete it immediately, or reject it with a visible error so the visitor can retry. Each type ships with the default that fits it: silent for the invisible v3, a visible error for the v2 checkbox, so a real person who forgot to tick it is asked again instead of being filed as spam. For your visitors' privacy, no request is made to Google until they start filling in the form - and with Cap running on your own server, no captcha request leaves your infrastructure at all.<\/p>\n\n<h4>Create Reusable Fields<\/h4>\n\n<p>Build custom fields to reuse multiple times, starting with 24 available field types, including Text Field, Text Area, Email, Autoreply Email, Telephone, Date, Checkbox, Multiple checkboxes, Radio buttons, Select, Multiple selections area, Post select, Color picker, Hidden value, File upload, Captcha, Custom HTML, Password, and more.<\/p>\n\n<h4>Customize Forms to Perfection<\/h4>\n\n<p>Apply visual styles to your forms using options in the \"Appearance and General\" tab. Select colors, margins, button styles, and more.<\/p>\n\n<h4>Custom Messages for Success<\/h4>\n\n<p>Each form can have its own unique online success message. So, when a form is completed, you can provide access to a file download link, coupon information, or simply a message to confirm that the form was submitted correctly.<\/p>\n\n<h4>Email Notifications for Administrators and Visitors<\/h4>\n\n<p>Send email notifications to administrators, including tracking information like visitor IP, referrer, date and time of form submission, and other user properties (for a full list, see the Beginners' Guide). Send an email notification to the visitor as further confirmation that the form was filled in correctly. The live preview in the form editor lets you check the form before you publish it.<\/p>\n\n<h4>Data Collection and Excel Export<\/h4>\n\n<p>All submitted data is securely stored in your WordPress database. Contacts received can be easily categorized into lead status categories and spam and tests can be easily discarded. Add notes on each contact received to keep track.<\/p>\n\n<p>All contact data received can be filtered, searched, and exported to Excel at any time: export all the columns, or only the ones currently visible in the list. Exports open with the header row frozen and the column filters already switched on.<\/p>\n\n<p>Contact Forms also includes a tracking graph in its Dashboard that displays the performance of all or each of your website forms over time.<\/p>\n\n<h4>Developer-Friendly API<\/h4>\n\n<p>Contact Forms by Cimatti includes an API to assist developers in customizing and adding their own features. WordPress Filters are used to customize forms during generation, to check and validate submitted form values, to execute custom code using sent data, and to add custom tokens for messages. Read the documentation on our site for more information.\nPowerful PHP Form Builder Class\nContact Forms by Cimatti utilizes a PHP form builder class to generate the forms, ensuring robust and efficient form creation and management.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload <code>\/contact-forms\/<\/code> directory to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress.<\/li>\n<li>Create one or more forms using the drag and drop interface.<\/li>\n<li>Edit posts (or pages or custom types) and add the desired form with the Contact Form block, with a shortcode, or with the Contact Forms button in the classic visual editor.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<p>You'll find the <a href=\"http:\/\/www.cimatti.it\/en\/wordpress-plugins\/contact-forms\/faq\/\">FAQ on our website<\/a>.<\/p>\n<dl>\n<dt id=\"where%20do%20i%20report%20security%20bugs%20found%20in%20this%20plugin%3F\"><h3>Where do I report security bugs found in this plugin?<\/h3><\/dt>\n<dd><p>Please report security bugs found in the source code of the\nContact Forms by Cimatti plugin through the <a href=\"https:\/\/patchstack.com\/database\/vdp\/contact-forms\">Patchstack\nVulnerability Disclosure Program<\/a>. The\nPatchstack team will assist you with verification, CVE assignment, and\nnotify the developers of this plugin.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.3.0<\/h4>\n\n<p>This release consolidates all changes since 2.2.32. See changelog.txt in the plugin folder for the detailed per-version history.<\/p>\n\n<p><strong>New features<\/strong><\/p>\n\n<ul>\n<li>Live preview on the Fields page: while you create or edit a field, a preview panel beside the editor renders it exactly as it will appear in a form \u2014 same rendering engine, styles, and scripts as the frontend. It updates as you type, for every field type: see the options of a select or radio group, the multiple-selection box, your custom HTML content, the file-upload drop zone, the date picker, and so on. The preview is interactive too: the field is treated as required there (only for demonstration \u2014 in your forms it is required only if you say so), so you can leave it empty or type an invalid value and see the validation messages exactly as visitors would, including your custom required\/format messages; the preview never actually submits anything. Fields with no visible output (hidden values, captcha fields whose keys are not configured yet) say so instead of showing an empty box.<\/li>\n<li>Fields page editing improvements: the field slug is suggested automatically from the label while you type (until you edit the slug yourself; emptying the slug resumes the suggestion), the slug is checked while you type \u2014 invalid characters, reserved prefixes, excessive length or a slug already used by another field are flagged immediately with a message under the input instead of after saving \u2014 deleting a field now asks for confirmation and the Delete button is styled as a destructive action, and when editing a field the heading shows which field you are on with a link back to the fields list.<\/li>\n<li><p>Choose your own essential columns: each field on the Fields page has a new \"Show in essential columns\" option, and the \"Essential Columns\" button of the submissions list now keeps visible exactly ID, Actions, Form, Submitted and the fields you flagged \u2014 one click to go from the full table to the compact view you actually scan. New installs flag the name, email and message fields; on updated sites the email column stays flagged so the button keeps showing it, while the technical IP, Page, Referrer and Language columns are no longer considered essential. The same flags choose which field columns are visible the first time you open the submissions list. The button's tooltip lists the columns it keeps on your site and points to where you choose the fields.<\/p><\/li>\n<li><p>Choose what happens to your data when the plugin is deleted: a new option in the plugin settings, Danger Zone tab, off by default. Left off, deleting Contact Forms from the Plugins screen keeps your forms, submissions and settings in the database, exactly as before \u2014 reinstalling the plugin brings everything back. Tick \"Delete all Contact Forms data when the plugin is deleted\" and deleting the plugin also removes everything it owns: forms, submissions, uploaded files and settings, with no further confirmation at that point. On a multisite network each site answers for itself.<\/p><\/li>\n<li><p>Google reCAPTCHA v3 support: add the new \"Captcha (reCAPTCHA v3)\" field to any form for invisible, score-based spam protection \u2014 no checkbox to tick. Configure the v3 key pair in the plugin settings (reCAPTCHA v3 uses different keys than v2). The existing reCAPTCHA v2 checkbox field keeps working unchanged, and both can be used on different forms of the same site. As with v2, no request is made to Google until the visitor starts filling the form.<\/p><\/li>\n<li>Cap captcha support: add the new \"Captcha (Cap)\" field to protect any form with <a href=\"https:\/\/capjs.js.org\">Cap<\/a>, an open-source, privacy-first CAPTCHA alternative based on proof-of-work: visitors just click a checkbox, no puzzles to solve and no data ever sent to third parties. Requires a self-hosted Cap Standalone server: enter its URL and the key pair in the plugin settings. The widget script is loaded from your own Cap server, so no request ever leaves your infrastructure.<\/li>\n<li>Per-form spam action on captcha fields: the new \"When the spam check fails\" setting on the reCAPTCHA v2 and v3 fields lets you choose what happens to submissions that fail the captcha check \u2014 accept them silently and mark them as Spam, move them to Trash, delete them immediately, or reject them with a visible error so the visitor can retry. The two captcha types ship with the default that suits them, each configurable site-wide in the settings and per field: reCAPTCHA v3 scores visitors invisibly, so a failed check is accepted silently and stored with the Spam lead status, with no notification emails; reCAPTCHA v2 shows a checkbox the visitor is asked to solve, so a failed check is rejected with a visible error and they can solve it again \u2014 otherwise a real person who forgot to tick the box, or whose challenge expired, would be filed as spam without ever being told.<\/li>\n<li>Spam management in the submissions list, working like the WordPress comments screen: a dedicated \"Spam\" view collects all submissions with the Spam lead status (including those classified automatically by the captcha spam action), and spam is hidden from the Active view. Each row has a \"Spam\" quick action (with a \"Mark as spam\" bulk action); inside the Spam view you can restore submissions with \"Not spam\", trash them, or delete them permanently.<\/li>\n<li>Dashboard: the \"Last 10 submissions\" table now shows a sortable Lead Status column with the same quick-edit dropdown as the submissions list, plus Spam \/ Not spam and Trash quick actions. Below the table, a \"Go to:\" row of quick links (Active, each lead status in use, Spam and Trash, with counts) jumps straight to the corresponding submissions-list view.<\/li>\n<li>\"Hide field title\" option on the reCAPTCHA v2, reCAPTCHA v3 and Cap fields, enabled by default: captcha widgets are self-explanatory, so their field title is no longer displayed in the form. The title stays in the page for screen readers and error messages; uncheck the option on the field in the form editor to show it again.<\/li>\n<li>Configurable reCAPTCHA v3 minimum score: reCAPTCHA v3 scores every visitor from 0.0 (almost certainly a bot) to 1.0 (almost certainly a person), and you can now decide where the line is. Set the site-wide minimum in the plugin settings (Google's suggested 0.5 out of the box) and, if one form needs to be stricter or more forgiving than the rest, override it on that form's reCAPTCHA v3 field.<\/li>\n<li>The reCAPTCHA v3 score of each submission is recorded and shown on the submission page, so you can see what your forms actually score before changing the minimum.<\/li>\n<li>reCAPTCHA v3 badge position: choose whether Google's floating badge sits at the bottom right (as before), at the bottom left, or is hidden. Hiding it is allowed by Google only if the reCAPTCHA branding is shown elsewhere, so the plugin automatically prints the required \"protected by reCAPTCHA\" notice in the form, where the reCAPTCHA v3 field sits.<\/li>\n<li>Site-wide defaults for the captcha options: \"When the spam check fails\" and \"Hide field title\" are now set once in the plugin settings and apply to every captcha field, with a per-field \"override\" checkbox \u2014 the same pattern as every other field setting. Existing forms keep the values already saved on their fields.<\/li>\n<\/ul>\n\n<p><strong>Improvements<\/strong><\/p>\n\n<ul>\n<li>The reCAPTCHA v2 loader script is now delivered as a regular cacheable file instead of inline code repeated for every captcha field. Google's reCAPTCHA script is still requested only when the visitor starts filling a form, never on page load.<\/li>\n<li>Removed the legacy reCAPTCHA v1 code, discontinued by Google in 2018. Existing forms are not affected: reCAPTCHA v2 keeps working with the same keys and settings.<\/li>\n<li>Submissions list: quick actions (Open, Trash, Spam \/ Not spam, Restore, Permanently delete) moved from the hover menu under the ID column to a dedicated always-visible \"Actions\" column \u2014 the first column of the list, available in the Trash view too, with the actions always kept on a single row. Column widths now adapt to their content instead of being evenly divided, while long page and referrer URLs stay compact behind the usual [+] toggle.<\/li>\n<li>Submissions list: long values now compress in the field columns too, not only in the URL ones \u2014 a long or multi-line message collapses to a single line behind a [+] toggle, keeping the rows compact; expanding shows the full text with the visitor's line breaks as paragraph breaks.<\/li>\n<li>Submission page: line breaks typed by the visitor in a message are preserved \u2014 an empty line renders as a paragraph break instead of the whole text collapsing into one block.<\/li>\n<li>Submissions list: two new icon buttons in the toolbar expand or collapse all the [+] compressed cells at once (\"Expand All Rows\" \/ \"Collapse All Rows\", named in the tooltip), and the \"Essential Columns\" button now lists in its tooltip which columns it keeps.<\/li>\n<li>Plugin Check (PCP) 2.0.0 compliance.<\/li>\n<li>Live demo (Playground): new \"Custom HTML Content\" example page showing one-off HTML blocks, a reusable HTML field shared by two forms, and a per-form content override; new \"Website Restyling Brief\" page (color picker field, custom submit button) and \"Member Registration\" page (password with confirmation stored only as a secure hash, submission without AJAX).<\/li>\n<li>Form editor: captcha field settings no longer show a \"Default value\" and a \"Custom required message\" row that had no effect on captcha fields.<\/li>\n<li>Leaner admin pages: removed leftover code from earlier versions, including two jQuery UI libraries that were loaded on every WordPress admin page without being used.<\/li>\n<li>Italian and Spanish translations updated.<\/li>\n<\/ul>\n\n<p><strong>Fixes<\/strong><\/p>\n\n<ul>\n<li>Cloudflare Turnstile field: the widget was not reset after a submission sent without reloading the page. A visitor who submitted the form again \u2014 for example after correcting another field \u2014 sent a verification token that had already been used, and got a \"Turnstile verification failed\" error they could only clear by reloading the page. The widget is now reset after every submission, so a retry always carries a fresh token.<\/li>\n<li>Fields page: the \"Custom HTML\" field type offered no way to edit its HTML content, and other field types were missing settings they support. Every field type now shows exactly the settings it uses, with matching labels (\"Custom HTML content\" for HTML fields, \"Additional query parameters\" for post fields), and field types added by extension plugins now get the generic settings (default value, custom required message) instead of none.<\/li>\n<li>Fields page: saving the pre-installed \"Turnstile\" field turned it into a plain text field, because its type was missing from the field type list. It is now listed as \"Captcha (Turnstile)\" next to the other captcha types.<\/li>\n<li>Fields page: the same could happen to any field whose type is temporarily unavailable \u2014 for example while the extension plugin providing it is deactivated. The type is now kept, shown as \"currently not registered\", and editing the field no longer overwrites it.<\/li>\n<li>The CSS Class and CSS ID settings on submit buttons and hidden fields had no effect; they are now applied to the rendered button and hidden input.<\/li>\n<li>Form editor: in the Messages tab, checking \"Customize\" on the notification email fields (To, Bcc, Subject, From name, From email) did not unlock the text field for editing.<\/li>\n<li>Form editor: clicking Save while the field widgets were still saving could silently lose part of the changes. All the saves triggered by the Save button now run in sequence, so the published form always matches what is on screen.<\/li>\n<li>Form editor: the live preview could stay clipped at its minimum height and live style updates could stay disabled when the preview loaded faster than the editor scripts.<\/li>\n<li>When the reCAPTCHA v2 check failed on the server, the error in the validation summary showed an internal field name with a link leading nowhere. It now shows the captcha field's label, the link scrolls to the captcha widget, and the error message also appears next to the widget itself.<\/li>\n<li>Submissions marked as Spam could show a different lead status in the dropdown, and the Spam quick-filter link above the list pointed to the wrong view.<\/li>\n<li>Searching the submissions list with the browser (Ctrl+F) counted every match inside a compressed long URL twice, because the compressed cell kept two copies of the text. It now keeps exactly one, in the submissions list and in the dashboard's last-submissions table.<\/li>\n<li>Fields page: the live preview appeared oversized and shrank to its real size a moment later; it now starts compact and grows smoothly to its real size, with a discreet loading spinner, and never flashes unstyled content or a stray scrollbar while it loads.<\/li>\n<li>Resolved PHP 8.4 deprecation warnings logged by several form element classes. No functional changes.<\/li>\n<li>\"Delete all data\" did not delete everything. If you had set your own upload folder, the files your visitors submitted were left on disk, and the captcha keys, the analytics and file settings, the cached dashboard statistics and your submissions-list column preferences all survived. They are all removed now. As a safeguard, the folder deletion refuses to touch anything that is not the plugin's own upload folder, so an unusual setting can never take your media library with it.<\/li>\n<li>On a small number of sites the list of fields had become unreadable to WordPress, usually after a site migration rewrote the stored text. Updating the plugin would have replaced it with the standard fields, losing the ones you had created. The update now repairs it instead, and keeps a copy of the original either way.<\/li>\n<li>Two fields whose slugs differ only in upper\/lower case (for example \"role\" and \"Role\") were treated as the same field by the database. The submissions list and the Excel export showed a single column for the pair, and \u2014 worse \u2014 only one of the two values was actually saved on each submission: the other was silently discarded. Slugs are now case-sensitive everywhere, so both fields keep their own column and their own stored values. Slugs of newly created fields are lowercased to avoid the confusion in the first place; slugs you already have are left exactly as they are.<\/li>\n<li>The submissions list offered columns for values the plugin stores for its own use \u2014 on sites with file upload fields, that included the internal download token, whose value also ended up in the Excel export. Those internal values are no longer treated as fields.<\/li>\n<li>Forms carried over from a very old installation (before version 2.0) saved submissions with no data in them. The form worked and looked normal, the submission was recorded, but every field value was missing, because the old conversion of those forms left their fields in a shape the submission handler could not match. Affected forms are repaired automatically when you update, including forms sitting in the trash.<\/li>\n<li>The \"Contact Form\" block produced an empty front end on WordPress 5.9 and 6.0: it declared its rendering in a way only WordPress 6.1 and later understand. The block now renders on every supported version.<\/li>\n<li>The high-contrast styles never actually applied: they used a media query value that browsers do not recognize. Visitors who ask their system for increased contrast now get the stronger borders, focus outline and bolder floating labels the forms were meant to show them.<\/li>\n<\/ul>\n\n<h4>2.2.32<\/h4>\n\n<p>Maintenance release consolidating all changes since 2.2.4. See changelog.txt in the plugin folder for the detailed per-version history.<\/p>\n\n<p><strong>New features<\/strong><\/p>\n\n<ul>\n<li>Fieldset group: new \"Border and Title\" style selector with 6 options (no border, border only, inline legend, title above, title inside, borderless with title). The fieldset border is now opt-in instead of always-on; re-enable it on existing forms via this option.<\/li>\n<li>Post select and Multiple post checkboxes fields: add <code>post_status=publish,private<\/code> to the custom query parameters to also list private posts. Draft and pending posts are never listed.<\/li>\n<li>Multiple post checkboxes field: the <code>post_type<\/code> custom query parameter now overrides the field's post type setting, matching the Post select field.<\/li>\n<li>Fields page: rebuilt as a WordPress-native list table with sortable columns, a \"Used in forms\" count, bulk delete, and row actions.<\/li>\n<li>Form editor: permanent \"Default Submit Button\" indicator at the bottom of the form area, hidden automatically when a custom submit field is present.<\/li>\n<\/ul>\n\n<p><strong>Improvements<\/strong><\/p>\n\n<ul>\n<li>Single submission page: redesigned with a WordPress-standard two-column layout, human-readable field labels, and fully AJAX notes (add and delete without a page reload).<\/li>\n<li>Dashboard: last 10 submissions table rebuilt with sortable columns and an Actions column; 30 individual queries per page load replaced with a single query.<\/li>\n<li>Submissions list: long page URLs and referrers collapse with an expand toggle; Page and Referrer columns are clickable links; \"Review\" column renamed to \"Open\"; export buttons repositioned for better discoverability.<\/li>\n<li>Dashboard widget: now shown only to administrators, the same users who can access the plugin pages, and its statistics are cached so the dashboard loads faster on sites with many submissions.<\/li>\n<li>Admin sidebar icon: now monochrome and follows the active WordPress admin color scheme, without flashing the brand color on page load.<\/li>\n<li>Plugin Check (PCP) 2.0.0 compliance; minimum required WordPress version raised to 5.9.<\/li>\n<li>Italian and Spanish translations completed.<\/li>\n<\/ul>\n\n<p><strong>Fixes<\/strong><\/p>\n\n<ul>\n<li>Translations no longer trigger a <code>_load_textdomain_just_in_time<\/code> deprecation notice on WordPress 6.7+.<\/li>\n<li>reCAPTCHA v2: on pages with two or more forms, the captcha now appears when the visitor starts filling any of the forms, not only the first one.<\/li>\n<li>Post select and Multiple post checkboxes fields: child posts are no longer dropped from the list; search by title, the <code>parent=<\/code>, <code>include=<\/code>, <code>child_of=<\/code> and <code>exclude_tree=<\/code> filters, and \"load more\" pagination now work correctly; lists appear in hierarchical order; the <code>{__post_id_*}<\/code> and <code>{__post_url_*}<\/code> email tokens output the correct values.<\/li>\n<li>Post select field: draft, private and pending post titles are no longer shown to site visitors, and a submitted value must match the field's post type.<\/li>\n<li>Validation summary links now scroll to and focus the correct field instead of jumping to the page top.<\/li>\n<li>Email format error no longer appears twice after a field loses focus following a previously displayed format error.<\/li>\n<li>AJAX form submission no longer changes the browser URL; non-AJAX submission sets the correct URL hash after page reload.<\/li>\n<li>Date field: fixed validation error for custom date fields with minimum or maximum date settings.<\/li>\n<li>Trashing a submission from the single-submission view now redirects correctly.<\/li>\n<li>Hidden field: the \"CSS ID\" setting now sets the id attribute on the hidden input element itself.<\/li>\n<li>Frontend CSS: focus styles for buttons, checkboxes and radios are scoped inside the form and no longer affect page-level styles.<\/li>\n<li>Form editor: Save\/Cancel button alignment fixed; sort indicator on the Submissions column in the forms list is no longer misaligned.<\/li>\n<\/ul>\n\n<h4>2.2.4<\/h4>\n\n<ul>\n<li>Form editor: Appearance tab labels are now clickable (native label elements for accessibility).<\/li>\n<li>Form editor: Section headings use proper h2 elements with consistent styling.<\/li>\n<li>Form editor: Consistent row heights for style options; color pickers hidden when row is unchecked.<\/li>\n<li>Form editor: Labels dropdown no longer overflows its container.<\/li>\n<li>Form editor: Responsive 2-column layout at viewports narrower than 1200px with preview below full-width.<\/li>\n<li>Form editor: Fixed flash of unstyled content (FOUC) on page load.<\/li>\n<li>i18n: Italian and Spanish translations updated.<\/li>\n<\/ul>\n\n<h4>2.2.3<\/h4>\n\n<ul>\n<li>Form editor: Added \"+\" button on each available field to add it to the form with a single click (appends as last, scrolls into view, opens settings).<\/li>\n<li>Form editor: Hidden the expand caret from available fields list for cleaner UI.<\/li>\n<li>Form editor: Long field names now wrap to multiple lines instead of being truncated. The \"+\" button and expand caret remain vertically centered and always clickable.<\/li>\n<li>i18n: Added Italian translations for new UI strings.<\/li>\n<\/ul>\n\n<h4>2.2.2<\/h4>\n\n<ul>\n<li>Form editor: Added instant search filter in the Available Fields column: type to quickly find fields by name (substring match).<\/li>\n<\/ul>\n\n<h4>2.2.1<\/h4>\n\n<ul>\n<li>Form editor: Redesigned Fields tab as a stable three-column CSS Grid layout (available fields, drop zone, live preview). The available fields column has its own scrollbar; the other columns use the main browser scroll. Fixes wrapping issues on high-zoom levels, small screens, and forms with many fields or long labels.<\/li>\n<li>Form editor: Each column now has its own heading styled consistently and aligned at the same height.<\/li>\n<li>Form editor: Drop zone title moved outside the dashed border for clearer visual hierarchy.<\/li>\n<\/ul>\n\n<h4>2.2.0<\/h4>\n\n<ul>\n<li>Tested up to WordPress 7.0.<\/li>\n<li>Added WordPress Playground blueprint for live preview on wordpress.org - five demo forms covering all field types including fieldsets, checkboxes, multi-select, post-select, and HTML blocks.<\/li>\n<li>Email notifications: Long URLs no longer break print\/PDF layout. Applied table-layout fixed and word-break on URL fields.<\/li>\n<li>Email notifications: Improved vertical spacing between submitted fields with proper cell padding.<\/li>\n<li>Email notifications: Fieldset labels now display correctly instead of raw field IDs.<\/li>\n<li>Email notifications: Fixed malformed font-family quotes in the email body wrapper.<\/li>\n<li>Single submission page: Restructured from 3-column to 2-column (30\/70) layout. Details and Lead Status are now in the left column, submitted fields in the right.<\/li>\n<li>Single submission page: Renamed \"Stats\" postbox to \"Details\".<\/li>\n<li>Single submission page: Long URLs now wrap properly in the submitted fields table.<\/li>\n<li>Submissions list: Added view links (Active, Trash, Lead Status) for quick filtering.<\/li>\n<li>Submissions list: Refactored filter controls into native WP_List_Table extra_tablenav pattern.<\/li>\n<li>Bugfix: Fieldset without a label no longer shows a gap in the border.<\/li>\n<li>Bugfix: Essential Columns button race condition - column settings no longer lost during batch save.<\/li>\n<li>Bugfix: Fields page - legacy-format fields now display correctly with proper name\/slug fallback.<\/li>\n<\/ul>\n\n<h4>2.1.4<\/h4>\n\n<ul>\n<li>Responsive sidebyside layout: labels automatically stack on top when the form container is narrower than 500px, using CSS container queries. Works across all themes regardless of viewport width.<\/li>\n<\/ul>\n\n<h4>2.1.3<\/h4>\n\n<ul>\n<li>Fixed: Post select field value was not saved to database and not included in notification emails. The submission handler now resolves posts directly instead of relying on empty lazy-loaded options.<\/li>\n<\/ul>\n\n<h4>2.1.2<\/h4>\n\n<ul>\n<li>Form editor: Added submission count with link to the submissions list, displayed inline with the page heading.<\/li>\n<li>Form editor: Title input now has proper spacing and sizing matching WordPress core post editor styling.<\/li>\n<li>Form editor: Google Ads and Tokens tabs now use WordPress postbox markup with form-table layout.<\/li>\n<li>Form editor: Added unsaved changes warning (beforeunload prompt) when the form has been modified.<\/li>\n<\/ul>\n\n<h4>2.1.1<\/h4>\n\n<ul>\n<li>Fixed single submission page: restored proper padding and spacing in the Lead status and Notes postbox<\/li>\n<li>Improved layout alignment for Lead status dropdown and help icon<\/li>\n<li>Italian: standardized terminology - \"compilazione\/compilazioni\" for submissions, fixed mixed \"modulo\/moduli\" back to \"form\/forms\", translated all missing strings<\/li>\n<li>Spanish: added ~260 missing translations (Theme Helper, Appearance, Danger Zone, default messages, block editor, GDPR)<\/li>\n<\/ul>\n\n<h4>2.1.0<\/h4>\n\n<p>Admin UI modernization with a more coherent design language aligned with native WordPress admin patterns.<\/p>\n\n<ul>\n<li>Flat single-level tab bar for the form editor (Fields, Appearance &amp; General, Messages, Data Retention, Google Ads, Tokens)<\/li>\n<li>Grid-based layout for form field editor and live preview<\/li>\n<li>Tab navigation on the settings page with ARIA-compliant accessible tabs<\/li>\n<li>Native WordPress postbox structure for all settings sections<\/li>\n<li>Messages tab: 2\u00d72 grid layout, accessible radio buttons with fieldset\/label, TinyMCE font selector with 10 email-safe fonts<\/li>\n<li>Default font changed from Lucida Sans to Arial for new forms<\/li>\n<li>Merged dashboard.css into admin.css, removed dead CSS selectors<\/li>\n<li>Bugfix: broken CSS selectors caused by panel ID renaming<\/li>\n<li>Bugfix: Messages, Data Retention, and Tokens panels not properly contained within the tab system<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<p>Major rewrite focused on accessibility, modern admin UI, and GDPR compliance. All existing forms continue to work without changes.<\/p>\n\n<p><strong>Important:<\/strong> CSS changes (35 removed <code>!important<\/code> declarations) may affect frontend layouts customized via theme CSS. Use Contact Forms &gt; Theme Helper to identify conflicts. Where possible, use the plugin's Appearance tab instead of theme CSS overrides.<\/p>\n\n<ul>\n<li>Accessibility rewrite: WCAG 2.2 AA \/ European Accessibility Act compliance<\/li>\n<li>Inline Labels layout (floating labels)<\/li>\n<li>Live preview in the form editor<\/li>\n<li>GDPR data retention, anonymization, and WordPress Privacy API<\/li>\n<li>Cloudflare Turnstile support (via Simple Cloudflare Turnstile plugin)<\/li>\n<li>Google reCAPTCHA v2 (checkbox) and reCAPTCHA v3 (invisible, score-based) with built-in key configuration<\/li>\n<li>Drag-and-drop file upload with keyboard navigation<\/li>\n<li>Telephone field with E.164 validation and country prefix<\/li>\n<li>Custom validation messages per field and per form<\/li>\n<li>Custom CSS class and ID on all field types<\/li>\n<li>Submissions list with sortable columns, row actions, and Excel export<\/li>\n<li>Dashboard charts with monthly-by-page breakdown<\/li>\n<li>Gutenberg block for inserting forms<\/li>\n<li>Settings page with Danger Zone and deactivation cleanup<\/li>\n<li>Theme Helper: diagnose CSS conflicts between your theme and Contact Forms<\/li>\n<li>English, Italian, and Spanish translations<\/li>\n<li>Plugin Check (PCP) fully compliant<\/li>\n<\/ul>\n\n<p>For the detailed per-beta changelog, see the plugin's changelog.txt file.<\/p>\n\n<h4>1.9.14<\/h4>\n\n<ul>\n<li>Added Cloudflare Turnstile field integration<\/li>\n<\/ul>","raw_excerpt":"Create accessible contact forms with drag-and-drop. WCAG 2.2 compliant with screen reader support, keyboard navigation, and clear error messages.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/24360","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=24360"}],"author":[{"embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/cimatti"}],"wp:attachment":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=24360"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=24360"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=24360"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=24360"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=24360"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=24360"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}