finished_at ), Ui::datetime( $last->finished_at ) ) ); } else { esc_html_e( 'No completed scan yet.', 'siteaudithub' ); } ?>

>
stage_label( $active->stage ) ) : ''; ?> %
processed_items ), number_format_i18n( $active->total_items ) ) ); } ?> status ), Ui::allowed_html() ) : ''; ?>

error_message ) ? '' : 'hidden'; ?>>error_message ) : ''; ?>

status ) { continue; } $counts = array_fill_keys( $levels, 0 ); foreach ( Repository::finding_matrix( $scan->id ) as $by_severity ) { foreach ( $levels as $level ) { $counts[ $level ] += isset( $by_severity[ $level ] ) ? (int) $by_severity[ $level ] : 0; } } $ts = strtotime( $scan->finished_at . ' UTC' ); $scans[] = array( 'id' => (int) $scan->id, 'date' => $ts ? wp_date( 'M j', $ts ) : '', 'time' => $ts ? wp_date( get_option( 'time_format' ), $ts ) : '', 'when' => Ui::datetime( $scan->finished_at ), 'counts' => $counts, 'total' => array_sum( $counts ), ); if ( count( $scans ) >= 10 ) { break; } } if ( ! $scans ) { return; } $scans = array_reverse( $scans ); // Oldest first, left to right. $dates = array_count_values( wp_list_pluck( $scans, 'date' ) ); $latest = end( $scans ); $prev = count( $scans ) > 1 ? $scans[ count( $scans ) - 2 ] : null; $uid = 'sah-trend-' . sanitize_key( $type ); ?>

1; $data = array(); foreach ( $scans as $s ) { $rows = array(); foreach ( $levels as $level ) { $rows[] = array( $level, $names[ $level ], number_format_i18n( $s['counts'][ $level ] ) ); } $data[] = array( 'total' => $s['total'], 'label' => number_format_i18n( $s['total'] ), 'date' => $s['date'], 'time' => $multi && $dates[ $s['date'] ] > 1 ? $s['time'] : '', 'title' => sprintf( /* translators: 1: scan id, 2: date */ __( 'Scan #%1$d · %2$s', 'siteaudithub' ), $s['id'], $s['when'] ), /* translators: %s: number of issues */ 'sum' => sprintf( _n( '%s issue', '%s issues', $s['total'], 'siteaudithub' ), number_format_i18n( $s['total'] ) ), 'rows' => $rows, ); } ?>

count. * @return string */ public static function severity_bar( array $counts ) { $total = array_sum( $counts ); if ( ! $total ) { return ''; } $out = ''; } /** * Severity legend with counts. * * @param array $counts severity => count. * @param array $link Base args for filter links (optional). * @return string */ public static function severity_legend( array $counts, array $link = array() ) { $out = ''; } /** * Filterable, paginated findings list. * * @param object $scan Scan. * @param string $module Module code. * @param string $page Admin page slug. * @param array $scope Optional: 'check_id' (limit to these checks), 'link' (extra query args kept by filters), 'title', 'empty' (text when nothing is found). */ public static function findings( $scan, $module, $page, array $scope = array() ) { $scope = wp_parse_args( $scope, array( 'check_id' => array(), 'link' => array(), 'title' => __( 'Findings', 'siteaudithub' ), 'empty' => __( 'No issues were detected by the checks performed in this scan. Automated checks cannot find every problem.', 'siteaudithub' ), ) ); $severity = Admin::filter( 'severity', array_keys( Catalog::severities() ) ); $class = Admin::filter( 'classification', array_keys( Catalog::classifications() ) ); $change = Admin::filter( 'change', array( 'new', 'recurring' ) ); $view = Admin::filter( 'view', array( 'open', 'ignored', 'all' ) ); $check = Admin::filter( 'check' ); $search = Admin::filter( 's' ); $paged = max( 1, absint( Admin::filter( 'paged' ) ) ); $view = $view ? $view : 'open'; $args = array( 'module' => $module, 'severity' => $severity, 'classification' => $class, 'change_status' => $change, 'check_id' => $check ? sanitize_key( $check ) : $scope['check_id'], 'search' => $search, 'view' => $view, 'page' => $paged, 'per_page' => 20, ); list( $rows, $total ) = Repository::query_findings( $scan->id, $args ); $ignored = Repository::ignored(); $base = array_filter( $scope['link'] + array( 'page' => $page, 'scan' => (int) $scan->id, 'severity' => $severity, 'classification' => $class, 'change' => $change, 'check' => $check, 's' => $search, 'view' => 'open' === $view ? '' : $view, ) ); $classes = array(); foreach ( Repository::check_counts( $scan->id, $module ) as $row ) { $classes[ $row->classification ] = true; } ?>

$siteaudithub_v ) : ?>

change_status ) ? $f->change_status : ''; ?>
  • severity ), Ui::allowed_html() ); ?> title ); ?> item_key ), Ui::allowed_html() ); ?> classification ), Ui::allowed_html() ); ?>

    description ); ?>

    evidence ) : ?>

    evidence ); ?>

    recommendation ); ?>

    detection_method ); ?>
    check_id ); ?>
    created_at ) ) : ?>
    created_at ) ); ?>
    fingerprint ) ) : ?>
  • id, $module ); if ( ! $rows ) { return; } $checks = Catalog::checks(); ?>

    check_id ] ) ? $checks[ $row->check_id ]['title'] : $row->title ); ?> severity ), Ui::allowed_html() ); ?> classification ), Ui::allowed_html() ); ?> c ) ); ?>
    '; } else { echo '
    '; } echo ''; echo '' . esc_html( is_numeric( $value ) ? number_format_i18n( (float) $value ) : $value ) . ''; echo '' . esc_html( $label ) . ''; echo $url ? '' : '
    '; } /** * Notice shown when a module has no completed scan yet. * * @param string $type Scan type. */ public static function no_scan( $type ) { $btn = ''; echo wp_kses( Ui::empty_state( __( 'No results yet', 'siteaudithub' ), 'integrity' === $type ? __( 'Run a malware & integrity scan to inspect your WordPress files. The scan is read-only and never changes files.', 'siteaudithub' ) : __( 'Run a site audit to discover your published URLs and check them for SEO, accessibility and technical issues.', 'siteaudithub' ), Repository::active_scan( $type ) ? '

    ' . esc_html__( 'A scan is in progress. Results appear here when it finishes.', 'siteaudithub' ) . '

    ' : $btn ), Ui::allowed_html() ); } }