Upload files to "ansico-contact-form"

This commit is contained in:
Andreas Andersen 2026-04-15 21:05:00 +00:00
parent bcd6a0e302
commit 683a400d1e
3 changed files with 286 additions and 0 deletions

View file

@ -0,0 +1,162 @@
<?php
/**
* Plugin Name: Ansico Contact Form
* Plugin URI: https://ansico.dk/Ansico/Ansico-Contact-Form
* Description: A lightweight, fully customizable contact form block for the Gutenberg editor with built-in math spam protection.
* Version: 1.0.0
* Author: Andreas Andersen (Ansico)
* Author URI: https://ansico.dk
* License: GPL-3.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
* Text Domain: ansico-contact-form
* Requires at least: 5.8
* Tested up to: 6.9.4
*/
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* Render function for the contact form frontend.
*/
function ansico_cf_v1_render_callback($attributes) {
// Attributes with defaults
$block_id = isset($attributes['blockId']) ? $attributes['blockId'] : uniqid('ansicocf_');
$recipient = !empty($attributes['recipientEmail']) ? $attributes['recipientEmail'] : get_option('admin_email');
$success_msg = isset($attributes['successMessage']) ? $attributes['successMessage'] : 'Message has been sent';
$spam_err_msg = isset($attributes['spamErrorMessage']) ? $attributes['spamErrorMessage'] : 'Wrong spam protection answer.';
$footer_msg = isset($attributes['footerMessage']) ? $attributes['footerMessage'] : 'Message has been sent on website';
$format = isset($attributes['emailFormat']) ? $attributes['emailFormat'] : 'text';
$label_name = isset($attributes['labelName']) ? $attributes['labelName'] : 'Name';
$label_email = isset($attributes['labelEmail']) ? $attributes['labelEmail'] : 'E-mail';
$label_subj = isset($attributes['labelSubject']) ? $attributes['labelSubject'] : 'Subject';
$label_msg = isset($attributes['labelMessage']) ? $attributes['labelMessage'] : 'Message';
$label_spam = isset($attributes['labelSpam']) ? $attributes['labelSpam'] : 'Spam check:';
$btn_text = isset($attributes['buttonText']) ? $attributes['buttonText'] : 'Send message';
$msg_html = '';
static $form_processed_once = false;
$posted_name = '';
$posted_email = '';
$posted_subject = '';
$posted_message = '';
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ansicocf_submit']) && isset($_POST['ansicocf_block_id']) && $_POST['ansicocf_block_id'] === $block_id) {
$posted_name = sanitize_text_field($_POST['ansicocf_name']);
$posted_email = sanitize_email($_POST['ansicocf_email']);
$posted_subject = sanitize_text_field($_POST['ansicocf_subject']);
$posted_message = sanitize_textarea_field($_POST['ansicocf_message']);
if (intval($_POST['ansicocf_spam_answer']) !== intval($_POST['ansicocf_spam_expected'])) {
$msg_html = '<p style="color:#d32f2f; font-weight:bold; padding:10px; border:1px solid #d32f2f; border-radius:4px;">' . esc_html($spam_err_msg) . '</p>';
} else {
if (!$form_processed_once) {
ansico_cf_v1_send_final_mail($posted_name, $posted_email, $posted_subject, $posted_message, $recipient, $format, $footer_msg, $label_name, $label_email, $label_subj, $label_msg);
$form_processed_once = true;
}
$msg_html = '<p style="color:#2e7d32; font-weight:bold; padding:10px; border:1px solid #2e7d32; border-radius:4px;">' . esc_html($success_msg) . '</p>';
$posted_name = $posted_email = $posted_subject = $posted_message = '';
}
}
$num1 = rand(1, 5);
$num2 = rand(1, 5);
$expected = $num1 + $num2;
ob_start();
?>
<div class="ansico-contact-form-wrapper" style="max-width:500px; margin-bottom: 25px;">
<?php echo $msg_html; ?>
<form method="post" style="font-family: inherit;">
<p style="margin-bottom: 15px;">
<label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php echo esc_html($label_name); ?></label>
<input type="text" name="ansicocf_name" value="<?php echo esc_attr($posted_name); ?>" required style="width:100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box;">
</p>
<p style="margin-bottom: 15px;">
<label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php echo esc_html($label_email); ?></label>
<input type="email" name="ansicocf_email" value="<?php echo esc_attr($posted_email); ?>" required style="width:100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box;">
</p>
<p style="margin-bottom: 15px;">
<label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php echo esc_html($label_subj); ?></label>
<input type="text" name="ansicocf_subject" value="<?php echo esc_attr($posted_subject); ?>" required style="width:100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box;">
</p>
<p style="margin-bottom: 15px;">
<label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php echo esc_html($label_msg); ?></label>
<textarea name="ansicocf_message" required style="width:100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; resize: none;" rows="5"><?php echo esc_textarea($posted_message); ?></textarea>
</p>
<p style="margin-bottom: 20px;">
<label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php echo esc_html($label_spam); ?> <?php echo "$num1 + $num2 = ?"; ?></label>
<input type="number" name="ansicocf_spam_answer" required style="width:100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box;">
<input type="hidden" name="ansicocf_spam_expected" value="<?php echo $expected; ?>">
</p>
<p style="margin-bottom: 0;">
<input type="hidden" name="ansicocf_block_id" value="<?php echo esc_attr($block_id); ?>">
<input type="submit" name="ansicocf_submit" value="<?php echo esc_attr($btn_text); ?>" style="padding: 12px 24px; background: #007cba; color: #fff; font-weight: bold; border: none; border-radius: 4px; cursor: pointer;">
</p>
</form>
</div>
<?php
return ob_get_clean();
}
/**
* Sends the email with all fields and user email as sender.
*/
function ansico_cf_v1_send_final_mail($name, $email, $subject, $message, $to, $format, $footer_msg, $l_name, $l_email, $l_subj, $l_msg) {
$site_name = get_bloginfo('name');
// Headers: Set sender name and user email as "From" address
$headers = array('Content-Type: text/' . $format . '; charset=UTF-8');
$headers[] = 'Reply-To: ' . $name . ' <' . $email . '>';
$headers[] = 'From: ' . $name . ' <' . $email . '>';
if ($format === 'html') {
$body = "<strong>" . esc_html($l_name) . ":</strong> " . esc_html($name) . "<br>";
$body .= "<strong>" . esc_html($l_email) . ":</strong> " . esc_html($email) . "<br>";
$body .= "<strong>" . esc_html($l_subj) . ":</strong> " . esc_html($subject) . "<br><br>";
$body .= "<strong>" . esc_html($l_msg) . ":</strong><br>" . nl2br(esc_html($message)) . "<br><br>";
$body .= "<hr><em>" . esc_html($footer_msg) . " " . esc_html($site_name) . "</em>";
} else {
$body = $l_name . ": " . $name . "\n";
$body .= $l_email . ": " . $email . "\n";
$body .= $l_subj . ": " . $subject . "\n\n";
$body .= $l_msg . ":\n" . $message . "\n\n";
$body .= "---\n" . $footer_msg . " " . $site_name;
}
wp_mail($to, $subject, $body, $headers);
}
/**
* Register the Gutenberg block.
*/
function ansico_cf_v1_init() {
wp_register_script(
'ansico-cf-js',
plugins_url('block.js', __FILE__),
array('wp-blocks', 'wp-element', 'wp-block-editor', 'wp-components'),
'1.0.0'
);
register_block_type('ansico/contact-form', array(
'editor_script' => 'ansico-cf-js',
'render_callback' => 'ansico_cf_v1_render_callback',
'attributes' => array(
'blockId' => array('type' => 'string', 'default' => ''),
'recipientEmail' => array('type' => 'string', 'default' => ''),
'successMessage' => array('type' => 'string', 'default' => 'Message has been sent'),
'spamErrorMessage' => array('type' => 'string', 'default' => 'Wrong spam protection answer.'),
'footerMessage' => array('type' => 'string', 'default' => 'Message has been sent on website'),
'emailFormat' => array('type' => 'string', 'default' => 'text'),
'labelName' => array('type' => 'string', 'default' => 'Name'),
'labelEmail' => array('type' => 'string', 'default' => 'E-mail'),
'labelSubject' => array('type' => 'string', 'default' => 'Subject'),
'labelMessage' => array('type' => 'string', 'default' => 'Message'),
'labelSpam' => array('type' => 'string', 'default' => 'Spam check:'),
'buttonText' => array('type' => 'string', 'default' => 'Send message'),
)
));
}
add_action('init', 'ansico_cf_v1_init');

