ID && !is_super_admin($user->ID) && !in_array(get_current_blog_id(), array_keys(get_blogs_of_user($user->ID)), TRUE)) $user_or_wp_error = new WP_Error('invalid_username', _x('ERROR: Invalid username for this site.', 's2member-front', 's2member')); return apply_filters('ws_plugin__s2member_ms_wp_authenticate_user', $user_or_wp_error, get_defined_vars()); } /** * Assists in User authentication (stops max simultaneous logins). * * @package s2Member\Login_Checks * @since 131025 * * @attaches-to ``add_filter('wp_authenticate_user');`` * * @param WP_User|WP_Error Expects either a WP_User or WP_Error object passed in by the Filter. * * @return WP_User|WP_Error WP_User or WP_Error object (if there was a problem). */ public static function stop_simultaneous_logins($user_or_wp_error) { if(!($max = $GLOBALS['WS_PLUGIN__']['s2member']['o']['max_simultaneous_logins'])) return $user_or_wp_error; // Simultaneous login monitoring not enabled here. foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_before_stop_simultaneous_logins', get_defined_vars()); unset($__refs, $__v); if(is_a($user_or_wp_error, 'WP_User') && ($user = $user_or_wp_error) && $user->ID && !is_super_admin($user->ID) && c_ws_plugin__s2member_login_checks::get_simultaneous_logins($user->user_login) + 1 > $max) $user_or_wp_error = new WP_Error('max_simultaneous_logins', sprintf(_x('ERROR: Max simultaneous logins for username: %1$s. Please wait %2$s and try again.', 's2member-front', 's2member'), $user->user_login, $GLOBALS['WS_PLUGIN__']['s2member']['o']['max_simultaneous_logins_timeout'])); return apply_filters('ws_plugin__s2member_stop_simultaneous_logins', $user_or_wp_error, get_defined_vars()); } /** * Monitors simultaneous logins (updates timer on each page view). * * @package s2Member\Login_Checks * @since 131025 * * @attaches-to ``add_action('init');`` * * @param WP_User|WP_Error Expects either a WP_User or WP_Error object passed in by the Filter. * * @return WP_User|WP_Error WP_User or WP_Error object (if there was a problem). */ public static function monitor_simultaneous_logins() { if(!is_user_logged_in() || is_super_admin()) return; // Nothing to do here. if(!($max = $GLOBALS['WS_PLUGIN__']['s2member']['o']['max_simultaneous_logins'])) return; // Simultaneous login monitoring not enabled here. foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_before_monitor_simultaneous_logins', get_defined_vars()); unset($__refs, $__v); $user = wp_get_current_user(); $username = $user->user_login; // The username. c_ws_plugin__s2member_login_checks::update_simultaneous_logins($username, $user, 'timer'); } /** * Handles simultaneous logouts. * * @package s2Member\Login_Checks * @since 131025 * * @attaches-to ``add_action('clear_auth_cookie');`` */ public static function simultaneous_logout() { if(!is_user_logged_in() || is_super_admin()) return; // Nothing to do here. if(!($max = $GLOBALS['WS_PLUGIN__']['s2member']['o']['max_simultaneous_logins'])) return; // Simultaneous login monitoring not enabled here. foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_before_simultaneous_logout', get_defined_vars()); unset($__refs, $__v); $user = wp_get_current_user(); $username = $user->user_login; // The username. c_ws_plugin__s2member_login_checks::update_simultaneous_logins($username, $user, 'decrement'); } /** * Get simultaneous logins for a particular username. * * @package s2Member\Login_Checks * @since 131025 * * @param string $username Expects a username (e.g., a `user_login` value). * * @return integer Current number of simultaneous logins. */ public static function get_simultaneous_logins($username) { if(!$username) return 0; // Nothing to get. foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_before_get_simultaneous_logins', get_defined_vars()); unset($__refs, $__v); $prefix = 's2m_slm_'; // s2Member Transient prefix for all simultaneous login monitoring. $transient_entries = $prefix.md5('s2member_simultaneous_login_entries_for_'.strtolower((string)$username)); $timeout = $GLOBALS['WS_PLUGIN__']['s2member']['o']['max_simultaneous_logins_timeout']; $timeout_ago = strtotime('-'.$timeout); // e.g., 30 minutes ago. $entries = (is_array($entries = get_transient($transient_entries))) ? $entries : array(); foreach($entries as $_entry => $_time /* Auto-expire entries, based on time. */) if($_time < $timeout_ago) unset($entries[$_entry]); return apply_filters('ws_plugin__s2member_get_simultaneous_logins', count($entries), get_defined_vars()); } /** * Update simultaneous logins for a particular username. * * @package s2Member\Login_Checks * @since 131025 * * @attaches-to ``add_action('wp_login');`` * * @param string $username Expects a username (e.g., a `user_login` value). * @param WP_User|null $user When fired against `wp_login` this receives a WP_User object also. * @param string $action Default action is to increment the counter. This can be set to `decrement` or NULL to do nothing. */ public static function update_simultaneous_logins($username, $user = NULL, $action = 'increment') { if(!$username) return; // Nothing to do. foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_before_update_simultaneous_logins', get_defined_vars()); unset($__refs, $__v); $prefix = 's2m_slm_'; // s2Member Transient prefix for all simultaneous login monitoring. $transient_entries = $prefix.md5('s2member_simultaneous_login_entries_for_'.strtolower((string)$username)); $timeout = $GLOBALS['WS_PLUGIN__']['s2member']['o']['max_simultaneous_logins_timeout']; $timeout_ago = strtotime('-'.$timeout); // e.g., 30 minutes ago. $entries = (is_array($entries = get_transient($transient_entries))) ? $entries : array(); foreach($entries as $_entry => $_time /* Auto-expire entries, based on time. */) if($_time < $timeout_ago) unset($entries[$_entry]); $total_entries = count($entries); // May need this below. if($action === 'increment') $entries[] = time(); // New entry. else if($action === 'decrement') array_pop($entries); // Remove last entry. else if($action === 'timer') // Update time on last entry; or add a new entry. $entries[(($total_entries) ? $total_entries - 1 : 0)] = time(); set_transient($transient_entries, $entries, strtotime('+'.$timeout) - time()); foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_after_update_simultaneous_logins', get_defined_vars()); unset($__refs, $__v); } } }