I have created a plugin to add extra fields to user profiles. These fields can only be edited buy admin and do not show on the user'profile page. The extra fields are shown and can be edited by admin. The problem is that when a user edits their profile it wipes all values from the extra fields for that user. I am using the wordpress plugin Admin Columns Pro and have contacted them but they say their plugin is not causing the problem. I'm not very experienced with coding and may have something wrong. You can see my code here: https://pastebin.com/5caMB9yZ
1 Answer
I see two problems in your code. The first one is the user capability level and the second one is how you're saving the data.
You can fix the first one by setting the capability requirement in your saving function higher, some capability that only administrators have. Regarding edit_user
capability, WordPress Capabilities: edit_user vs edit_users
The second one you can fix by adding isset()
check to see, if the custom field values are being sent or not with $_POST
. At the current form, if the custom field value is not set, then $_POST['field-key]
results in null
value, which overwrites any previous saved data. I.e. update_user_meta( $user_id, 'pin', $_POST['pin'] );
Here's one example how you could improve your code. In my example I've
added a nonce check, upgraded the capability requirement, added isset()
check and data sanitization.
function extra_user_profile_fields( $user ) {
// add nonce field
wp_nonce_field( 'my_extra_user_profile_fields', 'my_extra_user_profile_fields_nonce', true, true );
?>
<!-- your html as it was -->
<?php
}
function save_extra_user_profile_fields( $user_id ) {
// Nonce checks to know the $_POST is coming from the right source
if ( empty( $_POST['my_extra_user_profile_fields_nonce'] ) || ! wp_verify_nonce( 'my_extra_user_profile_fields_nonce', 'my_extra_user_profile_fields' ) ) {
return;
}
// Capabilities check
// create_users is administrator only capability
if ( ! current_user_can( 'create_users', $user_id ) ) {
return;
}
// valid field keys with related data type
// update types as needed
$fields = array(
'pin' => 'string',
'street-address' => 'string',
'suburb' => 'string',
'postcode' => 'string',
'phone' => 'string',
'mobile' => 'string',
'president-year' => 'int',
'secretary-year' => 'int',
'competition-secretary-year' => 'int',
'treasurer-year' => 'int',
'committee-member-year' => 'int',
'joining-date' => 'string',
'fees-paid' => 'bool',
'life-member' => 'string',
'comments' => 'string',
'other-roles' => 'string',
'year-left' => 'int',
);
// loop fields instead of typing each update separately
foreach ($fields as $key => $data_type) {
// check if field data is sent with $_POST
if ( isset( $_POST[$key] ) ) {
// update user meta with sanitized value
update_user_meta( $user_id, $key, my_sanitize_user_data($_POST[$key], $data_type) );
}
}
}
function my_sanitize_user_data( $value, string $type = '' ) {
switch ($type) {
case 'bool':
return in_array( $value, array(true, 'true', 1, 'yes') ); // returns true, if value is in array otherwise false
case 'int':
return is_numeric($value) ? absint( $value ) : 0;
default:
return sanitize_text_field( $value );
}
}
I think you should also be able to remove add_action( 'personal_options_update', 'save_extra_user_profile_fields' );
as add_action( 'edit_user_profile_update', 'save_extra_user_profile_fields' );
covers the data saving.
-
Thank you so much. changing from edit_user to edit_users has fixed my problem. I will attempt to implement your other suggestion when I get some time.– RhondaCommented Dec 23, 2019 at 8:38