• Resolved TWD

    (@twd)


    Can anyone tell me why this plugin is throwing the “undefined function” error?
    It needs work to actually “do” something … obviously.
    But I’ve stripped it back to basics to debug the error.

    <?php 
    
    /**
     * Plugin Name: Utility Functions
     * Author: Me
     * Version: 1.0
     * Author URI: https://www.mysite.com
     * Description: Adds role to body classes etc
     */
    
    if ( is_user_logged_in() ) {
      add_filter('body_class','add_role_to_body');
      add_filter('admin_body_class','add_role_to_body');
    }
    function add_role_to_body($classes) {
      
      return $classes;
    }
    /* Add logged in user role as a body class for front or back end*/
Viewing 15 replies - 1 through 15 (of 16 total)
  • Bunty

    (@bhargavbhandari90)

    Thread Starter TWD

    (@twd)

    Thanks! Thats good info.

    I read the codex.

    What’s the deal with “pluggable functions”?
    Are they all going to be deprecated over time?
    Am I setting myself up for future headaches by using them?

    Bunty

    (@bhargavbhandari90)

    What’s the deal with “pluggable functions”?

    – Sorry!!! Not sure what exactly you are asking here.

    Are they all going to be depreciated over time?

    – I don’t think so. But it’s up to WP. If WP is going to depreciate, they will inform us. It’s very rare case.

    Am I setting myself up for future headaches by using them?

    – Not really.

    Dion

    (@diondesigns)

    You can’t call is_user_logged_in() until WordPress initializes the user. Something like this will work:

    add_action('init', function() {
    	if (is_user_logged_in()) {
    		add_filter('body_class','add_role_to_body');
    		add_filter('admin_body_class','add_role_to_body');
    	}
    });

    Purists will object to the use of a closure (inline function) because it means another plugin can’t remove your action unless it removes all init actions. Since you probably don’t want your action removed, purists be dammed. ??

    Thread Starter TWD

    (@twd)

    Great! Thank you.

    To be on the extra safe side, can I add in “function_exists”?

    e.g.

    add_action('init', function() {
      if (function_exists('is_user_logged_in')){
    	if (is_user_logged_in()) {
    		add_filter('body_class','add_role_to_body');
    		add_filter('admin_body_class','add_role_to_body');
    	}
      }
    });
    • This reply was modified 4 years, 8 months ago by TWD.
    Dion

    (@diondesigns)

    The is_user_logged_in() function is in wp-includes/pluggable.php, so it will be available when the init action hook is called. But there is no harm in verifying the function exists…

    Moderator bcworkz

    (@bcworkz)

    FWIW, pluggable functions are each wrapped in if (function_exists()) logic. Since the pluggable.php file is loaded relatively late, defining the same function in a plugin or theme will supersede the same in pluggable.php. Thus you are able to “plug in” your own variation of the same function. Pluggable functions are no more or less likely to be deprecated than any other. They are merely functions the WP devs thought others might need to override for various reasons.

    Thread Starter TWD

    (@twd)

    Thanks for the help (and insights) everyone.

    I’m not sure why the method to append role into the $classes variable is different between admin and non-admin roles but this seems to work. I can’t recall where I copied the code from.

    if (is_admin()) {
                $classes .= 'role-'. $user_role;
              } else {
                $classes[] = 'role-'. $user_role;
              }

    Here is my final code, if anyone else is interested in adding logged in user role as a custom class to the body tag.

    add_action('init', function() {
      if (function_exists('is_user_logged_in')){
    	if (is_user_logged_in()) {
    		add_filter('body_class','add_role_to_body');
    		add_filter('admin_body_class','add_role_to_body');
    	}
            function add_role_to_body($classes) {
              $current_user = new WP_User(get_current_user_id());
              $user_role = array_shift($current_user->roles);
              if (is_admin()) {
                $classes .= 'role-'. $user_role;
              } else {
                $classes[] = 'role-'. $user_role;
              }
              return $classes;
            }  
      }
    });
    /* Add logged in user role as a body class for front or back end*/
    • This reply was modified 4 years, 8 months ago by TWD.
    • This reply was modified 4 years, 8 months ago by TWD.
    • This reply was modified 4 years, 8 months ago by TWD.
    Thread Starter TWD

    (@twd)

    Update:

    I tried to simplify this:

    if (is_admin()) {
                $classes .= 'role-'. $user_role;
              } else {
                $classes[] = 'role-'. $user_role;
              }

    into this:

    $classes[] = 'role-'. $user_role;

    which throws a fatal error while logged in as Admin.

    Fatal error: Uncaught Error: [] operator not supported for strings

    So I am left wondering why the $classes variable is a “string” when logged in as admin but an “array” when not??

    Moderator bcworkz

    (@bcworkz)

    It’s not whether one is logged in as admin or not, it’s whether the request is for front or back end. is_admin() reflects the request type, not role. The admin class filter always passes a string and the front end class filter always passes an array.

    Thread Starter TWD

    (@twd)

    OK. Thanks. This plugin makes sense now.

    fyi I needed to add a space in front of the “string” version otherwise
    the role class name gets concatenated to whatever class name was at the end of the string.

    QUESTION: On a WordPress MultiSite situation, it seems like it still returns “role-administrator” for a network super admin.

    Is there anyway to adjust the code to add a DIFFERENT body class for Super Admins?

    Moderator bcworkz

    (@bcworkz)

    Internally, there is no actual “Super Admin” role. Instead, the super admin’s user has additional capabilities added. Check for “manage_network” capability to determine if a user is super admin.

    Thread Starter TWD

    (@twd)

    So would this work?

    if ( current_user_can('manage_network') ) { do_something(); }

    • This reply was modified 4 years, 8 months ago by TWD.
    Moderator bcworkz

    (@bcworkz)

    Yes, that’s right. Or something like
    $user_role = current_user_can('manage_network') ? 'super-admin': $user_role;
    same idea, different syntax ??

    Thread Starter TWD

    (@twd)

    Thanks again for everyone’s help.
    This is the final code.

    add_action('init', function() {
      if (function_exists('is_user_logged_in')){
    	if (is_user_logged_in()) {
    		add_filter('body_class','add_role_to_body');
    		add_filter('admin_body_class','add_role_to_body');
    	}
            function add_role_to_body($classes) {
              $current_user = new WP_User(get_current_user_id());
                
              if (current_user_can('manage_network')){
                 $user_role = 'super-admin'; 
              } else {
                 $user_role = array_shift($current_user->roles);
              }
                
              if (is_admin()) {
                  $classes .= ' role-'. $user_role;
              } else {
                  $classes[] = 'role-'. $user_role;
              }
                  
              return $classes;
            }  
      }
    });
    /* Add logged in user role as a body class for front or back end*/
    /* Note - the class is added as part of a string for backend, array for front */
Viewing 15 replies - 1 through 15 (of 16 total)
  • The topic ‘Uncaught Error: Call to undefined function is_user_logged_in()’ is closed to new replies.