TenantAtlas/app/Services/Intune/GroupPolicyConfigurationNormalizer.php
2025-12-29 17:23:41 +01:00

163 lines
5.6 KiB
PHP

<?php
namespace App\Services\Intune;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class GroupPolicyConfigurationNormalizer implements PolicyTypeNormalizer
{
public function __construct(
private readonly DefaultPolicyNormalizer $defaultNormalizer,
) {}
public function supports(string $policyType): bool
{
return $policyType === 'groupPolicyConfiguration';
}
/**
* @return array{status: string, settings: array<int, array<string, mixed>>, settings_table?: array<string, mixed>, warnings: array<int, string>}
*/
public function normalize(?array $snapshot, string $policyType, ?string $platform = null): array
{
$snapshot = $snapshot ?? [];
$definitionValues = $snapshot['definitionValues'] ?? null;
$snapshot = Arr::except($snapshot, ['definitionValues']);
$normalized = $this->defaultNormalizer->normalize($snapshot, $policyType, $platform);
if (! is_array($definitionValues) || $definitionValues === []) {
$normalized['warnings'] = array_values(array_unique(array_merge(
$normalized['warnings'] ?? [],
['Administrative Template settings not hydrated for this policy.']
)));
return $normalized;
}
$rows = [];
foreach ($definitionValues as $index => $definitionValue) {
if (! is_array($definitionValue)) {
continue;
}
$definition = $definitionValue['#Definition_displayName'] ?? null;
$definitionId = $definitionValue['#Definition_Id'] ?? null;
$category = $definitionValue['#Definition_categoryPath'] ?? '-';
$enabled = (bool) ($definitionValue['enabled'] ?? false);
$path = $definitionValue['definition@odata.bind'] ?? (is_string($definitionId) ? $definitionId : "definitionValues[{$index}]");
$value = $this->formatGroupPolicyValue($definitionValue, $enabled);
$dataType = $this->inferGroupPolicyDataType($definitionValue);
$rows[] = [
'definition' => is_string($definition) && $definition !== '' ? $definition : 'Definition',
'definition_id' => is_string($definitionId) ? $definitionId : null,
'category' => is_string($category) && $category !== '' ? $category : '-',
'data_type' => $dataType,
'value' => $value,
'description' => '-',
'path' => is_string($path) ? Str::limit($path, 200) : "definitionValues[{$index}]",
'raw' => $definitionValue,
];
}
if ($rows !== []) {
$normalized['settings_table'] = [
'title' => 'Administrative Template settings',
'rows' => $rows,
];
}
return $normalized;
}
/**
* @return array<string, mixed>
*/
public function flattenForDiff(?array $snapshot, string $policyType, ?string $platform = null): array
{
$normalized = $this->normalize($snapshot ?? [], $policyType, $platform);
return $this->defaultNormalizer->flattenNormalizedForDiff($normalized);
}
private function inferGroupPolicyDataType(array $definitionValue): string
{
$presentationValues = $definitionValue['presentationValues'] ?? null;
if (! is_array($presentationValues) || $presentationValues === []) {
return 'Boolean';
}
foreach ($presentationValues as $presentationValue) {
if (! is_array($presentationValue)) {
continue;
}
if (array_key_exists('values', $presentationValue)) {
return 'Choice';
}
if (array_key_exists('value', $presentationValue)) {
$value = $presentationValue['value'];
if (is_bool($value)) {
return 'Boolean';
}
if (is_int($value) || is_float($value) || is_numeric($value)) {
return 'Number';
}
return 'Text';
}
}
return 'Text';
}
private function formatGroupPolicyValue(array $definitionValue, bool $enabled): string
{
$presentationValues = $definitionValue['presentationValues'] ?? null;
if (! is_array($presentationValues) || $presentationValues === []) {
return $enabled ? 'Enabled' : 'Disabled';
}
$parts = [];
foreach ($presentationValues as $presentationValue) {
if (! is_array($presentationValue)) {
continue;
}
$label = $presentationValue['#Presentation_Label'] ?? null;
$value = $presentationValue['value'] ?? null;
$values = $presentationValue['values'] ?? null;
$valueString = match (true) {
is_array($values) => json_encode($values),
is_bool($value) => $value ? 'true' : 'false',
is_scalar($value) => (string) $value,
default => null,
};
if ($valueString === null) {
$clean = Arr::except($presentationValue, ['presentation@odata.bind', '#Presentation_Label', '#Presentation_Id']);
$valueString = $clean !== [] ? json_encode($clean) : null;
}
if (is_string($label) && $label !== '') {
$parts[] = $label.': '.($valueString ?? '-');
} else {
$parts[] = $valueString ?? '-';
}
}
return implode(' | ', array_values(array_filter($parts, static fn ($part) => $part !== '')));
}
}