admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'markproof' ), 'i18n' => array( 'starting' => __( 'Starting…', 'markproof' ), 'working' => __( 'Checking pages…', 'markproof' ), 'done' => __( 'Scan finished.', 'markproof' ), 'failed' => __( 'Scan failed.', 'markproof' ), ), ) ); } public function page_dashboard() { if ( ! current_user_can( self::CAP ) ) { return; } $scan = Markproof_Store::latest_scan(); $summary = $scan ? Markproof_Store::summary_for_scan( $scan->id ) : array(); $meta = Markproof_Rules::metadata(); $errors = 0; $warns = 0; foreach ( $summary as $row ) { if ( 'error' === $row->severity ) { $errors += (int) $row->items; } else { $warns += (int) $row->items; } } ?>

urls_done; ?>

started_at ), (int) $scan->urls_done, (int) $scan->urls_failed ); ?> ·

rule_id ] ) ? $meta[ $row->rule_id ] : null; ?>
rule_id ); ?> severity ); ?> items; ?> pages; ?>

' . esc_html__( 'described here', 'markproof' ) . '' ); ?>

id, $per, $rule, ( $page - 1 ) * $per, $url ) : array(); ?>

id ) as $sum ) { if ( in_array( $sum->rule_id, array( 'img_missing_alt', 'img_alt_filename', 'img_alt_generic' ), true ) ) { $alt_items += (int) $sum->items; } } ?> 0 ) : ?>

.

rule_id ] ) ? $meta[ $row->rule_id ] : null; ?>
url, PHP_URL_PATH ) ? wp_parse_url( $row->url, PHP_URL_PATH ) : '/' ); ?> id, $row->url ); ?>
severity ); ?> rule_id ); ?> occurrences > 1 ) : ?> occurrences ); ?> message ); ?>

snippet ); ?>

1 ) : ?> « »

—'; return; } $count = isset( $latest['counts'][ $post_id ] ) ? (int) $latest['counts'][ $post_id ] : 0; if ( 0 === $count ) { echo '' . esc_html__( 'None found', 'markproof' ) . ''; return; } printf( '%s', esc_url( admin_url( 'admin.php?page=markproof-findings&url=' . rawurlencode( get_permalink( $post_id ) ) ) ), esc_html( sprintf( /* translators: %d: number of findings */ _n( '%d finding', '%d findings', $count, 'markproof' ), $count ) ) ); } /** One dismissible pointer to the first scan. Not an advert, and it never comes back. */ public function welcome_notice() { if ( ! current_user_can( self::CAP ) || get_option( 'markproof_welcome_dismissed' ) ) { return; } $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( (string) $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- reading which screen we are on, changing nothing. if ( 0 === strpos( $page, 'markproof' ) ) { return; // they are already there } // One dismissible sentence on the dashboard and the plugin list, not on every screen an // administrator visits. A notice that follows people around is the behaviour reviewers // rightly object to, and it is not how we would want to be treated either. $allowed = array( 'dashboard', 'plugins' ); if ( $screen && ! in_array( $screen->id, $allowed, true ) ) { return; } ?>

20, 'user-agent' => 'Markproof – Accessibility Checks/' . STOCHASTIC_SCANNER_VERSION ) ); $ms = (int) round( ( microtime( true ) - $started ) * 1000 ); if ( is_wp_error( $response ) ) { wp_send_json_success( array( 'ok' => false, 'detail' => $response->get_error_message(), 'ms' => $ms ) ); } wp_send_json_success( array( 'ok' => true, 'detail' => 'HTTP ' . (int) wp_remote_retrieve_response_code( $response ) . ', ' . strlen( wp_remote_retrieve_body( $response ) ) . ' bytes', 'ms' => $ms, ) ); } public function ajax_batch() { check_ajax_referer( 'markproof', 'nonce' ); if ( ! current_user_can( self::CAP ) ) { wp_send_json_error( 'forbidden', 403 ); } $scan_id = isset( $_POST['scan'] ) ? (int) $_POST['scan'] : 0; if ( ! $scan_id ) { wp_send_json_error( 'missing scan' ); } wp_send_json_success( Markproof_Scanner::process_batch( $scan_id, 5, 20 ) ); } public function export_csv() { if ( ! current_user_can( self::CAP ) ) { wp_die( esc_html__( 'Not allowed.', 'markproof' ) ); } check_admin_referer( 'markproof_export' ); $scan_id = isset( $_GET['scan'] ) ? (int) $_GET['scan'] : 0; $meta = Markproof_Rules::metadata(); nocache_headers(); header( 'Content-Type: text/csv; charset=utf-8' ); header( 'Content-Disposition: attachment; filename=markproof-' . $scan_id . '.csv' ); $out = fopen( 'php://output', 'w' ); fputcsv( $out, array( 'page_url', 'severity', 'problem', 'details', 'html_snippet', 'how_to_fix' ) ); $offset = 0; do { $rows = Markproof_Store::issues_for_scan( $scan_id, 500, '', $offset ); foreach ( $rows as $row ) { $info = isset( $meta[ $row->rule_id ] ) ? $meta[ $row->rule_id ] : null; fputcsv( $out, array( $row->url, $row->severity, $info ? $info['title'] : $row->rule_id, $row->message, $row->snippet, $info ? $info['fix'] : '', ) ); } $offset += 500; } while ( count( $rows ) === 500 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- streaming straight to the browser, not a file on disk. fclose( $out ); exit; } /** * A work list of images with no alt text, with the fix on the same screen. * * Reporting a problem is half a tool. The other half is being able to act on it without leaving * the page, which is why every row here can be filled in and saved in one go. */ public function page_alt_text() { if ( ! current_user_can( self::CAP ) ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- a display filter, it changes nothing. $show_all = isset( $_GET['show'] ) && 'all' === $_GET['show']; $images = get_posts( array( 'post_type' => 'attachment', 'post_mime_type' => 'image', 'post_status' => 'inherit', 'posts_per_page' => 200, 'orderby' => 'ID', 'order' => 'DESC', 'fields' => 'ids', ) ); $missing = array(); foreach ( $images as $id ) { $alt = (string) get_post_meta( $id, '_wp_attachment_image_alt', true ); if ( '' === trim( $alt ) ) { $missing[] = $id; } } $list = $show_all ? $images : $missing; ?>

'max-width:80px;height:auto' ) ); ?>

$text ) { $id = (int) $id; if ( $id <= 0 || 'attachment' !== get_post_type( $id ) ) { continue; } $clean = sanitize_text_field( (string) $text ); if ( (string) get_post_meta( $id, '_wp_attachment_image_alt', true ) === $clean ) { continue; } update_post_meta( $id, '_wp_attachment_image_alt', $clean ); $saved++; } wp_safe_redirect( add_query_arg( array( 'page' => 'markproof-alt-text', 'saved' => $saved, ), admin_url( 'admin.php' ) ) ); exit; } }