Zum Hauptinhalt springen

Social Actions

Die Action-Services kapseln komplexe, mehrstufige Geschäftsprozesse rund um Social Profiles. Sie orchestrieren Scraper, Image-Updates und Metrik-Erstellung in einer einzigen, transaktionalen Operation.

EnsureSocialProfileFromUrl

Location: app/Services/Social/Actions/EnsureSocialProfileFromUrl.php

Zentraler Entry Point für das Erstellen oder Aktualisieren eines Social Profiles aus einer URL. Diese Action dedupliziert Profile anhand von external_id (YouTube Channel-ID) oder handle + platform (Instagram). Bei bestehenden Profilen werden Daten aktualisiert, bei neuen Profilen wird ein vollständiger Datensatz angelegt.

Public Methods

MethodParameterReturnBeschreibung
execute()string $url, ?string $platform = nullSocialProfileProfil aus URL sicherstellen (Create oder Update)

Ablauf von execute()

  1. URL-Parsing: Plattform erkennen (YouTube/Instagram) und Handle extrahieren
  2. Scraping: Via ScraperFactory den passenden Scraper aufrufen, ScrapedProfile-DTO erhalten
  3. Deduplizierung: Prüfung ob Profil bereits existiert (via external_id oder handle+platform)
  4. Create/Update:
    • Neues Profil: SocialProfile::create() mit allen Feldern aus dem DTO
    • Bestehendes Profil: Update der veränderten Felder (Title, Description, Country, etc.)
  5. Daily Metric: SocialProfileDailyMetric für den aktuellen Tag erstellen/aktualisieren
  6. Profil-Bild: Via ProfileImageUpdater das Profilbild herunterladen (Hash-Vergleich)
  7. Bio-Parsing: Via ProfileDescriptionParser Links und Handles aus der Bio extrahieren
  8. Tracking: tracking_enabled = true setzen falls noch nicht aktiv

Deduplizierungs-Strategie

// YouTube: Deduplizierung über Channel-ID (external_id)
SocialProfile::where('external_id', $channelId)->where('platform', 'youtube')->first();

// Instagram: Deduplizierung über Handle
SocialProfile::where('handle', $handle)->where('platform', 'instagram')->first();

Race-Condition-Schutz

Bei parallelen Import-Jobs kann es vorkommen, dass zwei Jobs gleichzeitig kein bestehendes Profil finden und beide versuchen, es anzulegen. Der create()-Aufruf ist mit einem try/catch fuer UniqueConstraintViolationException geschuetzt. Bei einer Constraint-Violation wird das bereits von einem anderen Job erstellte Profil per Re-Fetch geladen und weiterverwendet.

Fehlerbehandlung

  • YouTube: hiddenSubscriberCount wirft eine Exception (Profil wird nicht angelegt)
  • Instagram: Collector-Fehler werden als RuntimeException propagiert
  • Netzwerkfehler: Retries auf API-Ebene (siehe YouTubeDataApiClient)

Abhängigkeiten

  • ScraperFactory
  • ProfileImageUpdater
  • ProfileDescriptionParser
  • SocialProfile Model, SocialProfileDailyMetric Model

Verwendet von

  • Watcher-Import (Livewire), InstagramWatcherImportProcessor, Admin-Profil-Erstellung, Related-Channel-Discovery

CompactNumber

Location: app/Services/Social/Support/CompactNumber.php

Final Class zur kompakten Formatierung großer Zahlen im deutschen Format. Wird primär in Blade-Views und Livewire-Components verwendet.

Formatierungsregeln

BereichFormatBeispiel
< 1.000Exakte Zahl843
1.000 - 999.999Tausender mit "K"12,3K
1.000.000 - 999.999.999Millionen mit "M"2,4M
>= 1.000.000.000Milliarden mit "B"1,2B

Verwendung

use App\Services\Social\Support\CompactNumber;

CompactNumber::format(1234567); // "1,2M"
CompactNumber::format(45678); // "45,7K"
CompactNumber::format(999); // "999"

Hinweis zur Tausenderformatierung

Für nicht-kompakte Darstellung mit deutschen Tausenderpunkten wird number_format() verwendet:

number_format($n, 0, ',', '.');  // z.B. "1.234.567"

Dieses Pattern ist im gesamten Codebase Standard für Follower-Counts, View-Counts und ähnliche metrische Werte, die in Tabellen oder Detail-Ansichten angezeigt werden.

Verwendet von

  • Explore Profile Cards, Leaderboard-Views, Dashboard-Widgets, Admin Social Profiles