Dan Brown

File upload deletion complete & added extension handling

Also fixed issue with file editing on JS side
...@@ -6,6 +6,16 @@ class File extends Ownable ...@@ -6,6 +6,16 @@ class File extends Ownable
6 protected $fillable = ['name', 'order']; 6 protected $fillable = ['name', 'order'];
7 7
8 /** 8 /**
9 + * Get the downloadable file name for this upload.
10 + * @return mixed|string
11 + */
12 + public function getFileName()
13 + {
14 + if (str_contains($this->name, '.')) return $this->name;
15 + return $this->name . '.' . $this->extension;
16 + }
17 +
18 + /**
9 * Get the page this file was uploaded to. 19 * Get the page this file was uploaded to.
10 * @return Page 20 * @return Page
11 */ 21 */
......
...@@ -196,7 +196,7 @@ class FileController extends Controller ...@@ -196,7 +196,7 @@ class FileController extends Controller
196 $fileContents = $this->fileService->getFile($file); 196 $fileContents = $this->fileService->getFile($file);
197 return response($fileContents, 200, [ 197 return response($fileContents, 200, [
198 'Content-Type' => 'application/octet-stream', 198 'Content-Type' => 'application/octet-stream',
199 - 'Content-Disposition' => 'attachment; filename="'. $file->name .'"' 199 + 'Content-Disposition' => 'attachment; filename="'. $file->getFileName() .'"'
200 ]); 200 ]);
201 } 201 }
202 202
......
...@@ -5,6 +5,7 @@ use BookStack\Book; ...@@ -5,6 +5,7 @@ use BookStack\Book;
5 use BookStack\Chapter; 5 use BookStack\Chapter;
6 use BookStack\Entity; 6 use BookStack\Entity;
7 use BookStack\Exceptions\NotFoundException; 7 use BookStack\Exceptions\NotFoundException;
8 +use BookStack\Services\FileService;
8 use Carbon\Carbon; 9 use Carbon\Carbon;
9 use DOMDocument; 10 use DOMDocument;
10 use DOMXPath; 11 use DOMXPath;
...@@ -633,6 +634,13 @@ class PageRepo extends EntityRepo ...@@ -633,6 +634,13 @@ class PageRepo extends EntityRepo
633 $page->revisions()->delete(); 634 $page->revisions()->delete();
634 $page->permissions()->delete(); 635 $page->permissions()->delete();
635 $this->permissionService->deleteJointPermissionsForEntity($page); 636 $this->permissionService->deleteJointPermissionsForEntity($page);
637 +
638 + // Delete AttachedFiles
639 + $fileService = app(FileService::class);
640 + foreach ($page->files as $file) {
641 + $fileService->deleteFile($file);
642 + }
643 +
636 $page->delete(); 644 $page->delete();
637 } 645 }
638 646
......
...@@ -38,6 +38,7 @@ class FileService extends UploadService ...@@ -38,6 +38,7 @@ class FileService extends UploadService
38 $file = File::forceCreate([ 38 $file = File::forceCreate([
39 'name' => $fileName, 39 'name' => $fileName,
40 'path' => $filePath, 40 'path' => $filePath,
41 + 'extension' => $uploadedFile->getClientOriginalExtension(),
41 'uploaded_to' => $page_id, 42 'uploaded_to' => $page_id,
42 'created_by' => user()->id, 43 'created_by' => user()->id,
43 'updated_by' => user()->id, 44 'updated_by' => user()->id,
...@@ -67,6 +68,7 @@ class FileService extends UploadService ...@@ -67,6 +68,7 @@ class FileService extends UploadService
67 $file->name = $fileName; 68 $file->name = $fileName;
68 $file->path = $filePath; 69 $file->path = $filePath;
69 $file->external = false; 70 $file->external = false;
71 + $file->extension = $uploadedFile->getClientOriginalExtension();
70 $file->save(); 72 $file->save();
71 return $file; 73 return $file;
72 } 74 }
...@@ -85,6 +87,7 @@ class FileService extends UploadService ...@@ -85,6 +87,7 @@ class FileService extends UploadService
85 'name' => $name, 87 'name' => $name,
86 'path' => $link, 88 'path' => $link,
87 'external' => true, 89 'external' => true,
90 + 'extension' => '',
88 'uploaded_to' => $page_id, 91 'uploaded_to' => $page_id,
89 'created_by' => user()->id, 92 'created_by' => user()->id,
90 'updated_by' => user()->id, 93 'updated_by' => user()->id,
......
...@@ -17,6 +17,7 @@ class CreateFilesTable extends Migration ...@@ -17,6 +17,7 @@ class CreateFilesTable extends Migration
17 $table->increments('id'); 17 $table->increments('id');
18 $table->string('name'); 18 $table->string('name');
19 $table->string('path'); 19 $table->string('path');
20 + $table->string('extension', 20);
20 $table->integer('uploaded_to'); 21 $table->integer('uploaded_to');
21 22
22 $table->boolean('external'); 23 $table->boolean('external');
...@@ -59,16 +60,12 @@ class CreateFilesTable extends Migration ...@@ -59,16 +60,12 @@ class CreateFilesTable extends Migration
59 { 60 {
60 Schema::dropIfExists('files'); 61 Schema::dropIfExists('files');
61 62
62 - // Get roles with permissions we need to change
63 - $adminRoleId = DB::table('roles')->where('system_name', '=', 'admin')->first()->id;
64 -
65 // Create & attach new entity permissions 63 // Create & attach new entity permissions
66 $ops = ['Create All', 'Create Own', 'Update All', 'Update Own', 'Delete All', 'Delete Own']; 64 $ops = ['Create All', 'Create Own', 'Update All', 'Update Own', 'Delete All', 'Delete Own'];
67 $entity = 'File'; 65 $entity = 'File';
68 foreach ($ops as $op) { 66 foreach ($ops as $op) {
69 $permName = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op)); 67 $permName = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op));
70 - $permission = DB::table('role_permissions')->where('name', '=', $permName)->get(); 68 + DB::table('role_permissions')->where('name', '=', $permName)->delete();
71 - DB::table('permission_role')->where('permission_id', '=', $permission->id)->delete();
72 } 69 }
73 } 70 }
74 } 71 }
......
...@@ -674,6 +674,7 @@ module.exports = function (ngApp, events) { ...@@ -674,6 +674,7 @@ module.exports = function (ngApp, events) {
674 if ($scope.editFile && !file.external) { 674 if ($scope.editFile && !file.external) {
675 $scope.editFile.link = ''; 675 $scope.editFile.link = '';
676 } 676 }
677 + $scope.editFile = false;
677 events.emit('success', 'Attachment details updated'); 678 events.emit('success', 'Attachment details updated');
678 }); 679 });
679 }; 680 };
...@@ -686,7 +687,7 @@ module.exports = function (ngApp, events) { ...@@ -686,7 +687,7 @@ module.exports = function (ngApp, events) {
686 */ 687 */
687 function filesIndexOf(file) { 688 function filesIndexOf(file) {
688 for (let i = 0; i < $scope.files.length; i++) { 689 for (let i = 0; i < $scope.files.length; i++) {
689 - if ($scope.files[i].id == file.id) return file.id; 690 + if ($scope.files[i].id == file.id) return i;
690 } 691 }
691 return -1; 692 return -1;
692 } 693 }
......