Edit WordPress user profile with Gravity Forms

As I was working on a new WordPress site, I found myself in need of a page on the front end, to edit some user profile settings. Instead of building the form by hand I thought it was easier to use Gravity Forms, but it wasn’t as easy as I thought it was. I decided to write it all down and maybe help somebody out who wants to do the same thing.

For the sake of this example I will only use three fields, the users first and last name, display name and the website, but it’s not hard to add other fields as well.

Create the Gravity Forms form

We will create a form called “Edit profile”, nothing fancy happening here.
Create form

We create the three fields we want to edit:

  • First and Last name
  • Display name
  • Users website

When we create the fields we need to add a class to each field, we will be using that class name to identify the field. We could use the Field ID, but if we ever change the form, these field could possible change. We also need to set the option to populated the fields dynamically and enter the Field Parameter Name we want to use for these fields.

First and Last name
We give this field the title “Name” and use the normal format.
Fill the rest as shown in the screen shot.
Edit Form - Field Name

Display name
We give this field the title “Display name publicy” and remove the default values in the drop down.
Fill the rest as shown in the screen shot.
Edit Form - Field Display Name

Users website
We give this field the title “Website”.
Fill the rest as shown in the screen shot.
Edit Form - Field Website

Create a page

This is the easy part, in WordPress you need to create a page and insert the above form.

Write the needed code

You can add all the code to your theme’s functions.php

Set up action and filters


 * All actions and filters
