1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-12-13 07:42:23 +03:00
Files
bookstack/app/Entities/Controllers/BookshelfController.php
Dan Brown 10f5ceee35 List page settings: Review of #5606
Updated setting display to show mulitple number inputs under one heading
group.
Updated settings to use general number field form view template.
Updated translations to match display changes, and to advise on counts.
Added page count control for search results.
Added setting service method, to get settings as integers, with
min/max/default control.
Updating sorting group to be names "Lists & Sorting".
Added tests to cover.
2025-12-06 23:10:54 +00:00

233 lines
8.0 KiB
PHP

<?php
namespace BookStack\Entities\Controllers;
use BookStack\Activity\ActivityQueries;
use BookStack\Activity\Models\View;
use BookStack\Entities\Queries\BookQueries;
use BookStack\Entities\Queries\BookshelfQueries;
use BookStack\Entities\Queries\EntityQueries;
use BookStack\Entities\Repos\BookshelfRepo;
use BookStack\Entities\Tools\ShelfContext;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Exceptions\NotFoundException;
use BookStack\Http\Controller;
use BookStack\Permissions\Permission;
use BookStack\References\ReferenceFetcher;
use BookStack\Util\SimpleListOptions;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
class BookshelfController extends Controller
{
public function __construct(
protected BookshelfRepo $shelfRepo,
protected BookshelfQueries $queries,
protected EntityQueries $entityQueries,
protected BookQueries $bookQueries,
protected ShelfContext $shelfContext,
protected ReferenceFetcher $referenceFetcher,
) {
}
/**
* Display a listing of bookshelves.
*/
public function index(Request $request)
{
$view = setting()->getForCurrentUser('bookshelves_view_type');
$listOptions = SimpleListOptions::fromRequest($request, 'bookshelves')->withSortOptions([
'name' => trans('common.sort_name'),
'created_at' => trans('common.sort_created_at'),
'updated_at' => trans('common.sort_updated_at'),
]);
$shelves = $this->queries->visibleForListWithCover()
->orderBy($listOptions->getSort(), $listOptions->getOrder())
->paginate(setting()->getInteger('lists-page-count-shelves', 18, 1, 1000));
$recents = $this->isSignedIn() ? $this->queries->recentlyViewedForCurrentUser()->get() : false;
$popular = $this->queries->popularForList()->get();
$new = $this->queries->visibleForList()
->orderBy('created_at', 'desc')
->take(4)
->get();
$this->shelfContext->clearShelfContext();
$this->setPageTitle(trans('entities.shelves'));
return view('shelves.index', [
'shelves' => $shelves,
'recents' => $recents,
'popular' => $popular,
'new' => $new,
'view' => $view,
'listOptions' => $listOptions,
]);
}
/**
* Show the form for creating a new bookshelf.
*/
public function create()
{
$this->checkPermission(Permission::BookshelfCreateAll);
$books = $this->bookQueries->visibleForList()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
$this->setPageTitle(trans('entities.shelves_create'));
return view('shelves.create', ['books' => $books]);
}
/**
* Store a newly created bookshelf in storage.
*
* @throws ValidationException
* @throws ImageUploadException
*/
public function store(Request $request)
{
$this->checkPermission(Permission::BookshelfCreateAll);
$validated = $this->validate($request, [
'name' => ['required', 'string', 'max:255'],
'description_html' => ['string', 'max:2000'],
'image' => array_merge(['nullable'], $this->getImageValidationRules()),
'tags' => ['array'],
]);
$bookIds = explode(',', $request->get('books', ''));
$shelf = $this->shelfRepo->create($validated, $bookIds);
return redirect($shelf->getUrl());
}
/**
* Display the bookshelf of the given slug.
*
* @throws NotFoundException
*/
public function show(Request $request, ActivityQueries $activities, string $slug)
{
try {
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
} catch (NotFoundException $exception) {
$shelf = $this->entityQueries->findVisibleByOldSlugs('bookshelf', $slug);
if (is_null($shelf)) {
throw $exception;
}
return redirect($shelf->getUrl());
}
$this->checkOwnablePermission(Permission::BookshelfView, $shelf);
$listOptions = SimpleListOptions::fromRequest($request, 'shelf_books')->withSortOptions([
'default' => trans('common.sort_default'),
'name' => trans('common.sort_name'),
'created_at' => trans('common.sort_created_at'),
'updated_at' => trans('common.sort_updated_at'),
]);
$sort = $listOptions->getSort();
$sortedVisibleShelfBooks = $shelf->visibleBooks()
->reorder($sort === 'default' ? 'order' : $sort, $listOptions->getOrder())
->get()
->values()
->all();
View::incrementFor($shelf);
$this->shelfContext->setShelfContext($shelf->id);
$view = setting()->getForCurrentUser('bookshelf_view_type');
$this->setPageTitle($shelf->getShortName());
return view('shelves.show', [
'shelf' => $shelf,
'sortedVisibleShelfBooks' => $sortedVisibleShelfBooks,
'view' => $view,
'activity' => $activities->entityActivity($shelf, 20, 1),
'listOptions' => $listOptions,
'referenceCount' => $this->referenceFetcher->getReferenceCountToEntity($shelf),
]);
}
/**
* Show the form for editing the specified bookshelf.
*/
public function edit(string $slug)
{
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
$this->checkOwnablePermission(Permission::BookshelfUpdate, $shelf);
$shelfBookIds = $shelf->books()->get(['id'])->pluck('id');
$books = $this->bookQueries->visibleForList()
->whereNotIn('id', $shelfBookIds)
->orderBy('name')
->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
$this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $shelf->getShortName()]));
return view('shelves.edit', [
'shelf' => $shelf,
'books' => $books,
]);
}
/**
* Update the specified bookshelf in storage.
*
* @throws ValidationException
* @throws ImageUploadException
* @throws NotFoundException
*/
public function update(Request $request, string $slug)
{
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
$this->checkOwnablePermission(Permission::BookshelfUpdate, $shelf);
$validated = $this->validate($request, [
'name' => ['required', 'string', 'max:255'],
'description_html' => ['string', 'max:2000'],
'image' => array_merge(['nullable'], $this->getImageValidationRules()),
'tags' => ['array'],
]);
if ($request->has('image_reset')) {
$validated['image'] = null;
} elseif (array_key_exists('image', $validated) && is_null($validated['image'])) {
unset($validated['image']);
}
$bookIds = explode(',', $request->get('books', ''));
$shelf = $this->shelfRepo->update($shelf, $validated, $bookIds);
return redirect($shelf->getUrl());
}
/**
* Shows the page to confirm deletion.
*/
public function showDelete(string $slug)
{
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
$this->checkOwnablePermission(Permission::BookshelfDelete, $shelf);
$this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $shelf->getShortName()]));
return view('shelves.delete', ['shelf' => $shelf]);
}
/**
* Remove the specified bookshelf from storage.
*
* @throws Exception
*/
public function destroy(string $slug)
{
$shelf = $this->queries->findVisibleBySlugOrFail($slug);
$this->checkOwnablePermission(Permission::BookshelfDelete, $shelf);
$this->shelfRepo->destroy($shelf);
return redirect('/shelves');
}
}