Files

61 lines
1.8 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace App\Domain\User;
/** Canonicalizes permission names and exposes only safe permission data. */
final class PermissionMatrix
{
/** @var list<string> */
private const DISPLAY_FIELDS = ['id', 'name', 'description', 'permissions'];
/**
* Trim permission names, canonicalize them, discard malformed entries, and
* preserve first-seen order while removing duplicates.
*
* @param array<mixed> $permissions
* @return list<string>
*/
public function normalize(array $permissions): array
{
$normalized = [];
$seen = [];
foreach ($permissions as $permission) {
if (!is_scalar($permission)) {
continue;
}
$permission = strtolower(trim((string) $permission));
if ($permission === '' || preg_match('/[\x00-\x20\x7F]/', $permission) === 1) {
continue;
}
if (!isset($seen[$permission])) {
$seen[$permission] = true;
$normalized[] = $permission;
}
}
return $normalized;
}
/** @param array<string, mixed> $record @return array<string, mixed> */
public function display(array $record): array
{
$safe = [];
foreach (self::DISPLAY_FIELDS as $field) {
if (array_key_exists($field, $record)) {
$safe[$field] = $field === 'permissions' && is_array($record[$field])
? $this->normalize($record[$field])
: $record[$field];
}
}
return $safe;
}
/** @param array<string, mixed> $record @return array<string, mixed> */
public function toDisplay(array $record): array
{
return $this->display($record);
}
}