]> BookStack Code Mirror - bookstack/commitdiff
do some cleanup and add doc 3377/head
authorjulesdevops <redacted>
Sun, 24 Apr 2022 08:16:45 +0000 (10:16 +0200)
committerjulesdevops <redacted>
Sun, 24 Apr 2022 08:49:29 +0000 (10:49 +0200)
app/Http/Controllers/Api/RecycleBinApiController.php
dev/api/responses/recycle_bin-destroy.json [new file with mode: 0644]
dev/api/responses/recycle_bin-list.json [new file with mode: 0644]
dev/api/responses/recycle_bin-restore.json [new file with mode: 0644]
tests/Api/RecycleBinApiTest.php

index f60115c167a5fe6b4b423cdae88be71659e2ed75..a2176a2c8a34af3c0211dfba077f4f3b4e246717 100644 (file)
@@ -2,14 +2,16 @@
 
 namespace BookStack\Http\Controllers\Api;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Deletion;
 use BookStack\Entities\Repos\DeletionRepo;
 use Closure;
 
 class RecycleBinApiController extends ApiController
 {
+    protected $fieldsToExpose = [
+        'id', 'deleted_by', 'created_at', 'updated_at', 'deletable_type', 'deletable_id',
+    ];
+
     public function __construct()
     {
         $this->middleware(function ($request, $next) {
@@ -20,9 +22,13 @@ class RecycleBinApiController extends ApiController
         });
     }
 
+    /**
+     * Get a top-level listing of the items in the recycle bin.
+     * Requires the permission to manage settings and restrictions.
+     */
     public function list()
     {
-        return $this->apiListingResponse(Deletion::query(), [
+        return $this->apiListingResponse(Deletion::query()->with('deletable'), [
             'id',
             'deleted_by',
             'created_at',
@@ -32,6 +38,10 @@ class RecycleBinApiController extends ApiController
         ], [Closure::fromCallable([$this, 'listFormatter'])]);
     }
 
+    /**
+     * Restore a single deletion from the recycle bin.
+     * You must provide the deletion id, not the id of the corresponding deleted item.
+     */
     public function restore(DeletionRepo $deletionRepo, string $id)
     {
         $restoreCount = $deletionRepo->restore((int) $id);
@@ -39,6 +49,11 @@ class RecycleBinApiController extends ApiController
         return response()->json(['restore_count' => $restoreCount]);
     }
 
+    /**
+     * Remove a single deletion from the recycle bin.
+     * Use this endpoint carefully as it will entirely remove the underlying deleted items from the system.
+     * You must provide the deletion id, not the id of the corresponding deleted item.
+     */
     public function destroy(DeletionRepo $deletionRepo, string $id)
     {
         $deleteCount = $deletionRepo->destroy((int) $id);
@@ -48,23 +63,26 @@ class RecycleBinApiController extends ApiController
 
     protected function listFormatter(Deletion $deletion)
     {
+        $deletion->makeVisible($this->fieldsToExpose);
+        $deletion->makeHidden('deletable');
+
         $deletable = $deletion->deletable;
-        $isBook = $deletable instanceof Book;
+        $isBook = $deletion->deletable_type === "BookStack\Book";
         $parent = null;
         $children = null;
 
         if ($isBook) {
-            $chapterCount = $deletable->chapters()->withTrashed()->count();       
-            $children['Bookstack\Chapter'] = $chapterCount;
+            $chapterCount = $deletable->chapters()->withTrashed()->count();
+            $children['BookStack\Chapter'] = $chapterCount;
         }
 
-        if ($isBook || $deletion->deletable instanceof Chapter) {
-            $pageCount = $deletable->pages()->withTrashed()->count();     
-            $children['Bookstack\Page'] = $pageCount;
+        if ($isBook || $deletion->deletable_type === "BookStack\Chapter") {
+            $pageCount = $deletable->pages()->withTrashed()->count();
+            $children['BookStack\Page'] = $pageCount;
         }
 
         $parentEntity = $deletable->getParent();
-        $parent = [];
+        $parent = null;
 
         if ($parentEntity) {
             $parent['type'] = $parentEntity->getMorphClass();
diff --git a/dev/api/responses/recycle_bin-destroy.json b/dev/api/responses/recycle_bin-destroy.json
new file mode 100644 (file)
index 0000000..21cfc40
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "delete_count": 2
+}
\ No newline at end of file
diff --git a/dev/api/responses/recycle_bin-list.json b/dev/api/responses/recycle_bin-list.json
new file mode 100644 (file)
index 0000000..025cc98
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "data": [
+    {
+      "id": 25,
+      "deleted_by": 1,
+      "created_at": "2022-04-24T07:59:34.000000Z",
+      "updated_at": "2022-04-24T07:59:34.000000Z",
+      "deletable_type": "BookStack\\Book",
+      "deletable_id": 4,
+      "parent": {
+        "type": "BookStack\\Book",
+        "id": 25
+      },
+      "children": {
+        "BookStack\\Chapter": 0,
+        "BookStack\\Page": 1
+      }
+    },
+    {
+      "id": 26,
+      "deleted_by": 1,
+      "created_at": "2022-04-24T07:59:35.000000Z",
+      "updated_at": "2022-04-24T07:59:35.000000Z",
+      "deletable_type": "BookStack\\Book",
+      "deletable_id": 3,
+      "parent": [],
+      "children": {
+        "BookStack\\Chapter": 1,
+        "BookStack\\Page": 1
+      }
+    }
+  ],
+  "total": 2
+}
\ No newline at end of file
diff --git a/dev/api/responses/recycle_bin-restore.json b/dev/api/responses/recycle_bin-restore.json
new file mode 100644 (file)
index 0000000..ac5c948
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "restore_count": 2
+}
\ No newline at end of file
index 28622789642fbb9608c222339c318dcc8dcb0c3e..4849080b9489902bd90bb8cb3ce691ae92b79570 100644 (file)
@@ -33,12 +33,12 @@ class RecycleBinApiTest extends TestCase
         }
     }
 
-    public function test_restrictions_manage_all_permission_neeed_for_all_endpoints()
+    public function test_restrictions_manage_all_permission_needed_for_all_endpoints()
     {
         $editor = $this->getEditor();
         $this->giveUserPermissions($editor, ['restrictions-manage-all']);
         $this->actingAs($editor);
-        
+
         foreach ($this->endpointMap as [$method, $uri]) {
             $resp = $this->json($method, $uri);
             $resp->assertStatus(403);
@@ -74,7 +74,7 @@ class RecycleBinApiTest extends TestCase
             });
 
         $resp->assertJson([
-            'data' => $expectedData->values()->all(), 
+            'data'  => $expectedData->values()->all(),
             'total' => 2,
         ]);
     }
@@ -82,7 +82,7 @@ class RecycleBinApiTest extends TestCase
     public function test_index_endpoint_returns_children()
     {
         $this->actingAsAuthorizedUser();
-        
+
         $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first();
         $editor = $this->getEditor();
         $this->actingAs($editor)->delete($book->getUrl());
@@ -100,15 +100,15 @@ class RecycleBinApiTest extends TestCase
                 'deletable_type'    => $book->getMorphClass(),
                 'deletable_id'      => $book->getKey(),
                 'children'          => [
-                    'Bookstack\Page'    => $book->pages_count,
-                    'Bookstack\Chapter' => $book->chapters_count,
+                    'BookStack\Page'    => $book->pages_count,
+                    'BookStack\Chapter' => $book->chapters_count,
                 ],
                 'parent' => null,
-            ]
+            ],
         ];
 
         $resp->assertJson([
-            'data' => $expectedData, 
+            'data'  => $expectedData,
             'total' => 1,
         ]);
     }
