]> BookStack Code Mirror - bookstack/commitdiff
Queries: Updated old use-specific entity query classes
authorDan Brown <redacted>
Thu, 8 Feb 2024 16:39:59 +0000 (16:39 +0000)
committerDan Brown <redacted>
Thu, 8 Feb 2024 16:39:59 +0000 (16:39 +0000)
- Updated name to align, and differentate from new 'XQueries' clases.
- Removed old sketchy base class with app resolving workarounds, to a
  proper injection-based approach.
- Also fixed wrong translation text used in PageQueries.

app/Activity/Controllers/FavouriteController.php
app/App/HomeController.php
app/Entities/Queries/EntityQuery.php [deleted file]
app/Entities/Queries/PageQueries.php
app/Entities/Queries/QueryPopular.php [moved from app/Entities/Queries/Popular.php with 80% similarity]
app/Entities/Queries/QueryRecentlyViewed.php [moved from app/Entities/Queries/RecentlyViewed.php with 61% similarity]
app/Entities/Queries/QueryTopFavourites.php [moved from app/Entities/Queries/TopFavourites.php with 71% similarity]
app/Entities/Tools/MixedEntityListLoader.php
app/Search/SearchController.php
resources/views/errors/404.blade.php

index b3aff1cef421e5c572e27024db762f719bad9781..3125a25ad33d313bb587df02ee804517ee81a68a 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace BookStack\Activity\Controllers;
 
-use BookStack\Entities\Queries\TopFavourites;
+use BookStack\Entities\Queries\QueryTopFavourites;
 use BookStack\Entities\Tools\MixedEntityRequestHelper;
 use BookStack\Http\Controller;
 use Illuminate\Http\Request;
