%s', esc_url(abc_integrity_mini_get_admin_page_url()), esc_html__('Run core scan', 'abc-integrity') ); return ['abc-integrity-mini-run-core-scan' => $scanLink] + $links; } function abc_integrity_mini_render_rescan_notice(): void { if (!current_user_can('manage_options')) { return; } $pageHook = abc_integrity_mini_get_page_hook(); $screen = get_current_screen(); if ($pageHook !== '' && is_object($screen) && ($screen->id ?? '') === $pageHook) { return; } $version = (string) get_bloginfo('version'); $rescanContext = abc_integrity_mini_get_rescan_context(abc_integrity_mini_get_scan_results(), $version); if ($rescanContext === null) { return; } $previousVersion = $rescanContext['previous_version']; $currentVersion = $rescanContext['current_version']; if ($previousVersion !== '' && $previousVersion === $currentVersion) { $message = sprintf( /* translators: %s: Current WordPress version. */ __('WordPress core was reinstalled. ABC Integrity needs a new scan for WordPress %s.', 'abc-integrity'), $currentVersion ); } elseif ($previousVersion !== '') { $message = sprintf( /* translators: 1: Previous WordPress version, 2: current WordPress version. */ __('WordPress was updated from version %1$s to %2$s. ABC Integrity needs a new core scan.', 'abc-integrity'), $previousVersion, $currentVersion ); } else { $message = sprintf( /* translators: %s: Current WordPress version. */ __('WordPress core was updated. ABC Integrity needs a new scan for WordPress %s.', 'abc-integrity'), $currentVersion ); } printf( '

%1$s %3$s

', esc_html($message), esc_url(abc_integrity_mini_get_admin_page_url()), esc_html__('Run core scan', 'abc-integrity') ); } /** * Register the mini page: nested as "Integrity Mini" under a running Direct * edition's menu, otherwise as the top-level "ABC Integrity" page. The two * calls return different hook suffixes, so the one returned is saved for the * asset and notice checks. */ function abc_integrity_mini_register_admin_page(): void { $parent = abc_integrity_mini_get_direct_parent_slug(); if ($parent !== null) { $hook = add_submenu_page( $parent, 'Integrity Mini', 'Integrity Mini', 'manage_options', ABC_INTEGRITY_MINI_ADMIN_PAGE_SLUG, 'abc_integrity_mini_render_admin_page' ); } else { $hook = add_menu_page( 'ABC Integrity', 'ABC Integrity', 'manage_options', ABC_INTEGRITY_MINI_ADMIN_PAGE_SLUG, 'abc_integrity_mini_render_admin_page', 'dashicons-flag', 80 ); } $GLOBALS['abc_integrity_mini_page_hook'] = is_string($hook) ? $hook : ''; } function abc_integrity_mini_enqueue_assets(string $hook): void { $pageHook = abc_integrity_mini_get_page_hook(); if ($pageHook === '' || $hook !== $pageHook) { return; } wp_enqueue_style( 'abc-integrity-mini-admin', plugin_dir_url(__FILE__) . 'assets/admin.css', [], ABC_INTEGRITY_MINI_VERSION ); wp_enqueue_script( 'abc-integrity-mini-admin', plugin_dir_url(__FILE__) . 'assets/admin.js', [], ABC_INTEGRITY_MINI_VERSION, true ); wp_localize_script('abc-integrity-mini-admin', 'ABCIntegrityMini', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('abc_integrity_mini_scan'), ]); } function abc_integrity_mini_time_ago(int $timestamp): string { $diff = time() - $timestamp; if ($diff < 60) { return 'just now'; } if ($diff < 3600) { $mins = (int) round($diff / 60); return $mins === 1 ? '1 minute ago' : "{$mins} minutes ago"; } if ($diff < 86400) { $hours = (int) round($diff / 3600); return $hours === 1 ? '1 hour ago' : "{$hours} hours ago"; } $days = (int) round($diff / 86400); return $days === 1 ? 'yesterday' : "{$days} days ago"; } function abc_integrity_mini_render_admin_page(): void { if (!current_user_can('manage_options')) { wp_die('Forbidden'); } $manifest = abc_integrity_mini_get_manifest(); $results = abc_integrity_mini_get_scan_results(); $version = (string) get_bloginfo('version'); $locale = get_locale() ?: 'en_US'; $rescanContext = abc_integrity_mini_get_rescan_context($results, $version); $hasResults = is_array($results) && ($results['version'] ?? '') === $version && ($results['locale'] ?? '') === $locale && $manifest !== null && ($results['manifest_fetched_at'] ?? 0) === (int) ($manifest['fetched_at'] ?? -1); $isStale = $hasResults && (time() - (int) ($results['scanned_at'] ?? 0)) > 4 * HOUR_IN_SECONDS; $dateFormat = get_option('date_format') . ' \a\t ' . get_option('time_format'); ?>
Your previous scan results were cleared because WordPress core was reinstalled. Run a new scan to verify WordPress . Your previous scan was for WordPress . Run a new scan to verify the core files for WordPress . Your previous scan results were cleared after WordPress was updated. Run a new scan to verify WordPress .
No scan results yet
Run your first scan to verify that your WordPress core files match the official checksums published by WordPress.org.
The scan downloads the official WordPress checksum manifest from WordPress.org and compares each core file’s MD5 hash. Plugin and theme files are not checked.

Scan results

300 ? ' (' . abc_integrity_mini_time_ago($scannedAt) . ')' : ''; ?>

Scanned

All core files match the official WordPress release
Run a fresh scan to verify your current files.
$count === 1 ? '1 file does not match its expected checksum' : "{$count} files do not match their expected checksums", 'missing' => $count === 1 ? '1 expected file is not present on disk' : "{$count} expected files are not present on disk", 'unreadable' => $count === 1 ? '1 file could not be read' : "{$count} files could not be read", ]; $desc = $failDescs[$type] ?? "{$count} {$type}"; } else { $desc = $passDesc; } $outcome = "{$count} {$type}"; $outcomeClass = $isPass ? 'pass-text' : ($type === 'missing' ? 'warn-text' : 'fail-text'); $rowClass = $isPass ? 'check-row pass' : 'check-row fail open'; $detailsId = 'abc-integrity-findings-' . $type; ?>
data-abc-toggle="check-row" role="button" tabindex="0" aria-expanded="true" aria-controls="">