1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-31 15:24:31 +03:00

Sorting: Renamed sort set to sort rule

Renamed based on feedback from Tim and Script on Discord.
Also fixed flaky test
This commit is contained in:
Dan Brown
2025-02-11 14:36:25 +00:00
parent a208c46b62
commit b9306a9029
30 changed files with 232 additions and 224 deletions

View File

@ -71,9 +71,9 @@ class ActivityType
const IMPORT_RUN = 'import_run';
const IMPORT_DELETE = 'import_delete';
const SORT_SET_CREATE = 'sort_set_create';
const SORT_SET_UPDATE = 'sort_set_update';
const SORT_SET_DELETE = 'sort_set_delete';
const SORT_RULE_CREATE = 'sort_rule_create';
const SORT_RULE_UPDATE = 'sort_rule_update';
const SORT_RULE_DELETE = 'sort_rule_delete';
/**
* Get all the possible values.

View File

@ -4,7 +4,7 @@ namespace BookStack\Console\Commands;
use BookStack\Entities\Models\Book;
use BookStack\Sorting\BookSorter;
use BookStack\Sorting\SortSet;
use BookStack\Sorting\SortRule;
use Illuminate\Console\Command;
class AssignSortSetCommand extends Command
@ -37,7 +37,7 @@ class AssignSortSetCommand extends Command
return $this->listSortSets();
}
$set = SortSet::query()->find($sortSetId);
$set = SortRule::query()->find($sortSetId);
if ($this->option('all-books')) {
$query = Book::query();
} else if ($this->option('books-without-sort')) {
@ -87,7 +87,7 @@ class AssignSortSetCommand extends Command
protected function listSortSets(): int
{
$sets = SortSet::query()->orderBy('id', 'asc')->get();
$sets = SortRule::query()->orderBy('id', 'asc')->get();
$this->error("Sort set ID required!");
$this->warn("\nAvailable sort sets:");
foreach ($sets as $set) {

View File

@ -2,7 +2,7 @@
namespace BookStack\Entities\Models;
use BookStack\Sorting\SortSet;
use BookStack\Sorting\SortRule;
use BookStack\Uploads\Image;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -17,14 +17,14 @@ use Illuminate\Support\Collection;
* @property string $description
* @property int $image_id
* @property ?int $default_template_id
* @property ?int $sort_set_id
* @property ?int $sort_rule_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
* @property ?SortRule $sortRule
*/
class Book extends Entity implements HasCoverImage
{
@ -88,9 +88,9 @@ class Book extends Entity implements HasCoverImage
/**
* Get the sort set assigned to this book, if existing.
*/
public function sortSet(): BelongsTo
public function sortRule(): BelongsTo
{
return $this->belongsTo(SortSet::class);
return $this->belongsTo(SortRule::class);
}
/**

View File

@ -8,7 +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\Sorting\SortRule;
use BookStack\Uploads\ImageRepo;
use Exception;
use Illuminate\Http\UploadedFile;
@ -35,8 +35,8 @@ class BookRepo
Activity::add(ActivityType::BOOK_CREATE, $book);
$defaultBookSortSetting = intval(setting('sorting-book-default', '0'));
if ($defaultBookSortSetting && SortSet::query()->find($defaultBookSortSetting)) {
$book->sort_set_id = $defaultBookSortSetting;
if ($defaultBookSortSetting && SortRule::query()->find($defaultBookSortSetting)) {
$book->sort_rule_id = $defaultBookSortSetting;
$book->save();
}

View File

@ -69,10 +69,10 @@ class BookSortController extends Controller
if ($request->filled('auto-sort')) {
$sortSetId = intval($request->get('auto-sort')) ?: null;
if ($sortSetId && SortSet::query()->find($sortSetId) === null) {
if ($sortSetId && SortRule::query()->find($sortSetId) === null) {
$sortSetId = null;
}
$book->sort_set_id = $sortSetId;
$book->sort_rule_id = $sortSetId;
$book->save();
$sorter->runBookAutoSort($book);
if (!$loggedActivityForBook) {

View File

@ -16,7 +16,7 @@ class BookSorter
) {
}
public function runBookAutoSortForAllWithSet(SortSet $set): void
public function runBookAutoSortForAllWithSet(SortRule $set): void
{
$set->books()->chunk(50, function ($books) {
foreach ($books as $book) {
@ -32,12 +32,12 @@ class BookSorter
*/
public function runBookAutoSort(Book $book): void
{
$set = $book->sortSet;
$set = $book->sortRule;
if (!$set) {
return;
}
$sortFunctions = array_map(function (SortSetOperation $op) {
$sortFunctions = array_map(function (SortRuleOperation $op) {
return $op->getSortFunction();
}, $set->getOperations());

View File

@ -17,24 +17,24 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class SortSet extends Model implements Loggable
class SortRule extends Model implements Loggable
{
use HasFactory;
/**
* @return SortSetOperation[]
* @return SortRuleOperation[]
*/
public function getOperations(): array
{
return SortSetOperation::fromSequence($this->sequence);
return SortRuleOperation::fromSequence($this->sequence);
}
/**
* @param SortSetOperation[] $options
* @param SortRuleOperation[] $options
*/
public function setOperations(array $options): void
{
$values = array_map(fn (SortSetOperation $opt) => $opt->value, $options);
$values = array_map(fn (SortRuleOperation $opt) => $opt->value, $options);
$this->sequence = implode(',', $values);
}
@ -45,7 +45,7 @@ class SortSet extends Model implements Loggable
public function getUrl(): string
{
return url("/settings/sorting/sets/{$this->id}");
return url("/settings/sorting/rules/{$this->id}");
}
public function books(): HasMany

View File

@ -6,7 +6,7 @@ use BookStack\Activity\ActivityType;
use BookStack\Http\Controller;
use Illuminate\Http\Request;
class SortSetController extends Controller
class SortRuleController extends Controller
{
public function __construct()
{
@ -15,9 +15,9 @@ class SortSetController extends Controller
public function create()
{
$this->setPageTitle(trans('settings.sort_set_create'));
$this->setPageTitle(trans('settings.sort_rule_create'));
return view('settings.sort-sets.create');
return view('settings.sort-rules.create');
}
public function store(Request $request)
@ -27,28 +27,28 @@ class SortSetController extends Controller
'sequence' => ['required', 'string', 'min:1'],
]);
$operations = SortSetOperation::fromSequence($request->input('sequence'));
$operations = SortRuleOperation::fromSequence($request->input('sequence'));
if (count($operations) === 0) {
return redirect()->withInput()->withErrors(['sequence' => 'No operations set.']);
}
$set = new SortSet();
$set->name = $request->input('name');
$set->setOperations($operations);
$set->save();
$rule = new SortRule();
$rule->name = $request->input('name');
$rule->setOperations($operations);
$rule->save();
$this->logActivity(ActivityType::SORT_SET_CREATE, $set);
$this->logActivity(ActivityType::SORT_RULE_CREATE, $rule);
return redirect('/settings/sorting');
}
public function edit(string $id)
{
$set = SortSet::query()->findOrFail($id);
$rule = SortRule::query()->findOrFail($id);
$this->setPageTitle(trans('settings.sort_set_edit'));
$this->setPageTitle(trans('settings.sort_rule_edit'));
return view('settings.sort-sets.edit', ['set' => $set]);
return view('settings.sort-rules.edit', ['rule' => $rule]);
}
public function update(string $id, Request $request, BookSorter $bookSorter)
@ -58,21 +58,21 @@ class SortSetController extends Controller
'sequence' => ['required', 'string', 'min:1'],
]);
$set = SortSet::query()->findOrFail($id);
$operations = SortSetOperation::fromSequence($request->input('sequence'));
$rule = SortRule::query()->findOrFail($id);
$operations = SortRuleOperation::fromSequence($request->input('sequence'));
if (count($operations) === 0) {
return redirect($set->getUrl())->withInput()->withErrors(['sequence' => 'No operations set.']);
return redirect($rule->getUrl())->withInput()->withErrors(['sequence' => 'No operations set.']);
}
$set->name = $request->input('name');
$set->setOperations($operations);
$changedSequence = $set->isDirty('sequence');
$set->save();
$rule->name = $request->input('name');
$rule->setOperations($operations);
$changedSequence = $rule->isDirty('sequence');
$rule->save();
$this->logActivity(ActivityType::SORT_SET_UPDATE, $set);
$this->logActivity(ActivityType::SORT_RULE_UPDATE, $rule);
if ($changedSequence) {
$bookSorter->runBookAutoSortForAllWithSet($set);
$bookSorter->runBookAutoSortForAllWithSet($rule);
}
return redirect('/settings/sorting');
@ -80,16 +80,16 @@ class SortSetController extends Controller
public function destroy(string $id, Request $request)
{
$set = SortSet::query()->findOrFail($id);
$rule = SortRule::query()->findOrFail($id);
$confirmed = $request->input('confirm') === 'true';
$booksAssigned = $set->books()->count();
$booksAssigned = $rule->books()->count();
$warnings = [];
if ($booksAssigned > 0) {
if ($confirmed) {
$set->books()->update(['sort_set_id' => null]);
$rule->books()->update(['sort_rule_id' => null]);
} else {
$warnings[] = trans('settings.sort_set_delete_warn_books', ['count' => $booksAssigned]);
$warnings[] = trans('settings.sort_rule_delete_warn_books', ['count' => $booksAssigned]);
}
}
@ -98,16 +98,16 @@ class SortSetController extends Controller
if ($confirmed) {
setting()->remove('sorting-book-default');
} else {
$warnings[] = trans('settings.sort_set_delete_warn_default');
$warnings[] = trans('settings.sort_rule_delete_warn_default');
}
}
if (count($warnings) > 0) {
return redirect($set->getUrl() . '#delete')->withErrors(['delete' => $warnings]);
return redirect($rule->getUrl() . '#delete')->withErrors(['delete' => $warnings]);
}
$set->delete();
$this->logActivity(ActivityType::SORT_SET_DELETE, $set);
$rule->delete();
$this->logActivity(ActivityType::SORT_RULE_DELETE, $rule);
return redirect('/settings/sorting');
}

View File

@ -5,7 +5,7 @@ namespace BookStack\Sorting;
use Closure;
use Illuminate\Support\Str;
enum SortSetOperation: string
enum SortRuleOperation: string
{
case NameAsc = 'name_asc';
case NameDesc = 'name_desc';
@ -26,13 +26,13 @@ enum SortSetOperation: string
$label = '';
if (str_ends_with($key, '_asc')) {
$key = substr($key, 0, -4);
$label = trans('settings.sort_set_op_asc');
$label = trans('settings.sort_rule_op_asc');
} elseif (str_ends_with($key, '_desc')) {
$key = substr($key, 0, -5);
$label = trans('settings.sort_set_op_desc');
$label = trans('settings.sort_rule_op_desc');
}
$label = trans('settings.sort_set_op_' . $key) . ' ' . $label;
$label = trans('settings.sort_rule_op_' . $key) . ' ' . $label;
return trim($label);
}
@ -43,12 +43,12 @@ enum SortSetOperation: string
}
/**
* @return SortSetOperation[]
* @return SortRuleOperation[]
*/
public static function allExcluding(array $operations): array
{
$all = SortSetOperation::cases();
$filtered = array_filter($all, function (SortSetOperation $operation) use ($operations) {
$all = SortRuleOperation::cases();
$filtered = array_filter($all, function (SortRuleOperation $operation) use ($operations) {
return !in_array($operation, $operations);
});
return array_values($filtered);
@ -57,12 +57,12 @@ enum SortSetOperation: string
/**
* Create a set of operations from a string sequence representation.
* (values seperated by commas).
* @return SortSetOperation[]
* @return SortRuleOperation[]
*/
public static function fromSequence(string $sequence): array
{
$strOptions = explode(',', $sequence);
$options = array_map(fn ($val) => SortSetOperation::tryFrom($val), $strOptions);
$options = array_map(fn ($val) => SortRuleOperation::tryFrom($val), $strOptions);
return array_filter($options);
}
}