SonarDeskRelease::orderByDesc('created_at')->paginate(20),'products'=>DownloadProduct::orderBy('name')->get()]);} public function release(Request $request){$data=$request->validate(['version'=>'required|string|max:40','build_number'=>'required|integer|min:1','channel'=>['required',Rule::in(['stable','beta'])],'minimum_macos'=>'nullable|string|max:30','release_notes'=>'nullable|string','sparkle_signature'=>'nullable|string|max:2048','is_published'=>'nullable|boolean','is_featured'=>'nullable|boolean','file'=>'required|file|max:512000|mimes:dmg,zip,pkg']);$file=$request->file('file');$path=$file->store('sonardesk-distribution/releases','local');$release=SonarDeskRelease::create(['version'=>$data['version'],'build_number'=>$data['build_number'],'channel'=>$data['channel'],'minimum_macos'=>$data['minimum_macos']??null,'release_notes'=>$data['release_notes']??null,'sparkle_signature'=>$data['sparkle_signature']??null,'file_path'=>$path,'original_filename'=>$file->getClientOriginalName(),'file_size'=>$file->getSize(),'sha256'=>hash_file('sha256',$file->getRealPath()),'is_published'=>(bool)($data['is_published']??false),'is_featured'=>(bool)($data['is_featured']??false),'published_at'=>!empty($data['is_published'])?now():null]);return redirect()->route('administration.sonardesk.distribution')->with('status','Release '.$release->version.' created');} public function product(Request $request){$data=$request->validate(['name'=>'required|string|max:150','description'=>'nullable|string','version'=>'nullable|string|max:60','platform'=>'nullable|string|max:60','is_published'=>'nullable|boolean','file'=>'required|file|max:512000']);$file=$request->file('file');$path=$file->store('sonardesk-distribution/products','local');DownloadProduct::create(['name'=>$data['name'],'description'=>$data['description']??null,'version'=>$data['version']??null,'platform'=>$data['platform']??null,'file_path'=>$path,'original_filename'=>$file->getClientOriginalName(),'file_size'=>$file->getSize(),'is_published'=>(bool)($data['is_published']??false)]);return redirect()->route('administration.sonardesk.distribution')->with('status','Download created');} public function publish(Request $request,SonarDeskRelease $release){$data=$request->validate(['is_published'=>'required|boolean']);$release->update(['is_published'=>(bool)$data['is_published'],'published_at'=>$data['is_published']?($release->published_at??now()):null]);return back()->with('status','Release status updated');} }