Using ACF Forms to manage third party metadata for posts or users

Out of the box, Advanced Forms Pro makes it really easy to map ACF field data submitted with a form to whatever post or page is being created or updated. Even if the ACF fields aren’t set up on the post/user, the data will be there in the database in the relevant meta table.

There may be times, however, where you need a form field to control data of a different nature. Perhaps you are using an ACF form to manage metadata in a WooCommerce product or maybe you need to manipulate metadata that is controlled and used by a membership plugin such as MemberPress or Restrict Content Pro.

Whilst there aren’t currently controls that make this possible via the admin UI, I’m going to demonstrate how you could do this using a few of the useful filters available to us in Advanced Forms Pro. In this example, I’m going to demonstrate this in the context of user creation and editing. We’ll whip up a form that takes a name, email, and a status field and creates/edits a WordPress user and in the process, we’ll cover the following techniques:

  1. How to use an ACF form to create new users.
  2. How to use an ACF form to edit existing users.
  3. How to intercept the ACF form data and store the status field under an alternative meta key.
  4. How to prefill the ACF fields in the form on page load so that the data from the alternative meta key is loaded, ready to edit.

User management using ACF forms

Creating the form and assigning ACF fields

First things first, let’s create our form. With Advanced Forms Pro installed, this is simply a case of heading to the WordPress admin, hovering over Forms in the left menu, then clicking the Add New link. Give the form a name and fill in the basics. Mine looks like the following:

From here, we need to add some fields to the form by setting up a new field group and setting this form as its location. Hit the blue publish button to the right of the screen to save the form in its current state and scroll down to the Fields meta box. This is what you are looking for:

The Advanced Forms Pro ‘Fields’ meta box indicates which ACF field groups will render on this form.

Click the Create field group button, give the field group a name, and set up some fields. For this example, I’m going with name, email, and status but you can go with whatever makes sense for your project. In addition to the fields, I’ve selected the form I created in the field group location settings. Here’s a look at my field group:

The ACF field group set up to render on our ACF form for user management

Now you can publish the field group and return to the form edit screen where we can further configure our form. At this point, the form’s Fields meta box will have fields in it as per the following screenshot:

From here, all we need to do is configure our form to create/edit users. Head to the Editing tab under the Form settings meta box and enable user creation. Assign whatever role makes sense and be sure to map the essential fields that appear under Field mappings. Here’s a look at the settings I’ve used on the form for this example:

Once your fields are set up, click the blue Update button on the right hand side of the page to save the form. You now have a form that is capable of creating new users and editing existing users.

Let’s move on and learn how to place the form on the site for the two different use cases.

Creating new users

Creating new users is as simple as placing the form on a page. The easiest way to do this is via the shortcode which you can copy and paste from the form edit screen:

The Advanced Forms Pro shortcode for rendering forms inside content areas that support shortcodes.

For the sake of this example, I’m using the shortcode within a basic WordPress page. Here’s how the shortcode looks in the post edit screen:

And when it renders on the front end, it’s an empty form:

At this point, when you enter details into that form, a new user is created from the data submitted.

Editing existing users

Advanced Forms Pro also provides support for editing existing users/posts. If you simply want the form to allow the current logged in user to edit their own data, you can pass the user="current" attribute to the shortcode as follows:

[advanced_form form="form_5f8f5999245e0" user="current"]

When Advanced Forms Pro renders the form, it’ll understand that the current user’s data needs to be loaded into the form ready to edit.

You may, however, need to provide support for editing other users in the database. The shortcode’s user attribute can accept a user ID but for a more dynamic solution, you could consider using the af/form/args filter in combination with a custom URL parameter to load up and edit the user you need.

Here is a very simple approach to demonstrate how you would do this. This code would go in either a custom plugin or your theme’s functions.php file.

<?php
add_filter( 'af/form/args', 'afp_demo_support_dynamic_user_editing', 10, 2 );
/**
* @param array $args
* @param array $form
*
* @return array
*/
function afp_demo_support_dynamic_user_editing( $args, $form ) {
// If there is no query arg, return early.
if ( ! isset( $_GET['afp_edit_user'] ) ) {
return $args;
}
// You should consider adding capability checks here to ensure the
// current logged in user is allowed to edit the requested user.
// Extract the user ID from the custom query arg and add it to the
// form args.
$args['user'] = intval( $_GET['afp_edit_user'] );
return $args;
}

With this code in place, you can append the afp_edit_user parameter to the page URL along with a user ID as follows:

http://example.com/create-new-user/?afp_edit_user=123

In this example, data from the user ID of 123 will be used to prefill the form on page load. Furthermore, when the form is saved, the data will be stored against that user ID. This effectively gives you a profile edit form, a user edit form, a customer edit form, etc.

