Skip to content

Commit 010e6cc

Browse files
authored
Add customer meta deletion functionality with simple delete link (#160)
Complete implementation for deleting orphaned custom meta fields: **Core functionality:** - Add secure deletion endpoint with nonce verification in page_loaded() method - Handle delete_meta_key parameter with proper sanitization - Delete customer meta using wu_delete_customer_meta() function - Clean redirect with success/error status and tab preservation - Remove query parameters from URL to prevent reprocessing **UI implementation:** - Add 'Supprimer' link for orphaned fields (fields without form reference) - Simple red text styling with text-decoration: none (no underline) - Right-aligned positioning using float: right within small tag - Matches existing 'Location:' text size and positioning - Direct deletion on click - no confirmation for simplicity **Security & behavior:** - WordPress nonce verification prevents unauthorized deletions - Only show delete option for orphaned fields (preserve form-linked fields) - Secure parameter handling with sanitize_key() and sanitize_text_field() - wp_safe_redirect() for secure page transitions - Maintains all existing customer edit functionality **Code approach:** - Minimal implementation using simple href link with inline styles - No JavaScript dependencies for maximum browser compatibility - Clean separation of deletable vs non-deletable field logic - Follows WordPress coding standards and security best practices
1 parent e5a93b7 commit 010e6cc

File tree

1 file changed

+58
-5
lines changed

1 file changed

+58
-5
lines changed

inc/admin-pages/class-customer-edit-admin-page.php

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,45 @@ public function hooks(): void {
9696
add_filter('removable_query_args', [$this, 'remove_query_args']);
9797
}
9898

99+
/**
100+
* Handle secure deletion of customer meta fields.
101+
*
102+
* @since 2.0.11
103+
* @return void
104+
*/
105+
public function page_loaded() {
106+
107+
// Handle delete meta field action
108+
if (isset($_GET['delete_meta_key']) && isset($_GET['_wpnonce'])) {
109+
110+
$meta_key = sanitize_key($_GET['delete_meta_key']);
111+
$nonce = sanitize_text_field($_GET['_wpnonce']);
112+
113+
// Verify nonce for security
114+
if ( ! wp_verify_nonce($nonce, 'delete_customer_meta_' . $meta_key)) {
115+
wp_die(__('Security check failed. Please try again.', 'multisite-ultimate'));
116+
}
117+
118+
$customer = $this->get_object();
119+
if ($customer) {
120+
$deleted = wu_delete_customer_meta($customer->get_id(), $meta_key);
121+
122+
$redirect_args = [
123+
'updated' => $deleted ? 'meta_deleted' : 'meta_delete_failed',
124+
'tab' => 'custom_meta'
125+
];
126+
127+
$redirect_url = add_query_arg($redirect_args, wu_network_admin_url('wp-ultimo-edit-customer', ['id' => $customer->get_id()]));
128+
129+
wp_safe_redirect($redirect_url);
130+
exit;
131+
}
132+
}
133+
134+
// Call parent to preserve existing functionality (e.g., adding new fields)
135+
parent::page_loaded();
136+
}
137+
99138
/**
100139
* Allow child classes to register scripts and styles that can be loaded on the output function, for example.
101140
*
@@ -411,10 +450,7 @@ public function generate_customer_meta_fields() {
411450

412451
foreach ($custom_meta_keys as $key => $value) {
413452
$field_location_breadcrumbs = [
414-
__(
415-
'orphan field - the original form no longer exists',
416-
'multisite-ultimate'
417-
),
453+
__('Custom field', 'multisite-ultimate'),
418454
];
419455

420456
$form = wu_get_isset($value, 'form');
@@ -444,10 +480,25 @@ public function generate_customer_meta_fields() {
444480

445481
$options = array_merge(['' => '--'], $options);
446482

483+
// Add simple delete link for orphaned fields (those without form reference)
484+
$delete_link = '';
485+
if ( ! $form) {
486+
$delete_url = add_query_arg([
487+
'delete_meta_key' => $key,
488+
'_wpnonce' => wp_create_nonce('delete_customer_meta_' . $key),
489+
]);
490+
491+
$delete_link = sprintf(
492+
'<small style="float: right;"><a href="%s" style="color: red; text-decoration: none;">%s</a></small>',
493+
esc_url($delete_url),
494+
__('Delete', 'multisite-ultimate')
495+
);
496+
}
497+
447498
$field_data = [
448499
'title' => wu_get_isset($value, 'title', wu_slug_to_name($key)),
449500
'type' => wu_get_isset($value, 'type', 'text'),
450-
'desc' => wu_get_isset($value, 'description', '') . $location,
501+
'desc' => wu_get_isset($value, 'description', '') . $location . $delete_link,
451502
'options' => $options,
452503
'tooltip' => wu_get_isset($value, 'tooltip', ''),
453504
'value' => wu_get_customer_meta($this->get_object()->get_id(), $key),
@@ -1248,6 +1299,8 @@ public function remove_query_args($removable_query_args) {
12481299
}
12491300

12501301
$removable_query_args[] = 'notice_verification_sent';
1302+
$removable_query_args[] = 'delete_meta_key';
1303+
$removable_query_args[] = '_wpnonce';
12511304

12521305
return $removable_query_args;
12531306
}

0 commit comments

Comments
 (0)