3 namespace BookStack\Api;
5 use BookStack\Entities\Models\BookChild;
6 use BookStack\Entities\Models\Entity;
7 use BookStack\Entities\Models\Page;
9 class ApiEntityListFormatter
12 * The list to be formatted.
15 protected array $list = [];
18 * The fields to show in the formatted data.
19 * Can be a plain string array item for a direct model field (If existing on model).
20 * If the key is a string, with a callable value, the return value of the callable
21 * will be used for the resultant value. A null return value will omit the property.
22 * @var array<string|int, string|callable>
24 protected array $fields = [
37 public function __construct(array $list)
41 // Default dynamic fields
42 $this->withField('url', fn(Entity $entity) => $entity->getUrl());
46 * Add a field to be used in the formatter, with the property using the given
47 * name and value being the return type of the given callback.
49 public function withField(string $property, callable $callback): self
51 $this->fields[$property] = $callback;
56 * Show the 'type' property in the response reflecting the entity type.
57 * EG: page, chapter, bookshelf, book
58 * To be included in results with non-pre-determined types.
60 public function withType(): self
62 $this->withField('type', fn(Entity $entity) => $entity->getType());
67 * Include tags in the formatted data.
69 public function withTags(): self
71 $this->withField('tags', fn(Entity $entity) => $entity->tags);
76 * Include parent book/chapter info in the formatted data.
78 public function withParents(): self
80 $this->withField('book', function (Entity $entity) {
81 if ($entity instanceof BookChild && $entity->book) {
82 return $entity->book->only(['id', 'name', 'slug']);
87 $this->withField('chapter', function (Entity $entity) {
88 if ($entity instanceof Page && $entity->chapter) {
89 return $entity->chapter->only(['id', 'name', 'slug']);
98 * Format the data and return an array of formatted content.
101 public function format(): array
105 foreach ($this->list as $item) {
106 $results[] = $this->formatSingle($item);
113 * Format a single entity item to a plain array.
115 protected function formatSingle(Entity $entity): array
118 $values = (clone $entity)->toArray();
120 foreach ($this->fields as $field => $callback) {
121 if (is_string($callback)) {
123 if (!isset($values[$field])) {
126 $value = $values[$field];
128 $value = $callback($entity);
129 if (is_null($value)) {
134 $result[$field] = $value;