wantsJson()) { abort(404); } $media = $this->getMedia($request); return response()->json($media); } public function admin_index(Request $request) { $media = $this->getMedia($request); return view('admin.media.index', [ 'media' => $media, ]); } public function getMedia(Request $request) { $query = Media::query(); $perPage = $request->input('per_page', 25); if(!empty($request->get('search'))) { $query->where(function($query) use ($request) { $query->where('title', 'like', '%' . $request->search . '%'); $query->orWhere('name', 'like', '%' . $request->search . '%'); }); } if($request->has('mime_type')) { $mime_types = explode(',', $request->mime_type); $query->where(function ($query) use ($mime_types) { foreach ($mime_types as $mime_type) { $mime_type = str_replace('*', '%', $mime_type); $query->orWhere('mime_type', 'like', $mime_type); } }); } $media = $query->orderBy('created_at', 'desc'); if($request->wantsJson() && !(empty($request->input('selected'))) && empty($request->get('search')) && !$request->has('page')) { $selected = $request->input('selected')[0]; $selectedMedia = $media->get(); $selectedMediaIndex = $selectedMedia->search(function ($item) use ($selected) { return $item->name == $selected; }); if ($selectedMediaIndex !== false) { $page = intdiv($selectedMediaIndex, $perPage) + 1; $request->merge(['page' => $page]); } } $media = $media->paginate($perPage)->onEachSide(1); return $media; } /** * Display the specified resource. */ public function show(Request $request, Media $media) { if(!$request->wantsJson()) { abort(404); } return response()->json($media); } /** * Show the form for creating a new resource. */ public function admin_create() { return view('admin.media.edit'); } /** * Store a newly created resource in storage. */ public function admin_store(Request $request) { $max_size = Helpers::getMaxUploadSize(); $validator = Validator::make($request->all(), [ 'title' => 'required', 'file' => 'required|file|max:' . (max(round($max_size / 1024),0)), ], [ 'title.required' => __('validation.custom_messages.title_required'), 'file.required' => __('validation.custom_messages.file_required'), 'file.file' => __('validation.custom_messages.file_file'), 'file.max' => __('validation.custom_messages.file_max', ['max' => Helpers::bytesToString($max_size)]) ]); if ($validator->fails()) { if($request->wantsJson()) { return response()->json([ 'message' => 'The given data was invalid.', 'errors' => $validator->errors(), ], 422); } else { return redirect()->back()->withErrors($validator)->withInput(); } } $file = $request->file('file'); $fileName = $request->input('filename', $file->getClientOriginalName()); $fileName = Helpers::cleanFileName($fileName); if(($request->has('filestart') || $request->has('fileappend')) && $request->has('filesize')) { $fileSize = $request->get('filesize'); if($fileSize > $max_size) { return response()->json([ 'message' => 'The file ' . $fileName . ' is larger than the maximum size allowed of ' . Helpers::bytesToString($max_size), 'errors' => [ 'file' => 'The file is larger than the maximum size allowed of ' . Helpers::bytesToString($max_size) ] ], 422); } $tempFilePath = sys_get_temp_dir() . '/chunk-' . $fileName; $filemode = 'a'; if($request->has('filestart')) { $filemode = 'w'; } // Append the chunk to the temporary file $fp = fopen($tempFilePath, $filemode); if ($fp) { fwrite($fp, file_get_contents($file->getRealPath())); fclose($fp); } // Check if the upload is complete if (filesize($tempFilePath) >= $fileSize) { $fileMime = mime_content_type($tempFilePath); if($fileMime === false) { $fileMime = 'application/octet-stream'; } $file = new UploadedFile($tempFilePath, $fileName, $fileMime, null, true); } else { return response()->json([ 'message' => 'Chunk stored', ]); } } $name = pathinfo($fileName, PATHINFO_FILENAME); $extension = pathinfo($fileName, PATHINFO_EXTENSION); $name = Helpers::cleanFileName($name); if(Media::find($name . '.' . $extension) !== null) { $increment = 1; $name = preg_replace('/-\d+$/', '', $name); while(Media::find($name . '-' . $increment . '.' . $extension) !== null) { $increment++; } $fileName = $name . '-' . $increment . '.' . $extension; } $hash = hash_file('sha256', $file->path()); $storage = Storage::disk('media'); if(!$storage->exists($hash)) { if($file->storeAs('/', $hash, 'media') === false) { if($request->wantsJson()) { return response()->json([ 'message' => 'A server error occurred uploading the file.', ], 500); } else { session()->flash('message', 'A server error occurred uploading the file.'); session()->flash('message-title', 'Upload failed'); session()->flash('message-type', 'danger'); return redirect()->back(); } } } $media = Media::Create([ 'title' => $request->get('title', Helpers::filenameToTitle($fileName)), 'user_id' => auth()->id(), 'name' => $fileName, 'size' => $file->getSize(), 'mime_type' => $file->getMimeType(), 'hash' => $hash ]); $media->generateVariants(false); unlink($file->getRealPath()); if($request->wantsJson()) { return response()->json([ 'message' => 'File has been uploaded', 'name' => $media->name, 'size' => $media->size, 'mime_type' => $media->mime_type ]); } else { session()->flash('message', 'Media has been uploaded'); session()->flash('message-title', 'Media uploaded'); session()->flash('message-type', 'success'); return redirect()->route('admin.media.index'); } } /** * Show the form for editing the specified resource. */ public function admin_edit(Media $media) { return view('admin.media.edit', ['medium' => $media]); } /** * Update the specified resource in storage. */ public function admin_update(Request $request, Media $media) { $max_size = Helpers::getMaxUploadSize(); $validator = Validator::make($request->all(), [ 'title' => 'required', // 'file' => 'nullable|file|max:' . (max(round($max_size / 1024),0)), ], [ 'title.required' => __('validation.custom_messages.title_required'), // 'file.required' => __('validation.custom_messages.file_required'), // 'file.file' => __('validation.custom_messages.file_file'), // 'file.max' => __('validation.custom_messages.file_max', ['max' => Helpers::bytesToString($max_size)]) ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); } $mediaData = $request->all(); // $file = null; // if($request->has('file')) { // $file = $request->file('file'); // // $name = $file->getClientOriginalName(); // $name = Helpers::cleanFileName($name); // if ($name !== $media->name) { // if (Media::find($name) !== null) { // $increment = 2; // while (Media::find($name . '-' . $increment) !== null) { // $increment++; // } // // $name = $name . '-' . $increment; // } // } // // $hash = hash_file('sha256', $file->path()); // // $storage = Storage::disk('media'); // if (!$storage->exists($hash)) { // if ($file->storeAs('/', $hash, 'media') === false) { // session()->flash('message', 'A server error occurred uploading the file.'); // session()->flash('message-title', 'Upload failed'); // session()->flash('message-type', 'danger'); // return redirect()->back(); // } // } // // $mediaData['name'] = $name; // $mediaData['size'] = $file->getSize(); // $mediaData['mime_type'] = $file->getMimeType(); // $mediaData['hash'] = $hash; // } if($request->get('password_clear') === 'on') { $mediaData['password'] = null; } else { $password = $request->get('password'); if($password !== null && $password !== '') { $mediaData['password'] = password_hash($request->get('password'), PASSWORD_DEFAULT); } else { unset($mediaData['password']); } } $media->update($mediaData); // if($file) { // $media->generateVariants(false); // unlink($file); // } session()->flash('message', 'Media has been updated'); session()->flash('message-title', 'Media updated'); session()->flash('message-type', 'success'); return redirect()->route('admin.media.index'); } /** * Remove the specified resource from storage. */ public function admin_destroy(Request $request, Media $media) { $media->delete(); session()->flash('message', 'Media has been deleted'); session()->flash('message-title', 'Media deleted'); session()->flash('message-type', 'danger'); if($request->wantsJson()) { return response()->json([ 'success' => true, 'redirect' => route('admin.media.index'), ]); } return redirect()->route('admin.media.index'); } public function upload(Request $request) { $request->validate([ 'file' => 'required|file', ]); if(auth()->guest()) { return response()->json([ 'message' => 'You must be logged in to upload media', ], 401); } if(!auth()->user()?->admin) { return response()->json([ 'message' => 'You do not have permission to upload media', ], 403); } if(!$request->hasFile('file')) { return response()->json([ 'message' => 'No file was received by the server', ], 422); } $max_size = Helpers::getMaxUploadSize(); $file = $request->file('file'); if($file->getSize() > $max_size) { return response()->json([ 'message' => 'The file ' . $file->getClientOriginalName() . ' is larger than the maximum size allowed of ' . Helpers::bytesToString($max_size) ], 422); } $name = $file->getClientOriginalName(); if(Media::find($name) !== null) { $increment = 2; while(Media::find($name . '-' . $increment) !== null) { $increment++; } $name = $name . '-' . $increment; } $media = Media::Create([ 'title' => $request->get('title', $name), 'user_id' => auth()->id(), 'name' => $name, 'size' => $file->getSize(), 'mime_type' => $file->getMimeType(), 'hash' => hash_file('sha256', $file->path()), ]); $file->storeAs('/', $media->hash, 'public'); $media->generateVariants(); unlink($file); return response()->json([ 'message' => 'File has been uploaded', 'name' => $media->name, 'size' => $media->size, 'mime_type' => $media->mime_type ]); } public function download(Request $request, Media $media) { $file = $media->path(); if($file === null) { abort(404, 'File not found'); } if($media->password !== null) { if(!$request->has('password')) { return view('media-password'); } else { $password = $request->get('password'); if($password === '' || $password === null) { return view('media-password', [ 'error' => 'Password is required', ]); } if(!password_verify(base64_decode($password), $media->password)) { return view('media-password', [ 'error' => 'Password is incorrect', ]); } } } $variant = ''; $download = false; $variants = array_keys($media->getVariantTypes()); $query = $request->getQueryString(); if($query !== '') { $queryList = explode('&', $query); foreach($queryList as $queryItem) { $parts = explode('=', $queryItem); if($variant === '' && in_array($parts[0], $variants) && ($parts[1] === '' || filter_var($parts[1], FILTER_VALIDATE_BOOLEAN))) { $variant = $parts[0]; } if($parts[0] === 'download' && ($parts[1] === '' || filter_var($parts[1], FILTER_VALIDATE_BOOLEAN))) { $download = true; } } } $mime_type = $media->mime_type; $name = $media->name; if($variant !== '') { $variantFile = $media->getClosestVariant($variant); $file = $variantFile['file']; $mime_type = $variantFile['mime_type']; $name = $variantFile['name']; } $headers = [ 'Content-Type' => $mime_type, 'Content-Disposition' => ($download ? 'attachment; ' : '') . 'filename="' . $name . '"', ]; return response()->file($file, $headers); } }