Skip to content
← Back to Snippets
Code

Record Change Set Formatter

Formats changed record fields into a compact change set for audit logs or admin review screens.

Purpose

Formats changed record fields into a compact change set for audit logs or admin review screens.

Snippet details

ContextArrayLevelAdvancedCopy-and-paste statusMarked safe after review.

Categories

  • Security

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.
 */

/**
 * Record Change Set Formatter.
 *
 * Purpose:
 * Builds a field-level change set by comparing an original record with an
 * updated record and including only values that changed.
 *
 * @param array $before Original record state.
 * @param array $after Updated record state.
 * @param array $labels Optional display labels keyed by field name.
 * @return array Formatted change set rows.
 */
function ogSnippetRecordChangeSetFormatter(array $before, array $after, array $labels): array {
	$changes = array();
	$keys = array();

	foreach ($before as $key => $value) {
		$keys[$key] = $key;
	}

	foreach ($after as $key => $value) {
		$keys[$key] = $key;
	}

	foreach ($keys as $field_name) {
		$before_value = null;
		$after_value = null;
		$label = (string) $field_name;

		if (array_key_exists($field_name, $before) === true) {
			$before_value = $before[$field_name];
		}

		if (array_key_exists($field_name, $after) === true) {
			$after_value = $after[$field_name];
		}

		if (isset($labels[$field_name]) === true && trim((string) $labels[$field_name]) !== '') {
			$label = trim((string) $labels[$field_name]);
		}

		if ($before_value !== $after_value) {
			$changes[] = array(
				'field' => (string) $field_name,
				'label' => $label,
				'before' => $before_value,
				'after' => $after_value
			);
		}
	}

	return $changes;
}

$before = array('mission' => 'Recon', 'status' => 'queued', 'ship' => 'Galactica');
$after = array('mission' => 'Recon', 'status' => 'launched', 'ship' => 'Galactica');
$labels = array('status' => 'Mission Status');
$change_set = ogSnippetRecordChangeSetFormatter($before, $after, $labels);

echo 'Battlestar record change set rows: '.count($change_set);