Add complete custom fields implementation and entry editing

- Add custom field CRUD in admin UI (create, read, update, delete)
- Display custom fields on frontend form with proper field types
- Save custom field values on form submission
- Display custom field columns in entries table (admin and public)
- Include custom field values in all export formats (CSV, PairGoTh, OpenGotha, McMahon)
- Add Edit button and form for entries
- Update entry handler to support editing with custom field values
- Add success/error notices for all admin actions

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-05-12 13:02:33 +02:00
parent bd7b9e1731
commit 2d537f07dd
5 changed files with 510 additions and 12 deletions

View File

@@ -7,6 +7,18 @@ if (isset($_GET['deleted']))
echo '<div class="notice notice-success"><p>Deleted!</p></div>';
if (isset($_GET['created']))
echo '<div class="notice notice-success"><p>Form created!</p></div>';
if (isset($_GET['created_field']))
echo '<div class="notice notice-success"><p>Custom field created!</p></div>';
if (isset($_GET['updated_field']))
echo '<div class="notice notice-success"><p>Custom field updated!</p></div>';
if (isset($_GET['deleted_field']))
echo '<div class="notice notice-success"><p>Custom field deleted!</p></div>';
if (isset($_GET['updated_entry']))
echo '<div class="notice notice-success"><p>Entry updated!</p></div>';
if (isset($_GET['error']) && $_GET['error'] == 'missing_required')
echo '<div class="notice notice-error"><p>First Name and Last Name are required!</p></div>';
if (isset($_GET['error']) && $_GET['error'] == 'missing_required_field')
echo '<div class="notice notice-error"><p>A required custom field is missing!</p></div>';
?>
<div class="wrap">
@@ -47,11 +59,165 @@ if (isset($_GET['created']))
action_button('go_form_export_opengotha', 'Export to Opengoth', 'Confrm Export', $selected_form_id);
action_button('go_form_export_mcmahon', 'Export to McMahon', 'Confrm Export', $selected_form_id);
echo '</div>';
// ========== Custom Fields Management ==========
$custom_fields = go_form_get_custom_fields($selected_form_id);
echo '<div style="margin-bottom:20px; padding:15px; background:#f9f9f9; border:1px solid #ddd; border-radius:4px;">';
echo '<h3>Custom Fields</h3>';
// Add new custom field form
echo '<details style="margin-bottom:15px;"><summary style="cursor:pointer; font-weight:bold;">+ Add New Custom Field</summary>';
echo '<form method="post" action="' . admin_url('admin-post.php') . '" style="margin-top:10px; padding-left:15px;">';
echo wp_nonce_field('go_form_create_custom_field_action', 'go_form_create_custom_field_nonce', true, false);
echo '<input type="hidden" name="action" value="go_form_create_custom_field">';
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
echo '<table class="form-table">';
echo '<tr><th><label for="field_name">Field Name:</label></th><td><input type="text" name="field_name" id="field_name" required></td></tr>';
echo '<tr><th><label for="field_type">Field Type:</label></th><td>';
echo '<select name="field_type" id="field_type">';
echo '<option value="text">Text</option>';
echo '<option value="select">Dropdown (Select)</option>';
echo '<option value="checkbox">Checkbox</option>';
echo '<option value="email">Email</option>';
echo '</select>';
echo '</td></tr>';
echo '<tr><th><label for="field_options">Options (for select, comma-separated):</label></th><td><textarea name="field_options" id="field_options" rows="2" style="width:100%;"></textarea><small>e.g., Option 1,Option 2,Option 3</small></td></tr>';
echo '<tr><th><label for="is_public">Public:</label></th><td><input type="checkbox" name="is_public" id="is_public" value="1" checked> <small>Show on public form</small></td></tr>';
echo '<tr><th><label for="is_required">Required:</label></th><td><input type="checkbox" name="is_required" id="is_required" value="1"> <small>Required field</small></td></tr>';
echo '</table>';
echo '<p class="submit"><input type="submit" class="button button-primary" value="Add Custom Field"></p>';
echo '</form>';
echo '</details>';
// List existing custom fields
if (!empty($custom_fields)) {
echo '<table class="wp-list-table widefat striped" style="margin-top:15px;">';
echo '<thead><tr><th>Field Name</th><th>Type</th><th>Public</th><th>Required</th><th>Actions</th></tr></thead><tbody>';
foreach ($custom_fields as $field) {
echo '<tr>';
echo '<td>' . esc_html($field->field_name) . '</td>';
echo '<td>' . esc_html($field->field_type) . '</td>';
echo '<td>' . ($field->is_public ? 'Yes' : 'No') . '</td>';
echo '<td>' . ($field->is_required ? 'Yes' : 'No') . '</td>';
echo '<td>';
// Edit button (toggle to show edit form)
echo '<a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id, 'edit_field' => $field->id), admin_url('admin.php')) . '" class="button button-small">Edit</a> ';
action_button('go_form_delete_custom_field', 'Delete', 'Delete this custom field?', $field->id);
echo '</td>';
echo '</tr>';
}
echo '</tbody></table>';
} else {
echo '<p><em>No custom fields yet.</em></p>';
}
// Edit custom field form
if (isset($_GET['edit_field']) && $edit_field_id = intval($_GET['edit_field'])) {
$edit_field = go_form_get_custom_field_by_id($edit_field_id);
if ($edit_field && $edit_field->form_id == $selected_form_id) {
echo '<details open style="margin-top:20px;"><summary style="cursor:pointer; font-weight:bold;">Edit Custom Field</summary>';
echo '<form method="post" action="' . admin_url('admin-post.php') . '" style="margin-top:10px; padding-left:15px;">';
echo wp_nonce_field('go_form_update_custom_field_action', 'go_form_update_custom_field_nonce', true, false);
echo '<input type="hidden" name="action" value="go_form_update_custom_field">';
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
echo '<input type="hidden" name="field_id" value="' . esc_attr($edit_field->id) . '">';
echo '<table class="form-table">';
echo '<tr><th><label for="field_name">Field Name:</label></th><td><input type="text" name="field_name" id="field_name" value="' . esc_attr($edit_field->field_name) . '" required></td></tr>';
echo '<tr><th><label for="field_type">Field Type:</label></th><td>';
echo '<select name="field_type" id="field_type">';
echo '<option value="text"' . selected($edit_field->field_type, 'text', false) . '>Text</option>';
echo '<option value="select"' . selected($edit_field->field_type, 'select', false) . '>Dropdown (Select)</option>';
echo '<option value="checkbox"' . selected($edit_field->field_type, 'checkbox', false) . '>Checkbox</option>';
echo '<option value="email"' . selected($edit_field->field_type, 'email', false) . '>Email</option>';
echo '</select>';
echo '</td></tr>';
echo '<tr><th><label for="field_options">Options (for select, comma-separated):</label></th><td><textarea name="field_options" id="field_options" rows="2" style="width:100%;">' . esc_textarea($edit_field->field_options) . '</textarea><small>e.g., Option 1,Option 2,Option 3</small></td></tr>';
echo '<tr><th><label for="is_public">Public:</label></th><td><input type="checkbox" name="is_public" id="is_public" value="1" ' . checked($edit_field->is_public, 1, false) . '> <small>Show on public form</small></td></tr>';
echo '<tr><th><label for="is_required">Required:</label></th><td><input type="checkbox" name="is_required" id="is_required" value="1" ' . checked($edit_field->is_required, 1, false) . '> <small>Required field</small></td></tr>';
echo '</table>';
echo '<p class="submit"><input type="submit" class="button button-primary" value="Update Custom Field"> <a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id), admin_url('admin.php')) . '" class="button">Cancel</a></p>';
echo '</form>';
echo '</details>';
}
}
echo '</div>';
// ========== Edit Entry Form ==========
if (isset($_GET['edit_entry']) && $edit_entry_id = intval($_GET['edit_entry'])) {
$entry = go_form_get_entry_by_id($edit_entry_id);
if ($entry && $entry->form_id == $selected_form_id) {
$custom_fields = go_form_get_custom_fields($selected_form_id);
echo '<div style="margin-bottom:20px; padding:15px; background:#fff; border:1px solid #ddd; border-radius:4px;">';
echo '<h3>Edit Entry</h3>';
echo '<form method="post" action="' . admin_url('admin-post.php') . '">';
echo wp_nonce_field('go_form_update_entry_action', 'go_form_update_entry_nonce', true, false);
echo '<input type="hidden" name="action" value="go_form_update_entry">';
echo '<input type="hidden" name="entry_id" value="' . esc_attr($entry->id) . '">';
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
echo '<table class="form-table">';
echo '<tr><th><label for="first_name">First Name*:</label></th><td><input type="text" name="first_name" id="first_name" value="' . esc_attr($entry->first_name) . '" required></td></tr>';
echo '<tr><th><label for="last_name">Last Name*:</label></th><td><input type="text" name="last_name" id="last_name" value="' . esc_attr($entry->last_name) . '" required></td></tr>';
echo '<tr><th><label for="country">Country:</label></th><td><input type="text" name="country" id="country" value="' . esc_attr($entry->country) . '"></td></tr>';
echo '<tr><th><label for="club">Club:</label></th><td><input type="text" name="club" id="club" value="' . esc_attr($entry->club) . '"></td></tr>';
echo '<tr><th><label for="rank">Rank:</label></th><td>';
echo '<select name="rank" id="rank">';
global $ranks;
foreach ($ranks as $value => $label) {
echo '<option value="' . esc_attr($value) . '" ' . selected($entry->rank, $value, false) . '>' . esc_html($label) . '</option>';
}
echo '</select>';
echo '</td></tr>';
echo '<tr><th><label for="rating">Rating:</label></th><td><input type="number" name="rating" id="rating" value="' . esc_attr($entry->rating) . '"></td></tr>';
echo '<tr><th><label for="egd_number">EGD Number:</label></th><td><input type="text" name="egd_number" id="egd_number" value="' . esc_attr($entry->egd_number) . '"></td></tr>';
// Custom fields
if (!empty($custom_fields)) {
foreach ($custom_fields as $field) {
$field_id = 'custom_field_' . $field->id;
$value = go_form_get_custom_value($entry->id, $field->id);
echo '<tr><th><label for="' . esc_attr($field_id) . '">' . esc_html($field->field_name) . ($field->is_required ? '*' : '') . ':</label></th><td>';
switch ($field->field_type) {
case 'text':
echo '<input type="text" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="' . esc_attr($value) . '"' . ($field->is_required ? ' required' : '') . '>';
break;
case 'email':
echo '<input type="email" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="' . esc_attr($value) . '"' . ($field->is_required ? ' required' : '') . '>';
break;
case 'select':
$options = $field->field_options ? explode(',', $field->field_options) : [];
echo '<select name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '"' . ($field->is_required ? ' required' : '') . '>';
echo '<option value="">-- Select --</option>';
foreach ($options as $option) {
$option = trim($option);
echo '<option value="' . esc_attr($option) . '" ' . selected($value, $option, false) . '>' . esc_html($option) . '</option>';
}
echo '</select>';
break;
case 'checkbox':
echo '<input type="checkbox" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="1" ' . checked($value, '1', false) . '>';
break;
}
echo '</td></tr>';
}
}
echo '</table>';
echo '<p class="submit">';
echo '<input type="submit" class="button button-primary" value="Update Entry">';
echo ' <a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id), admin_url('admin.php')) . '" class="button">Cancel</a>';
echo '</p>';
echo '</form>';
echo '</div>';
}
}
$entries = go_form_get_entries($selected_form_id);
go_form_render_entries_table($entries, true);
$custom_fields = go_form_get_custom_fields($selected_form_id);
go_form_render_entries_table($entries, true, $custom_fields, $selected_form_id);
} else {