Skip to content
wiki.fftac.org

Validationpage

**Site relevance:** Antichrist.net

**Memory type:** plugin source memory

**Source path:** Antichrist.net/wp-content/plugins/uaix-locale-router/src/Admin/ValidationPage.php

**Size:** 6.3 KB

Summary

namespace UAIXLocaleRouter\Admin;

Source Preview

This source file is short enough to preview directly on its source-memory page.

<?php

namespace UAIXLocaleRouter\Admin;

use UAIXLocaleRouter\DictionaryRepository;
use UAIXLocaleRouter\DictionaryValidator;
use UAIXLocaleRouter\Plugin;
use UAIXLocaleRouter\Support\Html;


if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class ValidationPage {
	/**
	 * Render the validation page.
	 *
	 * @return void
	 */
	public static function render_page() {
		global $wpdb;

		$table_ready = Plugin::validation_table_exists();
		$table_name  = Plugin::validation_table_name();
		$rows        = $table_ready ? $wpdb->get_results( "SELECT * FROM {$table_name} ORDER BY ValidationId DESC LIMIT 30", ARRAY_A ) : array(); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$manifest    = DictionaryRepository::dictionary_manifest();
		?>
		<div class="wrap">
			<h1>Dictionary Validation</h1>

			<div class="uaixlr-card">
				<h2>Run Full Validation</h2>
				<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
					<?php wp_nonce_field( 'uaixlr_run_validations' ); ?>
					<input type="hidden" name="action" value="uaixlr_run_validations" />
					<?php submit_button( 'Run Validation Suite', 'primary', 'submit', false ); ?>
				</form>
			</div>

			<div class="uaixlr-card uaixlr-card-wide">
				<h2>Current Dictionary State</h2>
				<?php if ( empty( $manifest ) ) : ?>
					<p>No dictionaries have been uploaded yet.</p>
				<?php else : ?>
					<table class="widefat striped">
						<thead>
							<tr>
								<th>Locale</th>
								<th>Status</th>
								<th>Issues</th>
								<th>Template Version</th>
								<th>Last Validated</th>
							</tr>
						</thead>
						<tbody>
							<?php foreach ( $manifest as $locale_tag => $entry ) : ?>
								<tr>
									<td><code><?php echo esc_html( $locale_tag ); ?></code></td>
									<td><?php echo wp_kses_post( Html::badge( isset( $entry['lastValidationStatus'] ) ? $entry['lastValidationStatus'] : 'draft', isset( $entry['lastValidationStatus'] ) && 'approved' === $entry['lastValidationStatus'] ? 'success' : ( isset( $entry['lastValidationStatus'] ) && 'rejected' === $entry['lastValidationStatus'] ? 'error' : 'warning' ) ) ); ?></td>
									<td><?php echo esc_html( isset( $entry['issueCount'] ) ? (int) $entry['issueCount'] : 0 ); ?></td>
									<td><?php echo esc_html( isset( $entry['templateVersion'] ) ? (int) $entry['templateVersion'] : 1 ); ?></td>
									<td><?php echo esc_html( isset( $entry['lastValidatedAt'] ) ? $entry['lastValidatedAt'] : ( isset( $entry['uploadedAt'] ) ? $entry['uploadedAt'] : '-' ) ); ?></td>
								</tr>
								<?php if ( ! empty( $entry['lastIssues'] ) && is_array( $entry['lastIssues'] ) ) : ?>
									<tr>
										<td colspan="5"><?php echo wp_kses_post( Html::issues_list( $entry['lastIssues'] ) ); ?></td>
									</tr>
								<?php endif; ?>
							<?php endforeach; ?>
						</tbody>
					</table>
				<?php endif; ?>
			</div>

			<div class="uaixlr-card uaixlr-card-wide">
				<h2>Validation History</h2>
				<?php if ( ! $table_ready ) : ?>
					<p>Validation history storage is not ready yet. Open the Status page and run the repair tasks to initialize it.</p>
				<?php elseif ( empty( $rows ) ) : ?>
					<p>No validation history has been recorded yet.</p>
				<?php else : ?>
					<table class="widefat striped">
						<thead>
							<tr>
								<th>ID</th>
								<th>Locale</th>
								<th>Status</th>
								<th>Issues</th>
								<th>Created UTC</th>
							</tr>
						</thead>
						<tbody>
							<?php foreach ( $rows as $row ) : ?>
								<tr>
									<td><?php echo esc_html( $row['ValidationId'] ); ?></td>
									<td><code><?php echo esc_html( $row['LocaleTag'] ); ?></code></td>
									<td><?php echo wp_kses_post( Html::badge( $row['Status'], 'approved' === $row['Status'] ? 'success' : ( 'rejected' === $row['Status'] ? 'error' : 'warning' ) ) ); ?></td>
									<td><?php echo esc_html( $row['IssueCount'] ); ?></td>
									<td><?php echo esc_html( $row['CreatedUtc'] ); ?></td>
								</tr>
							<?php endforeach; ?>
						</tbody>
					</table>
				<?php endif; ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Run validation across all stored dictionaries.
	 *
	 * @return void
	 */
	public static function handle_run_validations() {
		self::assert_permissions( 'uaixlr_run_validations' );

		$results  = DictionaryValidator::validate_all();
		$manifest = DictionaryRepository::dictionary_manifest();
		$summary  = array(
			'approved' => 0,
			'reviewed' => 0,
			'rejected' => 0,
		);

		foreach ( $results as $result ) {
			$locale_tag = isset( $result['localeTag'] ) ? (string) $result['localeTag'] : '';

			if ( '' === $locale_tag ) {
				continue;
			}

			$file_path = DictionaryRepository::dictionary_path( $locale_tag );
			$file_hash = file_exists( $file_path ) ? hash_file( 'sha256', $file_path ) : '';

			DictionaryValidator::record_validation_result( $result, get_current_user_id(), $file_hash );

			if ( ! isset( $manifest[ $locale_tag ] ) ) {
				$manifest[ $locale_tag ] = array( 'localeTag' => $locale_tag );
			}

			$manifest[ $locale_tag ]['lastValidationStatus'] = $result['status'];
			$manifest[ $locale_tag ]['issueCount']           = $result['issueCount'];
			$manifest[ $locale_tag ]['lastIssues']           = $result['issues'];
			$manifest[ $locale_tag ]['lastValidatedAt']      = gmdate( DATE_ATOM );
			$manifest[ $locale_tag ]['templateVersion']      = $result['templateVersion'];

			if ( isset( $summary[ $result['status'] ] ) ) {
				++$summary[ $result['status'] ];
			}
		}

		DictionaryRepository::save_dictionary_manifest( $manifest );

		Plugin::set_flash_notice(
			sprintf(
				'Validation complete. Approved: %d, Reviewed: %d, Rejected: %d.',
				$summary['approved'],
				$summary['reviewed'],
				$summary['rejected']
			),
			$summary['rejected'] > 0 ? 'warning' : 'success'
		);

		wp_safe_redirect( AdminPages::page_url( 'uaixlr-validation' ) );
		exit;
	}

	/**
	 * Capability and nonce guard.
	 *
	 * @param string $action Nonce action.
	 * @return void
	 */
	private static function assert_permissions( $action ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You are not allowed to validate dictionaries.', 'uaix-locale-router' ) );
		}

		check_admin_referer( $action );
	}
}