]> BookStack Code Mirror - bookstack/blobdiff - app/Api/ApiEntityListFormatter.php
respective book and chapter structure added.
[bookstack] / app / Api / ApiEntityListFormatter.php
index 23fa8e6ea7249274759e5b4fa98cf49b27a50a8a..7c2d09d4f3aa3dfe46ae02ba1614d1e69f1d4e16 100644 (file)
@@ -13,11 +13,6 @@ class ApiEntityListFormatter
      */
     protected array $list = [];
 
-    /**
-     * Whether to include related titles in the response.
-     */
-    protected bool $includeRelatedTitles = false;
-
     /**
      * The fields to show in the formatted data.
      * Can be a plain string array item for a direct model field (If existing on model).
@@ -79,20 +74,18 @@ class ApiEntityListFormatter
     /**
      * Enable the inclusion of related book and chapter titles in the response.
      */
-    public function withRelatedTitles(): self
+    public function withRelatedData(): self
     {
-        $this->includeRelatedTitles = true;
-
-        $this->withField('book_title', function (Entity $entity) {
+        $this->withField('book', function (Entity $entity) {
             if (method_exists($entity, 'book')) {
-                return $entity->book?->name;
+                return $entity->book()->select(['id', 'name', 'slug'])->first();
             }
             return null;
         });
 
-        $this->withField('chapter_title', function (Entity $entity) {
+        $this->withField('chapter', function (Entity $entity) {
             if ($entity instanceof Page && $entity->chapter_id) {
-                return optional($entity->getAttribute('chapter'))->name;
+                return $entity->chapter()->select(['id', 'name', 'slug'])->first();
             }
             return null;
         });
@@ -106,6 +99,8 @@ class ApiEntityListFormatter
      */
     public function format(): array
     {
+        $this->loadRelatedData();
+
         $results = [];
 
         foreach ($this->list as $item) {
@@ -115,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.
      */