Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Fore completion of BuddyPress Required Field
class BuddyDev_Profile_Field_Completion_Helper {
/**
* Show notice to user?
*
* @var bool
*/
private $show_notice = true;
/**
* Please do not set it. It is used for temporary notice.
*
* @var string
*/
private $notice = '';
/**
* Should we restrict user when they have incomplete profile?
* It will force redirect user to complete their profile if enabled.
*
* @var bool
*/
private $restrict_on_incomplete = true;
/**
* require profile photo to decide the profile completion.
*
* @var bool
*/
private $require_photo = false;
/**
* require profile field completion.
*
* @var bool
*/
private $require_fields = true;
/**
* Notice messages based on required field or photo.
*
* @var array
*/
private $notices = array(
'photo' => 'Please upload your profile photo!',
'fields' => 'Please complete your profile.'
);
/**
* Constructor.
*/
public function __construct() {
$this->setup();
}
/**
* Setup hooks.
*/
public function setup() {
// check on login for the profile completion.
add_action( 'wp_login', array( $this, 'on_login_check' ), 0 );
// check on account activation for the profile complete.
add_action( 'bp_core_activated_user', array( $this, 'check_on_update' ) );
// check on profile update for the profile completion.
add_action( 'xprofile_updated_profile', array( $this, 'check_on_update' ), 0 );
// ON AVATAR UPLOAD
//on avatar delete
// record on new avatar upload & check for profile completion
add_action( 'xprofile_avatar_uploaded', array( $this, 'log_uploaded' ) );
// on avatar delete, remove the log and mark profile incomplete.
add_action( 'bp_core_delete_existing_avatar', array( $this, 'log_deleted' ) );
// Show teh notice.
add_action( 'bp_template_redirect', array( $this, 'check_profile_completion_state' ) );
}
/**
* Check profile completion on login.
*
* @param string $user_login username.
*/
public function on_login_check( $user_login ) {
$user = get_user_by( 'login', $user_login );
if ( ! $user ) {
return;
}
$this->check_on_update( $user->ID );
}
/**
* Checks for profile update and triggers profile completed action.
*
* @param int $user_id user id.
*/
public function check_on_update( $user_id ) {
$this->show_notice_and_redirect( $user_id );
}
/**
* On New Avatar Upload, add the user meta to reflect that user has uploaded an avatar
*
* @param int $user_id user whose avatar changed.
*/
public function log_uploaded( $user_id ) {
bp_update_user_meta( $user_id, 'has_avatar', 1 );
$this->check_on_update( $user_id );
}
/**
* On Delete Avatar, delete the user meta to reflect the change
*
* @param array $args see args array.
*/
public function log_deleted( $args ) {
if ( $args['object'] != 'user' ) {
return;
}
$user_id = empty( $args['item_id'] ) ? 0 : absint( $args['item_id'] );
if ( ! $user_id ) {
if ( bp_is_user() && ( bp_is_my_profile() || is_super_admin() ) ) {
$user_id = bp_displayed_user_id();
} else {
$user_id = bp_loggedin_user_id();
}
}
// we are sure it was user avatar delete
// remove the log from user meta.
bp_delete_user_meta( $user_id, 'has_avatar' );
$this->mark_incomplete_profile( $user_id );
}
/**
* Check's user's profile completion state.
*/
public function check_profile_completion_state() {
if ( ! is_user_logged_in() ) {
return;
}
$this->show_notice_and_redirect( bp_loggedin_user_id() );
}
/**
* Check for profile completion and add notice.
*
* @param int $user_id user id.
*/
private function show_notice_and_redirect( $user_id ) {
if ( ! $this->has_incomplete_profile( $user_id ) ) {
// the profile is complete.
return;
}
if ( is_super_admin( $user_id ) ) {
return;// no need to force super admin.
}
if ( apply_filters( 'bp_force_profile_completion_skip_check', false ) ) {
return ;
}
$incomplete = true;
// consider that we have the has_field and avatar available by default.
$has_fields = $has_photo = true;
// check if fields are required
if ( $this->require_fields ) {
$has_fields = $this->has_required_field_data( $user_id );
}
if ( $this->require_photo ) {
$has_photo = $this->has_uploaded_avatar( $user_id );
}
$redirect_url = bp_core_get_user_domain( $user_id ) . bp_get_profile_slug();
// this might have happened magically(most probably someone update profile by code).
if ( $has_photo && $has_fields ) {
$this->mark_complete_profile( $user_id );
$incomplete = false;
do_action( 'buddydev_bp_user_profile_completed', $user_id );
} elseif ( ! $has_fields ) {
$this->notice = $this->notices['fields'];
$redirect_url = $redirect_url . '/edit/';
} else {
$this->notice = $this->notices['photo'];
$redirect_url = $redirect_url . '/change-avatar/';
}
if ( $incomplete ) {
if ( $this->show_notice && $this->notice ) {
bp_core_add_message( $this->notice, 'error' );
}
if ( $this->restrict_on_incomplete && ! bp_is_user_profile() ) {
bp_core_redirect( $redirect_url );
}
}
}
/**
* Mark profile incomplete.
*
* @param int $user_id user id.
*
* @return bool
*/
public function has_incomplete_profile( $user_id ) {
if ( get_user_meta( $user_id, '_has_complete_profile', true ) ) {
return false;
}
return true;
}
/**
* Mark profile as incomplete.
*
* @param int $user_id user id.
*
* @return bool
*/
public function mark_incomplete_profile( $user_id ) {
return delete_user_meta( $user_id, '_has_complete_profile' );
}
/**
* Check if user has incomplete profile field data.
*
* @param int $user_id user id.
*
* @return bool|int
*/
public function mark_complete_profile( $user_id ) {
return update_user_meta( $user_id, '_has_complete_profile', 1 );
}
public function has_uploaded_avatar( $user_id ) {
// assuming that you are using force profile photo plugin that allows tracking of the user avatar.
$has_avatar = bp_get_user_meta( $user_id, 'has_avatar', true );
if ( ! $has_avatar ) {
$has_avatar = bp_get_user_has_avatar( $user_id );// fallback.
}
return $has_avatar;
}
/**
* Check if all required fields is complete.
*
* @param $user_id
*
* @return bool|mixed
*/
public function has_required_field_data( $user_id ) {
global $wpdb;
$has_fields_complete = get_user_meta( $user_id, '_has_required_field_data', true );
if ( $has_fields_complete ) {
return $has_fields_complete; // no need to test further.
}
$required_fields = $this->get_all_required_profile_fields();
// no required field, so profile should be considered complete
if ( empty( $required_fields ) ) {
// update meta
update_user_meta( $user_id, '_has_required_field_data', 1 );
return true;
}
$fields_list = '(' . join( ',', $required_fields ) . ' )';
$table = buddypress()->profile->table_name_data;
$query = "SELECT field_id, value FROM {$table} WHERE user_id = %d AND field_id IN {$fields_list}";
$profile_entries = $wpdb->get_results( $wpdb->prepare( $query, $user_id ) );
$complete = false;
// not all fields are set.
// shortcut.
if ( count( $profile_entries ) != count( $required_fields ) ) {
// unset flag.
delete_user_meta( $user_id, '_has_required_field_data' );
} else {
$complete = true;
// it should be complete but is the value acually not empty?
// check by unserializing field values
foreach ( $profile_entries as $profile_entry ) {
$value = maybe_unserialize( $profile_entry->value );
if ( empty( $value ) ) {
$complete = false;
break;
}
}
if ( $complete ) {
update_user_meta( $user_id, '_has_required_field_data', 1 );
}
}
return $complete;
}
/**
* Get all required field ids.
*
* @return array
*/
public function get_all_required_profile_fields() {
global $wpdb;
$table = buddypress()->profile->table_name_fields;
$query = "SELECT id FROM {$table} WHERE is_required = %d";
$fields = $wpdb->get_col( $wpdb->prepare( $query, 1 ) );
return $fields;
}
}
new BuddyDev_Profile_Field_Completion_Helper();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.