mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-24 12:43:07 +00:00
Updated permission bookChildrenQuery to use QueryBuilder
This commit is contained in:
parent
598b07b53d
commit
ee5ded6e1e
2 changed files with 31 additions and 45 deletions
app
|
@ -318,15 +318,15 @@ class EntityRepo
|
||||||
*/
|
*/
|
||||||
public function getBookChildren(Book $book, $filterDrafts = false)
|
public function getBookChildren(Book $book, $filterDrafts = false)
|
||||||
{
|
{
|
||||||
$q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts);
|
$q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts)->get();
|
||||||
$entities = [];
|
$entities = [];
|
||||||
$parents = [];
|
$parents = [];
|
||||||
$tree = [];
|
$tree = [];
|
||||||
|
|
||||||
foreach ($q as $index => $rawEntity) {
|
foreach ($q as $index => $rawEntity) {
|
||||||
if ($rawEntity->entity_type === 'Bookstack\\Page') {
|
if ($rawEntity->entity_type === 'BookStack\\Page') {
|
||||||
$entities[$index] = $this->page->newFromBuilder($rawEntity);
|
$entities[$index] = $this->page->newFromBuilder($rawEntity);
|
||||||
} else if ($rawEntity->entity_type === 'Bookstack\\Chapter') {
|
} else if ($rawEntity->entity_type === 'BookStack\\Chapter') {
|
||||||
$entities[$index] = $this->chapter->newFromBuilder($rawEntity);
|
$entities[$index] = $this->chapter->newFromBuilder($rawEntity);
|
||||||
$key = $entities[$index]->entity_type . ':' . $entities[$index]->id;
|
$key = $entities[$index]->entity_type . ':' . $entities[$index]->id;
|
||||||
$parents[$key] = $entities[$index];
|
$parents[$key] = $entities[$index];
|
||||||
|
@ -338,7 +338,7 @@ class EntityRepo
|
||||||
|
|
||||||
foreach ($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
if ($entity->chapter_id === 0) continue;
|
if ($entity->chapter_id === 0) continue;
|
||||||
$parentKey = 'Bookstack\\Chapter:' . $entity->chapter_id;
|
$parentKey = 'BookStack\\Chapter:' . $entity->chapter_id;
|
||||||
$chapter = $parents[$parentKey];
|
$chapter = $parents[$parentKey];
|
||||||
$chapter->pages->push($entity);
|
$chapter->pages->push($entity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,49 +470,35 @@ class PermissionService
|
||||||
return $q;
|
return $q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the children of a book in an efficient single query, Filtered by the permission system.
|
||||||
|
* @param integer $book_id
|
||||||
|
* @param bool $filterDrafts
|
||||||
|
* @return \Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
public function bookChildrenQuery($book_id, $filterDrafts = false) {
|
public function bookChildrenQuery($book_id, $filterDrafts = false) {
|
||||||
|
$pageSelect = $this->db->table('pages')->selectRaw("'BookStack\\\\Page' as entity_type, id, slug, name, text, '' as description, book_id, priority, chapter_id, draft")->where('book_id', '=', $book_id)->where(function($query) use ($filterDrafts) {
|
||||||
// Draft setup
|
$query->where('draft', '=', 0);
|
||||||
$params = [
|
if (!$filterDrafts) {
|
||||||
'userId' => $this->currentUser()->id,
|
$query->orWhere(function($query) {
|
||||||
'bookIdPage' => $book_id,
|
$query->where('draft', '=', 1)->where('created_by', '=', $this->currentUser()->id);
|
||||||
'bookIdChapter' => $book_id
|
});
|
||||||
];
|
}
|
||||||
if (!$filterDrafts) {
|
});
|
||||||
$params['userIdDrafts'] = $this->currentUser()->id;
|
$chapterSelect = $this->db->table('chapters')->selectRaw("'BookStack\\\\Chapter' as entity_type, id, slug, name, '' as text, description, book_id, priority, 0 as chapter_id, 0 as draft")->where('book_id', '=', $book_id);
|
||||||
}
|
$whereQuery = $this->db->table('joint_permissions as jp')->selectRaw('COUNT(*)')
|
||||||
// Role setup
|
->whereRaw('jp.entity_id=U.id')->whereRaw('jp.entity_type=U.entity_type')
|
||||||
$userRoles = $this->getRoles();
|
->where('jp.action', '=', 'view')->whereIn('jp.role_id', $this->getRoles())
|
||||||
$roleBindings = [];
|
->where(function($query) {
|
||||||
$roleValues = [];
|
$query->where('jp.has_permission', '=', 1)->orWhere(function($query) {
|
||||||
foreach ($userRoles as $index => $roleId) {
|
$query->where('jp.has_permission_own', '=', 1)->where('jp.created_by', '=', $this->currentUser()->id);
|
||||||
$roleBindings[':role'.$index] = $roleId;
|
});
|
||||||
$roleValues['role'.$index] = $roleId;
|
});
|
||||||
}
|
$query = $this->db->query()->select('*')->from($this->db->raw("({$pageSelect->toSql()} UNION {$chapterSelect->toSql()}) AS U"))
|
||||||
// TODO - Clean this up, Maybe extract into a nice class for doing these kind of manual things
|
->mergeBindings($pageSelect)->mergeBindings($chapterSelect)
|
||||||
// Something which will handle the above role crap in a nice clean way
|
->whereRaw("({$whereQuery->toSql()}) > 0")->mergeBindings($whereQuery)->orderBy('draft', 'desc')->orderBy('priority', 'asc');
|
||||||
$roleBindingString = implode(',', array_keys($roleBindings));
|
|
||||||
$query = "SELECT * from (
|
|
||||||
(SELECT 'Bookstack\\\Page' as entity_type, id, slug, name, text, '' as description, book_id, priority, chapter_id, draft FROM {$this->page->getTable()}
|
|
||||||
where book_id = :bookIdPage AND ". ($filterDrafts ? '(draft = 0)' : '(draft = 0 OR (draft = 1 AND created_by = :userIdDrafts))') .")
|
|
||||||
UNION
|
|
||||||
(SELECT 'Bookstack\\\Chapter' as entity_type, id, slug, name, '' as text, description, book_id, priority, 0 as chapter_id, 0 as draft FROM {$this->chapter->getTable()} WHERE book_id = :bookIdChapter)
|
|
||||||
) as U WHERE (
|
|
||||||
SELECT COUNT(*) FROM {$this->jointPermission->getTable()} jp
|
|
||||||
WHERE
|
|
||||||
jp.entity_id=U.id AND
|
|
||||||
jp.entity_type=U.entity_type AND
|
|
||||||
jp.action = 'view' AND
|
|
||||||
jp.role_id IN ({$roleBindingString}) AND
|
|
||||||
(
|
|
||||||
jp.has_permission = 1 OR
|
|
||||||
(jp.has_permission_own = 1 AND jp.created_by = :userId)
|
|
||||||
)
|
|
||||||
) > 0
|
|
||||||
ORDER BY draft desc, priority asc";
|
|
||||||
|
|
||||||
$this->clean();
|
$this->clean();
|
||||||
return $this->db->select($query, array_replace($roleValues, $params));
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue