]> BookStack Code Mirror - bookstack/commitdiff
Sorting: Connected up default sort setting for books
authorDan Brown <redacted>
Wed, 5 Feb 2025 14:33:46 +0000 (14:33 +0000)
committerDan Brown <redacted>
Wed, 5 Feb 2025 14:33:46 +0000 (14:33 +0000)
app/Entities/Models/Book.php
app/Entities/Repos/BookRepo.php
app/Sorting/SortSet.php
app/Sorting/SortSetController.php
database/migrations/2025_02_05_150842_add_sort_set_id_to_books.php [new file with mode: 0644]
lang/en/settings.php
resources/views/settings/categories/sorting.blade.php

index c1644dcf5fb10afa03ebff7d38142e5162785c9d..7d240e5cab9b41f5995611dccdff8a9be4fb7694 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace BookStack\Entities\Models;
 
+use BookStack\Sorting\SortSet;
 use BookStack\Uploads\Image;
 use Exception;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -16,12 +17,14 @@ use Illuminate\Support\Collection;
  * @property string                                   $description
  * @property int                                      $image_id
  * @property ?int                                     $default_template_id
+ * @property ?int                                     $sort_set_id
  * @property Image|null                               $cover
  * @property \Illuminate\Database\Eloquent\Collection $chapters
  * @property \Illuminate\Database\Eloquent\Collection $pages
  * @property \Illuminate\Database\Eloquent\Collection $directPages
  * @property \Illuminate\Database\Eloquent\Collection $shelves
  * @property ?Page                                    $defaultTemplate
+ * @property ?SortSet                                 $sortSet
  */
 class Book extends Entity implements HasCoverImage
 {
@@ -82,6 +85,14 @@ class Book extends Entity implements HasCoverImage
         return $this->belongsTo(Page::class, 'default_template_id');
     }
 
+    /**
+     * Get the sort set assigned to this book, if existing.
+     */
+    public function sortSet(): BelongsTo
+    {
+        return $this->belongsTo(SortSet::class);
+    }
+
     /**
      * Get all pages within this book.
      */
index 19d159eb1e7e9cc539a86f6031ef8004a20e70ef..b3b81164785a5248acc17b1f033356dfe6f1610b 100644 (file)
@@ -8,6 +8,7 @@ use BookStack\Entities\Models\Book;
 use BookStack\Entities\Tools\TrashCan;
 use BookStack\Exceptions\ImageUploadException;
 use BookStack\Facades\Activity;
+use BookStack\Sorting\SortSet;
 use BookStack\Uploads\ImageRepo;
 use Exception;
 use Illuminate\Http\UploadedFile;
@@ -33,6 +34,12 @@ class BookRepo
         $this->baseRepo->updateDefaultTemplate($book, intval($input['default_template_id'] ?? null));
         Activity::add(ActivityType::BOOK_CREATE, $book);
 
+        $defaultBookSortSetting = intval(setting('sorting-book-default', '0'));
+        if ($defaultBookSortSetting && SortSet::query()->find($defaultBookSortSetting)) {
+            $book->sort_set_id = $defaultBookSortSetting;
+            $book->save();
+        }
+
         return $book;
     }
 
index 971b3e29aae243dddfe675da74cbe3c7f0addcc4..a73407bfa08e58e8c695701a34b98e12be034849 100644 (file)
@@ -3,8 +3,10 @@
 namespace BookStack\Sorting;
 
 use BookStack\Activity\Models\Loggable;
+use BookStack\Entities\Models\Book;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\HasMany;
 
 /**
  * @property int $id
@@ -41,4 +43,9 @@ class SortSet extends Model implements Loggable
     {
         return url("/settings/sorting/sets/{$this->id}");
     }
+
+    public function books(): HasMany
+    {
+        return $this->hasMany(Book::class);
+    }
 }
index 0d77bd88fcd88048c7087666b238520c00076369..8f51207918f80874830527414287996bb13fee65 100644 (file)
@@ -62,7 +62,7 @@ class SortSetController extends Controller
         $set = SortSet::query()->findOrFail($id);
         $operations = SortSetOperation::fromSequence($request->input('sequence'));
         if (count($operations) === 0) {
-            return redirect()->withInput()->withErrors(['sequence' => 'No operations set.']);
+            return redirect($set->getUrl())->withInput()->withErrors(['sequence' => 'No operations set.']);
         }
 
         $set->name = $request->input('name');
@@ -78,7 +78,16 @@ class SortSetController extends Controller
     {
         $set = SortSet::query()->findOrFail($id);
 
-        // TODO - Check if it's in use
+        if ($set->books()->count() > 0) {
+            $this->showErrorNotification(trans('settings.sort_set_delete_fail_books'));
+            return redirect($set->getUrl());
+        }
+
+        $defaultBookSortSetting = intval(setting('sorting-book-default', '0'));
+        if ($defaultBookSortSetting === intval($id)) {
+            $this->showErrorNotification(trans('settings.sort_set_delete_fail_default'));
+            return redirect($set->getUrl());
+        }
 
         $set->delete();
         $this->logActivity(ActivityType::SORT_SET_DELETE, $set);
diff --git a/database/migrations/2025_02_05_150842_add_sort_set_id_to_books.php b/database/migrations/2025_02_05_150842_add_sort_set_id_to_books.php
new file mode 100644 (file)
index 0000000..c0b32c5
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('books', function (Blueprint $table) {
+            $table->unsignedInteger('sort_set_id')->nullable()->default(null);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('books', function (Blueprint $table) {
+            $table->dropColumn('sort_set_id');
+        });
+    }
+};
index cda097590a02f7aa51bedfdc4d49314a8311e44f..eb046d278485db8d9387f66d1615f76029ac08c5 100644 (file)
@@ -84,6 +84,8 @@ return [
     'sort_set_edit' => 'Edit Sort Set',
     'sort_set_delete' => 'Delete Sort Set',
     'sort_set_delete_desc' => 'Remove this sort set from the system. Deletion will only go ahead if the sort is not in active use.',
+    'sort_set_delete_fail_books' => 'Unable to delete this sort set since it has books assigned.',
+    'sort_set_delete_fail_default' => 'Unable to delete this sort set since it\'s used as the default book sort.',
     'sort_set_details' => 'Sort Set Details',
     'sort_set_details_desc' => 'Set a name for this sort set, which will appear in lists when users are selecting a sort.',
     'sort_set_operations' => 'Sort Operations',
index b5d6138400321afda5bf58bc9baab06142b95924..0af3a8fb85b741b5d20afac5a5db3e1d90a79a6a 100644 (file)
@@ -1,5 +1,9 @@
 @extends('settings.layout')
 
+@php
+    $sortSets = \BookStack\Sorting\SortSet::query()->orderBy('name', 'asc')->get();
+@endphp
+
 @section('card')
     <h1 id="sorting" class="list-heading">{{ trans('settings.sorting') }}</h1>
     <form action="{{ url("/settings/sorting") }}" method="POST">
                         <option value="0" @if(intval(setting('sorting-book-default', '0')) === 0) selected @endif>
                             -- {{ trans('common.none') }} --
                         </option>
-{{--                        TODO--}}
-{{--                        @foreach(\BookStack\Users\Models\Role::all() as $role)--}}
-{{--                            <option value="{{$role->id}}"--}}
-{{--                                    data-system-role-name="{{ $role->system_name ?? '' }}"--}}
-{{--                                    @if(intval(setting('registration-role', '0')) === $role->id) selected @endif--}}
-{{--                            >--}}
-{{--                                {{ $role->display_name }}--}}
-{{--                            </option>--}}
-{{--                        @endforeach--}}
+                        @foreach($sortSets as $set)
+                            <option value="{{$set->id}}"
+                                    @if(intval(setting('sorting-book-default', '0')) === $set->id) selected @endif
+                            >
+                                {{ $set->name }}
+                            </option>
+                        @endforeach
                     </select>
                 </div>
             </div>
@@ -52,9 +54,6 @@
             </div>
         </div>
 
-        @php
-            $sortSets = \BookStack\Sorting\SortSet::query()->orderBy('name', 'asc')->get();
-        @endphp
         @if(empty($sortSets))
             <p class="italic text-muted">{{ trans('common.no_items') }}</p>
         @else