Created
February 23, 2026 16:33
-
-
Save vapvarun/6a2f2e3d4cbae433f59776e2a7531909 to your computer and use it in GitHub Desktop.
Custom BuddyPress Profile Fields - xprofile API Developer Guide (bpcustomdev.com)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // Core xprofile tables in the database | |
| global $wpdb; | |
| $bp = buddypress(); | |
| $groups_table = $bp->profile->table_name_groups; // bp_xprofile_groups | |
| $fields_table = $bp->profile->table_name_fields; // bp_xprofile_fields | |
| $data_table = $bp->profile->table_name_data; // bp_xprofile_data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Create a custom profile field group. | |
| * Hook into bp_init to ensure BuddyPress is loaded. | |
| */ | |
| function bpcdev_create_profile_groups() { | |
| // Check if the group already exists to avoid duplicates | |
| $groups = bp_xprofile_get_groups( array( | |
| 'fetch_fields' => false, | |
| ) ); | |
| $existing_names = wp_list_pluck( $groups, 'name' ); | |
| if ( ! in_array( 'Professional Details', $existing_names, true ) ) { | |
| $group_id = xprofile_insert_field_group( array( | |
| 'name' => 'Professional Details', | |
| 'description' => 'Your work experience and professional background.', | |
| 'can_delete' => true, | |
| ) ); | |
| if ( $group_id ) { | |
| // Store the group ID in an option for reference | |
| update_option( 'bpcdev_professional_group_id', $group_id ); | |
| } | |
| } | |
| } | |
| add_action( 'bp_init', 'bpcdev_create_profile_groups' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Create multiple profile fields in the Professional Details group. | |
| */ | |
| function bpcdev_create_profile_fields() { | |
| $group_id = get_option( 'bpcdev_professional_group_id' ); | |
| if ( ! $group_id ) { | |
| return; | |
| } | |
| // Text field: Job Title | |
| $job_title_id = xprofile_get_field_id_from_name( 'Job Title' ); | |
| if ( ! $job_title_id ) { | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'name' => 'Job Title', | |
| 'description' => 'Your current role or position.', | |
| 'type' => 'textbox', | |
| 'field_order' => 1, | |
| 'is_required' => false, | |
| 'can_delete' => true, | |
| ) ); | |
| } | |
| // Select field: Experience Level | |
| $exp_id = xprofile_get_field_id_from_name( 'Experience Level' ); | |
| if ( ! $exp_id ) { | |
| $field_id = xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'name' => 'Experience Level', | |
| 'description' => 'How many years of experience do you have?', | |
| 'type' => 'selectbox', | |
| 'field_order' => 2, | |
| 'is_required' => false, | |
| 'can_delete' => true, | |
| ) ); | |
| // Add options for the select field | |
| if ( $field_id ) { | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'parent_id' => $field_id, | |
| 'type' => 'option', | |
| 'name' => 'Junior (0-2 years)', | |
| 'option_order' => 1, | |
| ) ); | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'parent_id' => $field_id, | |
| 'type' => 'option', | |
| 'name' => 'Mid-Level (3-5 years)', | |
| 'option_order' => 2, | |
| ) ); | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'parent_id' => $field_id, | |
| 'type' => 'option', | |
| 'name' => 'Senior (6-10 years)', | |
| 'option_order' => 3, | |
| ) ); | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'parent_id' => $field_id, | |
| 'type' => 'option', | |
| 'name' => 'Expert (10+ years)', | |
| 'option_order' => 4, | |
| ) ); | |
| } | |
| } | |
| // URL field: Portfolio Website | |
| $portfolio_id = xprofile_get_field_id_from_name( 'Portfolio Website' ); | |
| if ( ! $portfolio_id ) { | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'name' => 'Portfolio Website', | |
| 'description' => 'Link to your portfolio or personal website.', | |
| 'type' => 'url', | |
| 'field_order' => 3, | |
| 'is_required' => false, | |
| 'can_delete' => true, | |
| ) ); | |
| } | |
| // Checkbox field: Skills | |
| $skills_id = xprofile_get_field_id_from_name( 'Skills' ); | |
| if ( ! $skills_id ) { | |
| $field_id = xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'name' => 'Skills', | |
| 'description' => 'Select all that apply.', | |
| 'type' => 'checkbox', | |
| 'field_order' => 4, | |
| 'is_required' => false, | |
| 'can_delete' => true, | |
| ) ); | |
| if ( $field_id ) { | |
| $skills = array( 'PHP', 'JavaScript', 'Python', 'Design', 'Project Management', 'Marketing', 'Data Analysis' ); | |
| foreach ( $skills as $order => $skill ) { | |
| xprofile_insert_field( array( | |
| 'field_group_id' => $group_id, | |
| 'parent_id' => $field_id, | |
| 'type' => 'option', | |
| 'name' => $skill, | |
| 'option_order' => $order + 1, | |
| ) ); | |
| } | |
| } | |
| } | |
| } | |
| add_action( 'bp_init', 'bpcdev_create_profile_fields', 20 ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Custom Star Rating field type for BuddyPress xprofile. | |
| */ | |
| class BPCDev_Field_Type_Star_Rating extends BP_XProfile_Field_Type { | |
| /** | |
| * Constructor. | |
| */ | |
| public function __construct() { | |
| parent::__construct(); | |
| $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bpcustomdev' ); | |
| $this->name = _x( 'Star Rating', 'xprofile field type', 'bpcustomdev' ); | |
| $this->set_format( '/^[1-5]$/', 'replace' ); | |
| do_action( 'bp_xprofile_field_type_star_rating', $this ); | |
| } | |
| /** | |
| * Output the edit field HTML for user profile editing. | |
| * | |
| * @param array $raw_properties Optional key/value array. | |
| */ | |
| public function edit_field_html( array $raw_properties = array() ) { | |
| $user_id = bp_displayed_user_id(); | |
| if ( isset( $raw_properties['user_id'] ) ) { | |
| $user_id = (int) $raw_properties['user_id']; | |
| } | |
| $field_value = (int) BP_XProfile_ProfileData::get_value_byid( | |
| $this->field_obj->id, | |
| $user_id | |
| ); | |
| ?> | |
| <legend> | |
| <?php bp_the_profile_field_name(); ?> | |
| <?php bp_the_profile_field_required_label(); ?> | |
| </legend> | |
| <?php do_action( bp_get_the_profile_field_errors_action() ); ?> | |
| <div class="bpcdev-star-rating" data-field-id="<?php echo esc_attr( $this->field_obj->id ); ?>"> | |
| <?php for ( $i = 1; $i <= 5; $i++ ) : ?> | |
| <label class="bpcdev-star <?php echo $i <= $field_value ? 'active' : ''; ?>"> | |
| <input | |
| type="radio" | |
| name="<?php echo esc_attr( bp_get_the_profile_field_input_name() ); ?>" | |
| value="<?php echo esc_attr( $i ); ?>" | |
| <?php checked( $field_value, $i ); ?> | |
| /> | |
| ★ | |
| </label> | |
| <?php endfor; ?> | |
| </div> | |
| <?php if ( bp_get_the_profile_field_description() ) : ?> | |
| <p class="description"> | |
| <?php bp_the_profile_field_description(); ?> | |
| </p> | |
| <?php endif; ?> | |
| <?php | |
| } | |
| /** | |
| * Output the admin field HTML. | |
| * | |
| * @param array $raw_properties Optional key/value array. | |
| * @param int $user_id ID of the user. | |
| */ | |
| public function admin_field_html( array $raw_properties = array(), $user_id = 0 ) { | |
| $field_value = (int) BP_XProfile_ProfileData::get_value_byid( | |
| $this->field_obj->id, | |
| $user_id | |
| ); | |
| echo '<select ' . $this->get_edit_field_html_elements( $raw_properties ) . '>'; | |
| echo '<option value="">--</option>'; | |
| for ( $i = 1; $i <= 5; $i++ ) { | |
| printf( | |
| '<option value="%1$d" %2$s>%1$d Star%3$s</option>', | |
| $i, | |
| selected( $field_value, $i, false ), | |
| $i > 1 ? 's' : '' | |
| ); | |
| } | |
| echo '</select>'; | |
| } | |
| /** | |
| * Output HTML for this field type on the wp-admin Profile Fields screen. | |
| * | |
| * @param BP_XProfile_Field $current_field The current profile field. | |
| * @param string $control_type Optional. HTML input type. Default: 'select'. | |
| */ | |
| public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { | |
| $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); | |
| if ( false === $type ) { | |
| return; | |
| } | |
| echo '<p>' . esc_html__( 'A 1-5 star rating field. No additional options needed.', 'bpcustomdev' ) . '</p>'; | |
| } | |
| } | |
| /** | |
| * Register the custom field type with BuddyPress. | |
| */ | |
| function bpcdev_register_star_rating_field_type( $fields ) { | |
| $fields['star_rating'] = 'BPCDev_Field_Type_Star_Rating'; | |
| return $fields; | |
| } | |
| add_filter( 'bp_xprofile_get_field_types', 'bpcdev_register_star_rating_field_type' ); | |
| /** | |
| * Enqueue styles for the star rating field. | |
| */ | |
| function bpcdev_star_rating_styles() { | |
| if ( ! bp_is_user_profile_edit() && ! bp_is_register_page() && ! bp_is_user_profile() ) { | |
| return; | |
| } | |
| $css = ' | |
| .bpcdev-star-rating { display: flex; gap: 4px; font-size: 24px; } | |
| .bpcdev-star-rating input[type="radio"] { display: none; } | |
| .bpcdev-star { cursor: pointer; color: #ccc; transition: color 0.2s; } | |
| .bpcdev-star.active, .bpcdev-star:hover { color: #f5a623; } | |
| '; | |
| wp_add_inline_style( 'bp-member-block', $css ); | |
| } | |
| add_action( 'wp_enqueue_scripts', 'bpcdev_star_rating_styles' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // Get a single field value for a specific user | |
| $job_title = xprofile_get_field_data( 'Job Title', $user_id ); | |
| // Get a field value by field ID (faster, avoids name lookup) | |
| $field_id = xprofile_get_field_id_from_name( 'Job Title' ); | |
| $job_title = xprofile_get_field_data( $field_id, $user_id ); | |
| // Get all field data for a user (returns array of groups with fields) | |
| $profile_data = BP_XProfile_ProfileData::get_all_for_user( $user_id ); | |
| // Get raw value (unformatted, useful for checkboxes/multi-select) | |
| $raw_value = BP_XProfile_ProfileData::get_value_byid( $field_id, $user_id ); | |
| // Check if a field has data for a user | |
| $has_data = xprofile_check_is_required_field( $field_id ) | |
| && ! empty( xprofile_get_field_data( $field_id, $user_id ) ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // Set a field value for a user | |
| xprofile_set_field_data( 'Job Title', $user_id, 'Senior Developer' ); | |
| // Set by field ID | |
| xprofile_set_field_data( $field_id, $user_id, 'Senior Developer' ); | |
| // Set a multi-value field (checkbox, multi-select) | |
| xprofile_set_field_data( 'Skills', $user_id, array( 'PHP', 'JavaScript', 'Python' ) ); | |
| // Set a date field | |
| xprofile_set_field_data( 'Birthday', $user_id, '1990-06-15 00:00:00' ); | |
| // Delete a field's data for a user | |
| xprofile_delete_field_data( 'Job Title', $user_id ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Find all users with a specific field value. | |
| * | |
| * @param string $field_name The profile field name. | |
| * @param mixed $value The value to search for. | |
| * @return array Array of user IDs. | |
| */ | |
| function bpcdev_get_users_by_field_value( $field_name, $value ) { | |
| global $wpdb; | |
| $bp = buddypress(); | |
| $field_id = xprofile_get_field_id_from_name( $field_name ); | |
| if ( ! $field_id ) { | |
| return array(); | |
| } | |
| $user_ids = $wpdb->get_col( | |
| $wpdb->prepare( | |
| "SELECT user_id FROM {$bp->profile->table_name_data} | |
| WHERE field_id = %d AND value = %s", | |
| $field_id, | |
| $value | |
| ) | |
| ); | |
| return array_map( 'intval', $user_ids ); | |
| } | |
| // Usage: Find all Senior Developers | |
| $senior_devs = bpcdev_get_users_by_field_value( 'Job Title', 'Senior Developer' ); | |
| // For multi-value fields (serialized data), use LIKE | |
| function bpcdev_get_users_by_skill( $skill ) { | |
| global $wpdb; | |
| $bp = buddypress(); | |
| $field_id = xprofile_get_field_id_from_name( 'Skills' ); | |
| if ( ! $field_id ) { | |
| return array(); | |
| } | |
| return $wpdb->get_col( | |
| $wpdb->prepare( | |
| "SELECT user_id FROM {$bp->profile->table_name_data} | |
| WHERE field_id = %d AND value LIKE %s", | |
| $field_id, | |
| '%' . $wpdb->esc_like( $skill ) . '%' | |
| ) | |
| ); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // Set the default visibility for a field | |
| $field_id = xprofile_get_field_id_from_name( 'Phone Number' ); | |
| xprofile_set_field_visibility_level( $field_id, $user_id, 'friends' ); | |
| // Set the allowed visibility levels for a field | |
| // This controls which options users see in their privacy settings | |
| $field = xprofile_get_field( $field_id ); | |
| bp_xprofile_update_field_meta( $field_id, 'allow_custom_visibility', 'allowed' ); | |
| bp_xprofile_update_field_meta( $field_id, 'default_visibility', 'loggedin' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Conditional field visibility based on user role and field values. | |
| * | |
| * Show "Company Name" and "Company Size" only if the user's | |
| * "Account Type" field is set to "Business". | |
| */ | |
| function bpcdev_conditional_field_visibility( $field_id, $field ) { | |
| // Define conditional rules: field_name => required_field_value | |
| $conditional_rules = array( | |
| 'Company Name' => array( | |
| 'depends_on' => 'Account Type', | |
| 'show_when' => 'Business', | |
| ), | |
| 'Company Size' => array( | |
| 'depends_on' => 'Account Type', | |
| 'show_when' => 'Business', | |
| ), | |
| 'Student ID' => array( | |
| 'depends_on' => 'Account Type', | |
| 'show_when' => 'Student', | |
| ), | |
| ); | |
| $field_name = $field->name; | |
| if ( ! isset( $conditional_rules[ $field_name ] ) ) { | |
| return; // No conditional rule for this field. | |
| } | |
| $rule = $conditional_rules[ $field_name ]; | |
| $user_id = bp_displayed_user_id() ?: bp_loggedin_user_id(); | |
| $parent_value = xprofile_get_field_data( $rule['depends_on'], $user_id ); | |
| if ( $parent_value !== $rule['show_when'] ) { | |
| // Hide the field by adding a CSS class | |
| echo '<style>#field_' . esc_attr( $field_id ) . ' { display: none; }</style>'; | |
| } | |
| } | |
| add_action( 'bp_custom_profile_edit_fields_pre_visibility', 'bpcdev_conditional_field_visibility', 10, 2 ); | |
| /** | |
| * Role-based field visibility. | |
| * | |
| * Only show certain fields to users with specific roles. | |
| */ | |
| function bpcdev_role_based_field_visibility( $has_data, $field ) { | |
| $role_restricted_fields = array( | |
| 'Internal Notes' => array( 'administrator', 'editor' ), | |
| 'Employee ID' => array( 'administrator', 'hr_manager' ), | |
| 'Security Clearance'=> array( 'administrator' ), | |
| ); | |
| if ( ! isset( $role_restricted_fields[ $field->name ] ) ) { | |
| return $has_data; | |
| } | |
| $current_user = wp_get_current_user(); | |
| $allowed_roles = $role_restricted_fields[ $field->name ]; | |
| if ( ! array_intersect( $current_user->roles, $allowed_roles ) ) { | |
| return false; // Hide the field for this user's role. | |
| } | |
| return $has_data; | |
| } | |
| add_filter( 'bp_xprofile_field_has_data', 'bpcdev_role_based_field_visibility', 10, 2 ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Enqueue conditional field JavaScript on profile edit pages. | |
| */ | |
| function bpcdev_enqueue_conditional_fields_js() { | |
| if ( ! bp_is_user_profile_edit() && ! bp_is_register_page() ) { | |
| return; | |
| } | |
| $conditional_rules = array( | |
| array( | |
| 'trigger_field' => 'Account Type', | |
| 'trigger_value' => 'Business', | |
| 'target_fields' => array( 'Company Name', 'Company Size', 'Industry' ), | |
| ), | |
| array( | |
| 'trigger_field' => 'Account Type', | |
| 'trigger_value' => 'Student', | |
| 'target_fields' => array( 'Student ID', 'University', 'Graduation Year' ), | |
| ), | |
| ); | |
| // Convert field names to field IDs for the JS | |
| $rules_with_ids = array(); | |
| foreach ( $conditional_rules as $rule ) { | |
| $trigger_id = xprofile_get_field_id_from_name( $rule['trigger_field'] ); | |
| $target_ids = array(); | |
| foreach ( $rule['target_fields'] as $target_name ) { | |
| $tid = xprofile_get_field_id_from_name( $target_name ); | |
| if ( $tid ) { | |
| $target_ids[] = $tid; | |
| } | |
| } | |
| if ( $trigger_id && $target_ids ) { | |
| $rules_with_ids[] = array( | |
| 'trigger_id' => $trigger_id, | |
| 'trigger_value' => $rule['trigger_value'], | |
| 'target_ids' => $target_ids, | |
| ); | |
| } | |
| } | |
| wp_add_inline_script( 'bp-legacy-js', ' | |
| (function() { | |
| var rules = ' . wp_json_encode( $rules_with_ids ) . '; | |
| function applyRules() { | |
| rules.forEach(function(rule) { | |
| var trigger = document.getElementById("field_" + rule.trigger_id); | |
| if (!trigger) return; | |
| var value = trigger.value; | |
| var show = (value === rule.trigger_value); | |
| rule.target_ids.forEach(function(targetId) { | |
| var wrapper = document.getElementById("field_" + targetId); | |
| if (wrapper) { | |
| wrapper.closest(".editfield").style.display = show ? "" : "none"; | |
| } | |
| }); | |
| }); | |
| } | |
| document.addEventListener("DOMContentLoaded", function() { | |
| applyRules(); | |
| rules.forEach(function(rule) { | |
| var trigger = document.getElementById("field_" + rule.trigger_id); | |
| if (trigger) { | |
| trigger.addEventListener("change", applyRules); | |
| } | |
| }); | |
| }); | |
| })(); | |
| ' ); | |
| } | |
| add_action( 'wp_enqueue_scripts', 'bpcdev_enqueue_conditional_fields_js' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // Inside a BuddyPress members loop or single member template | |
| if ( bp_has_profile( array( 'user_id' => bp_get_member_user_id() ) ) ) : | |
| while ( bp_profile_groups() ) : bp_the_profile_group(); | |
| while ( bp_profile_fields() ) : bp_the_profile_field(); | |
| if ( bp_field_has_data() ) : | |
| echo '<div class="profile-field">'; | |
| echo '<strong>' . bp_get_the_profile_field_name() . ':</strong> '; | |
| echo bp_get_the_profile_field_value(); | |
| echo '</div>'; | |
| endif; | |
| endwhile; | |
| endwhile; | |
| endif; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Display a member card with xprofile data. | |
| * | |
| * @param int $user_id The user ID. | |
| */ | |
| function bpcdev_render_member_card( $user_id ) { | |
| $name = bp_core_get_user_displayname( $user_id ); | |
| $avatar = bp_core_fetch_avatar( array( | |
| 'item_id' => $user_id, | |
| 'type' => 'thumb', | |
| 'html' => true, | |
| ) ); | |
| $job_title = xprofile_get_field_data( 'Job Title', $user_id ); | |
| $skills = xprofile_get_field_data( 'Skills', $user_id ); | |
| $profile_url = bp_members_get_user_url( $user_id ); | |
| ?> | |
| <div class="bpcdev-member-card"> | |
| <div class="member-avatar"> | |
| <a href="<?php echo esc_url( $profile_url ); ?>"><?php echo $avatar; ?></a> | |
| </div> | |
| <div class="member-info"> | |
| <h3><a href="<?php echo esc_url( $profile_url ); ?>"><?php echo esc_html( $name ); ?></a></h3> | |
| <?php if ( $job_title ) : ?> | |
| <p class="job-title"><?php echo esc_html( $job_title ); ?></p> | |
| <?php endif; ?> | |
| <?php if ( $skills ) : ?> | |
| <div class="skills"> | |
| <?php | |
| $skills_array = is_array( $skills ) | |
| ? $skills | |
| : explode( ',', $skills ); | |
| foreach ( $skills_array as $skill ) : | |
| ?> | |
| <span class="skill-tag"><?php echo esc_html( trim( $skill ) ); ?></span> | |
| <?php endforeach; ?> | |
| </div> | |
| <?php endif; ?> | |
| </div> | |
| </div> | |
| <?php | |
| } | |
| // Usage in any template | |
| bpcdev_render_member_card( 42 ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Shortcode to display any xprofile field value. | |
| * | |
| * Usage: [bp_field name="Job Title" user_id="42"] | |
| * If user_id is omitted, uses the currently displayed user. | |
| */ | |
| function bpcdev_profile_field_shortcode( $atts ) { | |
| $atts = shortcode_atts( array( | |
| 'name' => '', | |
| 'user_id' => bp_displayed_user_id(), | |
| ), $atts ); | |
| if ( empty( $atts['name'] ) || empty( $atts['user_id'] ) ) { | |
| return ''; | |
| } | |
| $value = xprofile_get_field_data( $atts['name'], (int) $atts['user_id'] ); | |
| if ( is_array( $value ) ) { | |
| return esc_html( implode( ', ', $value ) ); | |
| } | |
| return esc_html( $value ); | |
| } | |
| add_shortcode( 'bp_field', 'bpcdev_profile_field_shortcode' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Get a cached profile field value with fallback to database. | |
| * | |
| * @param int $field_id The field ID. | |
| * @param int $user_id The user ID. | |
| * @param string $group Cache group name. | |
| * @return mixed The field value. | |
| */ | |
| function bpcdev_get_cached_field_value( $field_id, $user_id, $group = 'bpcdev_xprofile' ) { | |
| $cache_key = "field_{$field_id}_user_{$user_id}"; | |
| $value = wp_cache_get( $cache_key, $group ); | |
| if ( false === $value ) { | |
| $value = xprofile_get_field_data( $field_id, $user_id ); | |
| wp_cache_set( $cache_key, $value, $group, HOUR_IN_SECONDS ); | |
| } | |
| return $value; | |
| } | |
| /** | |
| * Invalidate cache when profile data is updated. | |
| */ | |
| function bpcdev_invalidate_field_cache( $field_id, $user_id ) { | |
| $cache_key = "field_{$field_id}_user_{$user_id}"; | |
| wp_cache_delete( $cache_key, 'bpcdev_xprofile' ); | |
| } | |
| add_action( 'xprofile_data_after_save', function( $data ) { | |
| bpcdev_invalidate_field_cache( $data->field_id, $data->user_id ); | |
| } ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Bulk update a profile field for multiple users. | |
| * | |
| * @param int $field_id The field ID. | |
| * @param array $user_values Array of user_id => value pairs. | |
| */ | |
| function bpcdev_bulk_update_field( $field_id, $user_values ) { | |
| global $wpdb; | |
| $bp = buddypress(); | |
| foreach ( array_chunk( $user_values, 100, true ) as $chunk ) { | |
| $values = array(); | |
| $placeholders = array(); | |
| foreach ( $chunk as $user_id => $value ) { | |
| $serialized = maybe_serialize( $value ); | |
| $placeholders[] = '(%d, %d, %s, %s)'; | |
| $values[] = $field_id; | |
| $values[] = $user_id; | |
| $values[] = $serialized; | |
| $values[] = current_time( 'mysql' ); | |
| } | |
| $sql = "INSERT INTO {$bp->profile->table_name_data} | |
| (field_id, user_id, value, last_updated) | |
| VALUES " . implode( ', ', $placeholders ) . " | |
| ON DUPLICATE KEY UPDATE value = VALUES(value), | |
| last_updated = VALUES(last_updated)"; | |
| $wpdb->query( $wpdb->prepare( $sql, $values ) ); | |
| // Clear caches for updated users | |
| foreach ( $chunk as $user_id => $value ) { | |
| wp_cache_delete( "bp_xprofile_data_{$user_id}", 'bp' ); | |
| bpcdev_invalidate_field_cache( $field_id, $user_id ); | |
| } | |
| } | |
| } | |
| // Usage: Update job titles from an import | |
| bpcdev_bulk_update_field( $job_title_field_id, array( | |
| 42 => 'Senior Developer', | |
| 55 => 'Product Manager', | |
| 78 => 'UX Designer', | |
| // ... hundreds more | |
| ) ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Practical example: Sync job title changes to WordPress user meta | |
| * and send a notification to site admins. | |
| */ | |
| function bpcdev_on_field_save( $data ) { | |
| $job_title_field_id = xprofile_get_field_id_from_name( 'Job Title' ); | |
| if ( (int) $data->field_id !== $job_title_field_id ) { | |
| return; | |
| } | |
| // Sync to WordPress user meta for REST API access | |
| update_user_meta( $data->user_id, 'job_title', $data->value ); | |
| // Notify admin of profile changes (useful for moderated communities) | |
| $user = get_user_by( 'id', $data->user_id ); | |
| wp_mail( | |
| get_option( 'admin_email' ), | |
| sprintf( 'Profile Update: %s changed their Job Title', $user->display_name ), | |
| sprintf( | |
| '%s updated their Job Title to: %s', | |
| bp_core_get_user_displayname( $data->user_id ), | |
| $data->value | |
| ) | |
| ); | |
| } | |
| add_action( 'xprofile_data_after_save', 'bpcdev_on_field_save' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // GET all field groups | |
| GET /wp-json/buddypress/v1/xprofile/groups | |
| // GET fields in a specific group | |
| GET /wp-json/buddypress/v1/xprofile/fields?profile_group_id=2 | |
| // GET a user's field data | |
| GET /wp-json/buddypress/v1/xprofile/{field_id}/data/{user_id} | |
| // UPDATE a field value (requires authentication) | |
| POST /wp-json/buddypress/v1/xprofile/{field_id}/data/{user_id} | |
| Body: { "value": "New Value" } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Add xprofile fields to the members REST API response. | |
| * | |
| * This makes profile data available when fetching members via the API, | |
| * without requiring a separate xprofile API call. | |
| */ | |
| function bpcdev_add_xprofile_to_members_api() { | |
| $fields_to_include = array( 'Job Title', 'Skills', 'Experience Level' ); | |
| foreach ( $fields_to_include as $field_name ) { | |
| $field_id = xprofile_get_field_id_from_name( $field_name ); | |
| $rest_name = sanitize_title( $field_name ); | |
| if ( ! $field_id ) { | |
| continue; | |
| } | |
| register_rest_field( 'bp_members', "xprofile_{$rest_name}", array( | |
| 'get_callback' => function( $member ) use ( $field_id ) { | |
| return xprofile_get_field_data( $field_id, $member['id'] ); | |
| }, | |
| 'schema' => array( | |
| 'description' => sprintf( 'xprofile field: %s', $field_name ), | |
| 'type' => 'string', | |
| 'context' => array( 'view', 'edit' ), | |
| ), | |
| ) ); | |
| } | |
| } | |
| add_action( 'bp_rest_api_init', 'bpcdev_add_xprofile_to_members_api' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| bpcdev-custom-profiles/ | |
| bpcdev-custom-profiles.php (main plugin file) | |
| includes/ | |
| class-field-groups.php (group creation and management) | |
| class-field-types.php (custom field type definitions) | |
| class-visibility.php (conditional visibility logic) | |
| class-rest-api.php (REST API extensions) | |
| assets/ | |
| css/profile-fields.css (frontend styles) | |
| js/conditional-fields.js (conditional field logic) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Plugin Name: BPCDev Custom Profiles | |
| * Description: Custom xprofile fields, field types, and conditional visibility. | |
| * Version: 1.0.0 | |
| * Requires Plugins: buddypress | |
| * | |
| * @package BPCDev_Custom_Profiles | |
| */ | |
| defined( 'ABSPATH' ) || exit; | |
| define( 'BPCDEV_PROFILES_VERSION', '1.0.0' ); | |
| define( 'BPCDEV_PROFILES_PATH', plugin_dir_path( __FILE__ ) ); | |
| define( 'BPCDEV_PROFILES_URL', plugin_dir_url( __FILE__ ) ); | |
| /** | |
| * Initialize the plugin after BuddyPress loads. | |
| */ | |
| function bpcdev_profiles_init() { | |
| if ( ! function_exists( 'buddypress' ) || ! bp_is_active( 'xprofile' ) ) { | |
| add_action( 'admin_notices', function() { | |
| echo '<div class="error"><p>'; | |
| echo esc_html__( 'BPCDev Custom Profiles requires BuddyPress with the Extended Profiles component active.', 'bpcdev' ); | |
| echo '</p></div>'; | |
| } ); | |
| return; | |
| } | |
| require_once BPCDEV_PROFILES_PATH . 'includes/class-field-groups.php'; | |
| require_once BPCDEV_PROFILES_PATH . 'includes/class-field-types.php'; | |
| require_once BPCDEV_PROFILES_PATH . 'includes/class-visibility.php'; | |
| require_once BPCDEV_PROFILES_PATH . 'includes/class-rest-api.php'; | |
| } | |
| add_action( 'bp_loaded', 'bpcdev_profiles_init' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Debug helper: List all xprofile fields and their types. | |
| * Run from WP-CLI: wp eval-file debug-xprofile.php | |
| */ | |
| function bpcdev_debug_list_fields() { | |
| $groups = bp_xprofile_get_groups( array( | |
| 'fetch_fields' => true, | |
| ) ); | |
| foreach ( $groups as $group ) { | |
| WP_CLI::log( sprintf( 'Group %d: %s', $group->id, $group->name ) ); | |
| if ( ! empty( $group->fields ) ) { | |
| foreach ( $group->fields as $field ) { | |
| WP_CLI::log( sprintf( | |
| ' Field %d: %s (type: %s, required: %s)', | |
| $field->id, | |
| $field->name, | |
| $field->type, | |
| $field->is_required ? 'yes' : 'no' | |
| ) ); | |
| } | |
| } | |
| } | |
| } | |
| if ( defined( 'WP_CLI' ) && WP_CLI ) { | |
| bpcdev_debug_list_fields(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment