validate([ 'previous_file_id' => ['required', 'integer'], ]); $user = $request->user(); assert($user !== null); // Resolved through the same candidate rule the pickers use, so an // id outside this caller's reach is a 404 rather than a 403 that // confirms the file exists. $previous = $this->versions->resolveCandidate($file, $user, (int) $validated['previous_file_id']); abort_if($previous === null, 404); $this->versions->link($file, $previous, $user); return new FileResource($file->fresh() ?? $file); } /** * Remove this file's version link, making it stand on its own again. * * It stops inheriting the original's recipients, so it keeps a copy of * them: unlinking never takes access away from someone who already has * it. */ public function destroy(Request $request, File $file): FileResource { Gate::authorize('setVersion', $file); $user = $request->user(); assert($user !== null); $this->versions->unlink($file, $user); return new FileResource($file->fresh() ?? $file); } }