Signup fields via the REST API

With the purpose of adding parity between the web version and the REST API, we are introducing a minor breaking change in the next version of BuddyPress (v14.0.0 ) in how the BuddyPress REST API handles Signup XProfile fields.

In this article, I’ll try to explain what the change is, why is necessary, and how you can prepare your app for these changes which will be available when the new BuddyPress version is released.

What problem are we solving?

Currently, our REST API does not support getting Signup XProfile fields or saving them. This means that when creating a signup via the API, there is only one XProfile field available, the user_name argument. This argument is mapped to the required “Name (Primary)” field.

However, if a community administrator creates more custom Signup fields, they would not be able to use them via the REST API. This creates an incomplete experience for API consumers that need to have signup fields in their apps.

As part of the, not yet released, v14.0.0 version, we are changing this behavior. API consumers will be able to return the Signup XProfile fields, and send them while creating a signup via the API. 🥳

Fetch Signup fields

To fetch signup fields only, we introduced a new argument, signup_fields_only. Here is an example of a request to select the Signup group, using the XProfile Groups endpoint:

bp.apiRequest( {
  path: 'buddypress/v1/xprofile/groups',
  type: 'GET',
  data: {
    context: 'view',
    fetch_fields: true // <-- required, in this endpoint.
    signup_fields_only: true // <--- new argument.
  }
} ).done( function( data ) {
  return data; // <--- It returns the signup fields only.
} ).fail( function( error ) {
  return error;
} );

Here is an example of a request to select only the Signup fields, using the XProfile Fields endpoint:

bp.apiRequest( {
  path: 'buddypress/v1/xprofile/fields',
  type: 'GET',
  data: {
    context: 'view',
    signup_fields_only: true // <--- new argument.
  }
} ).done( function( data ) {
  return data; // <--- It returns the signup fields only.
} ).fail( function( error ) {
  return error;
} );

Send signup fields

While creating a signup via the API, a new argument, signup_field_data is required. This argument is mapped to the Signup fields (the order the field data is sent is not important).

bp.apiRequest( {
  path: 'buddypress/v1/signup',
  type: 'POST',
  data: {
    context: 'edit',
    user_login: 'testuser',
    user_email: 'test@user.mail',
    password: 'password' // Always use strong passwords, not like this one!
    "signup_field_data[0][field_id]": "36",
	"signup_field_data[0][value]": "Arabic, English",
	"signup_field_data[1][field_id]": "31",
	"signup_field_data[1][value]": "Sometimes, I never travel",
	"signup_field_data[2][field_id]": "35",
	"signup_field_data[2][value]": "This is some text for my profile.",
	"signup_field_data[3][field_id]": "1",
	"signup_field_data[3][value]": "New Profile",
	"signup_field_data[4][field_id]": "19",
	"signup_field_data[4][value]": "Option 01, Option 03",
  }
} ).done( function( data ) {
  return data;
} ).fail( function( error ) {
  return error;
} );

The most noticeable change is that required fields will be respected in the API now. If you send a request creating a signup without the required fields (or sending empty values for the required fields), the REST API will complain about it, just like the web version.

Here is an example of a failed request without a required field.

{
  "code": "bp_rest_signup_field_required",
  "data": {
    "status": 500
  },
  "message": "The CUSTOM field is required."
}

How to migrate

Now, how can you prepare for this change? If your project makes use of the now deprecated user_name argument, you’ll need to update your app to use the new signup_field_data argument when creating a signup via the REST API.

We haven’t updated our documentation yet with those changes, but here is the schema for the new argument:

"signup_field_data": {
  "description": "The XProfile field data for the new user.",
  "items": {
    "properties": {
      "field_id": {
        "description": "The XProfile field ID.",
        "required": true,
        "type": "integer",
      },
      "value": {
        "default": "",
        "description": "The value(s) (comma separated list of values needs to be used in case of multiple values) for the field data.",
        "required": true,
        "type": "string",
      },
      "visibility": {
        "default": "public",
        "description": "The visibility for the XProfile field.",
        "enum": [
          "public",
          "adminsonly",
          "loggedin",
          "friends"
        ],
        "required": false,
        "type": "string",
      }
    },
    "type": "object"
  },
}

The new field expects an array of data with the field_id, its value, and the visibility of the field.

Why do I need to move my code into the new signup_field_data?

One important goal of this change is to add parity with the web version. Keeping the new and the old argument user_name would defeat this purpose. It would also create unnecessary handling of fallbacks, and ultimately confusion.

A user could send the “Name (Primary)” field via user_name argument or using the new signup_field_data argument. Required fields would also not be truly required. Essentially, creating a lot of code to account for both situations.

It’s also accurate to say that the old behavior is a bug, not a feature (or at the very least an MVP of an MVP of an MVP). We are correcting this bug as part of this change.

=D

Untrash<\/a><\/li><\/ul><\/nav>","mentions":[],"mentionContext":"","commentCreated":"1716234439","hasChildren":false,"postStatus":null,"noprivUserName":"BP Dev-Chat Summary May 2, 2024 | BP Team Updates","noprivUserHash":"00000000000000000000000000000000","noprivUserURL":"https:\/\/bpdevel.wordpress.com\/2024\/05\/20\/bp-dev-chat-summary-may-2-2024\/"}],"postFormat":"standard","postMeta":{"isSticky":false},"postTerms":{"category":[{"label":"14.0","count":6,"link":"https:\/\/bpdevel.wordpress.com\/category\/development-notes\/14-0\/"},{"label":"Development Notes","count":31,"link":"https:\/\/bpdevel.wordpress.com\/category\/development-notes\/"},{"label":"rest-api","count":30,"link":"https:\/\/bpdevel.wordpress.com\/category\/rest-api\/"}],"post_tag":[{"label":"developers","count":7,"link":"https:\/\/bpdevel.wordpress.com\/tag\/developers\/"},{"label":"rest-api","count":2,"link":"https:\/\/bpdevel.wordpress.com\/tag\/rest-api\/"}],"post_format":[]},"pluginData":[],"isPage":false,"mentions":[],"mentionContext":"","isTrashed":false,"userLogin":"espellcaste","userNicename":"espellcaste"}]

