presseportale/app/Services/Import/UserAssociationLinker.php
Kevin Adametz 5b8bdf4182
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
12-05-2026 Frontend dev
2026-05-12 18:32:33 +02:00

91 lines
2.9 KiB
PHP

<?php
namespace App\Services\Import;
use Illuminate\Support\Facades\DB;
/**
* Post-Import-Schritt: verknüpft User direkt mit Kontakten.
*
* Logik: User → company_user → company → contacts
* Ein User der mit einer Firma verknüpft ist, bekommt automatisch alle
* Kontakte dieser Firma direkt in contact_user eingetragen.
*
* Läuft auf der NEUEN Datenbank (kein Legacy-DB-Zugriff nötig).
* Idempotent: insertOrIgnore() verhindert Duplikate bei Mehrfachläufen.
* Manuelle Admin-Zuordnungen (über Admin-UI erstellt) bleiben erhalten.
*/
class UserAssociationLinker
{
public function run(ImportContext $ctx): ImportResult
{
$result = new ImportResult;
if ($ctx->dryRun) {
$count = $this->countPotentialLinks($ctx);
for ($i = 0; $i < $count; $i++) {
$result->incrementImported();
}
return $result;
}
$inserted = $this->linkContactsViaCompany($ctx);
for ($i = 0; $i < $inserted; $i++) {
$result->incrementImported();
}
return $result;
}
private function linkContactsViaCompany(ImportContext $ctx): int
{
$portalFilter = $ctx->portal !== 'all' ? $ctx->portalEnum->value : null;
// Alle (user_id, contact_id) Paare aus der Firmenzugehörigkeit ableiten
$pairs = DB::table('company_user')
->join('contacts', 'contacts.company_id', '=', 'company_user.company_id')
->when($portalFilter, fn ($q) => $q->where('contacts.portal', $portalFilter))
->whereNull('contacts.deleted_at')
->select(
'company_user.user_id',
'contacts.id as contact_id',
DB::raw('NOW() as created_at'),
DB::raw('NOW() as updated_at'),
)
->distinct()
->get();
if ($pairs->isEmpty()) {
return 0;
}
// Chunked insert um Memory zu schonen
$inserted = 0;
foreach ($pairs->chunk(500) as $chunk) {
$inserted += DB::table('contact_user')->insertOrIgnore(
$chunk->map(fn ($row) => [
'contact_id' => $row->contact_id,
'user_id' => $row->user_id,
'created_at' => $row->created_at,
'updated_at' => $row->updated_at,
])->all()
);
}
return $inserted;
}
private function countPotentialLinks(ImportContext $ctx): int
{
$portalFilter = $ctx->portal !== 'all' ? $ctx->portalEnum->value : null;
return DB::table('company_user')
->join('contacts', 'contacts.company_id', '=', 'company_user.company_id')
->when($portalFilter, fn ($q) => $q->where('contacts.portal', $portalFilter))
->whereNull('contacts.deleted_at')
->distinct()
->count();
}
}