Mapping data to and from non-ACF controlled meta fields on form submission

If you have a situation where you wish to use an ACF form to modify data under a field key that isn’t represented by an ACF field, you can do this using a few hooks made available by the Advanced Forms Pro plugin.

In the following examples, we’ll be looking at the af/form/editing/user_created and af/form/editing/user_updated filters for user management but if you wish to apply this to posts, you’ll need to use the af/form/editing/post_created and af/form/editing/post_updated hooks instead.

In our example, we have three fields: name, email, and status. Name and email are already taken care of as these are mapped to core object fields but let’s say, for example, we want our status field to actually store as metadata under a different meta key. This could be a key we don’t control as it is introduced by a third party system such as a membership plugin or it might be metadata introduced by an eCommerce system such as WooCommerce.

For this example, we’ll use the field key membership_status.

There are two things to consider for this approach:

  1. We need to ensure our data is stored in the alternative location both when the user is created and edited.
  2. We need to ensure the field is pre-filled with the data from the alternative location on render.

Storing the status field under an alternative meta key

As demonstrated in the snippet below, we need to hook into two different filters to ensure we are updating the data both when a new user is created and when a user is updated. Fortunately, the callback for both of these hooks is the same so we only need to write one function.

In the callback function, we are doing the following:

  1. Checking to ensure we are intercepting the correct form using the form field key.
  2. Fetching the desired field value — in our case, status — from the submitted payload.
  3. Storing the value under an alternative user meta key.
<?php
add_action( 'af/form/editing/user_updated', 'afp_demo_store_additional_user_meta', 10, 3 );
add_action( 'af/form/editing/user_created', 'afp_demo_store_additional_user_meta', 10, 3 );
/**
* @param WP_User $user
* @param array $form
* @param array $args
*/
function afp_demo_store_additional_user_meta( $user, $form, $args ) {
// Only run on our desired form.
if ( $form['key'] !== 'form_5f8f5999245e0' ) {
return;
}
// Get the value from the submission.
$status = af_get_field( 'status' );
// If field value could not be retrieved, bail.
if ( $status === false ) {
return;
}
// Save the value in a custom user meta key.
update_user_meta( $user->ID, 'membership_status', $status );
}

Prefilling the ACF form field on form render so that the status field can be edited

Pre-filling the field is important when using the form to edit an existing record as we want to ensure any changes made to the record by other systems — perhaps WooCommerce, EDD, MemberPress, etc — are presented in the form.

Fortunately, Advanced Forms Pro provides a filter perfect for pre-filling the field values on form render. A complete example of pre-filling the status field is demonstrated below.

In the callback function, we’re doing the following:

  1. Checking to ensure we only run our code on the desired form.
  2. Retrieving the requested user ID.
  3. Looking up and returning the value we stored in our custom location.
<?php
add_filter( 'af/field/prefill_value', 'prefill_form_field', 10, 4 );
/**
* @param mixed $value
* @param array $field
* @param array $form
* @param array $args
*
* @return string
*/
function prefill_form_field( $value, $field, $form, $args ) {
// Only run on our desired form.
if ( $form['key'] !== 'form_5f8f5999245e0' ) {
return $value;
}
// If the user ID can't be determined, bail early and return the original value.
if ( ! isset( $args['user'] ) or ! is_numeric( $args['user'] ) ) {
return $value;
}
if ( $field['name'] === 'status' ) {
return get_user_meta( $args['user'], 'membership_status', true );
}
return $value;
}

We can now consider deactivating duplicate data

When we first set up our form, we chose to leave the Map all fields option enabled. This setting tells Advanced Forms Pro that it should store all field data and ACF key references in the relevant meta table for the post/user entry being created. In our case, because we are storing the value in an alternative location, we can deactivate this if we want to. This will help to reduce our data footprint and ensure we only have the value stored in one place.

Wrapping Up

In this article, we’ve explored some advanced usage of Advanced Forms Pro for user management and third-party plugin interaction. We’ve focused on managing users but these concepts can all be applied to post-management because the underlying systems are very similar and Advanced Forms Pro provides the same hooks and filters for both object types.

You now have the fundamental building blocks to build some pretty advanced systems using ACF forms. You could take this and apply it to user-submitted posts, user-submitted products, front-end profile- and post-editing, and even front-end user management systems.

References & Resources

About the author

Phil Kurth is a web developer living in Melbourne, Australia. Phil has a long history of WordPress development and enjoys building tools to empower others in their web design/development practice.

When not working with the web, Phil is usually spending time with his two young sons or is out hiking through the Australian bush.

Good dev stuff, delivered.

Product news, tips, and other cool things we make.

We never share your data. Read our Privacy Policy

© 2016 – 2024 Hookturn Digital. All rights reserved.