Question

I've made a form on WordPress theme frontend that let registered user change some of their user metadata on page, but it didn't work, code like below:

    <form name="update_basic_user_meta" id="update_basic_user_meta" action="<?php echo esc_url( home_url() ); ?>?update_basic_user_meta=true" method="POST">

    <select name="gender">
        <option value="male" ><?php _e('Male','text-domain');?></option>
        <option value="female" ><?php _e('Female','text-domain');?></option>
    </select>
    
    <div>
        <label><input type="radio" name="specialty" value="0"> <?php _e('Read','text-domain');?></label><br>
        <label><input type="radio" name="specialty" value="1"> <?php _e('Write','text-domain');?></label><br>
        <label><input type="radio" name="specialty" value="2"> <?php _e('Translate','text-domain');?></label>
    </div>
    
    <button name="submit" type="submit"><?php _e('Submit','text-domain');?></button>
    <input type="hidden" name="redirect_to" value="<?php echo $_SERVER['REQUEST_URI']; ?>" />

    </form>

    <?php
    function update_basic_user_meta() {
      $user_id = current_user_id();
    update_user_meta( $user_id, 'gender', $_POST['gender'] );
    update_user_meta( $user_id, 'specialty', $_POST['specialty'] );
    }
    add_filter('init', 'update_basic_user_meta');
    ?>

The "Gender" "Specialty" user metadata field is existed and work well on backend user profile page.

Don't have a clue how this form didn’t affect any of the user metadata.

Please help :) Thank you all.

Was it helpful?

Solution

There are 3 main issues in your code:

  1. I see you're using current_user_id() which does not exist in WordPress, so I believe that should be get_current_user_id().

  2. Your update_basic_user_meta() function basically would work in updating the user's metadata, but you need to check whether the POST data (gender and specialty) are actually set before proceeding to update the metadata, and that the GET data named update_basic_user_meta is also set, which means the form was submitted.

    However, if I were you, I would use a nonce field than a simple GET query.

  3. You need to highlight the current selection for the "Gender" and "Specialty" options, so that users know what have they selected and whether it was actually saved. So,

    • For the "Gender" option (which uses select menu), you can use selected().

    • For the "Specialty" option (which uses radio buttons), you can use checked().

And despite add_filter() works, init is an action hook, so you should use add_action():

add_action( 'init', 'update_basic_user_meta' );   // use this
//add_filter( 'init', 'update_basic_user_meta' ); // not this

Sample snippets that would make your form works as expected

  1. Highlight the current selection for the "Gender" option:

    <?php $gender = get_user_meta( get_current_user_id(), 'gender', true ); ?>
    <select name="gender">
        <option value="male"<?php selected( 'male', $gender ); ?>><?php _e( 'Male', 'text-domain' ); ?></option>
        <option value="female"<?php selected( 'female', $gender ); ?>><?php _e( 'Female', 'text-domain' ); ?></option>
    </select>
    
  2. Highlight the current selection for the "Specialty" option:

    <?php $specialty = get_user_meta( get_current_user_id(), 'specialty', true ); ?>
    <div>
        <label><input type="radio" name="specialty" value="0"<?php checked( '0', $specialty ); ?>> <?php _e( 'Read', 'text-domain' ); ?></label><br>
        <label><input type="radio" name="specialty" value="1"<?php checked( '1', $specialty ); ?>> <?php _e( 'Write', 'text-domain' ); ?></label><br>
        <label><input type="radio" name="specialty" value="2"<?php checked( '2', $specialty ); ?>> <?php _e( 'Translate', 'text-domain' ); ?></label>
    </div>
    
  3. Function to update the user's metadata:

    function update_basic_user_meta() {
        if ( ! empty( $_GET['update_basic_user_meta'] )    &&
            isset( $_POST['gender'], $_POST['specialty'] ) &&
            $user_id = get_current_user_id()
        ) {
            update_user_meta( $user_id, 'gender',    sanitize_text_field( $_POST['gender'] ) );
            update_user_meta( $user_id, 'specialty', sanitize_text_field( $_POST['specialty'] ) );
    
            if ( ! empty( $_POST['redirect_to'] ) ) {
                wp_redirect( $_POST['redirect_to'] );
                exit;
            }
        }
    }
    

OTHER TIPS

First I want to thank @SallyCJ, you helped me alot:)

I was modifying the code while you write the answer, and I've got a working code below.

<?php 
function update_basic_user_meta() {     //define this function
$user_id = get_current_user_id();       //save the current user id number for further use 

?>

<form name="update_basic_user_meta" id="update_basic_user_meta" action="" method="POST"> <!-- figured out should be empty on "action"  -->

        <input name="nickname" type="text" placeholder="<?php _e('Your name here','journey');?>">  <!-- A text field to get user's nickname change -->

        <select  name="gender">     <!-- An select to tell is it he or her -->
                <option value="male" ><?php _e('Male','journey');?></option>
                <option value="female" ><?php _e('Female','journey');?></option> 
        </select>

        <div>       <!-- Radio buttons to select what they are good at -->
            <label><input class="uk-radio" type="radio" name="specialty" value="0"> <?php _e('Strong','journey');?></label><br>
            <label><input class="uk-radio" type="radio" name="specialty" value="1"> <?php _e('Balanced','journey');?></label><br>
            <label><input class="uk-radio" type="radio" name="specialty" value="2"> <?php _e('Wise','journey');?></label>
        </div>
        
    <button name="submit" class="uk-button uk-button-primary uk-width-1 uk-margin-small-bottom" type="submit"><?php _e('Inject Soul','journey');?></button>

</form>
<?php
    if($_POST['nickname'] != ''){ //check one of the field is filled then go, prevent empty stuff goes to database.
    update_user_meta( $user_id, 'nickname', $_POST['nickname'] ); //Save Nickname
    update_user_meta( $user_id, 'gender', $_POST['gender'] );   //Save Gender
    update_user_meta( $user_id, 'specialty', $_POST['specialty'] ); //Save Specialty
    }
}           //end the function
update_basic_user_meta();   //call to the function
add_action('init', 'update_basic_user_meta'); // don't know is this necessary after calling the function but still add action of this function.
?>

Don't know if this is the right way, the main idea is, warp the form arround in a php function, then call to the function to let the form show up, when submit the form, php get the data with $_POST[].

As you @SallyCJ mentioned users should see what's already in the profile, thanks, indeed I will go further to add the get_user_meta() part to the form.

That's the progress I've got sofar, not pretty but it works.

Any way, should I call to add_action() again after call to(execute) the function? Still bothers me haha.

Thank you again. Really learned alot from your answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top