Signups are becoming members only after validating their accounts

BuddyPress is using the $wpdb->signups table to manage signups since 2.0.0. This table which is only available into the WordPress Multisite DB schema is generated by BuddyPress on regular WordPress installs.

For 10 years we’ve been carrying on creating users to preserve backwards compatibility with 3rd party plugins relying on our “prehistorical” way of dealing with signups on regular WordPress configs, today we are finally deprecating this behavior to improve BuddyPress consistency and fix this 9 years old issue.

If you are still playing with the activation_key user meta and the {$wpdb->users}.user_status (which we used to set to 2 to mark a user as a signup), please update your code so that you now fully enjoy our BP Signups API.

In 14.0.0, we are throwing deprecation notices if you use the BP “prehistorical” way to deal with signups, but please note we will completely remove this code in 15.0.0.

Untrash<\/a><\/li><\/ul><\/nav>","mentions":[],"mentionContext":"","commentCreated":"1713700680","hasChildren":false,"postStatus":null,"noprivUserName":"Br\u00e8ve publi\u00e9e le 21\/04\/2024 \u00e0 13h57 – imath","noprivUserHash":"00000000000000000000000000000000","noprivUserURL":"https:\/\/imathi.eu\/2024\/04\/21\/5088\/"},{"type":"comment","id":"31615","postID":"5196","postTitleRaw":"Signups are becoming members only after validating their\u00a0accounts","cssClasses":"comment byuser comment-author-johnkirkham even thread-even depth-1","parentID":"0","contentRaw":"Untrash<\/a><\/li><\/ul><\/nav>","mentions":[],"mentionContext":"","commentCreated":"1713704580","hasChildren":false,"postStatus":null,"userLogin":"johnkirkham","userNicename":"johnkirkham"},{"type":"comment","id":"31618","postID":"5196","postTitleRaw":"Signups are becoming members only after validating their\u00a0accounts","cssClasses":"pingback odd alt thread-odd thread-alt depth-1","parentID":"0","contentRaw":"[…] has been fixed, 14.0.0 won\u2019t create users during a regular WP user registration, see this developer note for additional […]","contentFiltered":"

[\u2026] has been fixed, 14.0.0 won\u2019t create users during a regular WP user registration, see this developer note for additional [\u2026]<\/p>\n","permalink":"https:\/\/bpdevel.wordpress.com\/2024\/04\/21\/signups-are-becoming-members-only-after-validating-their-accounts\/#comment-31618","unixtime":1714633318,"loginRedirectURL":"https:\/\/bpdevel.wordpress.com\/wp-login.php?redirect_to=https%3A%2F%2Fbpdevel.wordpress.com%2F2024%2F04%2F21%2Fsignups-are-becoming-members-only-after-validating-their-accounts%2F%23comment-31618","approved":true,"isTrashed":false,"prevDeleted":"","editURL":null,"depth":1,"commentDropdownActions":"","commentFooterActions":"

The last_activity user metadata is not mirrored by default anymore as of BuddyPress 7.0.0

Hi BuddyPress Plugin/Theme developers,

Since BuddyPress 2.0.0, the primary storage location for the user last_activity information is the activity DB table. For backward compatibility reasons, we used to mirror that data into the usermeta DB table.

This means you could get the last date the user was active on the community site in 2 ways:

  • The right one using the bp_get_user_last_activity( $user_id ) function.
  • The deprecated one using bp_get_user_meta( $user_id, 'last_activity', false ) function.

Please note, starting in BuddyPress 7.0.0, we will stop mirroring the last_activity user metadata, meaning the only way to get the last date the user was active is by using bp_get_user_last_activity( $user_id ).

If your development absolutely needs this piece of information to also be available into the usermeta DB table, then you’ll need to use the following filter to keep it there:

add_filter( 'bp_use_legacy_user_query', '__return_true' );

To read more about this change, see #7882.

#7-0-0, #developers

Building Bridges between Students and Educators in Nepal

Arjun Bhattarai shares how he built the largest community website for students in Nepal at https://buddypress.org/2017/05/building-bridges-between-students-and-educators-in-nepal/

#case-study, #developers

A Community for Organising Sweden’s Largest Environmental NGO

Alexander Berthelsen shares his case study of the development journey through the years for Naturkontakt, Sweden’s Largest Environmental NGO, at https://buddypress.org/2017/05/naturkontakt-organising-swedens-largest-environmental-ngo/

#case-study, #developers

Largest Turkish Recipe Site Spiced Up with BuddyPress

Mustafa Uysal (Twitter: m_uysl) of Nefisyemektarifleri.com shares how they scale their BuddyPress site with ~2.2 Million users at https://buddypress.org/2017/05/largest-turkish-recipe-site-spiced-up-with-buddypress/

#case-study, #developers

Total Wellness Challenge: Fitness with BuddyPress

Tara Claeys (Twitter: design_tlc) of Design TLC, LLC kicks off our new series of BuddyPress case studies from Developers and Site Builders. Read all about it at Total Wellness Challenge: Fitness with BuddyPress

#case-study, #developers