Hello Brajesh,
I have been thinking lately about the best way to deal with inactive buddypress members or dead profiles. digital dead profiles can lead to some issues like
1. Profile hijacking / identity theft
2. Misinformation and outdated content
3. Difficulty in maintaining connections
4. Privacy concerns
5. Unattended messages and notifications
6. Impact on data accuracy and user statisticsI would suggest creating a plugin that can deal with the issue of cleaning up inactive members as the reality of life is people cant live forever.
Possible plugin function can include:
1. Firstly identifying and categorising inactive members: For example I have a custom role called (Ghost Member) now if users last active time is more than a year then the user should be added to the role (Ghost Member)
2. Communicating with inactive members: Once a user has been classified as a (Ghost Member) at least 2 periodic emails should be sent to the inactive members encouraging them to login.
Note If the inactive members logs in to site then remove member from (Ghost Member) role3. Reporting system: There should be a shortcode that can be added to a dedicated page where other users can report a user as being biologically dead.
4. Automatic clean up of inactive members: A possible example could be if total (Ghost Member) count equal a specified number threshold the automatically delete all users that belong to the (Ghost Member) role.
5. Dealing with content created by inactive members: There should be a settings pages to assign all specific post type content to a specific user. For example when auto deleting ghost members assign their post to another user called (site memorials) but delete their advert post type.
This are my own suggestion but more suggestions are welcome
This is example code for classifying user inactive for a year
function check_inactive_users_and_assign_role() { $users = get_users(); // Get all users foreach ( $users as $user ) { $last_activity = bp_get_user_last_activity( $user->ID ); // Get the last activity timestamp if ( ! empty( $last_activity ) ) { $inactive_time = time() - strtotime( $last_activity ); // Calculate the time difference in seconds // Check if the user has been inactive for a year (31536000 seconds) if ( $inactive_time >= 31536000 ) { $ghost_member_role = 'ghost_member'; // The role slug for Ghost Member // Add the user to the Ghost Member role $user_obj = new WP_User( $user->ID ); $user_obj->add_role( $ghost_member_role ); } } } } add_action( 'bp_loaded', 'check_inactive_users_and_assign_role' );
Now how will the code affect site performance if the site has a least one million registered members. If the site has a large number of registered members, iterating through all users using get_users() and checking their activity status can potentially impact site performance, especially if the operation is performed on every page load.
Will this code be better
function schedule_inactive_users_check() { if ( ! wp_next_scheduled( 'check_inactive_users_event' ) ) { wp_schedule_event( time(), 'daily', 'check_inactive_users_event' ); } } add_action( 'bp_loaded', 'schedule_inactive_users_check' ); function check_inactive_users_and_assign_role() { $users = get_users( array( 'number' => 100 ) ); // Get 100 users at a time foreach ( $users as $user ) { $last_activity = bp_get_user_last_activity( $user->ID ); // Get the last activity timestamp if ( ! empty( $last_activity ) ) { $inactive_time = time() - strtotime( $last_activity ); // Calculate the time difference in seconds // Check if the user has been inactive for a year (31536000 seconds) if ( $inactive_time >= 31536000 ) { $ghost_member_role = 'ghost_member'; // The role slug for Ghost Member // Add the user to the Ghost Member role $user_obj = new WP_User( $user->ID ); $user_obj->add_role( $ghost_member_role ); } } } } function run_inactive_users_check() { check_inactive_users_and_assign_role(); // Check if there are more users to process if ( count( get_users() ) > 0 ) { wp_schedule_single_event( time() + 10, 'run_inactive_users_check' ); // Schedule the next batch after 10 seconds } } add_action( 'check_inactive_users_event', 'run_inactive_users_check' );
Hi Tosin,
Thank you for the suggestions.
This is interesting and we will add it to our list.1. Using get_users() has bad impact for large number of users. A better solution is to use get_users() but specify fields=ID, that is a lot more performing.
2. If you are handling 100 users per request on a 1 million user site in 24 hours, it will take around 7 requests per minute which does not seem to be feasible with the logic.
I believe a CLI based solution is more suitable for the use case as you don’t need to worry about the request timeout and can process continuously.
Regards
BrajeshThanks for the feddback Brajesh
Although I know nothing about CLI based solutions this is what I have now
function check_inactive_users_and_assign_role() { // Check if the current page is the BuddyPress sitewide activity directory page if ( function_exists( 'bp_is_activity_directory' ) && bp_is_activity_directory() ) { // Check if user is logged in if ( is_user_logged_in() ) { $users = get_users( array( 'fields' => 'ID', // Only retrieve the user IDs for efficiency 'role__not_in' => array( 'administrator' ), // Exclude users with the 'administrator' role 'number' => -1, // Retrieve all users at once ) ); foreach ( $users as $user_id ) { $last_activity = bp_get_user_last_activity( $user_id ); // Get the last activity timestamp if ( ! empty( $last_activity ) ) { $inactive_time = time() - strtotime( $last_activity ); // Calculate the time difference in seconds // Check if the user has been inactive for a year (31536000 seconds) if ( $inactive_time >= 31536000 ) { $ghost_member_role = 'ghost_member'; // The role slug for Ghost Member // Add the user to the Ghost Member role $user_obj = new WP_User( $user_id ); $user_obj->add_role( $ghost_member_role ); } } } } } } add_action( 'bp_loaded', 'check_inactive_users_and_assign_role' );
Maybe running this first code once a week might be better
/** * (Buddypress)- Remove users from the "Ghost Member" after login */ function remove_ghost_member_role_on_login( $user_login, $user ) { $ghost_member_role = get_role( 'ghost_member' ); // Get the Ghost Member role object if ( $ghost_member_role && in_array( $ghost_member_role->name, $user->roles ) ) { $user_obj = new WP_User( $user->ID ); $user_obj->remove_role( $ghost_member_role->name ); } } add_action( 'wp_login', 'remove_ghost_member_role_on_login', 10, 2 );
Since I dont have an efficient way for inactive user clean up without affecting site performance, maybe the method of cleanup should change, what would you suggest.
1. Automatic cleanup via code
2. Manual cleanup by clicking a button in admin area
3. Community cleanup by community members reporting other inactive users
4. Mix of both automatic cleanup and community clean up or the 3Personally I would have preferred automatic approach to save time
what’s your opinion
thanks
Please avoid running check on bp_loaded.
It is a bad idea. Also, is_user_logged_in() will return false on bp_loaded as the user is not authenticated/initialised at that hook.Regards
BrajeshI don’t want to give up on this so im trying another approach below
// change the role of inactive members over 1 year to ghost member function update_site_ghost_members() { // Check if it's the activity directory page and the user is an admin if (bp_is_activity_directory() && current_user_can('administrator')) { $last_run_timestamp = get_user_meta(0, 'last_ghost_member_role_update', true); // Check if a month (2592000 seconds = 30 days) has passed since the last run if (!$last_run_timestamp || (time() - $last_run_timestamp) >= 2592000) { // Get users with specific roles (e.g., 'contributor' and 'subscriber') $users = get_users(array( 'fields' => 'ID', 'role__in' => array('contributor', 'subscriber'), )); foreach ($users as $user_id) { // Check user's last activity using BuddyPress function $last_activity = bp_get_user_last_activity($user_id); // Calculate time difference $inactive_time = strtotime('now') - strtotime($last_activity); // If inactive for more than one year (31536000 seconds = 1 year) if ($inactive_time > 31536000) { // Assign 'Ghost Member' role to the user $user = new WP_User($user_id); $user->add_role('ghost_member'); } } // Update the timestamp to indicate the code ran update_user_meta(0, 'last_ghost_member_role_update', time()); } } } add_action('template_redirect', 'update_site_ghost_members');
running get_users would be awesome in batches
Hi Tosin,
Thank you for posting.
I am sorry, I have limited time available for assisting with custom code due to one of our high priority projects. I am unable to assist beyond our plugins for next 6-8 weeks. Will be glad to re-look at things after that.Regards
Brajesh
You must be logged in to reply to this topic.