get($url); if ($response->successful()) { $html = $response->body(); $text = strip_tags($html); $text = trim($text); return $text !== '' ? $text : null; } } catch (\Exception) { // Best-effort: Fehler stillschweigend behandeln } return null; } public function importTranslation(Song $song, string $text): void { $translatedLines = explode("\n", $text); $offset = 0; $defaultArr = $song->arrangements() ->where('is_default', true) ->with(['arrangementSections' => fn ($q) => $q->orderBy('order'), 'arrangementSections.section.slides']) ->first(); if ($defaultArr === null) { $this->markAsTranslated($song); return; } foreach ($defaultArr->arrangementSections->sortBy('order') as $arrangementSection) { $section = $arrangementSection->section; if ($section === null) { continue; } foreach ($section->slides->sortBy('order') as $slide) { $originalLineCount = count(explode("\n", $slide->text_content ?? '')); $chunk = array_slice($translatedLines, $offset, $originalLineCount); $offset += $originalLineCount; $slide->update([ 'text_content_translated' => implode("\n", $chunk), ]); } } $this->markAsTranslated($song); } public function markAsTranslated(Song $song): void { $song->update(['has_translation' => true]); } public function removeTranslation(Song $song): void { $sectionIds = $song->sections() ->pluck('id') ->unique() ->values(); if ($sectionIds->isNotEmpty()) { SongSlide::whereIn('song_section_id', $sectionIds)->update([ 'text_content_translated' => null, ]); } $song->update(['has_translation' => false]); } }