View file

@ -0,0 +1,80 @@
(function(wp) {
const { registerBlockType } = wp.blocks;
const { createElement: el } = wp.element;
const { InspectorControls } = wp.blockEditor || wp.editor;
const { PanelBody, TextControl, SelectControl } = wp.components;
registerBlockType('ansico/contact-form', {
title: 'Ansico Contact Form',
icon: 'email',
category: 'common',
attributes: {
blockId: { type: 'string', default: '' },
recipientEmail: { type: 'string', default: '' },
successMessage: { type: 'string', default: 'Message has been sent' },
spamErrorMessage: { type: 'string', default: 'Wrong spam protection answer.' },
footerMessage: { type: 'string', default: 'Message has been sent on website' },
emailFormat: { type: 'string', default: 'text' },
labelName: { type: 'string', default: 'Name' },
labelEmail: { type: 'string', default: 'E-mail' },
labelSubject: { type: 'string', default: 'Subject' },
labelMessage: { type: 'string', default: 'Message' },
labelSpam: { type: 'string', default: 'Spam check:' },
buttonText: { type: 'string', default: 'Send message' }
},
edit: function(props) {
const { attributes, setAttributes } = props;
if (!attributes.blockId) {
setAttributes({ blockId: Math.random().toString(36).substr(2, 9) });
}
const sidebar = el(InspectorControls, null,
el(PanelBody, { title: 'Email Settings', initialOpen: true },
el(TextControl, { label: 'Recipient Email (Blank = Site Admin)', value: attributes.recipientEmail, onChange: (val) => setAttributes({ recipientEmail: val }) }),
el(SelectControl, { label: 'Email Format', value: attributes.emailFormat, options: [{label: 'Plain Text', value: 'text'}, {label: 'HTML', value: 'html'}], onChange: (val) => setAttributes({ emailFormat: val }) }),
el(TextControl, { label: 'Success Message', value: attributes.successMessage, onChange: (val) => setAttributes({ successMessage: val }) }),
el(TextControl, { label: 'Spam Error Message', value: attributes.spamErrorMessage, onChange: (val) => setAttributes({ spamErrorMessage: val }) }),
el(TextControl, { label: 'Email Footer Text', value: attributes.footerMessage, onChange: (val) => setAttributes({ footerMessage: val }) })
),
el(PanelBody, { title: 'Form Labels & Buttons', initialOpen: false },
el(TextControl, { label: 'Name Label', value: attributes.labelName, onChange: (val) => setAttributes({ labelName: val }) }),
el(TextControl, { label: 'Email Label', value: attributes.labelEmail, onChange: (val) => setAttributes({ labelEmail: val }) }),
el(TextControl, { label: 'Subject Label', value: attributes.labelSubject, onChange: (val) => setAttributes({ labelSubject: val }) }),
el(TextControl, { label: 'Message Label', value: attributes.labelMessage, onChange: (val) => setAttributes({ labelMessage: val }) }),
el(TextControl, { label: 'Spam Check Label', value: attributes.labelSpam, onChange: (val) => setAttributes({ labelSpam: val }) }),
el(TextControl, { label: 'Button Text', value: attributes.buttonText, onChange: (val) => setAttributes({ buttonText: val }) })
)
);
const formPreview = el('div', { style: { maxWidth: '500px', fontFamily: 'inherit' } },
el('div', { style: { marginBottom: '15px' } },
el('label', { style: { fontWeight: '600', display: 'block', marginBottom: '5px' } }, attributes.labelName),
el('input', { type: 'text', disabled: true, style: { width: '100%', padding: '10px', border: '1px solid #ccc', borderRadius: '4px' } })
),
el('div', { style: { marginBottom: '15px' } },
el('label', { style: { fontWeight: '600', display: 'block', marginBottom: '5px' } }, attributes.labelEmail),
el('input', { type: 'email', disabled: true, style: { width: '100%', padding: '10px', border: '1px solid #ccc', borderRadius: '4px' } })
),
el('div', { style: { marginBottom: '15px' } },
el('label', { style: { fontWeight: '600', display: 'block', marginBottom: '5px' } }, attributes.labelSubject),
el('input', { type: 'text', disabled: true, style: { width: '100%', padding: '10px', border: '1px solid #ccc', borderRadius: '4px' } })
),
el('div', { style: { marginBottom: '15px' } },
el('label', { style: { fontWeight: '600', display: 'block', marginBottom: '5px' } }, attributes.labelMessage),
el('textarea', { disabled: true, rows: 4, style: { width: '100%', padding: '10px', border: '1px solid #ccc', borderRadius: '4px', resize: 'none' } })
),
el('div', { style: { marginBottom: '20px' } },
el('label', { style: { fontWeight: '600', display: 'block', marginBottom: '5px' } }, attributes.labelSpam + ' 2 + 3 = ?'),
el('input', { type: 'text', disabled: true, style: { width: '100%', padding: '10px', border: '1px solid #ccc', borderRadius: '4px' } })
),
el('button', { disabled: true, style: { padding: '12px 24px', background: '#007cba', color: '#fff', border: 'none', borderRadius: '4px', fontWeight: 'bold' } }, attributes.buttonText)
);
return el('div', null, sidebar, formPreview);
},
save: function() {
return null;
}
});
})(window.wp);

