Skip to content

Commit f5f96f8

Browse files
committed
404: Fixed entity list issue with entity with non-visible parent
Adds our mixed entity list loader to popular queries for more efficient loading.
1 parent 2009d4d commit f5f96f8

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

app/Entities/Queries/QueryPopular.php

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
use BookStack\Activity\Models\View;
66
use BookStack\Entities\EntityProvider;
7-
use BookStack\Entities\Models\BookChild;
8-
use BookStack\Entities\Models\Entity;
7+
use BookStack\Entities\Tools\MixedEntityListLoader;
98
use BookStack\Permissions\PermissionApplicator;
10-
use Illuminate\Database\Eloquent\Relations\BelongsTo;
119
use Illuminate\Support\Collection;
1210
use Illuminate\Support\Facades\DB;
1311

@@ -16,10 +14,11 @@ class QueryPopular
1614
public function __construct(
1715
protected PermissionApplicator $permissions,
1816
protected EntityProvider $entityProvider,
17+
protected MixedEntityListLoader $listLoader,
1918
) {
2019
}
2120

22-
public function run(int $count, int $page, array $filterModels = null)
21+
public function run(int $count, int $page, array $filterModels = null): Collection
2322
{
2423
$query = $this->permissions
2524
->restrictEntityRelationQuery(View::query(), 'views', 'viewable_id', 'viewable_type')
@@ -31,24 +30,13 @@ public function run(int $count, int $page, array $filterModels = null)
3130
$query->whereIn('viewable_type', $this->entityProvider->getMorphClasses($filterModels));
3231
}
3332

34-
$entities = $query->with('viewable')
33+
$views = $query
3534
->skip($count * ($page - 1))
3635
->take($count)
37-
->get()
38-
->pluck('viewable')
39-
->filter();
36+
->get();
4037

41-
$this->loadBooksForChildren($entities);
38+
$this->listLoader->loadIntoRelations($views->all(), 'viewable', false);
4239

43-
return $entities;
44-
}
45-
46-
protected function loadBooksForChildren(Collection $entities): void
47-
{
48-
$bookChildren = $entities->filter(fn(Entity $entity) => $entity instanceof BookChild);
49-
$eloquent = (new \Illuminate\Database\Eloquent\Collection($bookChildren));
50-
$eloquent->load(['book' => function (BelongsTo $query) {
51-
$query->scopes('visible');
52-
}]);
40+
return $views->pluck('viewable')->filter();
5341
}
5442
}

tests/ErrorTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,35 @@ public function test_404_page_does_not_show_login()
2323
$notFound->assertSeeText('tester');
2424
}
2525

26+
public function test_404_page_does_not_non_visible_content()
27+
{
28+
$editor = $this->users->editor();
29+
$book = $this->entities->book();
30+
31+
$this->actingAs($editor)->get($book->getUrl())->assertOk();
32+
33+
$this->permissions->disableEntityInheritedPermissions($book);
34+
35+
$this->actingAs($editor)->get($book->getUrl())->assertNotFound();
36+
}
37+
38+
public function test_404_page_shows_visible_content_within_non_visible_parent()
39+
{
40+
$editor = $this->users->editor();
41+
$book = $this->entities->book();
42+
$page = $book->pages()->first();
43+
44+
$this->actingAs($editor)->get($page->getUrl())->assertOk();
45+
46+
$this->permissions->disableEntityInheritedPermissions($book);
47+
$this->permissions->addEntityPermission($page, ['view'], $editor->roles()->first());
48+
49+
$resp = $this->actingAs($editor)->get($book->getUrl());
50+
$resp->assertNotFound();
51+
$resp->assertSee($page->name);
52+
$resp->assertDontSee($book->name);
53+
}
54+
2655
public function test_item_not_found_does_not_get_logged_to_file()
2756
{
2857
$this->actingAs($this->users->viewer());

0 commit comments

Comments
 (0)