1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2026-01-03 23:42:28 +03:00

Added per-item recycle-bin delete and restore

This commit is contained in:
Dan Brown
2020-11-02 22:47:48 +00:00
parent ff7cbd14fc
commit 9e033709a7
14 changed files with 291 additions and 38 deletions

View File

@@ -287,6 +287,22 @@ class Entity extends Ownable
return $path;
}
/**
* Get the parent entity if existing.
* This is the "static" parent and does not include dynamic
* relations such as shelves to books.
*/
public function getParent(): ?Entity
{
if ($this->isA('page')) {
return $this->chapter_id ? $this->chapter()->withTrashed()->first() : $this->book->withTrashed()->first();
}
if ($this->isA('chapter')) {
return $this->book->withTrashed()->first();
}
return null;
}
/**
* Rebuild the permissions for this entity.
*/

View File

@@ -180,24 +180,91 @@ class TrashCan
/**
* Destroy all items that have pending deletions.
* @throws Exception
*/
public function destroyFromAllDeletions(): int
{
$deletions = Deletion::all();
$deleteCount = 0;
foreach ($deletions as $deletion) {
// For each one we load in the relation since it may have already
// been deleted as part of another deletion in this loop.
$entity = $deletion->deletable()->first();
if ($entity) {
$count = $this->destroyEntity($deletion->deletable);
$deleteCount += $count;
}
$deletion->delete();
$deleteCount += $this->destroyFromDeletion($deletion);
}
return $deleteCount;
}
/**
* Destroy an element from the given deletion model.
* @throws Exception
*/
public function destroyFromDeletion(Deletion $deletion): int
{
// We directly load the deletable element here just to ensure it still
// exists in the event it has already been destroyed during this request.
$entity = $deletion->deletable()->first();
$count = 0;
if ($entity) {
$count = $this->destroyEntity($deletion->deletable);
}
$deletion->delete();
return $count;
}
/**
* Restore the content within the given deletion.
* @throws Exception
*/
public function restoreFromDeletion(Deletion $deletion): int
{
$shouldRestore = true;
$restoreCount = 0;
$parent = $deletion->deletable->getParent();
if ($parent && $parent->trashed()) {
$shouldRestore = false;
}
if ($shouldRestore) {
$restoreCount = $this->restoreEntity($deletion->deletable);
}
$deletion->delete();
return $restoreCount;
}
/**
* Restore an entity so it is essentially un-deleted.
* Deletions on restored child elements will be removed during this restoration.
*/
protected function restoreEntity(Entity $entity): int
{
$count = 1;
$entity->restore();
if ($entity->isA('chapter') || $entity->isA('book')) {
foreach ($entity->pages()->withTrashed()->withCount('deletions')->get() as $page) {
if ($page->deletions_count > 0) {
$page->deletions()->delete();
}
$page->restore();
$count++;
}
}
if ($entity->isA('book')) {
foreach ($entity->chapters()->withTrashed()->withCount('deletions')->get() as $chapter) {
if ($chapter->deletions_count === 0) {
$chapter->deletions()->delete();
}
$chapter->restore();
$count++;
}
}
return $count;
}
/**
* Destroy the given entity.
*/

View File

@@ -49,14 +49,6 @@ class Page extends BookChild
return $array;
}
/**
* Get the parent item
*/
public function parent(): Entity
{
return $this->chapter_id ? $this->chapter : $this->book;
}
/**
* Get the chapter that this page is in, If applicable.
* @return BelongsTo

View File

@@ -321,7 +321,7 @@ class PageRepo
*/
public function copy(Page $page, string $parentIdentifier = null, string $newName = null): Page
{
$parent = $parentIdentifier ? $this->findParentByIdentifier($parentIdentifier) : $page->parent();
$parent = $parentIdentifier ? $this->findParentByIdentifier($parentIdentifier) : $page->getParent();
if ($parent === null) {
throw new MoveOperationException('Book or chapter to move page into not found');
}
@@ -440,8 +440,9 @@ class PageRepo
*/
protected function getNewPriority(Page $page): int
{
if ($page->parent() instanceof Chapter) {
$lastPage = $page->parent()->pages('desc')->first();
$parent = $page->getParent();
if ($parent instanceof Chapter) {
$lastPage = $parent->pages('desc')->first();
return $lastPage ? $lastPage->priority + 1 : 0;
}