function GF_setup_actions_filters() {
	$_gf_edit_profile_id =  RGFormsModel::get_form_id('Edit profile');
	add_filter('gform_pre_render_' . $_gf_edit_profile_id, 'GF_populate_profile_fields');
	add_action('gform_after_submission_' . $_gf_edit_profile_id, 'GF_update_profile', 100, 2);

Explanation of the above code.

  • Line 07: Get the ID of the form by using its name. This is the title we gave the form when we create it in Gravity Forms.
  • Line 08: This filter will only run for the selected form and call the function that will populate the fields before they are displayed.
  • Line 09: This action triggers after the user presses the submit button and calls the function that will update the WordPress meta fields.

Some helper functions

 * Setup the fields
 * @return array
function GF_get_profile_fields ()
	$_fields['first_name'] = array ( 'gf_index' => '1.3', 'wp_meta' => 'first_name' );
	$_fields['last_name'] = array ( 'gf_index' => '1.6', 'wp_meta' => 'last_name' );
	$_fields['display_name'] = array ( 'gf_index' => '3', 'wp_meta' => 'display_name' );
	$_fields['website'] = array ( 'gf_index' => '8', 'wp_meta' => 'user_url' );
	return $_fields;

Explanation of the above code
This is an array that makes it easier for the other functions.

  • The array key corresponds with the parameter name we gave the field
  • The “gf_index” is the “Field ID” of the fields as shown in the screenshots. The first and last name have special indices, the 1 indicates the “Field ID”, the .3 and .6 represent the First and Last name.
  • The “wp_meta” corresponds with the meta value as they exist in WordPress

Populate the fields

 * Populate the fields before display
 * @filter gform_pre_render_
function GF_populate_profile_fields ($form)
	$_gf_fields = GF_get_profile_fields();
	$_profileuser = wp_get_current_user();

	foreach ($form['fields'] as &$field) {

		if (strpos($field['cssClass'], 'profile-name') !== false) {
			$field['defaultValue']['1.3'] = $_profileuser->first_name;
			$field['defaultValue']['1.6'] = $_profileuser->last_name;

		if (strpos($field['cssClass'], 'profile-display-name') !== false) {
			$_public_display = array ();
			$_public_display['display_nickname'] = $_profileuser->nickname;
			$_public_display['display_username'] = $_profileuser->user_login;

			if (! empty($_profileuser->first_name))
				$_public_display['display_firstname'] = $_profileuser->first_name;

			if (! empty($_profileuser->last_name))
				$_public_display['display_lastname'] = $_profileuser->last_name;

			if (! empty($_profileuser->first_name) && ! empty($_profileuser->last_name)) {
				$_public_display['display_firstlast'] = $_profileuser->first_name . ' ' . $_profileuser->last_name;
				$_public_display['display_lastfirst'] = $_profileuser->last_name . ' ' . $_profileuser->first_name;

			if (! in_array($_profileuser->display_name, $_public_display)) // Only add this if it isn't duplicated elsewhere
				$_public_display = array ( 'display_displayname' => $_profileuser->display_name ) + $_public_display;

			$_public_display = array_map('trim', $_public_display);
			$_public_display = array_unique($_public_display);
			foreach ($_public_display as $id => $item) {
				$_is_selected = ($_profileuser->display_name == $item ? 1 : null);
				$choices[] = array ( 'text' => $item, 'value' => $item, 'isSelected' => $_is_selected );
			$field['choices'] = $choices;

		foreach ($_gf_fields as $gf_key => $info) {
			if (strpos($field['cssClass'], 'profile-' . $gf_key) !== false) {
				$field['defaultValue'] = $_profileuser->$info['wp_meta'];

	return $form;

Explanation of the above code

  • We go through all the fields in the form and based on the class name we take some action.
  • Each field is an array.
  • The class names are stored in the element named “cssClass”
  • We store the populated values in the element named “defaultValue”
  • Lines 14 & 15: Gravity Forms defines the name as one field, but it keeps the First and Last name separate by means of the index .3 and .6. In order to populate the fields we need to create an array in the “defaultValue”. The index used is made up by the “Field ID” and the .3 or .6.
  • Lines 40-44: The drop down values are not stored in the field “defaultValue” but they are stored in the field “choices”. This is associative array made up of “text”, “value” and “isSelected”. The latter one determines which of the values is selected by default.

Update after submission

 * Update the user's profile with information from the received profile GF.
 * run last - just to make sure that everything is fine and dandy.
 * @action gform_after_submission_
function GF_update_profile ($entry, $form)
	global $wpdb;

	if (! is_user_logged_in()) {

	$_user_id = get_current_user_id();
	$_user = new stdClass();
	$_user->ID = (int) $_user_id;
	$_userdata = get_userdata($_user_id);
	$_user->user_login = $wpdb->escape($_userdata->user_login);

	$gf_fields = GF_get_profile_fields();

	$_user->first_name = sanitize_text_field($entry[$gf_fields['first_name']['gf_index']]);
	$_user->last_name = sanitize_text_field($entry[$gf_fields['last_name']['gf_index']]);
	$_user->display_name = sanitize_text_field($entry[$gf_fields['display_name']['gf_index']]);

	$_user->user_url = esc_url_raw($entry[$gf_fields['website']['gf_index']]);
	$_user->user_url = preg_match('/^(https?):/is', $_user->user_url) ? $_user->user_url : 'http://' . $_user->user_url;


Explanation of the above code

    • After submission this function is called and all the new values are held in the array called “$entry”.
    • I’m not 100% sure if Gravity Forms sanitizes all the fields correctly, so I decided to use the WordPress functions to sanitize the fields.
    • Line 29 is actually not needed as Gravity Forms checks if the field start with HTTP before submitting the form.

Final Thoughts
And that’s it. I’m sure there are several improvements that can be made in the code and don’t hesitate to give idea’s on how to improve the code.
If you find yourself thinking you want this on your site and you need Gravity Forms, please follow my link to buy Gravity Forms.
If you aren’t a programmer and you want this implemented on your site you can contact me and we can see if we can work something out.

This article is filed under the categories Development » WordPress » Code Snippet and has the following tag associated with it: .
  • Hey, great post-I have been looking everywhere for this. I cannot believe Gravity Forms wouldn’t just put out an add-on for this. It seems so logical. I would have thought someone would have at least made a plugin for this or something.

    Is there a way to add the email and password fields to this? I am not good enough with php to do just by copying what you did, is there any other tutorial like this you know of that may also have those two fields?

  • Peter

    The behavior of WordPress when changing the email needs to be emulated, I haven’t had the change (aka no need to implement it right now) to write this up, but it needs to implemented for my client’s site at some point and I’ll post a follow up.
    The password isn’t that difficult but the same as above, I didn’t have a need to implement this yet, but will in a few weeks.

  • Okay, sounds good. I may post a few bucks on wpquestions to see if someone on there could do it and I’ll forward any results along.

    For the password part I was thinking it wouldn’t be pre-populated–instead leave it as blank boxes that would update the new one if the user types something in or ‘leave blank to keep same password’, do you think that would be best?

    • Peter

      Yes , no pre-population.
      For the password you need to add the following line in the function GF_setup_actions_filters, otherwise there is no password field.

      add_filter("gform_enable_password_field", create_function("", "return true;"));
  • Leland


    Any chance you could add your ideas for password changing verification and email field updating? This is really helpful.

    • Leland

      Tried adding user_email and user_login to this form using your example as a guide but the output is not the value as expected but simply “Array” in both input fields. Thoughts?

      • Peter

        As WordPress doesn’t allow you to change your login, I have a feeling that if you want to change the user_login, you need to do some coding to make sure nothing breaks.

        I don’t have time to write an article about the E-Mail and password until the last week of August, but I promise I’ll write something up.

  • Just wanted to drop by this post again, is there anyway you could drop in the password field?

  • Hi,

    Is there any way I can add custom fields to this? I have custom registration fields set up (Address, Phone, Business Name etc.) that are stored in the user_meta table. I tried adding them into the above code, but it doesn’t seem to work (assuming because the functions are only reading the wp_users table maybe?)

    Any help would be great!

  • Worth mentioning that the new beta release of Gravity Forms User-Registration add-on does this now! Neil – including the option to add and update meta fields.

    • Perfect! I just upgraded to that beta version and it’s working exactly as I need it to! Thanks for the heads up there Kyle.

    • Hi Kyle, can you please point me to the documentation for Editing the user profile with the new version of GF, like you mention is possible in your post above…

      I cannot find that functionality you mention documented.


  • Sure, it is the beta release of the User Registration Add-On (you need a developer license). It is the last one on this page: http://www.gravityhelp.com/downloads/add-ons/

  • This tutorial saved me from writing a custom utility for updating member information on a website. Thank you so much for putting it together.

    I did add some fields, of course. One of them was the email address. I’m still working out the bugs on that code but it will display. The issue that I’m having is updating that information. The site seems to think it is a duplicate, even though it updates the field.

    If anyone else has had this problem and solved it, I’d appreciate any hints you have. Otherwise, I’ll come back and let you know how I remedied the issue.

    • Peter

      What’s the code like for the function called by the action gform_after_submission_ ?
      Please use something like a gist at github, or pastebin.com for that code.

    • Kyle

      I had the same problem awhile back, try this: http://pastie.org/private/gvqvvzzcmgbpuhqcrrzsq

      You will need to update your Form Id and Field ID where you see the ##

  • Byron


    Thank you for your contribution I have the gravity form plugin 1.6.7 + user reg add-on + custom post types + members plugin and a bunch of others.

    However I need some guidance in setting up my site:

    I’ve setup a custom user registration form with a bunch of fields which needs to populate a page which the user will only see and update as needed.

    1) I’ve setup the reg form
    2) how do I go about entering the info to a page displayed specifically to the user that the user may edit in their profile?

    Please excuse me, I’m new to this and would appreciate your guidance.

    Thank you

  • I need to add a select options into user profile.
    I studied bees gravity forms but my script does not work …
    In the documentation is written that the select type has a property “choises” (is array), theoretically setting the property under “isSelected” to 1, the option that I decided I should be ” …. “but it is not ..
    Why should appear above the selected value in the update …
    Can you help me?

    My source code:
    add_filter(“gform_pre_render_1”, “populate_profile”);

    //Note: when changing drop down values, we also need to use the gform_admin_pre_render so that the right values are displayed when editing the entry.
    //add_filter(“gform_admin_pre_render_1”, “populate_profile”);

    function populate_profile($form) {

    $result = array(
    1 => array(‘adminOnly’ => 0, ‘isRequired’ => 0, ‘allowsPrepopulate’ => 1),
    2 => array(‘adminOnly’ => 0, ‘isRequired’ => 0, ‘allowsPrepopulate’ => 1),
    3 => array(‘adminOnly’ => 0, ‘isRequired’ => 0, ‘allowsPrepopulate’ => 1),
    4 => array(‘adminOnly’ => 0, ‘isRequired’ => 0, ‘allowsPrepopulate’ => 1),
    5 => array(‘adminOnly’ => 0, ‘isRequired’ => 0, ‘allowsPrepopulate’ => 1),
    6 => array(‘adminOnly’ => 0, ‘isRequired’ => 0, ‘allowsPrepopulate’ => 1)

    $user_id = get_current_user_id();

    foreach ($form[“fields”] as &$field) {

    //echo “”;

    $id = (int) $field[“id”];
    $properties = (array) $result[$id];

    foreach ($properties as $name => $value) {
    $field[$name] = $value;

    $user_value = get_user_meta($user_id, ‘field_’ . $id, TRUE);

    switch ($field[‘type’]) {

    case ‘select’:
    echo ‘type: select, ID: ‘ . $field[‘id’] . ”;
    choices_selected($field[‘choices’], ‘value’, $user_value);
    case ‘radio’:
    echo ‘type: radio, ID: ‘ . $field[‘id’] . ”;
    choices_selected($field[‘choices’], ‘text’, $user_value);
    case ‘checkbox’:
    echo ‘type: checkbox, ID: ‘ . $field[‘id’] . ”;
    choices_selected($field[‘choices’], ‘text’, $user_value);
    default :
    $field[‘defaultValue’] = $user_value;

    return $form;

    function choices_selected($choices, $propertie, $u_value) {

    $found = FALSE;

    for ($i = 0; $i < count($choices) /* && !$found */; $i++) {

    if ($choices[$i][$propertie] == $u_value) {
    $choices[$i]['isSelected'] = 1;
    $found = TRUE;
    } else {
    $choices[$i]['isSelected'] = 0;

    echo "Choices [" . $i . '], value: [' . $choices[$i][$propertie] . '], isSelected [' . $choices[$i]['isSelected'] . ']’;

  • John-Henry Ross

    What is the security implications of using this code to update user info? Will it be fine if I have security certificates for my site? Or do I need to implement extra security?

    • Peter

      Not sure what you mean with security implications. If the front-end is not SSL data send to the server will not be encrypted. But the same is true for the admin side of WordPress.