Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Зуев Егор
/
wiki.dev
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Authored by
Dan Brown
2016-11-12 14:12:26 +0000
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Commit
e639600ba5909941db97fdd3a4df4220d80f4c7a
e639600b
1 parent
d439fb45
Renamed files to attachments
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
183 additions
and
183 deletions
app/File.php → app/Attachment.php
app/Http/Controllers/FileController.php → app/Http/Controllers/AttachmentController.php
app/Page.php
app/Repos/PageRepo.php
app/Services/FileService.php → app/Services/AttachmentService.php
database/migrations/2016_10_09_142037_create_files_table.php → database/migrations/2016_10_09_142037_create_attachments_table.php
resources/assets/js/controllers.js
resources/views/pages/form-toolbox.blade.php
resources/views/pages/sidebar-tree-list.blade.php
resources/views/settings/roles/form.blade.php
routes/web.php
tests/AttachmentTest.php
app/
File
.php
→
app/
Attachment
.php
View file @
e639600
<?php
namespace
BookStack
;
class
File
extends
Ownable
class
Attachment
extends
Ownable
{
protected
$fillable
=
[
'name'
,
'order'
];
...
...
@@ -30,7 +30,7 @@ class File extends Ownable
*/
public
function
getUrl
()
{
return
baseUrl
(
'/
file
s/'
.
$this
->
id
);
return
baseUrl
(
'/
attachment
s/'
.
$this
->
id
);
}
}
...
...
app/Http/Controllers/
File
Controller.php
→
app/Http/Controllers/
Attachment
Controller.php
View file @
e639600
<?php
namespace
BookStack\Http\Controllers
;
use
BookStack\Exceptions\FileUploadException
;
use
BookStack\
File
;
use
BookStack\
Attachment
;
use
BookStack\Repos\PageRepo
;
use
BookStack\Services\
File
Service
;
use
BookStack\Services\
Attachment
Service
;
use
Illuminate\Http\Request
;
use
BookStack\Http\Requests
;
class
FileController
extends
Controller
class
AttachmentController
extends
Controller
{
protected
$
file
Service
;
protected
$
file
;
protected
$
attachment
Service
;
protected
$
attachment
;
protected
$pageRepo
;
/**
*
File
Controller constructor.
* @param
FileService $file
Service
* @param
File $file
*
Attachment
Controller constructor.
* @param
AttachmentService $attachment
Service
* @param
Attachment $attachment
* @param PageRepo $pageRepo
*/
public
function
__construct
(
FileService
$fileService
,
File
$file
,
PageRepo
$pageRepo
)
public
function
__construct
(
AttachmentService
$attachmentService
,
Attachment
$attachment
,
PageRepo
$pageRepo
)
{
$this
->
fileService
=
$file
Service
;
$this
->
file
=
$file
;
$this
->
attachmentService
=
$attachment
Service
;
$this
->
attachment
=
$attachment
;
$this
->
pageRepo
=
$pageRepo
;
parent
::
__construct
();
}
/**
* Endpoint at which
file
s are uploaded to.
* Endpoint at which
attachment
s are uploaded to.
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response
*/
public
function
upload
(
Request
$request
)
{
...
...
@@ -42,27 +42,27 @@ class FileController extends Controller
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
);
$this
->
checkPermission
(
'
file
-create-all'
);
$this
->
checkPermission
(
'
attachment
-create-all'
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
$uploadedFile
=
$request
->
file
(
'file'
);
try
{
$
file
=
$this
->
file
Service
->
saveNewUpload
(
$uploadedFile
,
$pageId
);
$
attachment
=
$this
->
attachment
Service
->
saveNewUpload
(
$uploadedFile
,
$pageId
);
}
catch
(
FileUploadException
$e
)
{
return
response
(
$e
->
getMessage
(),
500
);
}
return
response
()
->
json
(
$
file
);
return
response
()
->
json
(
$
attachment
);
}
/**
* Update an uploaded
file
.
* @param int $
file
Id
* Update an uploaded
attachment
.
* @param int $
attachment
Id
* @param Request $request
* @return mixed
*/
public
function
uploadUpdate
(
$
file
Id
,
Request
$request
)
public
function
uploadUpdate
(
$
attachment
Id
,
Request
$request
)
{
$this
->
validate
(
$request
,
[
'uploaded_to'
=>
'required|integer|exists:pages,id'
,
...
...
@@ -71,33 +71,33 @@ class FileController extends Controller
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
);
$
file
=
$this
->
file
->
findOrFail
(
$file
Id
);
$
attachment
=
$this
->
attachment
->
findOrFail
(
$attachment
Id
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
$this
->
checkOwnablePermission
(
'
file-create'
,
$file
);
$this
->
checkOwnablePermission
(
'
attachment-create'
,
$attachment
);
if
(
intval
(
$pageId
)
!==
intval
(
$
file
->
uploaded_to
))
{
if
(
intval
(
$pageId
)
!==
intval
(
$
attachment
->
uploaded_to
))
{
return
$this
->
jsonError
(
'Page mismatch during attached file update'
);
}
$uploadedFile
=
$request
->
file
(
'file'
);
try
{
$
file
=
$this
->
fileService
->
saveUpdatedUpload
(
$uploadedFile
,
$file
);
$
attachment
=
$this
->
attachmentService
->
saveUpdatedUpload
(
$uploadedFile
,
$attachment
);
}
catch
(
FileUploadException
$e
)
{
return
response
(
$e
->
getMessage
(),
500
);
}
return
response
()
->
json
(
$
file
);
return
response
()
->
json
(
$
attachment
);
}
/**
* Update the details of an existing file.
* @param $
file
Id
* @param $
attachment
Id
* @param Request $request
* @return
File
|mixed
* @return
Attachment
|mixed
*/
public
function
update
(
$
file
Id
,
Request
$request
)
public
function
update
(
$
attachment
Id
,
Request
$request
)
{
$this
->
validate
(
$request
,
[
'uploaded_to'
=>
'required|integer|exists:pages,id'
,
...
...
@@ -107,21 +107,21 @@ class FileController extends Controller
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
);
$
file
=
$this
->
file
->
findOrFail
(
$file
Id
);
$
attachment
=
$this
->
attachment
->
findOrFail
(
$attachment
Id
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
$this
->
checkOwnablePermission
(
'
file-create'
,
$file
);
$this
->
checkOwnablePermission
(
'
attachment-create'
,
$attachment
);
if
(
intval
(
$pageId
)
!==
intval
(
$
file
->
uploaded_to
))
{
if
(
intval
(
$pageId
)
!==
intval
(
$
attachment
->
uploaded_to
))
{
return
$this
->
jsonError
(
'Page mismatch during attachment update'
);
}
$
file
=
$this
->
fileService
->
updateFile
(
$file
,
$request
->
all
());
return
$
file
;
$
attachment
=
$this
->
attachmentService
->
updateFile
(
$attachment
,
$request
->
all
());
return
$
attachment
;
}
/**
* Attach a link to a page
as a file
.
* Attach a link to a page.
* @param Request $request
* @return mixed
*/
...
...
@@ -136,18 +136,18 @@ class FileController extends Controller
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
);
$this
->
checkPermission
(
'
file
-create-all'
);
$this
->
checkPermission
(
'
attachment
-create-all'
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
$
file
Name
=
$request
->
get
(
'name'
);
$
attachment
Name
=
$request
->
get
(
'name'
);
$link
=
$request
->
get
(
'link'
);
$
file
=
$this
->
fileService
->
saveNewFromLink
(
$file
Name
,
$link
,
$pageId
);
$
attachment
=
$this
->
attachmentService
->
saveNewFromLink
(
$attachment
Name
,
$link
,
$pageId
);
return
response
()
->
json
(
$
file
);
return
response
()
->
json
(
$
attachment
);
}
/**
* Get the
file
s for a specific page.
* Get the
attachment
s for a specific page.
* @param $pageId
* @return mixed
*/
...
...
@@ -159,7 +159,7 @@ class FileController extends Controller
}
/**
* Update the
file
sorting.
* Update the
attachment
sorting.
* @param $pageId
* @param Request $request
* @return mixed
...
...
@@ -173,42 +173,43 @@ class FileController extends Controller
$page
=
$this
->
pageRepo
->
getById
(
$pageId
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
$
file
s
=
$request
->
get
(
'files'
);
$this
->
fileService
->
updateFileOrderWithinPage
(
$file
s
,
$pageId
);
$
attachment
s
=
$request
->
get
(
'files'
);
$this
->
attachmentService
->
updateFileOrderWithinPage
(
$attachment
s
,
$pageId
);
return
response
()
->
json
([
'message'
=>
'Attachment order updated'
]);
}
/**
* Get a file from storage.
* @param $fileId
* Get an attachment from storage.
* @param $attachmentId
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Symfony\Component\HttpFoundation\Response
*/
public
function
get
(
$
file
Id
)
public
function
get
(
$
attachment
Id
)
{
$
file
=
$this
->
file
->
findOrFail
(
$file
Id
);
$page
=
$this
->
pageRepo
->
getById
(
$
file
->
uploaded_to
);
$
attachment
=
$this
->
attachment
->
findOrFail
(
$attachment
Id
);
$page
=
$this
->
pageRepo
->
getById
(
$
attachment
->
uploaded_to
);
$this
->
checkOwnablePermission
(
'page-view'
,
$page
);
if
(
$
file
->
external
)
{
return
redirect
(
$
file
->
path
);
if
(
$
attachment
->
external
)
{
return
redirect
(
$
attachment
->
path
);
}
$
fileContents
=
$this
->
fileService
->
getFile
(
$file
);
return
response
(
$
file
Contents
,
200
,
[
$
attachmentContents
=
$this
->
attachmentService
->
getAttachmentFromStorage
(
$attachment
);
return
response
(
$
attachment
Contents
,
200
,
[
'Content-Type'
=>
'application/octet-stream'
,
'Content-Disposition'
=>
'attachment; filename="'
.
$
file
->
getFileName
()
.
'"'
'Content-Disposition'
=>
'attachment; filename="'
.
$
attachment
->
getFileName
()
.
'"'
]);
}
/**
* Delete a specific
file
in the system.
* @param $
file
Id
* Delete a specific
attachment
in the system.
* @param $
attachment
Id
* @return mixed
*/
public
function
delete
(
$
file
Id
)
public
function
delete
(
$
attachment
Id
)
{
$
file
=
$this
->
file
->
findOrFail
(
$file
Id
);
$this
->
checkOwnablePermission
(
'
file-delete'
,
$file
);
$this
->
fileService
->
deleteFile
(
$file
);
$
attachment
=
$this
->
attachment
->
findOrFail
(
$attachment
Id
);
$this
->
checkOwnablePermission
(
'
attachment-delete'
,
$attachment
);
$this
->
attachmentService
->
deleteFile
(
$attachment
);
return
response
()
->
json
([
'message'
=>
'Attachment deleted'
]);
}
}
...
...
app/Page.php
View file @
e639600
...
...
@@ -55,12 +55,12 @@ class Page extends Entity
}
/**
* Get the
files attach
ed to this page.
* Get the
attachments assign
ed to this page.
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public
function
file
s
()
public
function
attachment
s
()
{
return
$this
->
hasMany
(
File
::
class
,
'uploaded_to'
)
->
orderBy
(
'order'
,
'asc'
);
return
$this
->
hasMany
(
Attachment
::
class
,
'uploaded_to'
)
->
orderBy
(
'order'
,
'asc'
);
}
/**
...
...
app/Repos/PageRepo.php
View file @
e639600
...
...
@@ -5,7 +5,7 @@ use BookStack\Book;
use
BookStack\Chapter
;
use
BookStack\Entity
;
use
BookStack\Exceptions\NotFoundException
;
use
BookStack\Services\
File
Service
;
use
BookStack\Services\
Attachment
Service
;
use
Carbon\Carbon
;
use
DOMDocument
;
use
DOMXPath
;
...
...
@@ -636,9 +636,9 @@ class PageRepo extends EntityRepo
$this
->
permissionService
->
deleteJointPermissionsForEntity
(
$page
);
// Delete AttachedFiles
$
fileService
=
app
(
File
Service
::
class
);
foreach
(
$page
->
files
as
$file
)
{
$
fileService
->
deleteFile
(
$file
);
$
attachmentService
=
app
(
Attachment
Service
::
class
);
foreach
(
$page
->
attachments
as
$attachment
)
{
$
attachmentService
->
deleteFile
(
$attachment
);
}
$page
->
delete
();
...
...
@@ -647,6 +647,7 @@ class PageRepo extends EntityRepo
/**
* Get the latest pages added to the system.
* @param $count
* @return mixed
*/
public
function
getRecentlyCreatedPaginated
(
$count
=
20
)
{
...
...
@@ -656,6 +657,7 @@ class PageRepo extends EntityRepo
/**
* Get the latest pages added to the system.
* @param $count
* @return mixed
*/
public
function
getRecentlyUpdatedPaginated
(
$count
=
20
)
{
...
...
app/Services/
File
Service.php
→
app/Services/
Attachment
Service.php
View file @
e639600
<?php
namespace
BookStack\Services
;
use
BookStack\Exceptions\FileUploadException
;
use
BookStack\
File
;
use
BookStack\
Attachment
;
use
Exception
;
use
Illuminate\Contracts\Filesystem\FileNotFoundException
;
use
Illuminate\Support\Collection
;
use
Symfony\Component\HttpFoundation\File\UploadedFile
;
class
File
Service
extends
UploadService
class
Attachment
Service
extends
UploadService
{
/**
* Get a
file
from storage.
* @param
File $file
* Get a
n attachment
from storage.
* @param
Attachment $attachment
* @return string
*/
public
function
get
File
(
File
$file
)
public
function
get
AttachmentFromStorage
(
Attachment
$attachment
)
{
$
filePath
=
$this
->
getStorageBasePath
()
.
$file
->
path
;
return
$this
->
getStorage
()
->
get
(
$
file
Path
);
$
attachmentPath
=
$this
->
getStorageBasePath
()
.
$attachment
->
path
;
return
$this
->
getStorage
()
->
get
(
$
attachment
Path
);
}
/**
* Store a new
file
upon user upload.
* Store a new
attachment
upon user upload.
* @param UploadedFile $uploadedFile
* @param int $page_id
* @return
File
* @return
Attachment
* @throws FileUploadException
*/
public
function
saveNewUpload
(
UploadedFile
$uploadedFile
,
$page_id
)
{
$
file
Name
=
$uploadedFile
->
getClientOriginalName
();
$
filePath
=
$this
->
putFileInStorage
(
$file
Name
,
$uploadedFile
);
$largestExistingOrder
=
File
::
where
(
'uploaded_to'
,
'='
,
$page_id
)
->
max
(
'order'
);
$
attachment
Name
=
$uploadedFile
->
getClientOriginalName
();
$
attachmentPath
=
$this
->
putFileInStorage
(
$attachment
Name
,
$uploadedFile
);
$largestExistingOrder
=
Attachment
::
where
(
'uploaded_to'
,
'='
,
$page_id
)
->
max
(
'order'
);
$
file
=
File
::
forceCreate
([
'name'
=>
$
file
Name
,
'path'
=>
$
file
Path
,
$
attachment
=
Attachment
::
forceCreate
([
'name'
=>
$
attachment
Name
,
'path'
=>
$
attachment
Path
,
'extension'
=>
$uploadedFile
->
getClientOriginalExtension
(),
'uploaded_to'
=>
$page_id
,
'created_by'
=>
user
()
->
id
,
...
...
@@ -45,32 +42,32 @@ class FileService extends UploadService
'order'
=>
$largestExistingOrder
+
1
]);
return
$
file
;
return
$
attachment
;
}
/**
* Store a upload, saving to a file and deleting any existing uploads
* attached to that file.
* @param UploadedFile $uploadedFile
* @param
File $file
* @return
File
* @param
Attachment $attachment
* @return
Attachment
* @throws FileUploadException
*/
public
function
saveUpdatedUpload
(
UploadedFile
$uploadedFile
,
File
$file
)
public
function
saveUpdatedUpload
(
UploadedFile
$uploadedFile
,
Attachment
$attachment
)
{
if
(
!
$
file
->
external
)
{
$this
->
deleteFileInStorage
(
$
file
);
if
(
!
$
attachment
->
external
)
{
$this
->
deleteFileInStorage
(
$
attachment
);
}
$
file
Name
=
$uploadedFile
->
getClientOriginalName
();
$
filePath
=
$this
->
putFileInStorage
(
$file
Name
,
$uploadedFile
);
$
attachment
Name
=
$uploadedFile
->
getClientOriginalName
();
$
attachmentPath
=
$this
->
putFileInStorage
(
$attachment
Name
,
$uploadedFile
);
$
file
->
name
=
$file
Name
;
$
file
->
path
=
$file
Path
;
$
file
->
external
=
false
;
$
file
->
extension
=
$uploadedFile
->
getClientOriginalExtension
();
$
file
->
save
();
return
$
file
;
$
attachment
->
name
=
$attachment
Name
;
$
attachment
->
path
=
$attachment
Path
;
$
attachment
->
external
=
false
;
$
attachment
->
extension
=
$uploadedFile
->
getClientOriginalExtension
();
$
attachment
->
save
();
return
$
attachment
;
}
/**
...
...
@@ -78,12 +75,12 @@ class FileService extends UploadService
* @param string $name
* @param string $link
* @param int $page_id
* @return
File
* @return
Attachment
*/
public
function
saveNewFromLink
(
$name
,
$link
,
$page_id
)
{
$largestExistingOrder
=
File
::
where
(
'uploaded_to'
,
'='
,
$page_id
)
->
max
(
'order'
);
return
File
::
forceCreate
([
$largestExistingOrder
=
Attachment
::
where
(
'uploaded_to'
,
'='
,
$page_id
)
->
max
(
'order'
);
return
Attachment
::
forceCreate
([
'name'
=>
$name
,
'path'
=>
$link
,
'external'
=>
true
,
...
...
@@ -107,60 +104,60 @@ class FileService extends UploadService
/**
* Updates the file ordering for a listing of attached files.
* @param array $
file
List
* @param array $
attachment
List
* @param $pageId
*/
public
function
updateFileOrderWithinPage
(
$
file
List
,
$pageId
)
public
function
updateFileOrderWithinPage
(
$
attachment
List
,
$pageId
)
{
foreach
(
$
fileList
as
$index
=>
$file
)
{
File
::
where
(
'uploaded_to'
,
'='
,
$pageId
)
->
where
(
'id'
,
'='
,
$file
[
'id'
])
->
update
([
'order'
=>
$index
]);
foreach
(
$
attachmentList
as
$index
=>
$attachment
)
{
Attachment
::
where
(
'uploaded_to'
,
'='
,
$pageId
)
->
where
(
'id'
,
'='
,
$attachment
[
'id'
])
->
update
([
'order'
=>
$index
]);
}
}
/**
* Update the details of a file.
* @param
File $file
* @param
Attachment $attachment
* @param $requestData
* @return
File
* @return
Attachment
*/
public
function
updateFile
(
File
$file
,
$requestData
)
public
function
updateFile
(
Attachment
$attachment
,
$requestData
)
{
$
file
->
name
=
$requestData
[
'name'
];
$
attachment
->
name
=
$requestData
[
'name'
];
if
(
isset
(
$requestData
[
'link'
])
&&
trim
(
$requestData
[
'link'
])
!==
''
)
{
$
file
->
path
=
$requestData
[
'link'
];
if
(
!
$
file
->
external
)
{
$this
->
deleteFileInStorage
(
$
file
);
$
file
->
external
=
true
;
$
attachment
->
path
=
$requestData
[
'link'
];
if
(
!
$
attachment
->
external
)
{
$this
->
deleteFileInStorage
(
$
attachment
);
$
attachment
->
external
=
true
;
}
}
$
file
->
save
();
return
$
file
;
$
attachment
->
save
();
return
$
attachment
;
}
/**
* Delete a File from the database and storage.
* @param
File $file
* @param
Attachment $attachment
*/
public
function
deleteFile
(
File
$file
)
public
function
deleteFile
(
Attachment
$attachment
)
{
if
(
$
file
->
external
)
{
$
file
->
delete
();
if
(
$
attachment
->
external
)
{
$
attachment
->
delete
();
return
;
}
$this
->
deleteFileInStorage
(
$
file
);
$
file
->
delete
();
$this
->
deleteFileInStorage
(
$
attachment
);
$
attachment
->
delete
();
}
/**
* Delete a file from the filesystem it sits on.
* Cleans any empty leftover folders.
* @param
File $file
* @param
Attachment $attachment
*/
protected
function
deleteFileInStorage
(
File
$file
)
protected
function
deleteFileInStorage
(
Attachment
$attachment
)
{
$storedFilePath
=
$this
->
getStorageBasePath
()
.
$
file
->
path
;
$storedFilePath
=
$this
->
getStorageBasePath
()
.
$
attachment
->
path
;
$storage
=
$this
->
getStorage
();
$dirPath
=
dirname
(
$storedFilePath
);
...
...
@@ -172,33 +169,33 @@ class FileService extends UploadService
/**
* Store a file in storage with the given filename
* @param $
file
Name
* @param $
attachment
Name
* @param UploadedFile $uploadedFile
* @return string
* @throws FileUploadException
*/
protected
function
putFileInStorage
(
$
file
Name
,
UploadedFile
$uploadedFile
)
protected
function
putFileInStorage
(
$
attachment
Name
,
UploadedFile
$uploadedFile
)
{
$
file
Data
=
file_get_contents
(
$uploadedFile
->
getRealPath
());
$
attachment
Data
=
file_get_contents
(
$uploadedFile
->
getRealPath
());
$storage
=
$this
->
getStorage
();
$
file
BasePath
=
'uploads/files/'
.
Date
(
'Y-m-M'
)
.
'/'
;
$storageBasePath
=
$this
->
getStorageBasePath
()
.
$
file
BasePath
;
$
attachment
BasePath
=
'uploads/files/'
.
Date
(
'Y-m-M'
)
.
'/'
;
$storageBasePath
=
$this
->
getStorageBasePath
()
.
$
attachment
BasePath
;
$uploadFileName
=
$
file
Name
;
$uploadFileName
=
$
attachment
Name
;
while
(
$storage
->
exists
(
$storageBasePath
.
$uploadFileName
))
{
$uploadFileName
=
str_random
(
3
)
.
$uploadFileName
;
}
$
filePath
=
$file
BasePath
.
$uploadFileName
;
$
fileStoragePath
=
$this
->
getStorageBasePath
()
.
$file
Path
;
$
attachmentPath
=
$attachment
BasePath
.
$uploadFileName
;
$
attachmentStoragePath
=
$this
->
getStorageBasePath
()
.
$attachment
Path
;
try
{
$storage
->
put
(
$
fileStoragePath
,
$file
Data
);
$storage
->
put
(
$
attachmentStoragePath
,
$attachment
Data
);
}
catch
(
Exception
$e
)
{
throw
new
FileUploadException
(
'File path '
.
$
file
StoragePath
.
' could not be uploaded to. Ensure it is writable to the server.'
);
throw
new
FileUploadException
(
'File path '
.
$
attachment
StoragePath
.
' could not be uploaded to. Ensure it is writable to the server.'
);
}
return
$
file
Path
;
return
$
attachment
Path
;
}
}
\ No newline at end of file
...
...
database/migrations/2016_10_09_142037_create_
file
s_table.php
→
database/migrations/2016_10_09_142037_create_
attachment
s_table.php
View file @
e639600
...
...
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use
Illuminate\Database\Schema\Blueprint
;
use
Illuminate\Database\Migrations\Migration
;
class
Create
File
sTable
extends
Migration
class
Create
Attachment
sTable
extends
Migration
{
/**
* Run the migrations.
...
...
@@ -13,7 +13,7 @@ class CreateFilesTable extends Migration
*/
public
function
up
()
{
Schema
::
create
(
'
file
s'
,
function
(
Blueprint
$table
)
{
Schema
::
create
(
'
attachment
s'
,
function
(
Blueprint
$table
)
{
$table
->
increments
(
'id'
);
$table
->
string
(
'name'
);
$table
->
string
(
'path'
);
...
...
@@ -35,7 +35,7 @@ class CreateFilesTable extends Migration
// Create & attach new entity permissions
$ops
=
[
'Create All'
,
'Create Own'
,
'Update All'
,
'Update Own'
,
'Delete All'
,
'Delete Own'
];
$entity
=
'
File
'
;
$entity
=
'
Attachment
'
;
foreach
(
$ops
as
$op
)
{
$permissionId
=
DB
::
table
(
'role_permissions'
)
->
insertGetId
([
'name'
=>
strtolower
(
$entity
)
.
'-'
.
strtolower
(
str_replace
(
' '
,
'-'
,
$op
)),
...
...
@@ -58,11 +58,11 @@ class CreateFilesTable extends Migration
*/
public
function
down
()
{
Schema
::
dropIfExists
(
'
file
s'
);
Schema
::
dropIfExists
(
'
attachment
s'
);
// Create & attach new entity permissions
$ops
=
[
'Create All'
,
'Create Own'
,
'Update All'
,
'Update Own'
,
'Delete All'
,
'Delete Own'
];
$entity
=
'
File
'
;
$entity
=
'
Attachment
'
;
foreach
(
$ops
as
$op
)
{
$permName
=
strtolower
(
$entity
)
.
'-'
.
strtolower
(
str_replace
(
' '
,
'-'
,
$op
));
DB
::
table
(
'role_permissions'
)
->
where
(
'name'
,
'='
,
$permName
)
->
delete
();
...
...
resources/assets/js/controllers.js
View file @
e639600
...
...
@@ -570,7 +570,7 @@ export default function (ngApp, events) {
if
(
newOrder
===
currentOrder
)
return
;
currentOrder
=
newOrder
;
$http
.
put
(
window
.
baseUrl
(
`/
file
s/sort/page/
${
pageId
}
`
),
{
files
:
$scope
.
files
}).
then
(
resp
=>
{
$http
.
put
(
window
.
baseUrl
(
`/
attachment
s/sort/page/
${
pageId
}
`
),
{
files
:
$scope
.
files
}).
then
(
resp
=>
{
events
.
emit
(
'success'
,
resp
.
data
.
message
);
},
checkError
(
'sort'
));
}
...
...
@@ -581,14 +581,14 @@ export default function (ngApp, events) {
*/
$scope
.
getUploadUrl
=
function
(
file
)
{
let
suffix
=
(
typeof
file
!==
'undefined'
)
?
`/
${
file
.
id
}
`
:
''
;
return
window
.
baseUrl
(
`/
file
s/upload
${
suffix
}
`
);
return
window
.
baseUrl
(
`/
attachment
s/upload
${
suffix
}
`
);
};
/**
* Get files for the current page from the server.
*/
function
getFiles
()
{
let
url
=
window
.
baseUrl
(
`/
file
s/get/page/
${
pageId
}
`
)
let
url
=
window
.
baseUrl
(
`/
attachment
s/get/page/
${
pageId
}
`
)
$http
.
get
(
url
).
then
(
resp
=>
{
$scope
.
files
=
resp
.
data
;
currentOrder
=
resp
.
data
.
map
(
file
=>
{
return
file
.
id
}).
join
(
':'
);
...
...
@@ -636,7 +636,7 @@ export default function (ngApp, events) {
file
.
deleting
=
true
;
return
;
}
$http
.
delete
(
window
.
baseUrl
(
`/
file
s/
${
file
.
id
}
`
)).
then
(
resp
=>
{
$http
.
delete
(
window
.
baseUrl
(
`/
attachment
s/
${
file
.
id
}
`
)).
then
(
resp
=>
{
events
.
emit
(
'success'
,
resp
.
data
.
message
);
$scope
.
files
.
splice
(
$scope
.
files
.
indexOf
(
file
),
1
);
},
checkError
(
'delete'
));
...
...
@@ -648,7 +648,7 @@ export default function (ngApp, events) {
*/
$scope
.
attachLinkSubmit
=
function
(
file
)
{
file
.
uploaded_to
=
pageId
;
$http
.
post
(
window
.
baseUrl
(
'/
file
s/link'
),
file
).
then
(
resp
=>
{
$http
.
post
(
window
.
baseUrl
(
'/
attachment
s/link'
),
file
).
then
(
resp
=>
{
$scope
.
files
.
push
(
resp
.
data
);
events
.
emit
(
'success'
,
'Link attached'
);
$scope
.
file
=
getCleanFile
();
...
...
@@ -676,7 +676,7 @@ export default function (ngApp, events) {
* @param file
*/
$scope
.
updateFile
=
function
(
file
)
{
$http
.
put
(
window
.
baseUrl
(
`/
file
s/
${
file
.
id
}
`
),
file
).
then
(
resp
=>
{
$http
.
put
(
window
.
baseUrl
(
`/
attachment
s/
${
file
.
id
}
`
),
file
).
then
(
resp
=>
{
let
search
=
filesIndexOf
(
resp
.
data
);
if
(
search
!==
-
1
)
$scope
.
files
[
search
]
=
resp
.
data
;
...
...
@@ -692,7 +692,7 @@ export default function (ngApp, events) {
* Get the url of a file.
*/
$scope
.
getFileUrl
=
function
(
file
)
{
return
window
.
baseUrl
(
'/
file
s/'
+
file
.
id
);
return
window
.
baseUrl
(
'/
attachment
s/'
+
file
.
id
);
};
/**
...
...
resources/views/pages/form-toolbox.blade.php
View file @
e639600
...
...
@@ -4,7 +4,7 @@
<div
class=
"tabs primary-background-light"
>
<span
toolbox-toggle
><i
class=
"zmdi zmdi-caret-left-circle"
></i></span>
<span
toolbox-tab-button=
"tags"
title=
"Page Tags"
class=
"active"
><i
class=
"zmdi zmdi-tag"
></i></span>
@if(userCan('
file
-create-all'))
@if(userCan('
attachment
-create-all'))
<span
toolbox-tab-button=
"files"
title=
"Attachments"
><i
class=
"zmdi zmdi-attachment"
></i></span>
@endif
</div>
...
...
@@ -37,7 +37,7 @@
</div>
</div>
@if(userCan('
file
-create-all'))
@if(userCan('
attachment
-create-all'))
<div
toolbox-tab-content=
"files"
ng-controller=
"PageAttachmentController"
page-id=
"{{ $page->id or 0 }}"
>
<h4>
Attachments
</h4>
<div
class=
"padded files"
>
...
...
resources/views/pages/sidebar-tree-list.blade.php
View file @
e639600
<div
class=
"book-tree"
ng-non-bindable
>
@if (isset($page)
&&
$page->
file
s->count() > 0)
@if (isset($page)
&&
$page->
attachment
s->count() > 0)
<h6
class=
"text-muted"
>
Attachments
</h6>
@foreach($page->
files as $file
)
@foreach($page->
attachments as $attachment
)
<div
class=
"attachment"
>
<a
href=
"{{ $
file->getUrl() }}"
@
if
($
file-
>
external) target="_blank" @endif>
<i
class=
"zmdi zmdi-{{ $file->external ? 'open-in-new' : 'file' }}"
></i>
{{ $file
->name }}
</a>
<a
href=
"{{ $
attachment->getUrl() }}"
@
if
($
attachment-
>
external) target="_blank" @endif>
<i
class=
"zmdi zmdi-{{ $attachment->external ? 'open-in-new' : 'file' }}"
></i>
{{ $attachment
->name }}
</a>
</div>
@endforeach
@endif
...
...
resources/views/settings/roles/form.blade.php
View file @
e639600
...
...
@@ -107,16 +107,16 @@
</td>
</tr>
<tr>
<td>
Attach
ed
<br>
File
s
</td>
<td>
@include('settings/roles/checkbox', ['permission' => '
file
-create-all'])
</td>
<td>
Attach
ment
s
</td>
<td>
@include('settings/roles/checkbox', ['permission' => '
attachment
-create-all'])
</td>
<td
style=
"line-height:1.2;"
><small
class=
"faded"
>
Controlled by the asset they are uploaded to
</small></td>
<td>
<label>
@include('settings/roles/checkbox', ['permission' => '
file
-update-own']) Own
</label>
<label>
@include('settings/roles/checkbox', ['permission' => '
file
-update-all']) All
</label>
<label>
@include('settings/roles/checkbox', ['permission' => '
attachment
-update-own']) Own
</label>
<label>
@include('settings/roles/checkbox', ['permission' => '
attachment
-update-all']) All
</label>
</td>
<td>
<label>
@include('settings/roles/checkbox', ['permission' => '
file
-delete-own']) Own
</label>
<label>
@include('settings/roles/checkbox', ['permission' => '
file
-delete-all']) All
</label>
<label>
@include('settings/roles/checkbox', ['permission' => '
attachment
-delete-own']) Own
</label>
<label>
@include('settings/roles/checkbox', ['permission' => '
attachment
-delete-all']) All
</label>
</td>
</tr>
</table>
...
...
routes/web.php
View file @
e639600
...
...
@@ -87,15 +87,15 @@ Route::group(['middleware' => 'auth'], function () {
Route
::
delete
(
'/{imageId}'
,
'ImageController@destroy'
);
});
//
File
routes
Route
::
get
(
'/
files/{id}'
,
'File
Controller@get'
);
Route
::
post
(
'/
files/upload'
,
'File
Controller@upload'
);
Route
::
post
(
'/
files/upload/{id}'
,
'File
Controller@uploadUpdate'
);
Route
::
post
(
'/
files/link'
,
'File
Controller@attachLink'
);
Route
::
put
(
'/
files/{id}'
,
'File
Controller@update'
);
Route
::
get
(
'/
files/get/page/{pageId}'
,
'File
Controller@listForPage'
);
Route
::
put
(
'/
files/sort/page/{pageId}'
,
'File
Controller@sortForPage'
);
Route
::
delete
(
'/
files/{id}'
,
'File
Controller@delete'
);
//
Attachments
routes
Route
::
get
(
'/
attachments/{id}'
,
'Attachment
Controller@get'
);
Route
::
post
(
'/
attachments/upload'
,
'Attachment
Controller@upload'
);
Route
::
post
(
'/
attachments/upload/{id}'
,
'Attachment
Controller@uploadUpdate'
);
Route
::
post
(
'/
attachments/link'
,
'Attachment
Controller@attachLink'
);
Route
::
put
(
'/
attachments/{id}'
,
'Attachment
Controller@update'
);
Route
::
get
(
'/
attachments/get/page/{pageId}'
,
'Attachment
Controller@listForPage'
);
Route
::
put
(
'/
attachments/sort/page/{pageId}'
,
'Attachment
Controller@sortForPage'
);
Route
::
delete
(
'/
attachments/{id}'
,
'Attachment
Controller@delete'
);
// AJAX routes
Route
::
put
(
'/ajax/page/{id}/save-draft'
,
'PageController@saveDraft'
);
...
...
tests/AttachmentTest.php
View file @
e639600
...
...
@@ -21,7 +21,7 @@ class AttachmentTest extends TestCase
protected
function
uploadFile
(
$name
,
$uploadedTo
=
0
)
{
$file
=
$this
->
getTestFile
(
$name
);
return
$this
->
call
(
'POST'
,
'/
file
s/upload'
,
[
'uploaded_to'
=>
$uploadedTo
],
[],
[
'file'
=>
$file
],
[]);
return
$this
->
call
(
'POST'
,
'/
attachment
s/upload'
,
[
'uploaded_to'
=>
$uploadedTo
],
[],
[
'file'
=>
$file
],
[]);
}
/**
...
...
@@ -40,8 +40,8 @@ class AttachmentTest extends TestCase
*/
protected
function
deleteUploads
()
{
$fileService
=
$this
->
app
->
make
(
\BookStack\Services\
File
Service
::
class
);
foreach
(
\BookStack\
File
::
all
()
as
$file
)
{
$fileService
=
$this
->
app
->
make
(
\BookStack\Services\
Attachment
Service
::
class
);
foreach
(
\BookStack\
Attachment
::
all
()
as
$file
)
{
$fileService
->
deleteFile
(
$file
);
}
}
...
...
@@ -66,7 +66,7 @@ class AttachmentTest extends TestCase
$this
->
uploadFile
(
$fileName
,
$page
->
id
);
$this
->
assertResponseOk
();
$this
->
seeJsonContains
(
$expectedResp
);
$this
->
seeInDatabase
(
'
file
s'
,
$expectedResp
);
$this
->
seeInDatabase
(
'
attachment
s'
,
$expectedResp
);
$this
->
deleteUploads
();
}
...
...
@@ -94,7 +94,7 @@ class AttachmentTest extends TestCase
$admin
=
$this
->
getAdmin
();
$this
->
asAdmin
();
$this
->
call
(
'POST'
,
'
file
s/link'
,
[
$this
->
call
(
'POST'
,
'
attachment
s/link'
,
[
'link'
=>
'https://example.com'
,
'name'
=>
'Example Attachment Link'
,
'uploaded_to'
=>
$page
->
id
,
...
...
@@ -113,7 +113,7 @@ class AttachmentTest extends TestCase
$this
->
assertResponseOk
();
$this
->
seeJsonContains
(
$expectedResp
);
$this
->
seeInDatabase
(
'
file
s'
,
$expectedResp
);
$this
->
seeInDatabase
(
'
attachment
s'
,
$expectedResp
);
$this
->
visit
(
$page
->
getUrl
())
->
seeLink
(
'Example Attachment Link'
)
->
click
(
'Example Attachment Link'
)
->
seePageIs
(
'https://example.com'
);
...
...
@@ -126,15 +126,15 @@ class AttachmentTest extends TestCase
$page
=
\BookStack\Page
::
first
();
$this
->
asAdmin
();
$this
->
call
(
'POST'
,
'
file
s/link'
,
[
$this
->
call
(
'POST'
,
'
attachment
s/link'
,
[
'link'
=>
'https://example.com'
,
'name'
=>
'Example Attachment Link'
,
'uploaded_to'
=>
$page
->
id
,
]);
$attachmentId
=
\BookStack\
File
::
first
()
->
id
;
$attachmentId
=
\BookStack\
Attachment
::
first
()
->
id
;
$this
->
call
(
'PUT'
,
'
file
s/'
.
$attachmentId
,
[
$this
->
call
(
'PUT'
,
'
attachment
s/'
.
$attachmentId
,
[
'uploaded_to'
=>
$page
->
id
,
'name'
=>
'My new attachment name'
,
'link'
=>
'https://test.example.com'
...
...
@@ -148,7 +148,7 @@ class AttachmentTest extends TestCase
$this
->
assertResponseOk
();
$this
->
seeJsonContains
(
$expectedResp
);
$this
->
seeInDatabase
(
'
file
s'
,
$expectedResp
);
$this
->
seeInDatabase
(
'
attachment
s'
,
$expectedResp
);
$this
->
deleteUploads
();
}
...
...
@@ -164,10 +164,10 @@ class AttachmentTest extends TestCase
$this
->
assertTrue
(
file_exists
(
$filePath
),
'File at path '
.
$filePath
.
' does not exist'
);
$attachmentId
=
\BookStack\
File
::
first
()
->
id
;
$this
->
call
(
'DELETE'
,
'
file
s/'
.
$attachmentId
);
$attachmentId
=
\BookStack\
Attachment
::
first
()
->
id
;
$this
->
call
(
'DELETE'
,
'
attachment
s/'
.
$attachmentId
);
$this
->
dontSeeInDatabase
(
'
file
s'
,
[
$this
->
dontSeeInDatabase
(
'
attachment
s'
,
[
'name'
=>
$fileName
]);
$this
->
assertFalse
(
file_exists
(
$filePath
),
'File at path '
.
$filePath
.
' was not deleted as expected'
);
...
...
@@ -185,13 +185,13 @@ class AttachmentTest extends TestCase
$filePath
=
base_path
(
'storage/'
.
$this
->
getUploadPath
(
$fileName
));
$this
->
assertTrue
(
file_exists
(
$filePath
),
'File at path '
.
$filePath
.
' does not exist'
);
$this
->
seeInDatabase
(
'
file
s'
,
[
$this
->
seeInDatabase
(
'
attachment
s'
,
[
'name'
=>
$fileName
]);
$this
->
call
(
'DELETE'
,
$page
->
getUrl
());
$this
->
dontSeeInDatabase
(
'
file
s'
,
[
$this
->
dontSeeInDatabase
(
'
attachment
s'
,
[
'name'
=>
$fileName
]);
$this
->
assertFalse
(
file_exists
(
$filePath
),
'File at path '
.
$filePath
.
' was not deleted as expected'
);
...
...
Please
register
or
sign in
to post a comment