404: Fixed entity list issue with entity with non-visible parent
Adds our mixed entity list loader to popular queries for more efficient loading.
This commit is contained in:
		
							parent
							
								
									2009d4d6a8
								
							
						
					
					
						commit
						f5f96f84e7
					
				| 
						 | 
				
			
			@ -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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue