Skip to content

Instantly share code, notes, and snippets.

@sbrajesh
Created May 30, 2018 10:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbrajesh/3d7ab3f50dff9bc1ef2df1e9c5a28c53 to your computer and use it in GitHub Desktop.
Save sbrajesh/3d7ab3f50dff9bc1ef2df1e9c5a28c53 to your computer and use it in GitHub Desktop.
For Herve
class BuddyDev_Profile_Field_Completion_Helper {
/**
* Which member type should be set? PLease change it.
*
* @var string
*/
private $member_type = ''; // Use your own memver type. Please Change it.
/**
* Should this member type be appended to users existing member types or replace?
* Set true to append.
*
* @var bool
*/
private $append_member_type = false;
/**
* Show notice to user?
*
* @var bool
*/
private $show_notice = true;
/**
* Please do not set it. It ise 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 = true;
/**
* require profile field completion.
*
* @var bool
*/
private $require_fields = true;
/**
* Special field id.
*
* @var int
*/
private $special_field_id = 57;// use the id, update it.
/**
* The special field value to match for.
*
* @var string
*/
private $special_field_value = "Une Femme"; //your value.
/**
* 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() {
add_filter( 'bp_settings_admin_nav', '__return_empty_array' );
$this->setup();
}
/**
* Setup hooks.
*/
public function setup() {
// change member type when the profile completed(in the sense we want) is triggered.
add_action( 'buddydev_bp_user_profile_completed', array( $this, 'set_custom_member_type' ) );
// 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_profile_update' ) );
// check on profile update for the profile completion.
add_action( 'xprofile_updated_profile', array( $this, 'check_on_profile_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->show_notice_and_redirect( $user->ID );
}
/**
* Checks for profile update and makes the profile incomplete again.
*
* @param int $user_id user id.
*/
public function check_on_profile_update( $user_id ) {
// if profile is updated, a user may be marked as incomplete.
if ( $this->has_incomplete_profile( $user_id ) ) {
return ;// no need top do anything template_redirect will take care.
}
delete_user_meta( $user_id, '_has_required_field_data' );
// if we are here, the user profile is complete.
// the profile update might have caused it to become incomplete.
// let us check for the same
$special_field_data = xprofile_get_field_data( $this->special_field_id, $user_id );
if ( $special_field_data != $this->special_field_value || ! $this->has_required_field_data( $user_id )) {
$this->mark_incomplete_profile( $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->show_notice_and_redirect( $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.
}
// I have changed the filter name to render any code acting on it invalid.
if ( apply_filters( 'bp_force_profile_completion_skip_check2', 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).
// Edit Here
$special_value = xprofile_get_field_data( $this->special_field_id, $user_id );
if ( $has_photo && $has_fields && $special_value == $this->special_field_value ) {
$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
*/
private 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;
}
/**
* Check if the user has given role.
*
* @param int $user_id user id.
* @param string $role role name.
*
* @return bool
*/
private function has_role( $user_id, $role ) {
$user = get_user_by( 'id', $user_id );
if( ! $user ) {
return false;
}
return in_array( $role, (array) $user->roles );
}
/**
* Set custom member type if the profile just completed.
*
* @param int $user_id user id.
*/
private function set_custom_member_type( $user_id ) {
if ( $this->member_type ) {
bp_set_member_type( $user_id, $this->member_type, $this->append_member_type );
}
}
}
new BuddyDev_Profile_Field_Completion_Helper();
/**
* Change role on completion.
*
* @param int $user_id user id.
*/
function herve_trigger_role_change_on_completion( $user_id ) {;
$user = get_user_by( 'id', $user_id );
if( ! $user ) {
return ;
}
// if user is subscriber, mark him as
if ( in_array( 'subscriber', $user->roles ) ) {
// change role.
$user->set_role( 'membre0' );
}
}
add_action( 'buddydev_bp_user_profile_completed', 'herve_trigger_role_change_on_completion' );
@HDInfautre
Copy link

HDInfautre commented May 31, 2018

`class BuddyDev_Profile_Field_Completion_Helper {

/**
 * Which member type should be set? PLease change it.
 *
 * @var string
 */
private $member_type = 'membre0'; // Use your own memver type. Please Change it.

/**
 * Should this member type be appended to users existing member types or replace?
 * Set true to append.
 *
 * @var bool
 */
private $append_member_type = false;

/**
 * Show notice to user?
 *
 * @var bool
 */
private $show_notice = true;

/**
 * Please do not set it. It ise 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 = false;

/**
 * require profile photo to decide the profile completion.
 *
 * @var bool
 */
private $require_photo = true;

/**
 * require profile field completion.
 *
 * @var bool
 */
private $require_fields = true;

/**
 * Special field id.
 *
 * @var int
 */
private $special_field_id = 57;// use the id, update it.

/**
 * The special field value to match for.
 *
 * @var string
 */
private $special_field_value = "Une Femme"; //your value.
/**
 * Notice messages based on required field or photo.
 *
 * @var array
 */
private $notices = array(
	'photo'  => 'Merci ajouter une photo de profil!!',
	'fields' => 'Merci de compléter votre profil.'
);

/**
 * Constructor.
 */
public function __construct() {
	add_filter( 'bp_settings_admin_nav', '__return_empty_array' );
	$this->setup();
}

/**
 * Setup hooks.
 */
public function setup() {
	// change member type when the profile completed(in the sense we want) is triggered.
	add_action( 'buddydev_bp_user_profile_completed', array( $this, 'set_custom_member_type' ) );

	// 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_profile_update' ) );
	// check on profile update for the profile completion.
	add_action( 'xprofile_updated_profile', array( $this, 'check_on_profile_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.
	// HD maj 19/03/18 car ne fait pas dif entre sup. & changement photo ce qui a pour effet de finir avec rôle membre0, même si avant rôle supérieur  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->show_notice_and_redirect( $user->ID );
}

/**
 * Checks for profile update and makes the profile incomplete again.
 *
 * @param int $user_id user id. 
 */
public function check_on_profile_update( $user_id ) { // NOUVEAU 30/05/18 buddyDEV
    // if profile is updated, a user may be marked as incomplete.

    if ( $this->has_incomplete_profile( $user_id ) ) {
        return ;// no need top do anything template_redirect will take care.
    }

	delete_user_meta( $user_id, '_has_required_field_data' );
    // if we are here, the user profile is complete.
    // the profile update might have caused it to become incomplete.
    // let us check for the same

    $special_field_data = xprofile_get_field_data( $this->special_field_id, $user_id );

    if ( $special_field_data != $this->special_field_value || ! $this->has_required_field_data( $user_id )) {
        $this->mark_incomplete_profile( $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->show_notice_and_redirect( $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() { // NOUVEAU 30/05/18 buddyDEV
	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.
	}

	// I have changed the filter name to render any code acting on it invalid.
	if ( apply_filters( 'bp_force_profile_completion_skip_check2', 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).
    // Edit Here
    $special_value = xprofile_get_field_data( $this->special_field_id, $user_id );

	if ( $has_photo && $has_fields && $special_value == $this->special_field_value ) {
		$this->mark_complete_profile( $user_id );
		$incomplete = false;
		do_action( 'buddydev_bp_user_profile_completed', $user_id );
		do_action( 'arm_apply_plan_to_member', 2, $user_id); // 10/01/18: HD AJOUT pour rejoindre plan de base (& role: membre0)
	} 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 ) {
	do_action( 'arm_apply_plan_to_member', 1, $user_id); // 10/01/18: HD AJOUT pour rejoindre plan sans profil finalisé (& role: subscriber)
	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
 */
private 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;
}

/**
 * Check if the user has given role.
 *
 * @param int $user_id user id.
 * @param string $role role name.
 *
 * @return bool
 */
private function has_role( $user_id, $role ) {
    $user = get_user_by( 'id', $user_id );

    if( ! $user ) {
        return false;
    }

    return in_array( $role, (array) $user->roles );
}

/**
 * Set custom member type if the profile just completed.
 *
 * @param int $user_id user id.
 */
private function set_custom_member_type( $user_id ) {
	if ( $this->member_type ) {
		bp_set_member_type( $user_id, $this->member_type, $this->append_member_type );
	}
}

}

new BuddyDev_Profile_Field_Completion_Helper();

/**

  • Change role on completion.

  • @param int $user_id user id.
    */
    function herve_trigger_role_change_on_completion( $user_id ) {;

    $user = get_user_by( 'id', $user_id );

    if( ! $user ) {
    return ;
    }
    // if user is subscriber, mark him as

    if ( in_array( 'subscriber', $user->roles ) ) {
    // change role.
    $user->set_role( 'membre0' );
    }
    }

add_action( 'buddydev_bp_user_profile_completed', 'herve_trigger_role_change_on_completion' );
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment