Files
BookStack/app/Entities/Tools/HierarchyTransformer.php
T
Dan Brown 89978409cf Chapter Conversion: Fixed page cached permissions not being rebuilt
Fixes scenario where page access permissions are changed due to a change
of applied permission scope (where a parent book permissions were
active, but would no longer be post-promotion), but the page visibility
permissions were not being rebuilt.
Added test to cover.

Fixes #6226
2026-09-28 14:38:27 +01:00

86 lines
2.6 KiB
PHP

<?php
namespace BookStack\Entities\Tools;
use BookStack\Activity\ActivityType;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\BookRepo;
use BookStack\Entities\Repos\BookshelfRepo;
use BookStack\Facades\Activity;
class HierarchyTransformer
{
public function __construct(
protected BookRepo $bookRepo,
protected BookshelfRepo $shelfRepo,
protected Cloner $cloner,
protected TrashCan $trashCan,
protected ParentChanger $parentChanger,
) {
}
/**
* Transform a chapter into a book.
* Does not check permissions, check before calling.
*/
public function transformChapterToBook(Chapter $chapter): Book
{
$inputData = $this->cloner->entityToInputData($chapter);
$book = $this->bookRepo->create($inputData);
$this->cloner->copyEntityPermissions($chapter, $book);
/** @var Page $page */
foreach ($chapter->pages as $page) {
$page->chapter_id = 0;
$page->save();
$this->parentChanger->changeBook($page, $book->id);
}
$this->trashCan->destroyEntity($chapter);
Activity::add(ActivityType::BOOK_CREATE_FROM_CHAPTER, $book);
$book->rebuildPermissions();
return $book;
}
/**
* Transform a book into a shelf.
* Does not check permissions, check before calling.
*/
public function transformBookToShelf(Book $book): Bookshelf
{
$inputData = $this->cloner->entityToInputData($book);
$shelf = $this->shelfRepo->create($inputData, []);
$this->cloner->copyEntityPermissions($book, $shelf);
$shelfBookSyncData = [];
/** @var Chapter $chapter */
foreach ($book->chapters as $index => $chapter) {
$newBook = $this->transformChapterToBook($chapter);
$shelfBookSyncData[$newBook->id] = ['order' => $index];
if (!$newBook->hasPermissions()) {
$this->cloner->copyEntityPermissions($shelf, $newBook);
}
}
if ($book->directPages->count() > 0) {
$book->name .= ' ' . trans('entities.pages');
$shelfBookSyncData[$book->id] = ['order' => count($shelfBookSyncData) + 1];
$book->save();
} else {
$this->trashCan->destroyEntity($book);
}
$shelf->books()->sync($shelfBookSyncData);
Activity::add(ActivityType::BOOKSHELF_CREATE_FROM_BOOK, $shelf);
return $shelf;
}
}