|null
*/
private function site_health_summary() {
$health = get_transient( 'health-check-site-status-result' );
$health = is_string( $health ) ? json_decode( $health, true ) : $health;
if ( ! is_array( $health ) || ! isset( $health['critical'], $health['recommended'] ) || ! is_numeric( $health['critical'] ) || ! is_numeric( $health['recommended'] ) ) {
return null;
}
return array(
'critical' => absint( $health['critical'] ),
'recommended' => absint( $health['recommended'] ),
);
}
/** Stop direct access to page callbacks. */
private function require_access() {
if ( ! current_user_can( self::CAPABILITY ) ) {
wp_die( esc_html__( 'You do not have permission to access this page.', 'adminwatch-central' ) );
}
}
/** @return int */
private function requested_page() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only pagination state.
$paged = isset( $_GET['paged'] ) ? sanitize_text_field( wp_unslash( $_GET['paged'] ) ) : 1;
return max( 1, absint( $paged ) );
}
/**
* Render pagination preserving explicit AdminWatch Central query state.
*
* @param int $page Current page.
* @param int $total Total records.
* @param array $args Query arguments to preserve.
*/
private function pagination( $page, $total, $args = array() ) {
$pages = (int) ceil( $total / self::PER_PAGE );
if ( $pages < 2 ) {
return;
}
$base = add_query_arg( array_merge( $args, array( 'paged' => '%#%' ) ), admin_url( 'admin.php' ) );
echo wp_kses_post(
paginate_links(
array(
'base' => $base,
'format' => '',
'current' => $page,
'total' => $pages,
)
)
);
}
/**
* Render the shared AdminWatch Central page heading.
*
* @param string $title Current page title.
* @param string $description Short page description.
* @param bool $is_dashboard Whether this is the dashboard.
*/
private function page_header( $title, $description, $is_dashboard = false ) {
?>
$roles Eligible roles.
* @param string $selected Selected role slug.
* @param bool $sessions Whether the session filter is active.
*/
private function users_filter_navigation( $roles, $selected = '', $sessions = false ) {
?>
require_access();
$repository = new WebStudio_Admin_Watch_404_Repository();
$access_roles = $this->access_roles();
$available_roles = count_users()['avail_roles'];
$role_counts = array();
$health = $this->site_health_summary();
$access_user_ids = $this->access_user_ids( $access_roles );
$session_counts = $this->active_session_counts( $access_user_ids );
$session_total = array_sum( $session_counts );
$active_users = count( $session_counts );
$today_hits = $repository->daily_hit_count( $this->site_date(), $this->site_date() );
$seven_day_hits = $repository->daily_hit_count( $this->site_date( 6 ), $this->site_date() );
$mfa_detector = new WebStudio_Admin_Watch_MFA_Detector();
$security = array( 'password_recorded' => 0, 'strong_medium' => 0, 'mfa_enabled' => 0, 'mfa_unknown' => 0 );
foreach ( $access_roles as $slug => $name ) {
$count = isset( $available_roles[ $slug ] ) ? (int) $available_roles[ $slug ] : 0;
if ( $count ) {
$role_counts[ $name ] = $count;
}
}
$users = get_users(
array(
'meta_key' => WebStudio_Admin_Watch_Login_Monitor::META_KEY,
'number' => 5,
'orderby' => 'meta_value_num',
'order' => 'DESC',
'role__in' => array_keys( $access_roles ),
)
);
update_meta_cache( 'user', $access_user_ids );
foreach ( $access_user_ids as $user_id ) {
$password_changed = get_user_meta( $user_id, WebStudio_Admin_Watch_Password_Monitor::CHANGED_META_KEY, true );
$password_strength = get_user_meta( $user_id, WebStudio_Admin_Watch_Password_Monitor::STRENGTH_META_KEY, true );
$mfa_status = $mfa_detector->status_for_user( $user_id );
if ( $password_changed ) {
++$security['password_recorded'];
}
if ( in_array( $password_strength, array( 'medium', 'strong' ), true ) ) {
++$security['strong_medium'];
}
if ( WebStudio_Admin_Watch_MFA_Detector::ENABLED === $mfa_status ) {
++$security['mfa_enabled'];
}
if ( WebStudio_Admin_Watch_MFA_Detector::NOT_DETECTED === $mfa_status ) {
++$security['mfa_unknown'];
}
}
?>
page_header( __( 'AdminWatch Central', 'adminwatch-central' ), __( 'Know who can change your WordPress website.', 'adminwatch-central' ), true ); ?>
- display_name ); ?>role_label( $user ) ); ?>
$roles Eligible role labels.
* @param string $search Optional user search.
*/
private function active_session_users( $roles, $search ) {
$session_counts = $this->active_session_counts( $this->access_user_ids( $roles ) );
$users = $session_counts ? get_users( array( 'include' => array_keys( $session_counts ) ) ) : array();
if ( $search ) {
$users = array_filter(
$users,
function( $user ) use ( $search ) {
return false !== stripos( $user->display_name, $search ) || false !== stripos( $user->user_login, $search ) || false !== stripos( $user->user_email, $search );
}
);
}
usort(
$users,
function( $first, $second ) {
return (int) get_user_meta( $second->ID, WebStudio_Admin_Watch_Login_Monitor::META_KEY, true ) <=> (int) get_user_meta( $first->ID, WebStudio_Admin_Watch_Login_Monitor::META_KEY, true );
}
);
$total_matching = count( $users );
$users = array_slice( $users, 0, 3 );
?>
page_header( __( 'Users & Access', 'adminwatch-central' ), __( 'See which users can make meaningful changes to this website.', 'adminwatch-central' ) ); ?>
users_filter_navigation( $roles, '', true ); ?>
| | | |
| display_name ); ?> | role_label( $user ) ); ?> | time_label( get_user_meta( $user->ID, WebStudio_Admin_Watch_Login_Monitor::META_KEY, true ) ) ); ?> | ID ], 'adminwatch-central' ), $session_counts[ $user->ID ] ) ); ?> |
|
3 ) : ?>
require_access();
$roles = $this->access_roles();
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only filter state.
$session_filter = isset( $_GET['session'] ) && 'active' === sanitize_key( wp_unslash( $_GET['session'] ) );
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only filter state.
$selected = isset( $_GET['role'] ) ? sanitize_key( wp_unslash( $_GET['role'] ) ) : '';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only search state.
$search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
if ( $session_filter ) {
$this->active_session_users( $roles, $search );
return;
}
$page = $this->requested_page();
$args = array(
'number' => self::PER_PAGE,
'paged' => $page,
'orderby' => 'display_name',
'order' => 'ASC',
'role__in' => array_keys( $roles ),
'search' => $search ? '*' . $search . '*' : '',
'search_columns' => array( 'display_name', 'user_login', 'user_email' ),
);
if ( $selected && isset( $roles[ $selected ] ) ) {
unset( $args['role__in'] );
$args['role'] = $selected;
} else {
$selected = '';
}
$query = new WP_User_Query( $args );
$total = (int) $query->get_total();
$total_pages = max( 1, (int) ceil( $total / self::PER_PAGE ) );
if ( $page > $total_pages ) {
$page = $total_pages;
$args['paged'] = $page;
$query = new WP_User_Query( $args );
}
$mfa_detector = new WebStudio_Admin_Watch_MFA_Detector();
$user_results = $query->get_results();
update_meta_cache( 'user', wp_list_pluck( $user_results, 'ID' ) );
?>
page_header( __( 'Users & Access', 'adminwatch-central' ), __( 'See which users can make meaningful changes to this website.', 'adminwatch-central' ) ); ?>
users_filter_navigation( $roles, $selected ); ?>
| | | | | |
ID, WebStudio_Admin_Watch_Login_Monitor::META_KEY, true );
$password_changed = get_user_meta( $user->ID, WebStudio_Admin_Watch_Password_Monitor::CHANGED_META_KEY, true );
$password_strength = get_user_meta( $user->ID, WebStudio_Admin_Watch_Password_Monitor::STRENGTH_META_KEY, true );
$mfa_status = $mfa_detector->status_for_user( $user->ID );
?>
display_name ); ?> user_login ); ?> user_email ); ?> | role_label( $user ) ); ?> | time_label( $last_login ) ); ?> | time_label( $password_changed ) ); ?> | status_badge( $this->password_strength_label( $password_strength ), $password_strength ? 'strength-' . $password_strength : 'not-recorded' ); ?> | status_badge( $this->mfa_label( $mfa_status ), $mfa_status ); ?> |
|
pagination( $page, $total, array_filter( array( 'page' => 'admin-watch-users', 'role' => $selected, 's' => $search ) ) ); ?>
require_access();
$repository = new WebStudio_Admin_Watch_404_Repository();
$page = $this->requested_page();
$total = $repository->count_items();
$total_pages = max( 1, (int) ceil( $total / self::PER_PAGE ) );
$page = min( $page, $total_pages );
$items = $repository->get_items( $page, self::PER_PAGE );
?>
page_header( __( '404 Monitor', 'adminwatch-central' ), __( 'See broken URLs visitors are reaching.', 'adminwatch-central' ) ); ?>
| | |
url ); ?> | hit_count ) ); ?> | last_seen . ' UTC' ) ) ); ?> |
|
pagination( $page, $total, array( 'page' => 'admin-watch-404s' ) ); ?>
require_access();
$settings = wp_parse_args( get_option( 'admin_watch_settings', array() ), array( 'monitor_404s' => 1, 'retention_days' => 30, 'delete_data' => 0 ) );
?>
page_header( __( 'Settings', 'adminwatch-central' ), __( 'Configure AdminWatch Central Free.', 'adminwatch-central' ) ); ?>
require_access();
$website_url = 'https://webstudiowa.com.au/';
$github_url = 'https://github.com/asankalk/admin-watch-free';
$bug_url = 'mailto:hello@webstudiowa.com.au?subject=' . rawurlencode( __( 'AdminWatch Central Bug Report', 'adminwatch-central' ) );
$support_url = 'mailto:hello@webstudiowa.com.au?subject=' . rawurlencode( __( 'AdminWatch Central Support', 'adminwatch-central' ) );
?>
page_header( __( 'About & Support', 'adminwatch-central' ), __( 'Product information, support and privacy details for AdminWatch Central Free.', 'adminwatch-central' ) ); ?>