X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ac0b29fb6d05d6e943419b91fdbc09a59e20c89f..refs/pull/232/head:/app/Services/FileService.php diff --git a/app/Services/FileService.php b/app/Services/FileService.php index 7429f0e64..261695e1f 100644 --- a/app/Services/FileService.php +++ b/app/Services/FileService.php @@ -32,31 +32,13 @@ class FileService extends UploadService public function saveNewUpload(UploadedFile $uploadedFile, $page_id) { $fileName = $uploadedFile->getClientOriginalName(); - $fileData = file_get_contents($uploadedFile->getRealPath()); - - $storage = $this->getStorage(); - $fileBasePath = 'uploads/files/' . Date('Y-m-M') . '/'; - $storageBasePath = $this->getStorageBasePath() . $fileBasePath; - - $uploadFileName = $fileName; - while ($storage->exists($storageBasePath . $uploadFileName)) { - $uploadFileName = str_random(3) . $uploadFileName; - } - - $filePath = $fileBasePath . $uploadFileName; - $fileStoragePath = $this->getStorageBasePath() . $filePath; - - try { - $storage->put($fileStoragePath, $fileData); - } catch (Exception $e) { - throw new FileUploadException('File path ' . $fileStoragePath . ' could not be uploaded to. Ensure it is writable to the server.'); - } - + $filePath = $this->putFileInStorage($fileName, $uploadedFile); $largestExistingOrder = File::where('uploaded_to', '=', $page_id)->max('order'); $file = File::forceCreate([ 'name' => $fileName, 'path' => $filePath, + 'extension' => $uploadedFile->getClientOriginalExtension(), 'uploaded_to' => $page_id, 'created_by' => user()->id, 'updated_by' => user()->id, @@ -66,6 +48,53 @@ class FileService extends UploadService return $file; } + /** + * Store a upload, saving to a file and deleting any existing uploads + * attached to that file. + * @param UploadedFile $uploadedFile + * @param File $file + * @return File + * @throws FileUploadException + */ + public function saveUpdatedUpload(UploadedFile $uploadedFile, File $file) + { + if (!$file->external) { + $this->deleteFileInStorage($file); + } + + $fileName = $uploadedFile->getClientOriginalName(); + $filePath = $this->putFileInStorage($fileName, $uploadedFile); + + $file->name = $fileName; + $file->path = $filePath; + $file->external = false; + $file->extension = $uploadedFile->getClientOriginalExtension(); + $file->save(); + return $file; + } + + /** + * Save a new File attachment from a given link and name. + * @param string $name + * @param string $link + * @param int $page_id + * @return File + */ + public function saveNewFromLink($name, $link, $page_id) + { + $largestExistingOrder = File::where('uploaded_to', '=', $page_id)->max('order'); + return File::forceCreate([ + 'name' => $name, + 'path' => $link, + 'external' => true, + 'extension' => '', + 'uploaded_to' => $page_id, + 'created_by' => user()->id, + 'updated_by' => user()->id, + 'order' => $largestExistingOrder + 1 + ]); + } + /** * Get the file storage base path, amended for storage type. * This allows us to keep a generic path in the database. @@ -88,11 +117,48 @@ class FileService extends UploadService } } + + /** + * Update the details of a file. + * @param File $file + * @param $requestData + * @return File + */ + public function updateFile(File $file, $requestData) + { + $file->name = $requestData['name']; + if (isset($requestData['link']) && trim($requestData['link']) !== '') { + $file->path = $requestData['link']; + if (!$file->external) { + $this->deleteFileInStorage($file); + $file->external = true; + } + } + $file->save(); + return $file; + } + /** - * Delete a file and any empty folders the deletion leaves. + * Delete a File from the database and storage. * @param File $file */ public function deleteFile(File $file) + { + if ($file->external) { + $file->delete(); + return; + } + + $this->deleteFileInStorage($file); + $file->delete(); + } + + /** + * Delete a file from the filesystem it sits on. + * Cleans any empty leftover folders. + * @param File $file + */ + protected function deleteFileInStorage(File $file) { $storedFilePath = $this->getStorageBasePath() . $file->path; $storage = $this->getStorage(); @@ -102,8 +168,37 @@ class FileService extends UploadService if (count($storage->allFiles($dirPath)) === 0) { $storage->deleteDirectory($dirPath); } + } - $file->delete(); + /** + * Store a file in storage with the given filename + * @param $fileName + * @param UploadedFile $uploadedFile + * @return string + * @throws FileUploadException + */ + protected function putFileInStorage($fileName, UploadedFile $uploadedFile) + { + $fileData = file_get_contents($uploadedFile->getRealPath()); + + $storage = $this->getStorage(); + $fileBasePath = 'uploads/files/' . Date('Y-m-M') . '/'; + $storageBasePath = $this->getStorageBasePath() . $fileBasePath; + + $uploadFileName = $fileName; + while ($storage->exists($storageBasePath . $uploadFileName)) { + $uploadFileName = str_random(3) . $uploadFileName; + } + + $filePath = $fileBasePath . $uploadFileName; + $fileStoragePath = $this->getStorageBasePath() . $filePath; + + try { + $storage->put($fileStoragePath, $fileData); + } catch (Exception $e) { + throw new FileUploadException('File path ' . $fileStoragePath . ' could not be uploaded to. Ensure it is writable to the server.'); + } + return $filePath; } } \ No newline at end of file