Habari\ACL::get_user_token_access PHP Method

get_user_token_access() public static method

Return the access bitmask to a specific token for a specific user
public static get_user_token_access ( User | integer $user, string | integer $token ) : Bitmask
$user User | integer A User object instance or user id
$token string | integer A permission token name or token ID
return Bitmask An access bitmask
    public static function get_user_token_access($user, $token)
    {
        // Use only numeric ids internally
        $token_id = self::token_id($token);
        /**
         * Do we allow perms that don't exist?
         * When ACL is functional ACCESS_NONEXISTENT_PERMISSION should be false by default.
         */
        if (is_null($token_id)) {
            return self::get_bitmask(self::ACCESS_NONEXISTENT_PERMISSION);
        }
        // if we were given a user ID, use that to fetch the group membership from the DB
        if (is_numeric($user)) {
            $user_id = $user;
        } else {
            // otherwise, make sure we have a User object, and get
            // the groups from that
            if (!$user instanceof User) {
                $user = User::get($user);
            }
            $user_id = $user->id;
        }
        if (defined('LOCKED_OUT_SUPER_USER') && $token == 'super_user') {
            $su = User::get(LOCKED_OUT_SUPER_USER);
            if ($su->id == $user_id) {
                return new Bitmask(self::access_names(), 'read');
            }
        }
        // check the cache first for the user's access_mask on the token
        if (isset($_SESSION['user_token_access']) && isset($_SESSION['user_token_access'][$user_id][$token_id])) {
            if ($_SESSION['user_token_access'][$user_id][$token_id] == ACL::CACHE_NULL) {
                return null;
            } else {
                return self::get_bitmask($_SESSION['user_token_access'][$user_id][$token_id]);
            }
        }
        /**
         * Jay Pipe's explanation of the following SQL
         * 1) Look into user_permissions for the user and the token.
         * If exists, use that permission flag for the check. If not,
         * go to 2)
         *
         * 2) Look into the group_permissions joined to
         * users_groups for the user and the token.  Order the results
         * by the access bitmask. The lower the mask value, the
         * fewest permissions that group has. Use the first record's
         * access mask to check the ACL.
         *
         * This gives the system very fine grained control and grabbing
         * the permission flag and can be accomplished in a single SQL
         * call.
         */
        $exceptions = '';
        $default_groups = array();
        $default_groups = Plugins::filter('user_default_groups', $default_groups, $user_id);
        $default_groups = array_filter(array_map('intval', $default_groups));
        switch (count($default_groups)) {
            case 0:
                // do nothing
                break;
            case 1:
                // single argument
                $exceptions = 'OR ug.group_id = ' . reset($default_groups);
                break;
            default:
                // multiple arguments
                $exceptions = 'OR ug.group_id IN (' . implode(',', $default_groups) . ')';
                break;
        }
        $sql = <<<SQL
SELECT access_mask
\tFROM {user_token_permissions}
\tWHERE user_id = ?
\tAND token_id = ?
UNION ALL
SELECT gp.access_mask
\tFROM {users_groups} ug
\tINNER JOIN {group_token_permissions} gp
\tON ((ug.group_id = gp.group_id
\tAND ug.user_id = ?)
\t{$exceptions})
\tAND gp.token_id = ?
\tORDER BY access_mask ASC
SQL;
        if ($token_id == '') {
            $token_id = '0';
        }
        $accesses = DB::get_column($sql, array($user_id, $token_id, $user_id, $token_id));
        $accesses = Plugins::filter('user_token_access', $accesses, $user_id, $token_id);
        if (count($accesses) == 0) {
            if ($user_id == 0) {
                // @todo store this anonymous user token info in Cache
            } else {
                $_SESSION['user_token_access'][$user_id][$token_id] = ACL::CACHE_NULL;
            }
            return null;
        } else {
            $result = 0;
            foreach ((array) $accesses as $access) {
                if ($access == 0) {
                    $result = 0;
                    break;
                } else {
                    $result |= $access;
                }
            }
            if ($user_id == 0) {
                // @todo store this anonymous user token info in Cache
            } else {
                $_SESSION['user_token_access'][$user_id][$token_id] = $result;
            }
            return self::get_bitmask($result);
        }
    }