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
2017-01-01 16:05:44 +0000
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Commit
7f9de2c8ab1b137b1cc9e9a3c1dc969b010e4da4
7f9de2c8
1 parent
f91f33c2
Started refactor to merge entity repos
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
235 additions
and
299 deletions
app/Chapter.php
app/Http/Controllers/AttachmentController.php
app/Http/Controllers/BookController.php
app/Http/Controllers/ChapterController.php
app/Http/Controllers/HomeController.php
app/Http/Controllers/PageController.php
app/Page.php
app/Repos/BookRepo.php
app/Repos/ChapterRepo.php
app/Repos/EntityRepo.php
app/Repos/PageRepo.php
app/Repos/UserRepo.php
app/Services/PermissionService.php
tests/Permissions/RestrictionsTest.php
app/Chapter.php
View file @
7f9de2c
...
...
@@ -5,6 +5,8 @@ class Chapter extends Entity
{
protected
$fillable
=
[
'name'
,
'description'
,
'priority'
,
'book_id'
];
protected
$with
=
[
'book'
];
/**
* Get the book this chapter is within.
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
...
...
app/Http/Controllers/AttachmentController.php
View file @
7f9de2c
...
...
@@ -2,6 +2,7 @@
use
BookStack\Exceptions\FileUploadException
;
use
BookStack\Attachment
;
use
BookStack\Repos\EntityRepo
;
use
BookStack\Repos\PageRepo
;
use
BookStack\Services\AttachmentService
;
use
Illuminate\Http\Request
;
...
...
@@ -11,6 +12,7 @@ class AttachmentController extends Controller
protected
$attachmentService
;
protected
$attachment
;
protected
$pageRepo
;
protected
$entityRepo
;
/**
* AttachmentController constructor.
...
...
@@ -18,11 +20,13 @@ class AttachmentController extends Controller
* @param Attachment $attachment
* @param PageRepo $pageRepo
*/
public
function
__construct
(
AttachmentService
$attachmentService
,
Attachment
$attachment
,
PageRepo
$pageRepo
)
public
function
__construct
(
AttachmentService
$attachmentService
,
Attachment
$attachment
,
EntityRepo
$entityRepo
,
PageRepo
$pageRepo
)
{
$this
->
attachmentService
=
$attachmentService
;
$this
->
attachment
=
$attachment
;
// TODO - Remove this
$this
->
pageRepo
=
$pageRepo
;
$this
->
entityRepo
=
$entityRepo
;
parent
::
__construct
();
}
...
...
@@ -40,7 +44,7 @@ class AttachmentController extends Controller
]);
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
,
true
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$pageId
,
true
);
$this
->
checkPermission
(
'attachment-create-all'
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
...
...
@@ -70,7 +74,7 @@ class AttachmentController extends Controller
]);
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
,
true
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$pageId
,
true
);
$attachment
=
$this
->
attachment
->
findOrFail
(
$attachmentId
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
...
...
@@ -106,7 +110,7 @@ class AttachmentController extends Controller
]);
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
,
true
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$pageId
,
true
);
$attachment
=
$this
->
attachment
->
findOrFail
(
$attachmentId
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
...
...
@@ -134,7 +138,7 @@ class AttachmentController extends Controller
]);
$pageId
=
$request
->
get
(
'uploaded_to'
);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
,
true
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$pageId
,
true
);
$this
->
checkPermission
(
'attachment-create-all'
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
...
...
@@ -153,7 +157,7 @@ class AttachmentController extends Controller
*/
public
function
listForPage
(
$pageId
)
{
$page
=
$this
->
pageRepo
->
getById
(
$pageId
,
true
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$pageId
,
true
);
$this
->
checkOwnablePermission
(
'page-view'
,
$page
);
return
response
()
->
json
(
$page
->
attachments
);
}
...
...
@@ -170,7 +174,7 @@ class AttachmentController extends Controller
'files'
=>
'required|array'
,
'files.*.id'
=>
'required|integer'
,
]);
$page
=
$this
->
pageRepo
->
getById
(
$pageId
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$pageId
);
$this
->
checkOwnablePermission
(
'page-update'
,
$page
);
$attachments
=
$request
->
get
(
'files'
);
...
...
@@ -186,7 +190,7 @@ class AttachmentController extends Controller
public
function
get
(
$attachmentId
)
{
$attachment
=
$this
->
attachment
->
findOrFail
(
$attachmentId
);
$page
=
$this
->
pageRepo
->
getById
(
$attachment
->
uploaded_to
);
$page
=
$this
->
entityRepo
->
getById
(
'page'
,
$attachment
->
uploaded_to
);
$this
->
checkOwnablePermission
(
'page-view'
,
$page
);
if
(
$attachment
->
external
)
{
...
...
app/Http/Controllers/BookController.php
View file @
7f9de2c
<?php
namespace
BookStack\Http\Controllers
;
use
Activity
;
use
BookStack\Repos\EntityRepo
;
use
BookStack\Repos\UserRepo
;
use
Illuminate\Http\Request
;
use
BookStack\Http\Requests
;
...
...
@@ -13,6 +14,7 @@ use Views;
class
BookController
extends
Controller
{
protected
$entityRepo
;
protected
$bookRepo
;
protected
$pageRepo
;
protected
$chapterRepo
;
...
...
@@ -25,8 +27,10 @@ class BookController extends Controller
* @param ChapterRepo $chapterRepo
* @param UserRepo $userRepo
*/
public
function
__construct
(
BookRepo
$bookRepo
,
PageRepo
$pageRepo
,
ChapterRepo
$chapterRepo
,
UserRepo
$userRepo
)
public
function
__construct
(
EntityRepo
$entityRepo
,
BookRepo
$bookRepo
,
PageRepo
$pageRepo
,
ChapterRepo
$chapterRepo
,
UserRepo
$userRepo
)
{
$this
->
entityRepo
=
$entityRepo
;
// TODO - Remove below
$this
->
bookRepo
=
$bookRepo
;
$this
->
pageRepo
=
$pageRepo
;
$this
->
chapterRepo
=
$chapterRepo
;
...
...
@@ -40,9 +44,9 @@ class BookController extends Controller
*/
public
function
index
()
{
$books
=
$this
->
bookRepo
->
getAllPaginated
(
10
);
$recents
=
$this
->
signedIn
?
$this
->
bookRepo
->
getRecentlyViewed
(
4
,
0
)
:
false
;
$popular
=
$this
->
bookRepo
->
getPopular
(
4
,
0
);
$books
=
$this
->
entityRepo
->
getAllPaginated
(
'book'
,
10
);
$recents
=
$this
->
signedIn
?
$this
->
entityRepo
->
getRecentlyViewed
(
'book'
,
4
,
0
)
:
false
;
$popular
=
$this
->
entityRepo
->
getPopular
(
'book'
,
4
,
0
);
$this
->
setPageTitle
(
'Books'
);
return
view
(
'books/index'
,
[
'books'
=>
$books
,
'recents'
=>
$recents
,
'popular'
=>
$popular
]);
}
...
...
@@ -83,7 +87,7 @@ class BookController extends Controller
*/
public
function
show
(
$slug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$slug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$slug
);
$this
->
checkOwnablePermission
(
'book-view'
,
$book
);
$bookChildren
=
$this
->
bookRepo
->
getChildren
(
$book
);
Views
::
add
(
$book
);
...
...
@@ -98,7 +102,7 @@ class BookController extends Controller
*/
public
function
edit
(
$slug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$slug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$slug
);
$this
->
checkOwnablePermission
(
'book-update'
,
$book
);
$this
->
setPageTitle
(
trans
(
'entities.books_edit_named'
,[
'bookName'
=>
$book
->
getShortName
()]));
return
view
(
'books/edit'
,
[
'book'
=>
$book
,
'current'
=>
$book
]);
...
...
@@ -112,7 +116,7 @@ class BookController extends Controller
*/
public
function
update
(
Request
$request
,
$slug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$slug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$slug
);
$this
->
checkOwnablePermission
(
'book-update'
,
$book
);
$this
->
validate
(
$request
,
[
'name'
=>
'required|string|max:255'
,
...
...
@@ -130,7 +134,7 @@ class BookController extends Controller
*/
public
function
showDelete
(
$bookSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'book-delete'
,
$book
);
$this
->
setPageTitle
(
trans
(
'entities.books_delete_named'
,
[
'bookName'
=>
$book
->
getShortName
()]));
return
view
(
'books/delete'
,
[
'book'
=>
$book
,
'current'
=>
$book
]);
...
...
@@ -143,10 +147,10 @@ class BookController extends Controller
*/
public
function
sort
(
$bookSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'book-update'
,
$book
);
$bookChildren
=
$this
->
bookRepo
->
getChildren
(
$book
,
true
);
$books
=
$this
->
bookRepo
->
getAll
(
false
);
$books
=
$this
->
entityRepo
->
getAll
(
'book'
,
false
);
$this
->
setPageTitle
(
trans
(
'entities.books_sort_named'
,
[
'bookName'
=>
$book
->
getShortName
()]));
return
view
(
'books/sort'
,
[
'book'
=>
$book
,
'current'
=>
$book
,
'books'
=>
$books
,
'bookChildren'
=>
$bookChildren
]);
}
...
...
@@ -159,7 +163,7 @@ class BookController extends Controller
*/
public
function
getSortItem
(
$bookSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$bookChildren
=
$this
->
bookRepo
->
getChildren
(
$book
);
return
view
(
'books/sort-box'
,
[
'book'
=>
$book
,
'bookChildren'
=>
$bookChildren
]);
}
...
...
@@ -172,7 +176,7 @@ class BookController extends Controller
*/
public
function
saveSort
(
$bookSlug
,
Request
$request
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'book-update'
,
$book
);
// Return if no map sent
...
...
@@ -191,9 +195,9 @@ class BookController extends Controller
$priority
=
$bookChild
->
sort
;
$id
=
intval
(
$bookChild
->
id
);
$isPage
=
$bookChild
->
type
==
'page'
;
$bookId
=
$this
->
bookRepo
->
exists
(
$bookChild
->
book
)
?
intval
(
$bookChild
->
book
)
:
$defaultBookId
;
$bookId
=
$this
->
entityRepo
->
exists
(
'book'
,
$bookChild
->
book
)
?
intval
(
$bookChild
->
book
)
:
$defaultBookId
;
$chapterId
=
(
$isPage
&&
$bookChild
->
parentChapter
===
false
)
?
0
:
intval
(
$bookChild
->
parentChapter
);
$model
=
$
isPage
?
$this
->
pageRepo
->
getById
(
$id
)
:
$this
->
chapterRepo
->
getById
(
$id
);
$model
=
$
this
->
entityRepo
->
getById
(
$isPage
?
'page'
:
'chapter'
,
$id
);
// Update models only if there's a change in parent chain or ordering.
if
(
$model
->
priority
!==
$priority
||
$model
->
book_id
!==
$bookId
||
(
$isPage
&&
$model
->
chapter_id
!==
$chapterId
))
{
...
...
@@ -212,7 +216,7 @@ class BookController extends Controller
// Add activity for books
foreach
(
$sortedBooks
as
$bookId
)
{
$updatedBook
=
$this
->
bookRepo
->
getById
(
$bookId
);
$updatedBook
=
$this
->
entityRepo
->
getById
(
'book'
,
$bookId
);
Activity
::
add
(
$updatedBook
,
'book_sort'
,
$updatedBook
->
id
);
}
...
...
@@ -229,7 +233,7 @@ class BookController extends Controller
*/
public
function
destroy
(
$bookSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'book-delete'
,
$book
);
Activity
::
addMessage
(
'book_delete'
,
0
,
$book
->
name
);
Activity
::
removeEntity
(
$book
);
...
...
@@ -244,7 +248,7 @@ class BookController extends Controller
*/
public
function
showRestrict
(
$bookSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'restrictions-manage'
,
$book
);
$roles
=
$this
->
userRepo
->
getRestrictableRoles
();
return
view
(
'books/restrictions'
,
[
...
...
@@ -262,7 +266,7 @@ class BookController extends Controller
*/
public
function
restrict
(
$bookSlug
,
Request
$request
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'restrictions-manage'
,
$book
);
$this
->
bookRepo
->
updateEntityPermissionsFromRequest
(
$request
,
$book
);
session
()
->
flash
(
'success'
,
trans
(
'entities.books_permissions_updated'
));
...
...
app/Http/Controllers/ChapterController.php
View file @
7f9de2c
<?php
namespace
BookStack\Http\Controllers
;
use
Activity
;
use
BookStack\Repos\EntityRepo
;
use
BookStack\Repos\UserRepo
;
use
Illuminate\Http\Request
;
use
BookStack\Repos\BookRepo
;
...
...
@@ -14,15 +15,19 @@ class ChapterController extends Controller
protected
$bookRepo
;
protected
$chapterRepo
;
protected
$userRepo
;
protected
$entityRepo
;
/**
* ChapterController constructor.
* @param EntityRepo $entityRepo
* @param BookRepo $bookRepo
* @param ChapterRepo $chapterRepo
* @param UserRepo $userRepo
*/
public
function
__construct
(
BookRepo
$bookRepo
,
ChapterRepo
$chapterRepo
,
UserRepo
$userRepo
)
public
function
__construct
(
EntityRepo
$entityRepo
,
BookRepo
$bookRepo
,
ChapterRepo
$chapterRepo
,
UserRepo
$userRepo
)
{
$this
->
entityRepo
=
$entityRepo
;
// TODO - Remove below
$this
->
bookRepo
=
$bookRepo
;
$this
->
chapterRepo
=
$chapterRepo
;
$this
->
userRepo
=
$userRepo
;
...
...
@@ -36,7 +41,7 @@ class ChapterController extends Controller
*/
public
function
create
(
$bookSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-create'
,
$book
);
$this
->
setPageTitle
(
trans
(
'entities.chapters_create'
));
return
view
(
'chapters/create'
,
[
'book'
=>
$book
,
'current'
=>
$book
]);
...
...
@@ -54,7 +59,7 @@ class ChapterController extends Controller
'name'
=>
'required|string|max:255'
]);
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$book
=
$this
->
entityRepo
->
getBySlug
(
'book'
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-create'
,
$book
);
$input
=
$request
->
all
();
...
...
@@ -72,15 +77,14 @@ class ChapterController extends Controller
*/
public
function
show
(
$bookSlug
,
$chapterSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-view'
,
$chapter
);
$sidebarTree
=
$this
->
bookRepo
->
getChildren
(
$book
);
$sidebarTree
=
$this
->
bookRepo
->
getChildren
(
$
chapter
->
book
);
Views
::
add
(
$chapter
);
$this
->
setPageTitle
(
$chapter
->
getShortName
());
$pages
=
$this
->
chapterRepo
->
getChildren
(
$chapter
);
return
view
(
'chapters/show'
,
[
'book'
=>
$book
,
'book'
=>
$
chapter
->
book
,
'chapter'
=>
$chapter
,
'current'
=>
$chapter
,
'sidebarTree'
=>
$sidebarTree
,
...
...
@@ -96,11 +100,10 @@ class ChapterController extends Controller
*/
public
function
edit
(
$bookSlug
,
$chapterSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-update'
,
$chapter
);
$this
->
setPageTitle
(
trans
(
'entities.chapters_edit_named'
,
[
'chapterName'
=>
$chapter
->
getShortName
()]));
return
view
(
'chapters/edit'
,
[
'book'
=>
$book
,
'chapter'
=>
$chapter
,
'current'
=>
$chapter
]);
return
view
(
'chapters/edit'
,
[
'book'
=>
$
chapter
->
book
,
'chapter'
=>
$chapter
,
'current'
=>
$chapter
]);
}
/**
...
...
@@ -112,16 +115,15 @@ class ChapterController extends Controller
*/
public
function
update
(
Request
$request
,
$bookSlug
,
$chapterSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-update'
,
$chapter
);
if
(
$chapter
->
name
!==
$request
->
get
(
'name'
))
{
$chapter
->
slug
=
$this
->
chapterRepo
->
findSuitableSlug
(
$request
->
get
(
'name'
),
$book
->
id
,
$chapter
->
id
);
$chapter
->
slug
=
$this
->
chapterRepo
->
findSuitableSlug
(
$request
->
get
(
'name'
),
$
chapter
->
book
->
id
,
$chapter
->
id
);
}
$chapter
->
fill
(
$request
->
all
());
$chapter
->
updated_by
=
user
()
->
id
;
$chapter
->
save
();
Activity
::
add
(
$chapter
,
'chapter_update'
,
$book
->
id
);
Activity
::
add
(
$chapter
,
'chapter_update'
,
$
chapter
->
book
->
id
);
return
redirect
(
$chapter
->
getUrl
());
}
...
...
@@ -133,11 +135,10 @@ class ChapterController extends Controller
*/
public
function
showDelete
(
$bookSlug
,
$chapterSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-delete'
,
$chapter
);
$this
->
setPageTitle
(
trans
(
'entities.chapters_delete_named'
,
[
'chapterName'
=>
$chapter
->
getShortName
()]));
return
view
(
'chapters/delete'
,
[
'book'
=>
$book
,
'chapter'
=>
$chapter
,
'current'
=>
$chapter
]);
return
view
(
'chapters/delete'
,
[
'book'
=>
$
chapter
->
book
,
'chapter'
=>
$chapter
,
'current'
=>
$chapter
]);
}
/**
...
...
@@ -148,8 +149,8 @@ class ChapterController extends Controller
*/
public
function
destroy
(
$bookSlug
,
$chapterSlug
)
{
$
book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$
chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
)
;
$
chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$
book
=
$chapter
->
book
;
$this
->
checkOwnablePermission
(
'chapter-delete'
,
$chapter
);
Activity
::
addMessage
(
'chapter_delete'
,
$book
->
id
,
$chapter
->
name
);
$this
->
chapterRepo
->
destroy
(
$chapter
);
...
...
@@ -164,13 +165,12 @@ class ChapterController extends Controller
* @throws \BookStack\Exceptions\NotFoundException
*/
public
function
showMove
(
$bookSlug
,
$chapterSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
setPageTitle
(
trans
(
'entities.chapters_move_named'
,
[
'chapterName'
=>
$chapter
->
getShortName
()]));
$this
->
checkOwnablePermission
(
'chapter-update'
,
$chapter
);
return
view
(
'chapters/move'
,
[
'chapter'
=>
$chapter
,
'book'
=>
$book
'book'
=>
$
chapter
->
book
]);
}
...
...
@@ -183,8 +183,7 @@ class ChapterController extends Controller
* @throws \BookStack\Exceptions\NotFoundException
*/
public
function
move
(
$bookSlug
,
$chapterSlug
,
Request
$request
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'chapter-update'
,
$chapter
);
$entitySelection
=
$request
->
get
(
'entity_selection'
,
null
);
...
...
@@ -199,7 +198,7 @@ class ChapterController extends Controller
$parent
=
false
;
if
(
$entityType
==
'book'
)
{
$parent
=
$this
->
bookRepo
->
getById
(
$entityId
);
$parent
=
$this
->
entityRepo
->
getById
(
'book'
,
$entityId
);
}
if
(
$parent
===
false
||
$parent
===
null
)
{
...
...
@@ -222,8 +221,7 @@ class ChapterController extends Controller
*/
public
function
showRestrict
(
$bookSlug
,
$chapterSlug
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'restrictions-manage'
,
$chapter
);
$roles
=
$this
->
userRepo
->
getRestrictableRoles
();
return
view
(
'chapters/restrictions'
,
[
...
...
@@ -241,8 +239,7 @@ class ChapterController extends Controller
*/
public
function
restrict
(
$bookSlug
,
$chapterSlug
,
Request
$request
)
{
$book
=
$this
->
bookRepo
->
getBySlug
(
$bookSlug
);
$chapter
=
$this
->
chapterRepo
->
getBySlug
(
$chapterSlug
,
$book
->
id
);
$chapter
=
$this
->
entityRepo
->
getBySlug
(
'chapter'
,
$chapterSlug
,
$bookSlug
);
$this
->
checkOwnablePermission
(
'restrictions-manage'
,
$chapter
);
$this
->
chapterRepo
->
updateEntityPermissionsFromRequest
(
$request
,
$chapter
);
session
()
->
flash
(
'success'
,
trans
(
'entities.chapters_permissions_success'
));
...
...
app/Http/Controllers/HomeController.php
View file @
7f9de2c
...
...
@@ -5,6 +5,7 @@ namespace BookStack\Http\Controllers;
use
Activity
;
use
BookStack\Repos\EntityRepo
;
use
BookStack\Http\Requests
;
use
Illuminate\Http\Response
;
use
Views
;
class
HomeController
extends
Controller
...
...
@@ -31,9 +32,9 @@ class HomeController extends Controller
$activity
=
Activity
::
latest
(
10
);
$draftPages
=
$this
->
signedIn
?
$this
->
entityRepo
->
getUserDraftPages
(
6
)
:
[];
$recentFactor
=
count
(
$draftPages
)
>
0
?
0.5
:
1
;
$recents
=
$this
->
signedIn
?
Views
::
getUserRecentlyViewed
(
12
*
$recentFactor
,
0
)
:
$this
->
entityRepo
->
getRecentlyCreated
Books
(
10
*
$recentFactor
);
$recentlyCreatedPages
=
$this
->
entityRepo
->
getRecentlyCreated
Pages
(
5
);
$recentlyUpdatedPages
=
$this
->
entityRepo
->
getRecentlyUpdated
Pages
(
5
);
$recents
=
$this
->
signedIn
?
Views
::
getUserRecentlyViewed
(
12
*
$recentFactor
,
0
)
:
$this
->
entityRepo
->
getRecentlyCreated
(
'book'
,
10
*
$recentFactor
);
$recentlyCreatedPages
=
$this
->
entityRepo
->
getRecentlyCreated
(
'page'
,
5
);
$recentlyUpdatedPages
=
$this
->
entityRepo
->
getRecentlyUpdated
(
'page'
,
5
);
return
view
(
'home'
,
[
'activity'
=>
$activity
,
'recents'
=>
$recents
,
...
...
app/Http/Controllers/PageController.php
View file @
7f9de2c
This diff is collapsed.
Click to expand it.
app/Page.php
View file @
7f9de2c
...
...
@@ -7,6 +7,8 @@ class Page extends Entity
protected
$simpleAttributes
=
[
'name'
,
'id'
,
'slug'
];
protected
$with
=
[
'book'
];
/**
* Converts this page into a simplified array.
* @return mixed
...
...
app/Repos/BookRepo.php
View file @
7f9de2c
<?php
namespace
BookStack\Repos
;
use
Alpha\B
;
use
BookStack\Exceptions\NotFoundException
;
use
Illuminate\Database\Eloquent\Collection
;
use
Illuminate\Support\Str
;
use
BookStack\Book
;
use
Views
;
class
BookRepo
extends
EntityRepo
{
...
...
@@ -25,105 +20,6 @@ class BookRepo extends EntityRepo
}
/**
* Base query for getting books.
* Takes into account any restrictions.
* @return mixed
*/
private
function
bookQuery
()
{
return
$this
->
permissionService
->
enforceBookRestrictions
(
$this
->
book
,
'view'
);
}
/**
* Get the book that has the given id.
* @param $id
* @return mixed
*/
public
function
getById
(
$id
)
{
return
$this
->
bookQuery
()
->
findOrFail
(
$id
);
}
/**
* Get all books, Limited by count.
* @param int $count
* @return mixed
*/
public
function
getAll
(
$count
=
10
)
{
$bookQuery
=
$this
->
bookQuery
()
->
orderBy
(
'name'
,
'asc'
);
if
(
!
$count
)
return
$bookQuery
->
get
();
return
$bookQuery
->
take
(
$count
)
->
get
();
}
/**
* Get all books paginated.
* @param int $count
* @return mixed
*/
public
function
getAllPaginated
(
$count
=
10
)
{
return
$this
->
bookQuery
()
->
orderBy
(
'name'
,
'asc'
)
->
paginate
(
$count
);
}
/**
* Get the latest books.
* @param int $count
* @return mixed
*/
public
function
getLatest
(
$count
=
10
)
{
return
$this
->
bookQuery
()
->
orderBy
(
'created_at'
,
'desc'
)
->
take
(
$count
)
->
get
();
}
/**
* Gets the most recently viewed for a user.
* @param int $count
* @param int $page
* @return mixed
*/
public
function
getRecentlyViewed
(
$count
=
10
,
$page
=
0
)
{
return
Views
::
getUserRecentlyViewed
(
$count
,
$page
,
$this
->
book
);
}
/**
* Gets the most viewed books.
* @param int $count
* @param int $page
* @return mixed
*/
public
function
getPopular
(
$count
=
10
,
$page
=
0
)
{
return
Views
::
getPopular
(
$count
,
$page
,
$this
->
book
);
}
/**
* Get a book by slug
* @param $slug
* @return mixed
* @throws NotFoundException
*/
public
function
getBySlug
(
$slug
)
{
$book
=
$this
->
bookQuery
()
->
where
(
'slug'
,
'='
,
$slug
)
->
first
();
if
(
$book
===
null
)
throw
new
NotFoundException
(
trans
(
'errors.book_not_found'
));
return
$book
;
}
/**
* Checks if a book exists.
* @param $id
* @return bool
*/
public
function
exists
(
$id
)
{
return
$this
->
bookQuery
()
->
where
(
'id'
,
'='
,
$id
)
->
exists
();
}
/**
* Get a new book instance from request input.
* @param array $input
* @return Book
...
...
app/Repos/ChapterRepo.php
View file @
7f9de2c
...
...
@@ -22,58 +22,6 @@ class ChapterRepo extends EntityRepo
}
/**
* Base query for getting chapters, Takes permissions into account.
* @return mixed
*/
private
function
chapterQuery
()
{
return
$this
->
permissionService
->
enforceChapterRestrictions
(
$this
->
chapter
,
'view'
);
}
/**
* Check if an id exists.
* @param $id
* @return bool
*/
public
function
idExists
(
$id
)
{
return
$this
->
chapterQuery
()
->
where
(
'id'
,
'='
,
$id
)
->
count
()
>
0
;
}
/**
* Get a chapter by a specific id.
* @param $id
* @return mixed
*/
public
function
getById
(
$id
)
{
return
$this
->
chapterQuery
()
->
findOrFail
(
$id
);
}
/**
* Get all chapters.
* @return \Illuminate\Database\Eloquent\Collection|static[]
*/
public
function
getAll
()
{
return
$this
->
chapterQuery
()
->
all
();
}
/**
* Get a chapter that has the given slug within the given book.
* @param $slug
* @param $bookId
* @return mixed
* @throws NotFoundException
*/
public
function
getBySlug
(
$slug
,
$bookId
)
{
$chapter
=
$this
->
chapterQuery
()
->
where
(
'slug'
,
'='
,
$slug
)
->
where
(
'book_id'
,
'='
,
$bookId
)
->
first
();
if
(
$chapter
===
null
)
throw
new
NotFoundException
(
trans
(
'errors.chapter_not_found'
));
return
$chapter
;
}
/**
* Get the child items for a chapter
* @param Chapter $chapter
*/
...
...
app/Repos/EntityRepo.php
View file @
7f9de2c
...
...
@@ -3,11 +3,12 @@
use
BookStack\Book
;
use
BookStack\Chapter
;
use
BookStack\Entity
;
use
BookStack\Exceptions\NotFoundException
;
use
BookStack\Page
;
use
BookStack\Services\PermissionService
;
use
BookStack\User
;
use
BookStack\Services\ViewService
;
use
Illuminate\Database\Eloquent\Builder
;
use
Illuminate\Support\Collection
;
use
Illuminate\Support\Facades\Log
;
class
EntityRepo
{
...
...
@@ -28,11 +29,22 @@ class EntityRepo
public
$page
;
/**
* Base entity instances keyed by type
* @var []Entity
*/
protected
$entities
;
/**
* @var PermissionService
*/
protected
$permissionService
;
/**
* @var ViewService
*/
protected
$viewService
;
/**
* Acceptable operators to be used in a query
* @var array
*/
...
...
@@ -43,69 +55,144 @@ class EntityRepo
*/
public
function
__construct
()
{
// TODO - Redo this to come via injection
$this
->
book
=
app
(
Book
::
class
);
$this
->
chapter
=
app
(
Chapter
::
class
);
$this
->
page
=
app
(
Page
::
class
);
$this
->
entities
=
[
'page'
=>
$this
->
page
,
'chapter'
=>
$this
->
chapter
,
'book'
=>
$this
->
book
];
$this
->
viewService
=
app
(
ViewService
::
class
);
$this
->
permissionService
=
app
(
PermissionService
::
class
);
}
/**
* Get the latest books added to the system.
* @param int $count
* @param int $page
* @param bool $additionalQuery
* @return
* Get an entity instance via type.
* @param $type
* @return Entity
*/
p
ublic
function
getRecentlyCreatedBooks
(
$count
=
20
,
$page
=
0
,
$additionalQuery
=
fals
e
)
p
rotected
function
getEntity
(
$typ
e
)
{
$query
=
$this
->
permissionService
->
enforceBookRestrictions
(
$this
->
book
)
->
orderBy
(
'created_at'
,
'desc'
);
if
(
$additionalQuery
!==
false
&&
is_callable
(
$additionalQuery
))
{
$additionalQuery
(
$query
);
return
$this
->
entities
[
strtolower
(
$type
)];
}
/**
* Base query for searching entities via permission system
* @param string $type
* @param bool $allowDrafts
* @return \Illuminate\Database\Query\Builder
*/
protected
function
entityQuery
(
$type
,
$allowDrafts
=
false
)
{
$q
=
$this
->
permissionService
->
enforceEntityRestrictions
(
$type
,
$this
->
getEntity
(
$type
),
'view'
);
if
(
strtolower
(
$type
)
===
'page'
&&
!
$allowDrafts
)
{
$q
=
$q
->
where
(
'draft'
,
'='
,
false
);
}
return
$q
uery
->
skip
(
$page
*
$count
)
->
take
(
$count
)
->
get
()
;
return
$q
;
}
/**
*
Get the most recently updated book
s.
* @param $
count
* @param
int $page
* @return
mixed
*
Check if an entity with the given id exist
s.
* @param $
type
* @param
$id
* @return
bool
*/
public
function
getRecentlyUpdatedBooks
(
$count
=
20
,
$page
=
0
)
public
function
exists
(
$type
,
$id
)
{
return
$this
->
permissionService
->
enforceBookRestrictions
(
$this
->
book
)
->
orderBy
(
'updated_at'
,
'desc'
)
->
skip
(
$page
*
$count
)
->
take
(
$count
)
->
get
();
return
$this
->
entityQuery
(
$type
)
->
where
(
'id'
,
'='
,
$id
)
->
exists
();
}
/**
* Get the latest pages added to the system.
* Get an entity by ID
* @param string $type
* @param integer $id
* @param bool $allowDrafts
* @return Entity
*/
public
function
getById
(
$type
,
$id
,
$allowDrafts
=
false
)
{
return
$this
->
entityQuery
(
$type
,
$allowDrafts
)
->
findOrFail
(
$id
);
}
/**
* Get an entity by its url slug.
* @param string $type
* @param string $slug
* @param string|bool $bookSlug
* @return Entity
* @throws NotFoundException
*/
public
function
getBySlug
(
$type
,
$slug
,
$bookSlug
=
false
)
{
$q
=
$this
->
entityQuery
(
$type
)
->
where
(
'slug'
,
'='
,
$slug
);
if
(
strtolower
(
$type
)
===
'chapter'
||
strtolower
(
$type
)
===
'page'
)
{
$q
=
$q
->
where
(
'book_id'
,
'='
,
function
(
$query
)
use
(
$bookSlug
)
{
$query
->
select
(
'id'
)
->
from
(
$this
->
book
->
getTable
())
->
where
(
'slug'
,
'='
,
$bookSlug
)
->
limit
(
1
);
});
}
$entity
=
$q
->
first
();
if
(
$entity
===
null
)
throw
new
NotFoundException
(
trans
(
'errors.'
.
strtolower
(
$type
)
.
'_not_found'
));
return
$entity
;
}
/**
* Get all entities of a type limited by count unless count if false.
* @param string $type
* @param integer|bool $count
* @return Collection
*/
public
function
getAll
(
$type
,
$count
=
20
)
{
$q
=
$this
->
entityQuery
(
$type
)
->
orderBy
(
'name'
,
'asc'
);
if
(
$count
!==
false
)
$q
=
$q
->
take
(
$count
);
return
$q
->
get
();
}
/**
* Get all entities in a paginated format
* @param $type
* @param int $count
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public
function
getAllPaginated
(
$type
,
$count
=
10
)
{
return
$this
->
entityQuery
(
$type
)
->
orderBy
(
'name'
,
'asc'
)
->
paginate
(
$count
);
}
/**
* Get the most recently created entities of the given type.
* @param string $type
* @param int $count
* @param int $page
* @param bool $additionalQuery
* @return
* @param bool|callable $additionalQuery
*/
public
function
getRecentlyCreated
Pages
(
$count
=
20
,
$page
=
0
,
$additionalQuery
=
false
)
public
function
getRecentlyCreated
(
$type
,
$count
=
20
,
$page
=
0
,
$additionalQuery
=
false
)
{
$query
=
$this
->
permissionService
->
enforcePageRestrictions
(
$this
->
page
)
->
orderBy
(
'created_at'
,
'desc'
)
->
where
(
'draft'
,
'='
,
false
);
$query
=
$this
->
permissionService
->
enforceEntityRestrictions
(
$type
,
$this
->
getEntity
(
$type
))
->
orderBy
(
'created_at'
,
'desc'
);
if
(
strtolower
(
$type
)
===
'page'
)
$query
=
$query
->
where
(
'draft'
,
'='
,
false
);
if
(
$additionalQuery
!==
false
&&
is_callable
(
$additionalQuery
))
{
$additionalQuery
(
$query
);
}
return
$query
->
with
(
'book'
)
->
skip
(
$page
*
$count
)
->
take
(
$count
)
->
get
();
return
$query
->
skip
(
$page
*
$count
)
->
take
(
$count
)
->
get
();
}
/**
* Get the latest chapters added to the system.
* Get the most recently updated entities of the given type.
* @param string $type
* @param int $count
* @param int $page
* @param bool $additionalQuery
* @return
* @param bool|callable $additionalQuery
*/
public
function
getRecently
CreatedChapters
(
$count
=
20
,
$page
=
0
,
$additionalQuery
=
false
)
public
function
getRecently
Updated
(
$type
,
$count
=
20
,
$page
=
0
,
$additionalQuery
=
false
)
{
$query
=
$this
->
permissionService
->
enforceChapterRestrictions
(
$this
->
chapter
)
->
orderBy
(
'created_at'
,
'desc'
);
$query
=
$this
->
permissionService
->
enforceEntityRestrictions
(
$type
,
$this
->
getEntity
(
$type
))
->
orderBy
(
'updated_at'
,
'desc'
);
if
(
strtolower
(
$type
)
===
'page'
)
$query
=
$query
->
where
(
'draft'
,
'='
,
false
);
if
(
$additionalQuery
!==
false
&&
is_callable
(
$additionalQuery
))
{
$additionalQuery
(
$query
);
}
...
...
@@ -113,16 +200,29 @@ class EntityRepo
}
/**
* Get the most recently updated pages.
* @param $count
* Get the most recently viewed entities.
* @param string|bool $type
* @param int $count
* @param int $page
* @return mixed
*/
public
function
getRecentlyViewed
(
$type
,
$count
=
10
,
$page
=
0
)
{
$filter
=
is_bool
(
$type
)
?
false
:
$this
->
getEntity
(
$type
);
return
$this
->
viewService
->
getUserRecentlyViewed
(
$count
,
$page
,
$filter
);
}
/**
* Get the most popular entities base on all views.
* @param string|bool $type
* @param int $count
* @param int $page
* @return mixed
*/
public
function
get
RecentlyUpdatedPages
(
$count
=
2
0
,
$page
=
0
)
public
function
get
Popular
(
$type
,
$count
=
1
0
,
$page
=
0
)
{
return
$this
->
permissionService
->
enforcePageRestrictions
(
$this
->
page
)
->
where
(
'draft'
,
'='
,
false
)
->
orderBy
(
'updated_at'
,
'desc'
)
->
with
(
'book'
)
->
skip
(
$page
*
$count
)
->
take
(
$count
)
->
get
();
$filter
=
is_bool
(
$type
)
?
false
:
$this
->
getEntity
(
$type
);
return
$this
->
viewService
->
getPopular
(
$count
,
$page
,
$filter
);
}
/**
...
...
app/Repos/PageRepo.php
View file @
7f9de2c
...
...
@@ -46,31 +46,6 @@ class PageRepo extends EntityRepo
}
/**
* Get a page via a specific ID.
* @param $id
* @param bool $allowDrafts
* @return Page
*/
public
function
getById
(
$id
,
$allowDrafts
=
false
)
{
return
$this
->
pageQuery
(
$allowDrafts
)
->
findOrFail
(
$id
);
}
/**
* Get a page identified by the given slug.
* @param $slug
* @param $bookId
* @return Page
* @throws NotFoundException
*/
public
function
getBySlug
(
$slug
,
$bookId
)
{
$page
=
$this
->
pageQuery
()
->
where
(
'slug'
,
'='
,
$slug
)
->
where
(
'book_id'
,
'='
,
$bookId
)
->
first
();
if
(
$page
===
null
)
throw
new
NotFoundException
(
trans
(
'errors.page_not_found'
));
return
$page
;
}
/**
* Search through page revisions and retrieve
* the last page in the current book that
* has a slug equal to the one given.
...
...
app/Repos/UserRepo.php
View file @
7f9de2c
...
...
@@ -168,13 +168,13 @@ class UserRepo
public
function
getRecentlyCreated
(
User
$user
,
$count
=
20
)
{
return
[
'pages'
=>
$this
->
entityRepo
->
getRecentlyCreated
Pages
(
$count
,
0
,
function
(
$query
)
use
(
$user
)
{
'pages'
=>
$this
->
entityRepo
->
getRecentlyCreated
(
'page'
,
$count
,
0
,
function
(
$query
)
use
(
$user
)
{
$query
->
where
(
'created_by'
,
'='
,
$user
->
id
);
}),
'chapters'
=>
$this
->
entityRepo
->
getRecentlyCreated
Chapters
(
$count
,
0
,
function
(
$query
)
use
(
$user
)
{
'chapters'
=>
$this
->
entityRepo
->
getRecentlyCreated
(
'chapter'
,
$count
,
0
,
function
(
$query
)
use
(
$user
)
{
$query
->
where
(
'created_by'
,
'='
,
$user
->
id
);
}),
'books'
=>
$this
->
entityRepo
->
getRecentlyCreated
Books
(
$count
,
0
,
function
(
$query
)
use
(
$user
)
{
'books'
=>
$this
->
entityRepo
->
getRecentlyCreated
(
'book'
,
$count
,
0
,
function
(
$query
)
use
(
$user
)
{
$query
->
where
(
'created_by'
,
'='
,
$user
->
id
);
})
];
...
...
app/Services/PermissionService.php
View file @
7f9de2c
...
...
@@ -8,8 +8,8 @@ use BookStack\Ownable;
use
BookStack\Page
;
use
BookStack\Role
;
use
BookStack\User
;
use
Illuminate\Database\Eloquent\Builder
;
use
Illuminate\Support\Collection
;
use
Illuminate\Support\Facades\Log
;
class
PermissionService
{
...
...
@@ -469,17 +469,8 @@ class PermissionService
*/
public
function
enforcePageRestrictions
(
$query
,
$action
=
'view'
)
{
// Prevent drafts being visible to others.
$query
=
$query
->
where
(
function
(
$query
)
{
$query
->
where
(
'draft'
,
'='
,
false
);
if
(
$this
->
currentUser
())
{
$query
->
orWhere
(
function
(
$query
)
{
$query
->
where
(
'draft'
,
'='
,
true
)
->
where
(
'created_by'
,
'='
,
$this
->
currentUser
()
->
id
);
});
}
});
return
$this
->
enforceEntityRestrictions
(
$query
,
$action
);
// TODO - remove this
return
$this
->
enforceEntityRestrictions
(
'page'
,
$query
,
$action
);
}
/**
...
...
@@ -490,7 +481,8 @@ class PermissionService
*/
public
function
enforceChapterRestrictions
(
$query
,
$action
=
'view'
)
{
return
$this
->
enforceEntityRestrictions
(
$query
,
$action
);
// TODO - remove this
return
$this
->
enforceEntityRestrictions
(
'chapter'
,
$query
,
$action
);
}
/**
...
...
@@ -501,21 +493,36 @@ class PermissionService
*/
public
function
enforceBookRestrictions
(
$query
,
$action
=
'view'
)
{
return
$this
->
enforceEntityRestrictions
(
$query
,
$action
);
// TODO - remove this
return
$this
->
enforceEntityRestrictions
(
'book'
,
$query
,
$action
);
}
/**
* Add restrictions for a generic entity
* @param $query
* @param string $entityType
* @param Builder|Entity $query
* @param string $action
* @return mixed
*/
public
function
enforceEntityRestrictions
(
$query
,
$action
=
'view'
)
public
function
enforceEntityRestrictions
(
$
entityType
,
$
query
,
$action
=
'view'
)
{
if
(
strtolower
(
$entityType
)
===
'page'
)
{
// Prevent drafts being visible to others.
$query
=
$query
->
where
(
function
(
$query
)
{
$query
->
where
(
'draft'
,
'='
,
false
);
if
(
$this
->
currentUser
())
{
$query
->
orWhere
(
function
(
$query
)
{
$query
->
where
(
'draft'
,
'='
,
true
)
->
where
(
'created_by'
,
'='
,
$this
->
currentUser
()
->
id
);
});
}
});
}
if
(
$this
->
isAdmin
())
{
$this
->
clean
();
return
$query
;
}
$this
->
currentAction
=
$action
;
return
$this
->
entityRestrictionQuery
(
$query
);
}
...
...
tests/Permissions/RestrictionsTest.php
View file @
7f9de2c
...
...
@@ -65,9 +65,9 @@ class RestrictionsTest extends TestCase
$this
->
forceVisit
(
$bookUrl
)
->
see
(
'Book not found'
);
$this
->
forceVisit
(
$bookPage
->
getUrl
())
->
see
(
'
Book
not found'
);
->
see
(
'
Page
not found'
);
$this
->
forceVisit
(
$bookChapter
->
getUrl
())
->
see
(
'
Book
not found'
);
->
see
(
'
Chapter
not found'
);
$this
->
setEntityRestrictions
(
$book
,
[
'view'
]);
...
...
Please
register
or
sign in
to post a comment