TenantAtlas/apps/platform/app/Services/TenantConfiguration/GenericPayloadNormalizer.php
ahmido f7d06621a0 feat: implement Exchange Teams evidence identity readiness (#493)
Automated PR for spec 426 exchange teams core evidence identity readiness. Includes service changes and coverage/requirement/spec updates from commit fb4dc20c.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #493
2026-07-03 11:43:11 +00:00

90 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\TenantConfiguration;
final class GenericPayloadNormalizer
{
/**
* @param array<string, mixed> $payload
* @param list<string> $volatileFields
* @return array<string, mixed>
*/
public function normalize(array $payload, array $volatileFields = []): array
{
$volatileLookup = array_fill_keys(array_map('strval', $volatileFields), true);
return $this->normalizeValue($payload, $volatileLookup);
}
/**
* @param array<string, mixed> $normalizedPayload
*/
public function payloadHash(array $normalizedPayload): string
{
return hash('sha256', $this->canonicalJson($this->hashablePayload($normalizedPayload)));
}
/**
* @param array<string, mixed> $payload
*/
public function canonicalJson(array $payload): string
{
return json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
}
/**
* @param array<string, mixed> $payload
* @return array<string, mixed>
*/
private function hashablePayload(array $payload): array
{
if (isset($payload['diagnostics']) && is_array($payload['diagnostics'])) {
unset($payload['diagnostics']['volatile_fields']);
if ($payload['diagnostics'] === []) {
unset($payload['diagnostics']);
}
}
return $payload;
}
/**
* @param array<string, bool> $volatileLookup
* @return mixed
*/
private function normalizeValue(mixed $value, array $volatileLookup): mixed
{
if (! is_array($value)) {
return $value;
}
if ($this->isList($value)) {
return array_map(fn (mixed $item): mixed => $this->normalizeValue($item, $volatileLookup), $value);
}
$normalized = [];
foreach ($value as $key => $nestedValue) {
$key = (string) $key;
if (isset($volatileLookup[$key])) {
continue;
}
$normalized[$key] = $this->normalizeValue($nestedValue, $volatileLookup);
}
ksort($normalized);
return $normalized;
}
private function isList(array $value): bool
{
return array_is_list($value);
}
}