refactor(support): centralize ID-array normalization in toIntIds()

Consolidates the scattered `array_values(array_unique(array_map('intval',
$x)))` + manual positive-filter pattern behind a single lenient helper
`toIntIds(mixed $value): array` in core/Support/helpers/array.php.

- `RepositoryArrayHelper::sanitizePositiveIds()` now delegates (keeps
  strict array-input contract + existing tests intact).
- Drops two private duplicates: `UserProfileViewService::normalizeIds()`
  and `AddressBookService::normalizeIds()`.
- Replaces 12 inline occurrences across admin action pages with the
  helper, cutting boilerplate by 3-5 lines per site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 19:11:53 +02:00
parent 52f10ae46c
commit 6c99c040b2
14 changed files with 99 additions and 68 deletions

View File

@@ -26,7 +26,7 @@ if (!$decision->isAllowed()) {
Guard::deny();
}
$capabilities = $decision->attribute('capabilities', []);
$allowedTenantIds = is_array($capabilities) ? array_values(array_unique(array_map('intval', (array) ($capabilities['allowed_tenant_ids'] ?? [])))) : [];
$allowedTenantIds = is_array($capabilities) ? toIntIds($capabilities['allowed_tenant_ids'] ?? []) : [];
$isStrictScope = is_array($capabilities) ? (bool) ($capabilities['is_strict_scope'] ?? false) : false;
$errorBag = formErrors();

View File

@@ -11,7 +11,7 @@ gridRequireGetRequest();
$currentUserId = (int) ($session['user']['id'] ?? 0);
$decision = Guard::requireAbilityDecisionOrForbidden(DepartmentAuthorizationPolicy::ABILITY_ADMIN_DEPARTMENTS_VIEW);
$capabilities = $decision->attribute('capabilities', []);
$tenantIds = is_array($capabilities) ? array_values(array_unique(array_map('intval', (array) ($capabilities['allowed_tenant_ids'] ?? [])))) : [];
$tenantIds = is_array($capabilities) ? toIntIds($capabilities['allowed_tenant_ids'] ?? []) : [];
$filters = gridParseFiltersFromSchemaFile(__DIR__ . '/filter-schema.php');

View File

@@ -18,7 +18,7 @@ if (!$decision->isAllowed()) {
Guard::deny();
}
$capabilities = $decision->attribute('capabilities', []);
$allowedTenantIds = is_array($capabilities) ? array_values(array_unique(array_map('intval', (array) ($capabilities['allowed_tenant_ids'] ?? [])))) : [];
$allowedTenantIds = is_array($capabilities) ? toIntIds($capabilities['allowed_tenant_ids'] ?? []) : [];
$isStrictScope = is_array($capabilities) ? (bool) ($capabilities['is_strict_scope'] ?? false) : false;
$canCreateDepartments = is_array($capabilities) ? (bool) ($capabilities['can_create_department'] ?? false) : false;
$filterSchema = require __DIR__ . '/filter-schema.php';

View File

