- * Shows the view which allows pages to be re-ordered and sorted.
- * @param string $bookSlug
- * @return View
- * @throws NotFoundException
- */
- public function sort(string $bookSlug)
- {
- $book = $this->bookRepo->getBySlug($bookSlug);
- $this->checkOwnablePermission('book-update', $book);
-
- $bookChildren = $this->bookRepo->getBookChildren($book, true);
-
- $this->setPageTitle(trans('entities.books_sort_named', ['bookName'=>$book->getShortName()]));
- return view('books.sort', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
- }
-
- /**
- * Shows the sort box for a single book.
- * Used via AJAX when loading in extra books to a sort.
- * @param string $bookSlug
- * @return Factory|View
- * @throws NotFoundException
- */
- public function getSortItem(string $bookSlug)
- {
- $book = $this->bookRepo->getBySlug($bookSlug);
- $bookChildren = $this->bookRepo->getBookChildren($book);
- return view('books.sort-box', ['book' => $book, 'bookChildren' => $bookChildren]);
- }
-
- /**
- * Saves an array of sort mapping to pages and chapters.
- * @param Request $request
- * @param string $bookSlug
- * @return RedirectResponse|Redirector
- * @throws NotFoundException
- */
- public function saveSort(Request $request, string $bookSlug)
- {
- $book = $this->bookRepo->getBySlug($bookSlug);
- $this->checkOwnablePermission('book-update', $book);
-
- // Return if no map sent
- if (!$request->filled('sort-tree')) {
- return redirect($book->getUrl());
- }
-
- // Sort pages and chapters
- $sortMap = collect(json_decode($request->get('sort-tree')));
- $bookIdsInvolved = collect([$book->id]);
-
- // Load models into map
- $sortMap->each(function ($mapItem) use ($bookIdsInvolved) {
- $mapItem->type = ($mapItem->type === 'page' ? 'page' : 'chapter');
- $mapItem->model = $this->bookRepo->getById($mapItem->type, $mapItem->id);
- // Store source and target books
- $bookIdsInvolved->push(intval($mapItem->model->book_id));
- $bookIdsInvolved->push(intval($mapItem->book));
- });
-
- // Get the books involved in the sort
- $bookIdsInvolved = $bookIdsInvolved->unique()->toArray();
- $booksInvolved = $this->bookRepo->getManyById('book', $bookIdsInvolved, false, true);
- // Throw permission error if invalid ids or inaccessible books given.
- if (count($bookIdsInvolved) !== count($booksInvolved)) {
- $this->showPermissionError();
- }
- // Check permissions of involved books
- $booksInvolved->each(function (Book $book) {
- $this->checkOwnablePermission('book-update', $book);
- });
-
- // Perform the sort
- $sortMap->each(function ($mapItem) {
- $model = $mapItem->model;
-
- $priorityChanged = intval($model->priority) !== intval($mapItem->sort);
- $bookChanged = intval($model->book_id) !== intval($mapItem->book);
- $chapterChanged = ($mapItem->type === 'page') && intval($model->chapter_id) !== $mapItem->parentChapter;
-
- if ($bookChanged) {
- $this->bookRepo->changeBook($mapItem->type, $mapItem->book, $model);
- }
- if ($chapterChanged) {
- $model->chapter_id = intval($mapItem->parentChapter);
- $model->save();
- }
- if ($priorityChanged) {
- $model->priority = intval($mapItem->sort);
- $model->save();
- }
- });
-
- // Rebuild permissions and add activity for involved books.
- $booksInvolved->each(function (Book $book) {
- $this->bookRepo->buildJointPermissionsForBook($book);
- Activity::add($book, 'book_sort', $book->id);
- });
-
- return redirect($book->getUrl());
- }
-
- /**
- * Remove the specified book from storage.
- * @param string $bookSlug
- * @return Response
- * @throws NotFoundException