0

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.

4
  • WordPress doesn't have a function named current_user_id, so that should be get_current_user_id. – Sally CJ Oct 12 '20 at 3:29
  • @SallyCJ Thank you for your reply, I've change the current_user_id to get_current_user_id(), but still not wok TT. – Duke Yin Oct 12 '20 at 8:39
  • I believe there are something wrong with this code, is it because of the "action="..."" part? So what is the right way to send html form data to php? – Duke Yin Oct 12 '20 at 8:41
  • Have a look at my answer. Let me know. – Sally CJ Oct 12 '20 at 12:32
1

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;
            }
        }
    }
    
1
  • Thank you Sally, there are a lot to say, so I started a new answer below. – Duke Yin Oct 12 '20 at 13:04
0

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.

2
  • I appreciate your efforts, but the form should be separated from the function which updates the user's metadata, and form processing should be done on page load (so that if needed, actions like redirection and setting cookies would work without issues like "headers already sent"). So for example, put the form in a function named my_form and call it in your template, then just keep the add_action() call as is, but don't explicitly call the function which updates the user's metadata - because the function is already hooked to init and be called automatically on page load. – Sally CJ Oct 12 '20 at 13:52
  • 1
    @SallyCJ Thanks, you are right, after couple of test, the “redirection” problem shows up LOL, I will start from beginning and keep trying, and I will put the final pieces here after everything goes fine. Big thanks. – Duke Yin Oct 12 '20 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.