Skip to content
← Back to Functions
Code

Data Quality Scorecard

Scores records for missing fields, invalid values, duplicates, and formatting problems.

Function signature

ogBuildDataQualityScorecard(records = array(), rules = array())

Categories

  • Forms and Validation

Parameters

recordsRecords to inspect.rulesOptional required_fields, unique_fields, and validators. Recognized keys: `required_fields`, `unique_fields`.

Return value

Short public-safe status message.

  • total_rows
  • total_issues
  • duplicate_count
  • score
  • rows

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Scores records for missing fields, invalid values, duplicates, and formatting problems.
 *
 * Primary use case: Import validation and admin dashboards.
 * Typical inputs: records, quality rules.
 * Typical output: scorecard report.
 *
 * Implementation note: Keep rule names visible for repair guidance.
 *
 * @param array $records Records to inspect.
 * @param array $rules Optional required_fields, unique_fields, and validators.
 * @return array Structured quality scorecard.
 */
function ogBuildDataQualityScorecard($records = array(), $rules = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($records)) {
		$result['message'] = 'Records must be an array.';
		return $result;
	}

	if (!is_array($rules)) {
		$rules = array();
	}

	$required_fields = array();
	if (!empty($rules['required_fields']) && is_array($rules['required_fields'])) {
		$required_fields = $rules['required_fields'];
	}

	$unique_fields = array();
	if (!empty($rules['unique_fields']) && is_array($rules['unique_fields'])) {
		$unique_fields = $rules['unique_fields'];
	}

	$row_reports = array();
	$seen = array();
	$total_issues = 0;
	$duplicate_count = 0;

	foreach ($records as $row_number => $record) {
		$row_issues = array();
		if (!is_array($record)) {
			$row_issues[] = 'Record is not an array.';
			$total_issues++;
			$row_reports[] = array('row' => $row_number, 'issues' => $row_issues);
			continue;
		}

		foreach ($required_fields as $field) {
			$field = (string)$field;
			if (!array_key_exists($field, $record) || trim((string)$record[$field]) === '') {
				$row_issues[] = 'Missing required field: ' . $field;
				$total_issues++;
			}
		}

		foreach ($unique_fields as $field) {
			$field = (string)$field;
			if (array_key_exists($field, $record)) {
				$key = $field . ':' . strtolower(trim((string)$record[$field]));
				if (!empty($seen[$key])) {
					$row_issues[] = 'Duplicate value for field: ' . $field;
					$total_issues++;
					$duplicate_count++;
				} else {
					$seen[$key] = true;
				}
			}
		}

		$row_reports[] = array('row' => $row_number, 'issues' => $row_issues);
	}

	$total_rows = count($records);
	$score = 100;
	if ($total_rows > 0) {
		$score = 100 - min(100, round(($total_issues / $total_rows) * 20, 2));
	}

	$result['success'] = true;
	$result['message'] = 'Data quality scorecard built.';
	$result['data'] = array(
		'total_rows' => $total_rows,
		'total_issues' => $total_issues,
		'duplicate_count' => $duplicate_count,
		'score' => $score,
		'rows' => $row_reports
	);

	return $result;
}