diff --git a/app/Entities/Models/Book.php b/app/Entities/Models/Book.php index 8217d2cab..bf42f2008 100644 --- a/app/Entities/Models/Book.php +++ b/app/Entities/Models/Book.php @@ -19,6 +19,7 @@ use Illuminate\Support\Collection; * @property \Illuminate\Database\Eloquent\Collection $chapters * @property \Illuminate\Database\Eloquent\Collection $pages * @property \Illuminate\Database\Eloquent\Collection $directPages + * @property \Illuminate\Database\Eloquent\Collection $shelves */ class Book extends Entity implements HasCoverImage { diff --git a/app/Entities/Tools/Cloner.php b/app/Entities/Tools/Cloner.php index 92b62a754..86f392e61 100644 --- a/app/Entities/Tools/Cloner.php +++ b/app/Entities/Tools/Cloner.php @@ -4,6 +4,7 @@ namespace BookStack\Entities\Tools; use BookStack\Actions\Tag; use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Page; @@ -71,8 +72,10 @@ class Cloner $bookDetails = $this->entityToInputData($original); $bookDetails['name'] = $newName; + // Clone book $copyBook = $this->bookRepo->create($bookDetails); + // Clone contents $directChildren = $original->getDirectChildren(); foreach ($directChildren as $child) { if ($child instanceof Chapter && userCan('chapter-create', $copyBook)) { @@ -84,6 +87,14 @@ class Cloner } } + // Clone bookshelf relationships + /** @var Bookshelf $shelf */ + foreach ($original->shelves as $shelf) { + if (userCan('bookshelf-update', $shelf)) { + $shelf->appendBook($copyBook); + } + } + return $copyBook; } diff --git a/tests/Entity/BookTest.php b/tests/Entity/BookTest.php index 2e6f8e9de..2f04fcf25 100644 --- a/tests/Entity/BookTest.php +++ b/tests/Entity/BookTest.php @@ -4,6 +4,7 @@ namespace Tests\Entity; use BookStack\Entities\Models\Book; use BookStack\Entities\Models\BookChild; +use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Repos\BookRepo; use Tests\TestCase; use Tests\Uploads\UsesImages; @@ -344,11 +345,34 @@ class BookTest extends TestCase $bookRepo->updateCoverImage($book, $coverImageFile); $this->asEditor()->post($book->getUrl('/copy'), ['name' => 'My copy book']); - /** @var Book $copy */ $copy = Book::query()->where('name', '=', 'My copy book')->first(); $this->assertNotNull($copy->cover); $this->assertNotEquals($book->cover->id, $copy->cover->id); } + + public function test_copy_adds_book_to_shelves_if_edit_permissions_allows() + { + /** @var Bookshelf $shelfA */ + /** @var Bookshelf $shelfB */ + [$shelfA, $shelfB] = Bookshelf::query()->take(2)->get(); + /** @var Book $book */ + $book = Book::query()->first(); + + $shelfA->appendBook($book); + $shelfB->appendBook($book); + + $viewer = $this->getViewer(); + $this->giveUserPermissions($viewer, ['book-update-all', 'book-create-all', 'bookshelf-update-all']); + $this->setEntityRestrictions($shelfB); + + + $this->asEditor()->post($book->getUrl('/copy'), ['name' => 'My copy book']); + /** @var Book $copy */ + $copy = Book::query()->where('name', '=', 'My copy book')->first(); + + $this->assertTrue($copy->shelves()->where('id', '=', $shelfA->id)->exists()); + $this->assertFalse($copy->shelves()->where('id', '=', $shelfB->id)->exists()); + } }