where('is_featured', true)->orderByDesc('published_at')->first() ?? SonarDeskRelease::published()->where('channel', 'stable')->orderByDesc('published_at')->orderByDesc('id')->first(); $releases = SonarDeskRelease::published()->orderByDesc('published_at')->paginate(12); $settings = $this->settings(); return view('downloads.index', compact('latest', 'releases', 'settings')); } public function latest(): BinaryFileResponse { $release = SonarDeskRelease::published()->where('channel', 'stable')->orderByDesc('published_at')->firstOrFail(); return $this->send($release); } public function download(SonarDeskRelease $release): BinaryFileResponse { abort_unless($release->is_published && $release->published_at && $release->file_path, 404); return $this->send($release); } public function appcast(): Response { $releases = SonarDeskRelease::published()->where('channel', 'stable')->orderByDesc('published_at')->limit(20)->get(); return response()->view('downloads.appcast', compact('releases'), 200, ['Content-Type' => 'application/rss+xml; charset=UTF-8']); } private function send(SonarDeskRelease $release): BinaryFileResponse { abort_unless(Storage::disk('local')->exists($release->file_path), 404); $release->increment('download_count'); return response()->download(Storage::disk('local')->path($release->file_path), $release->original_filename ?: 'SonarDesk-'.$release->version.'.dmg'); } private function settings(): array { return [ 'eyebrow' => SiteSetting::valueFor('downloads.eyebrow', 'SonarDesk for macOS'), 'title' => SiteSetting::valueFor('downloads.title', 'Download SonarDesk'), 'intro' => SiteSetting::valueFor('downloads.intro', 'A focused native SonarQube workspace, designed for macOS and built for daily engineering work.'), 'requirements' => SiteSetting::valueFor('downloads.requirements', 'Apple silicon and Intel Macs supported. A SonarQube server and valid SonarDesk licence are required.'), 'support_text' => SiteSetting::valueFor('downloads.support_text', 'Need help installing or activating SonarDesk? Our support team can help.'), ]; } }