Search code examples
phpwordpresshookmultiple-users

how to fire 'profile_update' hook on adding/removing roles from wp-admin/users.php page? (or what other hook to use in this case)


Background

On adding a specific role (referee) to a profile I add a profile page on a custom post type and link it to that user with a meta value on both the post and the user. I also check if a user has previously been that role (by a meta value on that user) and then add/ edit their profile page accordingly.

All of that works fine when I add the role from the user-edit page
http://localhost:8888/wp-admin/user-edit.php?user_id={SOME USER ID}

Problem

But when the role is added(or removed) from the bulk-actions / actions buttons on /wp-admin/users.php(Edit page reference) the profile_update hook doesn't get triggered.

So is there a way I could either extend the profile_update to include updates from the /wp-admin/users.php or remove the actions buttons from /wp-admin/users.php altogether (or some other solution)?

Atempts at solving
I was able to remove the bulk-actions button with this filter add_filter('bulk_actions-users','__return_empty_array');
but couldn't find a a filter to remove the action buttons on the right.


Code in question

function site_refProfile_existingUser( $user_id, $old_user_data ){
  if ((get_user_meta( $user_id, 'wp_capabilities')[0]['referee'] !== null) && (metadata_exists('user', $user_id, 'ref_pageID'))) {
    $profileID = get_user_meta( $user_id, 'ref_pageID')[0];
    $postUpdateArgs = array(
      'ID'          => $profileID,
      'post_status' => "private"
    );
    wp_update_post($postUpdateArgs);
    error_log("making profile :".$profileID." private (User : ".$user_id.")");
  }
  elseif ((get_user_meta( $user_id, 'wp_capabilities')[0]['referee'] == null) && (!metadata_exists('user', $user_id, 'ref_pageID'))) {
    $refProfileName = "".get_user_meta( $user_id, 'first_name')[0]." ".get_user_meta( $user_id, 'last_name')[0]."";
    if(substr($refProfileName,-1)== 's'){
      $refProfileNameCleaned = $refProfileName."' ";
    } else{
      $refProfileNameCleaned = $refProfileName."'s ";
    }
    $refProfileArgs = array(
      'post_title'       =>  $refProfileNameCleaned."Profile",
      'post_excerpt'     => "Read {$refProfileNameCleaned}profile on Bootle Referees' Association's official website",
      'post_name'        => $refProfileName,
      'post_type'        => "refprofile",
      'post_status'      => "publish",
      'post_author'      => $user_id,
    );
    $refProfilePost = wp_insert_post($refProfileArgs);
    update_post_meta( $refProfilePost, 'profile_refID', $user_id);
    update_user_meta( $user_id, 'ref_pageID', $refProfilePost);
    update_user_meta( $user_id, 'user_url', get_the_permalink($refProfilePost));
    error_log("Creating profile :".$profileID." (User : ".$user_id.")");
  }
  elseif ((get_user_meta( $user_id, 'wp_capabilities')[0]['referee'] == null) && (metadata_exists('user', $user_id, 'ref_pageID'))) {
    $profileID = get_user_meta( $user_id, 'ref_pageID')[0];
    $postUpdateArgs = array(
      'ID'          => $profileID,
      'post_status' => "publish"
    );
    wp_update_post($postUpdateArgs);
    error_log("Publishing profile :".$profileID." (User : ".$user_id.")");
  }
}
add_action( 'profile_update', 'site_refProfile_existingUser',10, 2);

Solution

  • Update: Found solution

    So I don't think the profile_update hook works the way its supposed to or I am using it wrong either way. what I found was that profile_update fired before the updates to the post/user were pushed, which meant if i was to check the values of the meta they would be the old ones, even though in the WP Docs it says it passes on the old values for the user as a variable to the called function which i amused meant that if I query for a metavalue in the function it would be the updated one.

    If you need a hook which checks if any metavalue on any post type (even user) and more importantly fires AFTER the update is pushed to the data tables use updated_{YOUR POST TYPE}_meta (WP Docs).

    so instead of

    add_action( 'profile_update', 'site_refProfile_existingUser', 10, 2);
    

    I used this

    add_action( 'updated_user_meta', 'site_refProfile_existingUser',10, 2);
    

    Also make sure in your function you remove_action at the start and add_action at the end if you are updating the meta of the user otherwise i assume it will get stuck in a infinite loop

    function site_refProfile_existingUser( $meta_id, $user_id) {
        remove_action( 'updated_user_meta', 'site_refProfile_existingUser',10, 2);
    
        // your code.....
    
        add_action( 'updated_user_meta', 'site_refProfile_existingUser',10, 2);
    }
    

    (The infinite loop thing is an assumption as its happened to me before while using another hook)