How to allow registered users to change their user role through frontend?

From time to time i want to give my registered users the chance to upgrade their user role by themselves for free. I tried this by writing a little plugin, but sady i can’t get the html form to show when using the shortcode, and therefore cant test if it works or not. I would be really thankful for any assistance.

function upgrade_to_premium() {
    if( is_user_logged_in() ) {
        if( is_page( 'upgrade-to-premium' ) ) {
            $current_user = wp_get_current_user();
            if( $current_user->roles[0] == "subscriber" || $current_user->roles[0] == "premium" ) {
                $user_id = $current_user->id;
                $role = $current_user->roles[0];
                if( $_POST['role']){
                    if( $_POST['role'] == $role ) {
                        echo "Sorry, you are already a " . $role . "!";
                    } else {
                        $role = $_POST['role'];
                        $userdata = array();
                        $userdata['ID'] = $user_id;
                        $userdata['role'] = $role;
                        wp_update_user($userdata);
                        echo "Your user type has been changed!  You are now a " . $role . "!";
                    }
                }
                ?>

                    <form method="post" action="">
                        Please select a role:<br/>
                        <select name="role">
                            <option value="subscriber" selected="selected">Subscriber</option>
                            <option value="premium">Premium</option>
                        </select>
                        <INPUT TYPE="submit" name="submit" />
                    </form>

                <?php
            }
        }
    }
}
add_shortcode( 'upgrade_to_premium', 'upgrade_to_premium' );

1 Answer
1

I’ve edited the code a bit and this works on my localhost. Try it and let me know if it does the job.

Be careful to edit your own admin role though. Or put in another condition to prevent updating your admin role in case of a use error.

Edit: added ob_start() thanks to Mark Kaplun. Shortcodes need to be returned not echoed.

add_shortcode( 'upgrade_to_premium', 'upgrade_to_premium' );
function upgrade_to_premium() {

    // Stop if user is not logged in.
    if ( ! is_user_logged_in() )
        return;

    ob_start();

    ?>

    <form method="post" action="">
        Please select a role:<br/>
        <select name="role">
            <option value="subscriber" selected="selected">Subscriber</option>
            <option value="premium">Premium</option>
        </select>
        <input type="submit" name="submit" />
    </form>

    <?php

    // Do not process anything if it's not $_POST
    if ( ! isset( $_POST['role'] ) )
        return;

    // Never trust user input.
    $role = sanitize_key( $_POST['role'] );
    if ( ! in_array( $role, array( 'subscriber', 'premium' ) ) )
        return;

    // Get the user object
    $user = new WP_User( get_current_user_id() );
    $index = key( $user->roles );
    $user_role = $user->roles[ $index ];

    // User already got that user
    if ( $user_role == $role ) {

        echo sprintf( __( 'You already have %s role.' ), $role );

    } else {

        // update user role
        $user->set_role( $role );
        echo sprintf( __( 'Your role was changed to %s.' ), $role );

    }

    $output = ob_get_contents();
    ob_end_clean();
    return $output;
}

Leave a Comment