@@ -136,22 +136,22 @@ class RecycleBinApiTest extends TestCase
                 'deletable_id'      => $page->getKey(),
                 'parent'            => [
                     'type'  => 'BookStack\Chapter',
-                    'id'    => $page->chapter->getKey()
+                    'id'    => $page->chapter->getKey(),
                 ],
                 'children' => null,
-            ]
+            ],
         ];
 
         $resp->assertJson([
-            'data' => $expectedData, 
-            'total' => 1
+            'data'  => $expectedData,
+            'total' => 1,
         ]);
     }
 
     public function test_restore_endpoint()
     {
         $this->actingAsAuthorizedUser();
-        
+
         $page = Page::query()->first();
         $editor = $this->getEditor();
         $this->actingAs($editor)->delete($page->getUrl());
@@ -160,22 +160,22 @@ class RecycleBinApiTest extends TestCase
         $deletion = Deletion::query()->orderBy('id')->first();
 
         $this->assertDatabaseHas('pages', [
-            'id' => $page->getKey(),
-            'deleted_at' => $page->deleted_at,
+            'id'            => $page->getKey(),
+            'deleted_at'    => $page->deleted_at,
         ]);
 
         $this->putJson($this->baseEndpoint . '/' . $deletion->getKey());
 
         $this->assertDatabaseHas('pages', [
-            'id' => $page->getKey(),
-            'deleted_at' => null,
+            'id'            => $page->getKey(),
+            'deleted_at'    => null,
         ]);
     }
 
     public function test_destroy_endpoint()
     {
         $this->actingAsAuthorizedUser();
-        
+
         $page = Page::query()->first();
         $editor = $this->getEditor();
         $this->actingAs($editor)->delete($page->getUrl());
@@ -184,8 +184,8 @@ class RecycleBinApiTest extends TestCase
         $deletion = Deletion::query()->orderBy('id')->first();
 
         $this->assertDatabaseHas('pages', [
-            'id' => $page->getKey(),
-            'deleted_at' => $page->deleted_at,
+            'id'            => $page->getKey(),
+            'deleted_at'    => $page->deleted_at,
         ]);
 
         $this->deleteJson($this->baseEndpoint . '/' . $deletion->getKey());