Created
November 26, 2024 11:30
-
-
Save paulgibbs/ce2b132285e676df4f09cabb32599aa5 to your computer and use it in GitHub Desktop.
put Xprofile fields into a Group (BuddyPress)
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 | |
// 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