$left; } ); if ( count( $results ) > self::MAX_RESULTS ) { $results = array_slice( $results, 0, self::MAX_RESULTS, true ); } // Explicitly non-autoloaded: this can reach a few hundred kilobytes and // has no business being loaded on every front-end request. update_option( self::OPTION, $results, false ); } /** * Fetch one stored result. * * @param string $url Page URL. * @return array|null */ public static function get( $url ) { $results = self::all(); $key = self::key_for( $url ); return isset( $results[ $key ] ) ? $results[ $key ] : null; } /** * Remove one stored result. * * @param string $url Page URL. * @return void */ public static function forget( $url ) { $results = self::all(); $key = self::key_for( $url ); if ( isset( $results[ $key ] ) ) { unset( $results[ $key ] ); update_option( self::OPTION, $results, false ); } } /** * Drop every stored result. * * @return void */ public static function clear() { delete_option( self::OPTION ); } /** * Site-wide roll-up across every scanned page. * * @return array */ public static function summary() { $results = self::all(); $summary = array( 'pages' => count( $results ), 'critical' => 0, 'serious' => 0, 'moderate' => 0, 'minor' => 0, 'elements' => 0, 'average_score' => null, 'worst_page' => null, 'last_scanned_at' => 0, 'fixable_rules' => array(), 'top_issues' => array(), ); if ( ! $results ) { return $summary; } $scores = array(); $issue_tally = array(); $worst = null; foreach ( $results as $result ) { $counts = isset( $result['counts'] ) ? $result['counts'] : array(); foreach ( array( 'critical', 'serious', 'moderate', 'minor' ) as $level ) { $summary[ $level ] += isset( $counts[ $level ] ) ? (int) $counts[ $level ] : 0; } $summary['elements'] += isset( $result['elements'] ) ? (int) $result['elements'] : 0; $scores[] = isset( $result['score'] ) ? (int) $result['score'] : 100; if ( isset( $result['scanned_at'] ) && $result['scanned_at'] > $summary['last_scanned_at'] ) { $summary['last_scanned_at'] = (int) $result['scanned_at']; } if ( null === $worst || $result['score'] < $worst['score'] ) { $worst = $result; } if ( ! empty( $result['issues'] ) && is_array( $result['issues'] ) ) { foreach ( $result['issues'] as $issue ) { $rule = isset( $issue['id'] ) ? $issue['id'] : ''; if ( '' === $rule ) { continue; } if ( ! isset( $issue_tally[ $rule ] ) ) { $issue_tally[ $rule ] = array( 'id' => $rule, 'impact' => isset( $issue['impact'] ) ? $issue['impact'] : 'moderate', 'pages' => 0, 'elements' => 0, 'autoFixable' => ! empty( $issue['autoFixable'] ), ); } $issue_tally[ $rule ]['pages']++; $issue_tally[ $rule ]['elements'] += isset( $issue['count'] ) ? (int) $issue['count'] : 0; if ( ! empty( $issue['autoFixable'] ) ) { $summary['fixable_rules'][ $rule ] = true; } } } } $summary['average_score'] = (int) round( array_sum( $scores ) / count( $scores ) ); $summary['worst_page'] = $worst; $summary['fixable_rules'] = array_keys( $summary['fixable_rules'] ); $order = array( 'critical' => 0, 'serious' => 1, 'moderate' => 2, 'minor' => 3, ); uasort( $issue_tally, static function ( $a, $b ) use ( $order ) { $left = isset( $order[ $a['impact'] ] ) ? $order[ $a['impact'] ] : 4; $right = isset( $order[ $b['impact'] ] ) ? $order[ $b['impact'] ] : 4; if ( $left !== $right ) { return $left <=> $right; } return $b['elements'] <=> $a['elements']; } ); $summary['top_issues'] = array_values( $issue_tally ); return $summary; } /** * Stable storage key for a URL. * * @param string $url Page URL. * @return string */ private static function key_for( $url ) { return md5( untrailingslashit( (string) $url ) ); } }