Skip to content

Instantly share code, notes, and snippets.

@paulgibbs
Created November 26, 2024 11:30
Show Gist options
  • Save paulgibbs/ce2b132285e676df4f09cabb32599aa5 to your computer and use it in GitHub Desktop.
Save paulgibbs/ce2b132285e676df4f09cabb32599aa5 to your computer and use it in GitHub Desktop.
put Xprofile fields into a Group (BuddyPress)
<?php
// Increment used to store xprofile data for a user ID that's unlikely to exist.
const GROUP_USER_ID_INCREMENT = 1000000;
/**
* Add xprofile profile fields to a BuddyPress Group.
*/
class Groups_Extension_Profile_Fields extends \BP_Group_Extension
{
/**
* Group_Extension_Profile_Fields constructor.
*
* Initializes the group extension with specific arguments.
*/
public function __construct() {
$args = array(
'slug' => 'myplugin-xprofile-fields',
'name' => __( 'Profile', 'my-plugin' ),
'nav_item_name' => __( 'Profile', 'my-plugin' ),
'nav_item_position' => 90,
);
parent::init( $args );
}
/**
* Display the xProfile field group form for the group.
*
* @param int|null $group_id The ID of the group.
*/
public function display( $group_id = null ) : void
{
$group_fake_user_id = GROUP_USER_ID_INCREMENT + $group_id;
$group_type = bp_groups_get_group_type( $group_id );
$r = [
'hide_empty_fields' => true,
'fetch_visibility_level' => bp_current_user_can( 'bp_moderate' ) || bp_group_is_admin() || bp_group_is_mod(),
'user_id' => $group_fake_user_id,
];
if ( $group_type ) {
// A custom group type is set.
$r['member_type'] = \MyPlugin\BuddyPress\get_member_type_from_group_type( $group_type );
}
if ( ! bp_has_profile( $r ) ) {
/**
* Hey! Regarding `member_type` above - as of BP 14.2.1, it's overriden by fetching the member_type(s) from the specified `user_id`.
* As our fake group user IDs intentionally don't exist, this breaks things. :(
*
* Instead, check out the `filter_bp_get_member_type()` function we've implemented on this project, which implements the same thing on
* the `bp_get_member_type()` function which is used by the underlying SQL query which we're unable to modify.
*
* We're leaving both here in case the internals of `bp_has_profile()` get changed in future versions (and we can remove our workaround).
*/
return;
}
while ( bp_profile_groups() ) {
bp_the_profile_group();
if ( bp_profile_group_has_fields() ) {
?>
<div class="<?php bp_the_profile_group_slug(); ?>">
<?php bp_the_profile_group_name(); ?>
<table class="profile-fields bp-tables-user">
<?php
while ( bp_profile_fields() ) :
bp_the_profile_field();
?>
<?php if ( bp_field_has_data() ) : ?>
<tr<?php bp_field_css_class(); ?>>
<td class="label"><?php bp_the_profile_field_name(); ?></td>
<td class="data"><?php bp_the_profile_field_value(); ?></td>
</tr>
<?php endif; ?>
<?php endwhile; ?>
</table>
</div>
<?php
}
}
}
/**
* Display the edit screen of the xProfile field group form for the group.
*
* @param int|null $group_id The ID of the group.
*/
public function settings_screen( $group_id = null ) : void
{
$group_fake_user_id = GROUP_USER_ID_INCREMENT + $group_id;
$group_type = bp_groups_get_group_type( $group_id );
$r = [
'hide_empty_fields' => false,
'fetch_visibility_level' => bp_current_user_can( 'bp_moderate' ) || bp_group_is_admin() || bp_group_is_mod(),
'user_id' => $group_fake_user_id,
];
if ( $group_type ) {
// A custom group type is set.
$r['member_type'] = \MyPlugin\BuddyPress\get_member_type_from_group_type( $group_type );
}
if ( ! bp_has_profile( $r ) ) {
/**
* Please read the comment in the `display()` method!
*/
return;
}
while ( bp_profile_groups() ) :
bp_the_profile_group();
?>
<?php
while ( bp_profile_fields() ) :
bp_the_profile_field();
?>
<div<?php bp_field_css_class( 'editfield' ); ?>>
<fieldset>
<?php
$field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() );
$field_type->edit_field_html();
?>
<?php bp_nouveau_xprofile_edit_visibilty(); ?>
</fieldset>
</div>
<?php endwhile; ?>
<input type="hidden" name="field_ids" id="field_ids" value="<?php bp_the_profile_field_ids(); ?>" />
<?php
endwhile;
}
/**
* Save the xProfile field group data for the group.
*
* @param int|null $group_id The ID of the group.
*/
public function settings_screen_save( $group_id = null ) : void
{
// Check to see if any new information has been submitted.
if ( empty( $_POST['field_ids'] ) ) {
return;
}
$group_fake_user_id = GROUP_USER_ID_INCREMENT + $group_id;
// Explode the posted field IDs into an array so we know which fields have been submitted.
$posted_field_ids = wp_parse_id_list( $_POST['field_ids'] );
$is_required = array();
// Loop through the posted fields formatting any datebox values then validate the field.
foreach ( (array) $posted_field_ids as $field_id ) {
bp_xprofile_maybe_format_datebox_post_data( $field_id );
$is_required[ $field_id ] = xprofile_check_is_required_field( $field_id ) && ! bp_current_user_can( 'bp_moderate' );
if ( $is_required[ $field_id ] && empty( $_POST[ 'field_' . $field_id ] ) ) {
$errors = true;
}
}
if ( $errors ) {
bp_core_add_message( __( 'The changes have not been saved. Please fill in all required fields, and save your changes again.', 'my-plugin' ), 'error' );
return;
}
// Now we've checked for required fields, let's save the values.
$old_values = $new_values = array();
foreach ( (array) $posted_field_ids as $field_id ) {
// Certain types of fields (checkboxes, multiselects) may come through empty. Save them as an empty array so that they don't get overwritten by the default on the next edit.
$value = isset( $_POST[ 'field_' . $field_id ] ) ? $_POST[ 'field_' . $field_id ] : '';
$visibility_level = ! empty( $_POST[ 'field_' . $field_id . '_visibility' ] ) ? $_POST[ 'field_' . $field_id . '_visibility' ] : 'public';
// Save the old and new values. They will be passed to the filter and used to determine whether an activity item should be posted.
$old_values[ $field_id ] = array(
'value' => xprofile_get_field_data( $field_id, $group_fake_user_id ),
'visibility' => xprofile_get_field_visibility_level( $field_id, $group_fake_user_id ),
);
// Update the field data and visibility level.
xprofile_set_field_visibility_level( $field_id, $group_fake_user_id, $visibility_level );
$field_updated = xprofile_set_field_data( $field_id, $group_fake_user_id, $value, $is_required[ $field_id ] );
$value = xprofile_get_field_data( $field_id, $group_fake_user_id );
$new_values[ $field_id ] = array(
'value' => $value,
'visibility' => xprofile_get_field_visibility_level( $field_id, $group_fake_user_id ),
);
if ( ! $field_updated ) {
$errors = true;
}
}
// Set the feedback messages.
if ( $errors ) {
bp_core_add_message( __( 'There was a problem updating some of the profile information. Please try again.', 'my-plugin' ), 'error' );
} else {
bp_core_add_message( __( 'Changes saved.', 'my-plugin' ) );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment