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
| Method | Parameter | Return | Beschreibung |
|---|---|---|---|
execute() | string $url, ?string $platform = null | SocialProfile | Profil aus URL sicherstellen (Create oder Update) |
Ablauf von execute()
- URL-Parsing: Plattform erkennen (YouTube/Instagram) und Handle extrahieren
- Scraping: Via
ScraperFactoryden passenden Scraper aufrufen,ScrapedProfile-DTO erhalten - Deduplizierung: Prüfung ob Profil bereits existiert (via
external_idoderhandle+platform) - Create/Update:
- Neues Profil:
SocialProfile::create()mit allen Feldern aus dem DTO - Bestehendes Profil: Update der veränderten Felder (Title, Description, Country, etc.)
- Neues Profil:
- Daily Metric:
SocialProfileDailyMetricfür den aktuellen Tag erstellen/aktualisieren - Profil-Bild: Via
ProfileImageUpdaterdas Profilbild herunterladen (Hash-Vergleich) - Bio-Parsing: Via
ProfileDescriptionParserLinks und Handles aus der Bio extrahieren - Tracking:
tracking_enabled = truesetzen 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:
hiddenSubscriberCountwirft eine Exception (Profil wird nicht angelegt) - Instagram: Collector-Fehler werden als
RuntimeExceptionpropagiert - Netzwerkfehler: Retries auf API-Ebene (siehe
YouTubeDataApiClient)
Abhängigkeiten
ScraperFactoryProfileImageUpdaterProfileDescriptionParserSocialProfileModel,SocialProfileDailyMetricModel
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
| Bereich | Format | Beispiel |
|---|---|---|
| < 1.000 | Exakte Zahl | 843 |
| 1.000 - 999.999 | Tausender mit "K" | 12,3K |
| 1.000.000 - 999.999.999 | Millionen mit "M" | 2,4M |
| >= 1.000.000.000 | Milliarden 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