星期四 , 17 4 月 2025

form插件

<?php
/**
* Plugin Name: Dynamic Feedback Form
* Description: Creates a customizable feedback form with admin management and database storage
* Version: 1.0
* Author: Claude
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
// Plugin Activation: Create database table
function feedback_form_activation() {
global $wpdb;
$table_name = $wpdb->prefix . 'feedback_submissions';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
submission_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
siteid varchar(100) NOT NULL,
pagename varchar(255) NOT NULL DEFAULT '',
pageurl varchar(255) NOT NULL DEFAULT '',
customer varchar(100) NOT NULL,
email varchar(100) NOT NULL,
company varchar(100),
phone varchar(50),
content text NOT NULL,
PRIMARY KEY  (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'feedback_form_activation');
// Handle form submission via AJAX
function handle_feedback_form_submission() {
// Verify nonce for security
if (!isset($_POST['feedback_form_nonce']) || !wp_verify_nonce($_POST['feedback_form_nonce'], 'feedback_form_submission')) {
wp_send_json_error('Security check failed');
return;
}
// Sanitize and validate form data
$siteid = isset($_POST['siteid']) ? sanitize_text_field($_POST['siteid']) : '1';
// Fix for pagename and pageurl - provide default values if empty
$pagename = isset($_POST['pagename']) && !empty($_POST['pagename']) 
? sanitize_text_field($_POST['pagename']) 
: get_the_title();
$pageurl = isset($_POST['pageurl']) && !empty($_POST['pageurl']) 
? esc_url_raw($_POST['pageurl']) 
: get_permalink();
$customer = isset($_POST['customer']) ? sanitize_text_field($_POST['customer']) : '';
$email = isset($_POST['email']) ? sanitize_email($_POST['email']) : '';
$company = isset($_POST['company']) ? sanitize_text_field($_POST['company']) : '';
$phone = isset($_POST['phone']) ? sanitize_text_field($_POST['phone']) : '';
$content = isset($_POST['content']) ? sanitize_textarea_field($_POST['content']) : '';
// Validate required fields
if (empty($customer) || empty($email) || empty($content)) {
wp_send_json_error('Please fill in all required fields');
return;
}
if (!is_email($email)) {
wp_send_json_error('Please enter a valid email address');
return;
}
// Save data to the database
global $wpdb;
$table_name = $wpdb->prefix . 'feedback_submissions';
$result = $wpdb->insert(
$table_name,
array(
'siteid' => $siteid,
'pagename' => $pagename,
'pageurl' => $pageurl,
'customer' => $customer,
'email' => $email,
'company' => $company,
'phone' => $phone,
'content' => $content,
)
);
if ($result === false) {
wp_send_json_error('Failed to save feedback submission: ' . $wpdb->last_error);
} else {
wp_send_json_success('Thank you for your message. We will get back to you soon!');
}
}
add_action('wp_ajax_feedback_form_submission', 'handle_feedback_form_submission');
add_action('wp_ajax_nopriv_feedback_form_submission', 'handle_feedback_form_submission');
// Enqueue necessary scripts and styles
function feedback_form_enqueue_scripts() {
wp_enqueue_style('feedback-form-style', plugin_dir_url(__FILE__) . 'feedback-form.css');
wp_enqueue_script('feedback-form-script', plugin_dir_url(__FILE__) . 'feedback-form.js', array('jquery'), '1.0', true);
wp_localize_script('feedback-form-script', 'feedback_form_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('feedback_form_submission'),
'current_page' => get_the_title(),
'current_url' => get_permalink()
));
}
add_action('wp_enqueue_scripts', 'feedback_form_enqueue_scripts');
// Create CSS file in plugin directory
function feedback_form_create_css() {
$css_file = plugin_dir_path(__FILE__) . 'feedback-form.css';
if (!file_exists($css_file)) {
$css_content = "
.form-feedback .form-group {
margin-bottom: 15px;
}
.form-feedback .form-control {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.form-feedback .btn {
background-color: #0073aa;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.form-feedback .btn:hover {
background-color: #005177;
}
.feedback-result {
margin-top: 10px;
padding: 10px;
}
.feedback-result.success {
background-color: #d4edda;
border-color: #c3e6cb;
color: #155724;
}
.feedback-result.error {
background-color: #f8d7da;
border-color: #f5c6cb;
color: #721c24;
}
";
file_put_contents($css_file, $css_content);
}
}
// Create JS file in plugin directory
function feedback_form_create_js() {
$js_file = plugin_dir_path(__FILE__) . 'feedback-form.js';
if (!file_exists($js_file)) {
$js_content = "
jQuery(document).ready(function($) {
// Set page info when form loads - FIXED
$('.form-feedback').each(function() {
$(this).find('input[name=\"pagename\"]').val(feedback_form_ajax.current_page);
$(this).find('input[name=\"pageurl\"]').val(feedback_form_ajax.current_url);
});
// Form submission
$(document).on('click', '#post-message', function(e) {
e.preventDefault();
var form = $(this).closest('form');
var resultContainer = form.find('.feedback-result');
// Validate form
var isValid = true;
form.find('[required]').each(function() {
if (!$(this).val().trim()) {
isValid = false;
$(this).addClass('error');
} else {
$(this).removeClass('error');
}
});
if (!isValid) {
resultContainer.removeClass('success').addClass('error').html('Please fill in all required fields');
return;
}
// Double-check that pagename and pageurl are set
if (form.find('input[name=\"pagename\"]').val() === '') {
form.find('input[name=\"pagename\"]').val(feedback_form_ajax.current_page);
}
if (form.find('input[name=\"pageurl\"]').val() === '') {
form.find('input[name=\"pageurl\"]').val(feedback_form_ajax.current_url);
}
// Collect form data
var formData = form.serializeArray();
formData.push({
name: 'action',
value: 'feedback_form_submission'
});
formData.push({
name: 'feedback_form_nonce',
value: feedback_form_ajax.nonce
});
// Send AJAX request
$.ajax({
type: 'POST',
url: feedback_form_ajax.ajax_url,
data: formData,
success: function(response) {
if (response.success) {
resultContainer.removeClass('error').addClass('success').html(response.data);
form.find('input:not([type=hidden]), textarea').val('');
} else {
resultContainer.removeClass('success').addClass('error').html(response.data);
}
},
error: function() {
resultContainer.removeClass('success').addClass('error').html('An error occurred. Please try again later.');
}
});
});
});
";
file_put_contents($js_file, $js_content);
}
}
// Create necessary files when plugin is activated
register_activation_hook(__FILE__, 'feedback_form_create_css');
register_activation_hook(__FILE__, 'feedback_form_create_js');
// Shortcode to display the feedback form
function feedback_form_shortcode($atts) {
// Process attributes to allow customization
$atts = shortcode_atts(array(
'siteid' => '1',
'button_text' => 'Send Message',
'button_class' => 'btn btn-block',
'show_company' => 'true',
'show_phone' => 'true',
'name_placeholder' => '* Name',
'email_placeholder' => '* Email',
'company_placeholder' => 'Company',
'phone_placeholder' => 'Telephone',
'content_placeholder' => '* Inquiry Content'
), $atts);
// Start output buffering
ob_start();
// Get current page info
$current_page = get_the_title();
$current_url = get_permalink();
?>
<form id="form-feedback" class="form-feedback" novalidate>
<input type="hidden" name="siteid" value="<?php echo esc_attr($atts['siteid']); ?>">
<input type="hidden" name="pagename" value="<?php echo esc_attr($current_page); ?>">
<input type="hidden" name="pageurl" value="<?php echo esc_url($current_url); ?>">
<div class="form-row">
<div class="col-md-6 form-group">
<input type="text" name="customer" placeholder="<?php echo esc_attr($atts['name_placeholder']); ?>" class="form-control" aria-label="Name" required>
</div>
<div class="col-md-6 form-group">
<input type="email" name="email" placeholder="<?php echo esc_attr($atts['email_placeholder']); ?>" class="form-control" aria-label="Email" required>
</div>
<?php if ($atts['show_company'] === 'true'): ?>
<div class="col-md-6 form-group">
<input type="text" name="company" placeholder="<?php echo esc_attr($atts['company_placeholder']); ?>" class="form-control" aria-label="Company">
</div>
<?php endif; ?>
<?php if ($atts['show_phone'] === 'true'): ?>
<div class="col-md-6 form-group">
<input type="text" name="phone" placeholder="<?php echo esc_attr($atts['phone_placeholder']); ?>" class="form-control" aria-label="Telephone">
</div>
<?php endif; ?>
</div>
<div class="form-row">
<div class="col-md-12 form-group">
<textarea name="content" placeholder="<?php echo esc_attr($atts['content_placeholder']); ?>" cols="20" rows="4" class="form-control" aria-label="Inquiry Content" required></textarea>
</div>
<div class="col-md-12">
<div class="form-row">
<div class="col-md-6">
<button type="button" class="<?php echo esc_attr($atts['button_class']); ?>" id="post-message" data-provider="post-message" data-track="google" data-track-category="" data-track-action="" data-track-opt=""><?php echo esc_html($atts['button_text']); ?></button>
<div class="feedback-result"></div>
</div>
</div>
</div>
</div>
</form>
<?php
return ob_get_clean();
}
add_shortcode('feedback_form', 'feedback_form_shortcode');
// Add admin menu
function feedback_form_admin_menu() {
add_menu_page(
'Feedback Submissions',
'Feedback',
'manage_options',
'feedback-submissions',
'feedback_form_admin_page',
'dashicons-feedback',
30
);
}
add_action('admin_menu', 'feedback_form_admin_menu');
// Admin page to display submissions
function feedback_form_admin_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'feedback_submissions';
// Handle delete action
if (isset($_POST['action']) && $_POST['action'] == 'delete' && isset($_POST['submission_id'])) {
check_admin_referer('delete_feedback_submission');
$id = intval($_POST['submission_id']);
$wpdb->delete($table_name, array('id' => $id), array('%d'));
echo '<div class="notice notice-success is-dismissible"><p>Submission deleted successfully.</p></div>';
}
// Search functionality
$search = isset($_GET['feedback_search']) ? sanitize_text_field($_GET['feedback_search']) : '';
$where = '';
if (!empty($search)) {
$where = $wpdb->prepare(
" WHERE customer LIKE %s OR email LIKE %s OR company LIKE %s OR content LIKE %s OR pagename LIKE %s",
'%' . $wpdb->esc_like($search) . '%',
'%' . $wpdb->esc_like($search) . '%',
'%' . $wpdb->esc_like($search) . '%',
'%' . $wpdb->esc_like($search) . '%',
'%' . $wpdb->esc_like($search) . '%'
);
}
// Get submissions
$submissions = $wpdb->get_results("SELECT * FROM $table_name $where ORDER BY submission_date DESC");
?>
<div class="wrap">
<h1>Feedback Submissions</h1>
<!-- Search Form -->
<form method="get">
<input type="hidden" name="page" value="feedback-submissions">
<p class="search-box">
<label class="screen-reader-text" for="feedback_search">Search Submissions:</label>
<input type="search" id="feedback_search" name="feedback_search" value="<?php echo esc_attr($search); ?>" placeholder="Search submissions...">
<input type="submit" id="search-submit" class="button" value="Search">
</p>
</form>
<!-- Submissions Table -->
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>ID</th>
<th>Date</th>
<th>Name</th>
<th>Email</th>
<th>Company</th>
<th>Phone</th>
<th>Page</th>
<th>Message</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (empty($submissions)): ?>
<tr>
<td colspan="9">No submissions found.</td>
</tr>
<?php else: ?>
<?php foreach ($submissions as $submission): ?>
<tr>
<td><?php echo esc_html($submission->id); ?></td>
<td><?php echo esc_html(date('Y-m-d H:i:s', strtotime($submission->submission_date))); ?></td>
<td><?php echo esc_html($submission->customer); ?></td>
<td><?php echo esc_html($submission->email); ?></td>
<td><?php echo esc_html($submission->company); ?></td>
<td><?php echo esc_html($submission->phone); ?></td>
<td><?php echo esc_html($submission->pagename); ?><br><small><?php echo esc_html($submission->pageurl); ?></small></td>
<td><?php echo esc_html($submission->content); ?></td>
<td>
<form method="post" onsubmit="return confirm('Are you sure you want to delete this submission?');">
<?php wp_nonce_field('delete_feedback_submission'); ?>
<input type="hidden" name="action" value="delete">
<input type="hidden" name="submission_id" value="<?php echo esc_attr($submission->id); ?>">
<input type="submit" class="button button-small button-link-delete" value="Delete">
</form>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<div class="shortcode-info" style="margin-top: 20px; background: #fff; padding: 15px; border: 1px solid #ccc;">
<h3>Shortcode Usage</h3>
<p>Use the following shortcode to display the feedback form on any page or post:</p>
<code>[feedback_form]</code>
<h4>Shortcode Parameters</h4>
<ul>
<li><code>siteid</code> - Site ID (default: 1)</li>
<li><code>button_text</code> - Button text (default: "Send Message")</li>
<li><code>button_class</code> - Button CSS classes (default: "btn btn-block")</li>
<li><code>show_company</code> - Show company field (true/false, default: true)</li>
<li><code>show_phone</code> - Show phone field (true/false, default: true)</li>
<li><code>name_placeholder</code> - Name field placeholder (default: "* Name")</li>
<li><code>email_placeholder</code> - Email field placeholder (default: "* Email")</li>
<li><code>company_placeholder</code> - Company field placeholder (default: "Company")</li>
<li><code>phone_placeholder</code> - Phone field placeholder (default: "Telephone")</li>
<li><code>content_placeholder</code> - Content field placeholder (default: "* Inquiry Content")</li>
</ul>
<h4>Example</h4>
<code>[feedback_form button_text="Submit" show_company="false" content_placeholder="* Your Message"]</code>
</div>
</div>
<?php
}