namespace BookStack\Api;
use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Models\Page;
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)
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) {
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.
*/