View file

@ -0,0 +1,44 @@
=== Ansico Contact Form ===
Contributors: ansico
Tags: contact form, gutenberg, block, spam protection, customizable
Requires at least: 5.8
Tested up to: 6.9.4
Stable tag: 1.0.0
License: GPLv3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html
A lightweight, fully customizable contact form block for the Gutenberg editor with built-in math spam protection.
== Description ==
Ansico Contact Form is a simple yet powerful Gutenberg block that allows you to add contact forms to any page or post. Every label, button, and message is customizable directly within the editor.
Key features:
* Native Gutenberg block.
* Math-based spam protection.
* Supports both Plain Text and HTML emails.
* Customizable labels for all fields.
* Customizable success and error messages.
* Remembers user input if spam check fails.
* Individual block settings.
== Installation ==
1. Upload the plugin files to the `/wp-content/plugins/ansico-contact-form` directory, or install the plugin through the WordPress plugins screen directly.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Search for the "Ansico Contact Form" block in the editor and add it to your page.
== Screenshots ==
1. The contact form block settings in the Gutenberg sidebar.
2. The contact form as it appears on the frontend.
== Changelog ==
= 1.0.0 =
* Official production release.
* Added readme.txt for WordPress.org compliance.
* Set sender email to use the user's inputted email address.
* Improved email headers to show sender name.
* Included all field data in the email body.
* Fixed double-sending issues.