Files
breadcrumb-the-shire/core/Repository/CustomField/UserCustomFieldValueOptionRepository.php
fs 6b05bbfe9c refactor(customfield): interface-based DI for repositories
Align CustomField-Schicht mit core/Repository/Access-Muster. Vier
Repositories (Tenant-Definition, Tenant-Option, User-Value, User-Value-Option)
bekommen je ein Interface, werden von static auf instance umgestellt und
ueber CustomFieldRepositoryFactory injiziert.

TenantCustomFieldService und UserCustomFieldValueService injizieren die
Repository-Interfaces statt statisch aufzurufen. CustomFieldServicesFactory
reicht Instanzen durch. AddressBookService (Modul) bekommt
TenantCustomFieldOptionRepositoryInterface per Container — Interface-Kopplung
verbessert Modul-Isolation gegenueber dem vorherigen statischen Aufruf.

Kein Verhaltenswechsel, keine SQL-Aenderung, keine Service-Signatur-Aenderung.
Alle tenant_id-Parameter erhalten (GR-SEC-009, Security-Review SR-002).

Oeffnet den Weg fuer Cluster B1 (TenantCustomFieldService-Tests) und B2
(UserCustomFieldValueService-Tests), die nun mit createMock() moeglich sind.

Nebenbei zwei PHPStan-Folge-Findings korrigiert:
- Veralteter Ignore-Eintrag fuer findById aus phpstan-baseline.neon entfernt
- Redundanter is_array-Check in TenantCustomFieldOptionRepository entfernt
  (durch typisierte Interface-Signatur abgedeckt)

Gates: QG-001 (1945 Tests, 28581 Assertions) / QG-002 / QG-003 / QG-006 pass.

Workflow: .agents/runs/CUSTOMFIELD-DI-REFACTOR-001/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 19:32:14 +02:00

80 lines
2.4 KiB
PHP

<?php
namespace MintyPHP\Repository\CustomField;
use MintyPHP\DB;
/** Manages selected option links for user custom field values (atomic replace). */
class UserCustomFieldValueOptionRepository implements UserCustomFieldValueOptionRepositoryInterface
{
public function replaceForValueId(int $valueId, array $optionIds): bool
{
if ($valueId <= 0) {
return false;
}
$deleted = DB::delete('delete from user_custom_field_value_options where value_id = ?', (string) $valueId);
if ($deleted === false) {
return false;
}
$optionIds = array_values(array_unique(array_map('intval', $optionIds)));
$optionIds = array_values(array_filter($optionIds, static fn ($id) => $id > 0));
if (!$optionIds) {
return true;
}
foreach ($optionIds as $optionId) {
$inserted = DB::insert(
'insert into user_custom_field_value_options (value_id, option_id, created) values (?,?,NOW())',
(string) $valueId,
(string) $optionId
);
if ($inserted === false) {
return false;
}
}
return true;
}
public function listOptionIdsByValueIds(array $valueIds): array
{
$valueIds = array_values(array_unique(array_map('intval', $valueIds)));
$valueIds = array_values(array_filter($valueIds, static fn ($id) => $id > 0));
if (!$valueIds) {
return [];
}
$rows = DB::select(
'select value_id, option_id from user_custom_field_value_options where value_id in (???)',
$valueIds
);
if (!is_array($rows)) {
return [];
}
$map = [];
foreach ($rows as $row) {
$data = $row['user_custom_field_value_options'] ?? $row;
if (!is_array($data)) {
continue;
}
$valueId = (int) ($data['value_id'] ?? 0);
$optionId = (int) ($data['option_id'] ?? 0);
if ($valueId <= 0 || $optionId <= 0) {
continue;
}
$map[$valueId] ??= [];
$map[$valueId][] = $optionId;
}
foreach ($map as &$ids) {
$ids = array_values(array_unique(array_map('intval', $ids)));
sort($ids, SORT_NUMERIC);
}
unset($ids);
return $map;
}
}