@@ -21,7 +21,7 @@ class FavouriteController extends Controller
     {
         $viewCount = 20;
         $page = intval($request->get('page', 1));
-        $favourites = (new TopFavourites())->run($viewCount + 1, (($page - 1) * $viewCount));
+        $favourites = (new QueryTopFavourites())->run($viewCount + 1, (($page - 1) * $viewCount));
 
         $hasMoreLink = ($favourites->count() > $viewCount) ? url('/favourites?page=' . ($page + 1)) : null;
 
index 56f3d81a8db9d686e2a1a8729414ae4f576cdd34..116f5c8a4bce024a3ba531fdfe5b9241628f9c66 100644 (file)
@@ -5,8 +5,8 @@ namespace BookStack\App;
 use BookStack\Activity\ActivityQueries;
 use BookStack\Entities\Models\Page;
 use BookStack\Entities\Queries\EntityQueries;
-use BookStack\Entities\Queries\RecentlyViewed;
-use BookStack\Entities\Queries\TopFavourites;
+use BookStack\Entities\Queries\QueryRecentlyViewed;
+use BookStack\Entities\Queries\QueryTopFavourites;
 use BookStack\Entities\Tools\PageContent;
 use BookStack\Http\Controller;
 use BookStack\Uploads\FaviconHandler;
@@ -23,8 +23,12 @@ class HomeController extends Controller
     /**
      * Display the homepage.
      */
-    public function index(Request $request, ActivityQueries $activities)
-    {
+    public function index(
+        Request $request,
+        ActivityQueries $activities,
+        QueryRecentlyViewed $recentlyViewed,
+        QueryTopFavourites $topFavourites,
+    ) {
         $activity = $activities->latest(10);
         $draftPages = [];
 
@@ -38,9 +42,9 @@ class HomeController extends Controller
 
         $recentFactor = count($draftPages) > 0 ? 0.5 : 1;
         $recents = $this->isSignedIn() ?
-            (new RecentlyViewed())->run(12 * $recentFactor, 1)
+            $recentlyViewed->run(12 * $recentFactor, 1)
             : $this->queries->books->visibleForList()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get();
-        $favourites = (new TopFavourites())->run(6);
+        $favourites = $topFavourites->run(6);
         $recentlyUpdatedPages = $this->queries->pages->visibleForList()
             ->where('draft', false)
             ->orderBy('updated_at', 'desc')
diff --git a/app/Entities/Queries/EntityQuery.php b/app/Entities/Queries/EntityQuery.php
deleted file mode 100644 (file)
index bd7a98b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-namespace BookStack\Entities\Queries;
-
-use BookStack\Entities\EntityProvider;
-use BookStack\Entities\Tools\MixedEntityListLoader;
-use BookStack\Permissions\PermissionApplicator;
-
-abstract class EntityQuery
-{
-    protected function mixedEntityListLoader(): MixedEntityListLoader
-    {
-        return app()->make(MixedEntityListLoader::class);
-    }
-
-    protected function permissionService(): PermissionApplicator
-    {
-        return app()->make(PermissionApplicator::class);
-    }
-
-    protected function entityProvider(): EntityProvider
-    {
-        return app()->make(EntityProvider::class);
-    }
-}
index ec27ba4aa6e3e6302d511c0eefe43b9c1d4c8622..8fb02075ae37f796cf8aeb54c5cd27c98450368a 100644 (file)
@@ -50,7 +50,7 @@ class PageQueries implements ProvidesEntityQueries
             ->first();
 
         if (is_null($page)) {
-            throw new NotFoundException(trans('errors.chapter_not_found'));
+            throw new NotFoundException(trans('errors.page_not_found'));
         }
 
         return $page;
similarity index 80%
rename from app/Entities/Queries/Popular.php
rename to app/Entities/Queries/QueryPopular.php
index a934f346b95f43e778f1688f76f3285c723d9fe2..b2ca565eb055db8e8d0a161acd7627535f236ac4 100644 (file)
@@ -3,24 +3,32 @@
 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\Permissions\PermissionApplicator;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\DB;
 
-class Popular extends EntityQuery
+class QueryPopular
 {
+    public function __construct(
+        protected PermissionApplicator $permissions,
+        protected EntityProvider $entityProvider,
+    ) {
+    }
+
     public function run(int $count, int $page, array $filterModels = null)
     {
-        $query = $this->permissionService()
+        $query = $this->permissions
             ->restrictEntityRelationQuery(View::query(), 'views', 'viewable_id', 'viewable_type')
             ->select('*', 'viewable_id', 'viewable_type', DB::raw('SUM(views) as view_count'))
             ->groupBy('viewable_id', 'viewable_type')
             ->orderBy('view_count', 'desc');
 
         if ($filterModels) {
-            $query->whereIn('viewable_type', $this->entityProvider()->getMorphClasses($filterModels));
+            $query->whereIn('viewable_type', $this->entityProvider->getMorphClasses($filterModels));
         }
 
         $entities = $query->with('viewable')
@@ -35,7 +43,7 @@ class Popular extends EntityQuery
         return $entities;
     }
 
-    protected function loadBooksForChildren(Collection $entities)
+    protected function loadBooksForChildren(Collection $entities): void
     {
         $bookChildren = $entities->filter(fn(Entity $entity) => $entity instanceof BookChild);
         $eloquent = (new \Illuminate\Database\Eloquent\Collection($bookChildren));
similarity index 61%
rename from app/Entities/Queries/RecentlyViewed.php
rename to app/Entities/Queries/QueryRecentlyViewed.php
index fed15ca5aca77868b4ec3014246f8eeb8dac0233..f28b8f8652f8e99a2dae267ac02036abec6e510c 100644 (file)
@@ -3,10 +3,18 @@
 namespace BookStack\Entities\Queries;
 
 use BookStack\Activity\Models\View;
+use BookStack\Entities\Tools\MixedEntityListLoader;
+use BookStack\Permissions\PermissionApplicator;
 use Illuminate\Support\Collection;
 
-class RecentlyViewed extends EntityQuery
+class QueryRecentlyViewed
 {
+    public function __construct(
+        protected PermissionApplicator $permissions,
+        protected MixedEntityListLoader $listLoader,
+    ) {
+    }
+
     public function run(int $count, int $page): Collection
     {
         $user = user();
@@ -14,7 +22,7 @@ class RecentlyViewed extends EntityQuery
             return collect();
         }
 
-        $query = $this->permissionService()->restrictEntityRelationQuery(
+        $query = $this->permissions->restrictEntityRelationQuery(
             View::query(),
             'views',
             'viewable_id',
@@ -28,7 +36,7 @@ class RecentlyViewed extends EntityQuery
             ->take($count)
             ->get();
 
-        $this->mixedEntityListLoader()->loadIntoRelations($views->all(), 'viewable', false);
+        $this->listLoader->loadIntoRelations($views->all(), 'viewable', false);
 
         return $views->pluck('viewable')->filter();
     }
similarity index 71%
rename from app/Entities/Queries/TopFavourites.php
rename to app/Entities/Queries/QueryTopFavourites.php
index 47d4b77f7b361cffa9387f1b1dde78228af87eb8..6340e35ef18c63be91ebc925507062f34d43a1be 100644 (file)
@@ -3,10 +3,18 @@
 namespace BookStack\Entities\Queries;
 
 use BookStack\Activity\Models\Favourite;
+use BookStack\Entities\Tools\MixedEntityListLoader;
+use BookStack\Permissions\PermissionApplicator;
 use Illuminate\Database\Query\JoinClause;
 
-class TopFavourites extends EntityQuery
+class QueryTopFavourites
 {
+    public function __construct(
+        protected PermissionApplicator $permissions,
+        protected MixedEntityListLoader $listLoader,
+    ) {
+    }
+
     public function run(int $count, int $skip = 0)
     {
         $user = user();
@@ -14,7 +22,7 @@ class TopFavourites extends EntityQuery
             return collect();
         }
 
-        $query = $this->permissionService()
+        $query = $this->permissions
             ->restrictEntityRelationQuery(Favourite::query(), 'favourites', 'favouritable_id', 'favouritable_type')
             ->select('favourites.*')
             ->leftJoin('views', function (JoinClause $join) {
@@ -30,7 +38,7 @@ class TopFavourites extends EntityQuery
             ->take($count)
             ->get();
 
-        $this->mixedEntityListLoader()->loadIntoRelations($favourites->all(), 'favouritable', false);
+        $this->listLoader->loadIntoRelations($favourites->all(), 'favouritable', false);
 
         return $favourites->pluck('favouritable')->filter();
     }
index a0df791db5b705ff476e25b382b5f5986e444781..f9a940b981b7f4261c33776c2e2897b054701e40 100644 (file)
@@ -3,20 +3,13 @@
 namespace BookStack\Entities\Tools;
 
 use BookStack\App\Model;
-use BookStack\Entities\EntityProvider;
+use BookStack\Entities\Queries\EntityQueries;
 use Illuminate\Database\Eloquent\Relations\Relation;
 
 class MixedEntityListLoader
 {
-    protected array $listAttributes = [
-        'page'      => ['id', 'name', 'slug', 'book_id', 'chapter_id', 'text', 'draft'],
-        'chapter'   => ['id', 'name', 'slug', 'book_id', 'description'],
-        'book'      => ['id', 'name', 'slug', 'description'],
-        'bookshelf' => ['id', 'name', 'slug', 'description'],
-    ];
-
     public function __construct(
-        protected EntityProvider $entityProvider
+        protected EntityQueries $queries,
     ) {
     }
 
@@ -61,14 +54,7 @@ class MixedEntityListLoader
         $modelMap = [];
 
         foreach ($idsByType as $type => $ids) {
-            if (!isset($this->listAttributes[$type])) {
-                continue;
-            }
-
-            $instance = $this->entityProvider->get($type);
-            $models = $instance->newQuery()
-                ->select(array_merge($this->listAttributes[$type], $this->getSubSelectsForQuery($type)))
-                ->scopes('visible')
+            $models = $this->queries->visibleForList($type)
                 ->whereIn('id', $ids)
                 ->with($eagerLoadParents ? $this->getRelationsToEagerLoad($type) : [])
                 ->get();
@@ -100,19 +86,4 @@ class MixedEntityListLoader
 
         return $toLoad;
     }
-
-    protected function getSubSelectsForQuery(string $type): array
-    {
-        $subSelects = [];
-
-        if ($type === 'chapter' || $type === 'page') {
-            $subSelects['book_slug'] = function ($builder) {
-                $builder->select('slug')
-                    ->from('books')
-                    ->whereColumn('books.id', '=', 'book_id');
-            };
-        }
-
-        return $subSelects;
-    }
 }
index b94ec1ec7cefcca9b77acccf0821c97e1032d95f..2fce6a3d53fb86e14e1b773f4126f0b1ba456fb2 100644 (file)
@@ -3,7 +3,7 @@
 namespace BookStack\Search;
 
 use BookStack\Entities\Queries\PageQueries;
-use BookStack\Entities\Queries\Popular;
+use BookStack\Entities\Queries\QueryPopular;
 use BookStack\Entities\Tools\SiblingFetcher;
 use BookStack\Http\Controller;
 use Illuminate\Http\Request;
@@ -67,7 +67,7 @@ class SearchController extends Controller
      * Search for a list of entities and return a partial HTML response of matching entities.
      * Returns the most popular entities if no search is provided.
      */
-    public function searchForSelector(Request $request)
+    public function searchForSelector(Request $request, QueryPopular $queryPopular)
     {
         $entityTypes = $request->filled('types') ? explode(',', $request->get('types')) : ['page', 'chapter', 'book'];
         $searchTerm = $request->get('term', false);
@@ -78,7 +78,7 @@ class SearchController extends Controller
             $searchTerm .= ' {type:' . implode('|', $entityTypes) . '}';
             $entities = $this->searchRunner->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 20)['results'];
         } else {
-            $entities = (new Popular())->run(20, 0, $entityTypes);
+            $entities = $queryPopular->run(20, 0, $entityTypes);
         }
 
         return view('search.parts.entity-selector-list', ['entities' => $entities, 'permission' => $permission]);
index 27d66b30bb9a7a71ad6ea34e235b1d17e1c75f2b..dc24a558d84f2d660f0452c299167e71da3f398b 100644 (file)
@@ -1,5 +1,5 @@
 @extends('layouts.simple')
-
+@inject('popular', \BookStack\Entities\Queries\QueryPopular::class)
 @section('content')
     <div class="container mt-l">
 
@@ -28,7 +28,7 @@
                     <div class="card mb-xl">
                         <h3 class="card-title">{{ trans('entities.pages_popular') }}</h3>
                         <div class="px-m">
-                            @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['page']), 'style' => 'compact'])
+                            @include('entities.list', ['entities' => $popular->run(10, 0, ['page']), 'style' => 'compact'])
                         </div>
                     </div>
                 </div>
@@ -36,7 +36,7 @@
                     <div class="card mb-xl">
                         <h3 class="card-title">{{ trans('entities.books_popular') }}</h3>
                         <div class="px-m">
-                            @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['book']), 'style' => 'compact'])
+                            @include('entities.list', ['entities' => $popular->run(10, 0, ['book']), 'style' => 'compact'])
                         </div>
                     </div>
                 </div>
@@ -44,7 +44,7 @@
                     <div class="card mb-xl">
                         <h3 class="card-title">{{ trans('entities.chapters_popular') }}</h3>
                         <div class="px-m">
-                            @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['chapter']), 'style' => 'compact'])
+                            @include('entities.list', ['entities' => $popular->run(10, 0, ['chapter']), 'style' => 'compact'])
                         </div>
                     </div>
                 </div>