]> BookStack Code Mirror - bookstack/blobdiff - app/Api/ApiEntityListFormatter.php
respective book and chapter structure added.
[bookstack] / app / Api / ApiEntityListFormatter.php
index 436d66d598e8f2fb86fc27622f9016900b2a7c8e..7c2d09d4f3aa3dfe46ae02ba1614d1e69f1d4e16 100644 (file)
@@ -3,6 +3,7 @@
 namespace BookStack\Api;
 
 use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Models\Page;
 
 class ApiEntityListFormatter
 {
@@ -20,8 +21,16 @@ class ApiEntityListFormatter
      * @var array<string|int, string|callable>
      */
     protected array $fields = [
-        'id', 'name', 'slug', 'book_id', 'chapter_id', 'draft',
-        'template', 'priority', 'created_at', 'updated_at',
+        'id',
+        'name',
+        'slug',
+        'book_id',
+        'chapter_id',
+        'draft',
+        'template',
+        'priority',
+        'created_at',
+        'updated_at',
     ];
 
     public function __construct(array $list)
@@ -62,12 +71,36 @@ class ApiEntityListFormatter
         return $this;
     }
 
+    /**
+     * Enable the inclusion of related book and chapter titles in the response.
+     */
+    public function withRelatedData(): self
+    {
+        $this->withField('book', function (Entity $entity) {
+            if (method_exists($entity, 'book')) {
+                return $entity->book()->select(['id', 'name', 'slug'])->first();
+            }
+            return null;
+        });
+
+        $this->withField('chapter', function (Entity $entity) {
+            if ($entity instanceof Page && $entity->chapter_id) {
+                return $entity->chapter()->select(['id', 'name', 'slug'])->first();
+            }
+            return null;
+        });
+
+        return $this;
+    }
+
     /**
      * Format the data and return an array of formatted content.
      * @return array[]
      */
     public function format(): array
     {
+        $this->loadRelatedData();
+
         $results = [];
 
         foreach ($this->list as $item) {
@@ -77,6 +110,23 @@ class ApiEntityListFormatter
         return $results;
     }
 
+    /**
+     * Eager load the related book and chapter data when needed.
+     */
+    protected function loadRelatedData(): void
+    {
+        $pages = collect($this->list)->filter(fn($item) => $item instanceof Page);
+
+        foreach ($this->list as $entity) {
+            if (method_exists($entity, 'book')) {
+                $entity->load('book');
+            }
+            if ($entity instanceof Page && $entity->chapter_id) {
+                $entity->load('chapter');
+            }
+        }
+    }
+
     /**
      * Format a single entity item to a plain array.
      */