mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-12-13 07:42:23 +03:00
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.
233 lines
8.0 KiB
PHP
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');
|
|
}
|
|
}
|