@@ -63,18 +63,10 @@ if ($request->isMethod('POST')) {
$result = app(\MintyPHP\Service\Access\PermissionService::class)->updateFromAdmin($id, $request->bodyAll());
$form = $result['form'] ?? $form;
$errorBag->merge($result['errors'] ?? []);
$selectedRoleIds = $request->body('role_ids', $selectedRoleIds);
if (!is_array($selectedRoleIds)) {
$selectedRoleIds = [$selectedRoleIds];
}
$selectedRoleIds = array_values(array_unique(array_map('intval', $selectedRoleIds)));
$selectedRoleIds = toIntIds($request->body('role_ids', $selectedRoleIds));
if (($result['ok'] ?? false) && !$errorBag->hasAny()) {
$roleIds = $request->body('role_ids', []);
if (!is_array($roleIds)) {
$roleIds = [$roleIds];
}
$roleIds = array_values(array_unique(array_map('intval', $roleIds)));
$roleIds = toIntIds($request->body('role_ids', []));
$syncSucceeded = false;
$dbSession = app(\MintyPHP\Repository\Support\DatabaseSessionRepository::class);
$dbSession->beginTransaction();

View File

@@ -52,18 +52,10 @@ if ($request->isMethod('POST')) {
$form = $result['form'] ?? $form;
$warnings = $result['warnings'] ?? [];
$errorBag->merge($result['errors'] ?? []);
$selectedPermissionIds = $request->body('permission_ids', $selectedPermissionIds);
if (!is_array($selectedPermissionIds)) {
$selectedPermissionIds = [$selectedPermissionIds];
}
$selectedPermissionIds = array_values(array_unique(array_map('intval', $selectedPermissionIds)));
$selectedPermissionIds = toIntIds($request->body('permission_ids', $selectedPermissionIds));
if (($result['ok'] ?? false) && !$errorBag->hasAny()) {
$permissionIds = $request->body('permission_ids', []);
if (!is_array($permissionIds)) {
$permissionIds = [$permissionIds];
}
$permissionIds = array_values(array_unique(array_map('intval', $permissionIds)));
$permissionIds = toIntIds($request->body('permission_ids', []));
$createdId = (int) ($result['id'] ?? 0);
if ($createdId <= 0) {
throw new \RuntimeException('role_create_missing_id');

View File

@@ -68,23 +68,11 @@ if ($request->isMethod('POST')) {
$form = $result['form'] ?? $form;
$warnings = $result['warnings'] ?? [];
$errorBag->merge($result['errors'] ?? []);
$selectedPermissionIds = $request->body('permission_ids', $selectedPermissionIds);
if (!is_array($selectedPermissionIds)) {
$selectedPermissionIds = [$selectedPermissionIds];
}
$selectedPermissionIds = array_values(array_unique(array_map('intval', $selectedPermissionIds)));
$selectedAssignableRoleIds = $request->body('assignable_role_ids', $selectedAssignableRoleIds);
if (!is_array($selectedAssignableRoleIds)) {
$selectedAssignableRoleIds = [$selectedAssignableRoleIds];
}
$selectedAssignableRoleIds = array_values(array_unique(array_map('intval', $selectedAssignableRoleIds)));
$selectedPermissionIds = toIntIds($request->body('permission_ids', $selectedPermissionIds));
$selectedAssignableRoleIds = toIntIds($request->body('assignable_role_ids', $selectedAssignableRoleIds));
if (($result['ok'] ?? false) && !$errorBag->hasAny()) {
$permissionIds = $request->body('permission_ids', []);
if (!is_array($permissionIds)) {
$permissionIds = [$permissionIds];
}
$permissionIds = array_values(array_unique(array_map('intval', $permissionIds)));
$permissionIds = toIntIds($request->body('permission_ids', []));
$syncSucceeded = false;
$dbSession = app(\MintyPHP\Repository\Support\DatabaseSessionRepository::class);
$dbSession->beginTransaction();

View File

@@ -9,7 +9,7 @@ gridRequireGetRequest();
$decision = Guard::requireAbilityDecisionOrForbidden(TenantAuthorizationPolicy::ABILITY_ADMIN_TENANTS_VIEW);
$capabilities = $decision->attribute('capabilities', []);
$allowedTenantIds = is_array($capabilities) ? array_values(array_unique(array_map('intval', (array) ($capabilities['allowed_tenant_ids'] ?? [])))) : [];
$allowedTenantIds = is_array($capabilities) ? toIntIds($capabilities['allowed_tenant_ids'] ?? []) : [];
$isStrictScope = is_array($capabilities) ? (bool) ($capabilities['is_strict_scope'] ?? false) : false;
$hasGlobalAccess = is_array($capabilities) ? (bool) ($capabilities['has_global_access'] ?? false) : false;

View File

@@ -798,14 +798,8 @@ foreach ($tenants as $tenant) {
? $customFieldScalarPosted[$scalarPostedKey]
: null;
$multiPostedRaw = $customFieldMultiPosted[$scalarPostedKey] ?? null;
$multiPosted = is_array($multiPostedRaw)
? array_values(array_unique(array_map('intval', $multiPostedRaw)))
: [];
$multiPosted = array_values(array_filter($multiPosted, static fn (int $id): bool => $id > 0));
$currentOptionIds = is_array($currentValue['option_ids'] ?? null)
? array_values(array_unique(array_map('intval', $currentValue['option_ids'])))
: [];
$currentOptionIds = array_values(array_filter($currentOptionIds, static fn (int $id): bool => $id > 0));
$multiPosted = is_array($multiPostedRaw) ? toIntIds($multiPostedRaw) : [];
$currentOptionIds = toIntIds($currentValue['option_ids'] ?? null);
$valueText = array_key_exists('value_text', $currentValue) ? (string) ($currentValue['value_text'] ?? '') : '';
$valueBool = array_key_exists('value_bool', $currentValue) && $currentValue['value_bool'] !== null
? (string) ((int) $currentValue['value_bool'])