Last active
February 3, 2020 11:59
-
-
Save sbrajesh/238153f70f770f957fd1c4b2ba60be77 to your computer and use it in GitHub Desktop.
Specific use case for Herve for profile completion.
This file contains 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
class BuddyDev_Profile_Field_Completion_Helper { | |
/** | |
* Which member type should be set? PLease change it. | |
* | |
* @var string | |
*/ | |
private $member_type = 'YOUR_MEMBER_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 = 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() { | |
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_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 ); | |
} | |
/** | |
* Set custom member type if the profile just completed. | |
* | |
* @param int $user_id user id. | |
*/ | |
public function set_custom_member_type( $user_id ) { | |
bp_set_member_type( $user_id, $this->member_type, $this->append_member_type ); | |
} | |
/** | |
* 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(); | |
/** | |
* Do not redirect users on non bp pages while using BP Profile completion test. | |
* | |
* @param bool $skip should we skip or redirect. | |
* | |
* @return bool | |
*/ | |
function buddydev_skip_check_for_profile_completion( $skip ) { | |
if ( ! is_buddypress() ) { | |
$skip = true; | |
} | |
return $skip; | |
} | |
add_filter( 'bp_force_profile_completion_skip_check', 'buddydev_skip_check_for_profile_completion' ); |
I have updated the gist with the placeholders now.
`new BuddyDev_Profile_Field_Completion_Helper();
class BuddyDev_Profile_Field_Completion_Helper {
/**
* Which member type should be set? PLease change it.
*
* @var string
*/
private $member_type = 'membre0'; // Membre de base
/**
* Ce type de membre doit-il être ajouté aux types de membre existants des utilisateurs ou remplacer? * Définissez true pour ajouter.
*
* @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;
/**
* 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_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 );
}
/**
* Set custom member type if the profile just completed.
*
* @param int $user_id user id.
*/
public function set_custom_member_type( $user_id ) {
bp_set_member_type( $user_id, $this->member_type, $this->append_member_type );
}
/**
* 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 );
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
*/
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;
}
}`
Hello,
It works pretty well :-) but I just realized that if a person removes his picture, it does not change role and plan !.
Where ? do I have to put a piece of code ? to go back to the previous plan and role of subscriber?
Regards
` new BuddyDev_Profile_Field_Completion_Helper();
class BuddyDev_Profile_Field_Completion_Helper {
/**
* Which member type should be set? PLease change it.
*
* @var string
*/
private $member_type = 'membre0'; // Membre de base
/**
* Ce type de membre doit-il être ajouté aux types de membre existants des utilisateurs ou remplacer? * Définissez true pour ajouter.
*
* @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;
/**
* 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_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 );
}
/**
* Set custom member type if the profile just completed.
*
* @param int $user_id user id.
*/
public function set_custom_member_type( $user_id ) {
bp_set_member_type( $user_id, $this->member_type, $this->append_member_type );
}
/**
* 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 );
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
*/
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;
}
}`
`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();
}
}
$user = get_user_by( 'id', $user_id );
if( $user && ! is_super_admin( $user_id ) ) {
$user->set_role('subscriber' );
}
}
new BuddyDev_Profile_Field_Completion_Helper();
class BuddyDev_Profile_Field_Completion_Helper {
/**
* Which member type should be set? PLease change it.
*
* @var string
*/
private $member_type = 'membre0'; // Membre de base
/**
* Ce type de membre doit-il être ajouté aux types de membre existants des utilisateurs ou remplacer? * Définissez true pour ajouter.
*
* @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;
/**
* 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_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 );
}
/**
* Set custom member type if the profile just completed.
*
* @param int $user_id user id.
*/
public function set_custom_member_type( $user_id ) {
bp_set_member_type( $user_id, $this->member_type, $this->append_member_type );
}
/**
* 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 );
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
*/
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;
}
}`
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello Brajesh,
Wow :-) , I did not expect such a complete program!!
Some questions:
1/ if there will be no conflict using the BP force profile plugin at the same time?
It's a pretty different programming. To avoid breaking the code, I want to know where to put my codes
2/ where put in variable of the type of member (not to forget it and ... no problem):
3/ when I switch from member type, I have to switch also with the armember plugin:
4/ where put my message for mandatory fields not entered:
public function has_required_field_data( $user_id ) {
...
***********// ??????? OK ????????
Regards