Support

Account

Home Forums General Issues Show online offline status automatically

Solving

Show online offline status automatically

  • Hey guys,

    I would like to use ACF to show whether or not a user with the role ‘advisor’ is online. As of now I have a true/false field set up (inside a group) and I can manually switch between the different statuses for each user and see the update reflected on the frontend. However I would like this to function automatically, and this is where I’m lost.

    This is the function I have produced so far – but it’s not working.

    add_action('wp_loaded', 'itc_assign_advisor_online_status');
    
    function itc_assign_advisor_online_status() {
    	$online_status = get_field('onlinestatus');
    
    	if (is_user_logged_in() && ! current_user_can( 'administrator' )) {
    		$online_status['is_online'] = 1;
    	} else {
    		update_field($online_status['is_online'], 0);
    	}
    }

    Am I using the wrong hook, maybe?

    For the record, this is my graphical interface code:

    <?php
    
    $online_status = get_field('onlinestatus');
    $green_status = 'online';
    $yellow_fill_status = 'busy--filled';
    $red_fill_status = 'offline--filled';
    $yellow_border_status = 'busy';
    $red_border_status = 'offline';
    
            if ($online_status) { ?>
              <div class="card__btn-block">
                <a href="#" class="btn rounded <?php
                  if ($online_status['is_online']) {
                    echo $green_status;
                  }
                  if ($online_status['is_busy']) {
                    echo $yellow_border_status;
                  }
                  if ($online_status['is_offline']) {
                    echo $red_border_status;
                  } ?>"><?php
                  if ($online_status['is_online']) {
                    echo 'Available';
                  }
                  if ($online_status['is_busy']) {
                    echo 'Busy';
                  }
                  if ($online_status['is_offline']) {
                    echo 'Offline';
                  }
                  ?></a>
              </div>
            <?php } ?>

    Any help is highly appreciated!

  • You have several issues and I’m not sure where to start.

    This is the current user and would have nothing some other user that may or may not be logged in.

    
    is_user_logged_in()
    

    In order to update the field for the user when they log in you would need to use the wp_login hook and to set the value when they log out you would need to use the wp_logout hook.

    Unfortunately wp_logout only fires when the user actually logs out. A user can simply close their browser, this could log them out and make them unavailable without actually firing the logout hook.

    When getting or updating a field on a user you must supply the correct user ID to ACF. This would not be the value returned by is_user_logged_in(), this only returns the current user an could not be used to check a value on another user. So you need to determine what user you actually want to see if they are online and then construct the correct ID to give ACF.

    The post ID that ACF is expecting is

    
    $post_id = "user_{$user_id}";
    

    Then you can get or update the value for the field for that user

    
    // get field
    $online_status = get_field('onlinestatus', $post_id);
    // update field
    update_field('onlinestatus', $value, $post_id);
    

    When updating a field you should really used the field key and not the field name so the above should be something like this.

    
    // where field_XXXXXXX is the field key of the field named 'onlinestatus'
    update_field('field_XXXXXXX', $value, $post_id);
    

    In addition to this, when updating a group field ACF expects and array of field key => value pairs to be updated and you must supply a value for every sub field even if you are not changing the value. Any sub field the you do not include will likely be set to NULL.

    
    $value = array(
      'field_YYYYYYY' => 'value for field',
      'field_ZZZZZZZ' => 'value for field',
      // etc
    );
    update_field('field_XXXXXXX', $value, $post_id);
    

    Now what you need to figure out is how to get the Advisor user ID that is associated with the user that is currently logged in.

  • Hi, thank you for your answer. I will give your proposals a try. But this isn’t the actual format though, is it $post_id = "user_{$user_id}";? Looks weird, almost like the javascript template literals. Please correct me if I’m wrong.

    I have found a different possible solution involving the use of get_transient() function that may or may not be a better way of handling this. I’m not sure yet, because I haven’t got it working as of yet.

    I know it’s off topic in this forum but if it could help someaone else with a similar issue, I’ll post my current code here. And just to clarify, my “advisors” are actually a custom post type where each post will have an author (user) connected to them.

    In functions.php:

    <?php
    function is_user_online( $user_id ) {
        // get the online users list
        $logged_in_users = get_transient( 'users_online' );
    
        // online, if user is in the list and last activity was less than 15   minutes ago
        return isset( $logged_in_users[$user_id] ) && ( $logged_in_users[$user_id] >     ( current_time( 'timestamp' ) - ( 15 * 60 ) ) );
    }
    ?>

    And in the template file (in my case this is in a child theme, template partial file):

    <?php
                  if (is_user_online( $post->post_author )) {
                    echo $green_status;
                  } else {
                      echo $red_border_status;
                  } ?>"><?php
                  if (is_user_online( $post->post_author )) {
                    echo 'Available';
                  } else {
                      echo 'Offline';
                  }
    
    // and the card status message
    
    if (is_user_online( $post->post_author )) {
              echo $green_status;
            }
            if (! is_user_online( $post->post_author )) {
              echo $red_fill_status;
            } ?>">
            <?php
            if (is_user_online( $post->post_author )) {
              echo 'online';
            }
            if (! is_user_online( $post->post_author )) {
              echo 'offline';
                  ?>

    This is working in the way that the css selector is actually echoed out, giving the button and the status message color AND text content. However it still does not seem to recognize if the user is actually logged in or not, because it always returns the same value – the css selector for the red color and the “Offline” status text.

  • I thought you were getting fields from a user. See this doc https://www.advancedcustomfields.com/resources/how-to-get-values-from-a-user/

    Transients would be a better way to go. I would set a different transient for each user with a small expiration time. If the transient has expired then the user in no longer logged in. Updated it each time the user interacts with a page or build a JavaScript/AJAX script that updates the transient as long at user has the site open.

  • Hi John,

    Please forget everything mentioned above because the circumstances have changed drastically since my last post. So, here comes the new conditions:

    A custom post type called “agents” is used to retrieve data from an external api, where all the info about each agent is entered and saved.

    I have registered some custom REST fields for all the incoming data (collected by an AJAX call) and then collecting and returning the data for these into any given custom field. This is the code used for that:

    // Register custom Rest field
    add_action('rest_api_init','itc_custom_rest');
    
    // Collect the data from REST and return the given custom field
    function itc_custom_rest() {
        register_rest_field('radgivare', 'minutePrice', array(
    		'get_callback' => function() {
    			return get_field('price_per_minute');
    		},
    		'get_callback' => function() {
    			return get_field('agent_status_available');
    		},
    		'get_callback' => function() {
    			return get_field('agent_status_inCall');
    		},
    		'get_callback' => function() {
    			return get_field('agent_status_loggedOut');
    		}
    	));
    }

    The new fields show up in REST alright.

    My big question now is, can I use the following code in order to echo whatever is retrieved from REST, or do I need to use something else?

    // Example used to echo certain colors and texts if the fields (which are type bool) are true
    <div class="card__btn-block">
                <a href="#" class="btn rounded <?php
                  if (get_field('agent_status_available')) {
                    echo $green_status;
                  }
                  if (get_field('agent_status_inCall')) {
                    echo $yellow_border_status;
                  } else {
                      echo $red_border_status;
                  } ?>">
                  <?php
                  if (get_field('agent_status_available')) {
                    echo 'Call Now';
                  } 
                  if (get_field('agent_status_inCall')) {
                    echo 'In Call';
                  } else {
                      echo 'Offline';
                  }
                  ?></a>
              </div>

    Thank you very much for your superior efforts of helping clueless people like myself!

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.