Use acf_form to update custom user fields

Today we are going to show you how to use acf_form to update custom user fields created with Advanced Custom Fields (ACF). We will create some custom fields using ACF then add the fields to a form on the front-end of the website. We will then demonstrate how to add, modify and save the custom user fields for the current user. The form will be processed using admin-post.php, which is the recommended way to process form data in WordPress. Let’s get started!

Creating Custom Fields

The first thing we must do is create the custom fields in ACF. Select “Custom Fields” from the main menu and select “Add New” at the top of the page. We will call our custom field group “User Profile”. Next, add a field to the newly created group and name it “Profile Image” and make the field type “Image”. The last thing to do here is to set the display rules. I have selected to show the field group when the “Add/Edit User Form” is displayed. This will ensure that the field group shows up on the user’s profile page in the admin area.

Now that we have created our custom field group, it’s time to add the form to our page template. In order to make sure our form displays and functions correctly, we must ensure all ACF scripts and styles are enqueued by adding the following line to the top of your template file.

acf_form_head();

To tell acf_form which fields to display, we must first find the IDs for the Field and Field Group you just created. Navigate to the edit page for the “User Profile” custom field and select “Screen Options” near the top of the page. To show the Field Group ID make sure “Slug” is checked. To show the Field IDs, make sure that “Field Keys” is checked. The field keys will now be displayed next to each individual Field and the Field Group ID will be displayed under “Slug” near the bottom of the page. The Field Group ID should look something like group_5cbd99ef0f584 and the Field IDs should look something like field_5cbd99f3922ce.

Setting up acf_form

Now we must create an array called “options”, that we will pass to acf_form() allowing us to customise the form. The “options” array accepts either a “field_groups” or “fields” index to determine which fields to display. Use one of the IDs you found in the last step to set either the “fields” or “field_groups” index. In our example, we have used the “fields” index, but it is up to you which one you choose. Paste the below code into your template file, making sure to substitute the Field or Group ID you found in the last step.

$user = wp_get_current_user();

$options = array(
  // 'field_groups' => ['group_5cbd99ef0f584'],
  'fields' => ['field_5cbd99f3922ce'],
  'form_attributes' => array(
    'method' => 'POST',
    'action' => admin_url("admin-post.php"),
  ),
  'html_before_fields' => sprintf(
    '<input type="hidden" name="action" value="adaptiveweb_save_profile_form">
    <input type="hidden" name="user_id" value="user_%s">',
    $user->ID
  ),
  'post_id' => "user_{$user->ID}",
  'form' => true,
  'html_submit_button' => '<button type="submit" class="acf-button button button-primary button-large" value="Update Profile">Update Profile</button>',
);

acf_form($options);

In order to make sure the form data is saved to the current user, the post_id index must be in the format “user_{$user_id}”. To get the current user_id we use the wp_get_current_user() function. The following snippet shows how to get the current user_id.

$user = wp_get_current_user();
$user_id = $user->ID;

We make the “form” index true so that ACF creates all the form markup for us using the options we pass to acf_form(). We also create a custom submit button by adding the markup to the “html_submit_button” index.

As we mentioned earlier, we will be processing the form the recommended way, using admin-post.php. To learn more about this method of processing forms in WordPress, you can read our post Handle POST and GET requests in WordPress using admin-post.php.

Processing the form

Next, we will create a custom function to save the user’s data. The following function will be called when a form is submitted with a (usually hidden) field with the name “action” with a value of “adaptiveweb_save_profile_form”. The function gets the user_id from the form data and calls the ‘acf/save_post’ action passing the user_id as the second parameter. Place this function in your functions.php file.

add_action( 'admin_post_adaptiveweb_save_profile_form', 'adaptiveweb_save_profile_form' );
function adaptiveweb_save_profile_form() {
  if(!isset($_REQUEST['user_id'])) return;

  do_action('acf/save_post', $_REQUEST['user_id']);

  wp_redirect(add_query_arg('updated', 'success', wp_get_referer()));
  exit;
}

In order to call this function when the form is submitted, we must use the “form_attributes” and “html_before_fields” indexes of the options array that we pass to acf_form(). We add an array to the “form_attributes” index with 2 indexes, method and action. The action index calls the script ‘wp-admin/admin-post.php’ using the admin_url function. We pass a string to the “html_before_fields” index with a hidden input field named action with the value adaptiveweb_save_profile_form as well as a hidden field named user_id with a value of $user->ID. Now when the form is submitted, the custom function we created will be called and the form data will be saved to the current user.

So there you have it, we have learned how to use acf_form to update custom user fields using a custom front-end form. If there is anything I have missed, please feel free to leave a comment. Thanks for reading!

References