options = is_array( $options ) ? $options : []; if ( ! self::$runtime_loaded ) { add_action( 'admin_init', [ $this, 'block_admin_access' ] ); self::$runtime_loaded = true; } } /** * Block admin access for specified roles * * @return void */ public function block_admin_access() { if ( wp_doing_ajax() ) { return; } $user = wp_get_current_user(); if ( ! $user || ! $user->exists() ) { return; } if ( isset( $this->options['block_user_roles'] ) && is_array( $this->options['block_user_roles'] ) ) { $roles = []; if ( is_array( $user->roles ) ) { foreach ( $user->roles as $role ) { if ( ! is_scalar( $role ) ) { continue; } $role = sanitize_key( (string) $role ); if ( '' !== $role ) { $roles[] = $role; } } } $roles = array_values( array_unique( $roles ) ); if ( empty( $roles ) ) { return; } if ( in_array( 'administrator', $roles, true ) ) { // Don't block admin. return; } if ( self::should_block_user_roles( $roles, $this->options['block_user_roles'] ) ) { $redirect_url = ! empty( $this->options['block_redirect'] ) ? $this->options['block_redirect'] : home_url(); wp_safe_redirect( $redirect_url ); exit; } } } /** * Whether all of a user's assigned roles are configured as blocked. * * @param array $user_roles User role keys. * @param array $blocked_roles Blocked role keys. * * @return bool */ public static function should_block_user_roles( array $user_roles, array $blocked_roles ): bool { $normalized_user_roles = []; foreach ( $user_roles as $role ) { if ( ! is_scalar( $role ) ) { continue; } $role = sanitize_key( (string) $role ); if ( '' !== $role ) { $normalized_user_roles[] = $role; } } $normalized_user_roles = array_values( array_unique( $normalized_user_roles ) ); if ( empty( $normalized_user_roles ) || in_array( 'administrator', $normalized_user_roles, true ) ) { return false; } $normalized_blocked_roles = []; foreach ( $blocked_roles as $role ) { if ( ! is_scalar( $role ) ) { continue; } $role = sanitize_key( (string) $role ); if ( '' !== $role ) { $normalized_blocked_roles[] = $role; } } $normalized_blocked_roles = array_values( array_unique( $normalized_blocked_roles ) ); return ! empty( $normalized_blocked_roles ) && empty( array_diff( $normalized_user_roles, $normalized_blocked_roles ) ); } /** * Sanitize Block Admin Access options. * * @param array $options Raw options. * * @return array */ public static function sanitize_options( array $options ): array { $sanitized = []; if ( isset( $options['block_user_roles'] ) ) { $roles = array_diff( array_keys( get_editable_roles() ), [ 'administrator' ] ); if ( is_array( $options['block_user_roles'] ) ) { $selected = []; foreach ( $options['block_user_roles'] as $role ) { if ( ! is_scalar( $role ) ) { continue; } $role = sanitize_key( (string) $role ); if ( in_array( $role, $roles, true ) ) { $selected[] = $role; } } $selected = array_values( array_unique( $selected ) ); if ( ! empty( $selected ) ) { $sanitized['block_user_roles'] = $selected; } } } if ( isset( $options['block_redirect'] ) && is_scalar( $options['block_redirect'] ) ) { $sanitized['block_redirect'] = sanitize_url( (string) $options['block_redirect'] ); } $sanitized['hide_admin_bar_globally'] = ! empty( $options['hide_admin_bar_globally'] ) ? 1 : 0; return $sanitized; } }