]> BookStack Code Mirror - bookstack/commitdiff
404: Fixed entity list issue with entity with non-visible parent
authorDan Brown <redacted>
Wed, 28 Feb 2024 13:07:34 +0000 (13:07 +0000)
committerDan Brown <redacted>
Wed, 28 Feb 2024 13:08:06 +0000 (13:08 +0000)
Adds our mixed entity list loader to popular queries for more efficient
loading.

app/Entities/Queries/QueryPopular.php
tests/ErrorTest.php

index b2ca565eb055db8e8d0a161acd7627535f236ac4..2b46ebfbcf937caf1a1546290a6ce89c139aa868 100644 (file)
@@ -4,10 +4,8 @@ namespace BookStack\Entities\Queries;
 
 use BookStack\Activity\Models\View;
 use BookStack\Entities\EntityProvider;
-use BookStack\Entities\Models\BookChild;
-use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Tools\MixedEntityListLoader;
 use BookStack\Permissions\PermissionApplicator;
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\DB;
 
@@ -16,10 +14,11 @@ class QueryPopular
     public function __construct(
         protected PermissionApplicator $permissions,
         protected EntityProvider $entityProvider,
+        protected MixedEntityListLoader $listLoader,
     ) {
     }
 
-    public function run(int $count, int $page, array $filterModels = null)
+    public function run(int $count, int $page, array $filterModels = null): Collection
     {
         $query = $this->permissions
             ->restrictEntityRelationQuery(View::query(), 'views', 'viewable_id', 'viewable_type')
@@ -31,24 +30,13 @@ class QueryPopular
             $query->whereIn('viewable_type', $this->entityProvider->getMorphClasses($filterModels));
         }
 
-        $entities = $query->with('viewable')
+        $views = $query
             ->skip($count * ($page - 1))
             ->take($count)
-            ->get()
-            ->pluck('viewable')
-            ->filter();
+            ->get();
 
-        $this->loadBooksForChildren($entities);
+        $this->listLoader->loadIntoRelations($views->all(), 'viewable', false);
 
-        return $entities;
-    }
-
-    protected function loadBooksForChildren(Collection $entities): void
-    {
-        $bookChildren = $entities->filter(fn(Entity $entity) => $entity instanceof BookChild);
-        $eloquent = (new \Illuminate\Database\Eloquent\Collection($bookChildren));
-        $eloquent->load(['book' => function (BelongsTo $query) {
-            $query->scopes('visible');
-        }]);
+        return $views->pluck('viewable')->filter();
     }
 }
index 0d2ef808c48af0cfa1ed608ea2c4c6d23e3eec08..642945d438830a3be5fef79349fefea2ce8701b7 100644 (file)
@@ -23,6 +23,35 @@ class ErrorTest extends TestCase
         $notFound->assertSeeText('tester');
     }
 
+    public function test_404_page_does_not_non_visible_content()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->book();
+
+        $this->actingAs($editor)->get($book->getUrl())->assertOk();
+
+        $this->permissions->disableEntityInheritedPermissions($book);
+
+        $this->actingAs($editor)->get($book->getUrl())->assertNotFound();
+    }
+
+    public function test_404_page_shows_visible_content_within_non_visible_parent()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->book();
+        $page = $book->pages()->first();
+
+        $this->actingAs($editor)->get($page->getUrl())->assertOk();
+
+        $this->permissions->disableEntityInheritedPermissions($book);
+        $this->permissions->addEntityPermission($page, ['view'], $editor->roles()->first());
+
+        $resp = $this->actingAs($editor)->get($book->getUrl());
+        $resp->assertNotFound();
+        $resp->assertSee($page->name);
+        $resp->assertDontSee($book->name);
+    }
+
     public function test_item_not_found_does_not_get_logged_to_file()
     {
         $this->actingAs($this->users->viewer());