]> BookStack Code Mirror - bookstack/blob - app/Api/ApiEntityListFormatter.php
Added php8.2 to GH action checks
[bookstack] / app / Api / ApiEntityListFormatter.php
1 <?php
2
3 namespace BookStack\Api;
4
5 use BookStack\Entities\Models\Entity;
6
7 class ApiEntityListFormatter
8 {
9     /**
10      * The list to be formatted.
11      * @var Entity[]
12      */
13     protected $list = [];
14
15     /**
16      * The fields to show in the formatted data.
17      * Can be a plain string array item for a direct model field (If existing on model).
18      * If the key is a string, with a callable value, the return value of the callable
19      * will be used for the resultant value. A null return value will omit the property.
20      * @var array<string|int, string|callable>
21      */
22     protected $fields = [
23         'id', 'name', 'slug', 'book_id', 'chapter_id',
24         'draft', 'template', 'created_at', 'updated_at',
25     ];
26
27     public function __construct(array $list)
28     {
29         $this->list = $list;
30
31         // Default dynamic fields
32         $this->withField('url', fn(Entity $entity) => $entity->getUrl());
33     }
34
35     /**
36      * Add a field to be used in the formatter, with the property using the given
37      * name and value being the return type of the given callback.
38      */
39     public function withField(string $property, callable $callback): self
40     {
41         $this->fields[$property] = $callback;
42         return $this;
43     }
44
45     /**
46      * Show the 'type' property in the response reflecting the entity type.
47      * EG: page, chapter, bookshelf, book
48      * To be included in results with non-pre-determined types.
49      */
50     public function withType(): self
51     {
52         $this->withField('type', fn(Entity $entity) => $entity->getType());
53         return $this;
54     }
55
56     /**
57      * Include tags in the formatted data.
58      */
59     public function withTags(): self
60     {
61         $this->withField('tags', fn(Entity $entity) => $entity->tags);
62         return $this;
63     }
64
65     /**
66      * Format the data and return an array of formatted content.
67      * @return array[]
68      */
69     public function format(): array
70     {
71         $results = [];
72
73         foreach ($this->list as $item) {
74             $results[] = $this->formatSingle($item);
75         }
76
77         return $results;
78     }
79
80     /**
81      * Format a single entity item to a plain array.
82      */
83     protected function formatSingle(Entity $entity): array
84     {
85         $result = [];
86         $values = (clone $entity)->toArray();
87
88         foreach ($this->fields as $field => $callback) {
89             if (is_string($callback)) {
90                 $field = $callback;
91                 if (!isset($values[$field])) {
92                     continue;
93                 }
94                 $value = $values[$field];
95             } else {
96                 $value = $callback($entity);
97                 if (is_null($value)) {
98                     continue;
99                 }
100             }
101
102             $result[$field] = $value;
103         }
104
105         return $result;
106     }
107 }