]> BookStack Code Mirror - bookstack/blob - app/Api/ApiEntityListFormatter.php
add tests for priority
[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         'priority'
26     ];
27
28     public function __construct(array $list)
29     {
30         $this->list = $list;
31
32         // Default dynamic fields
33         $this->withField('url', fn(Entity $entity) => $entity->getUrl());
34     }
35
36     /**
37      * Add a field to be used in the formatter, with the property using the given
38      * name and value being the return type of the given callback.
39      */
40     public function withField(string $property, callable $callback): self
41     {
42         $this->fields[$property] = $callback;
43         return $this;
44     }
45
46     /**
47      * Show the 'type' property in the response reflecting the entity type.
48      * EG: page, chapter, bookshelf, book
49      * To be included in results with non-pre-determined types.
50      */
51     public function withType(): self
52     {
53         $this->withField('type', fn(Entity $entity) => $entity->getType());
54         return $this;
55     }
56
57     /**
58      * Include tags in the formatted data.
59      */
60     public function withTags(): self
61     {
62         $this->withField('tags', fn(Entity $entity) => $entity->tags);
63         return $this;
64     }
65
66     /**
67      * Format the data and return an array of formatted content.
68      * @return array[]
69      */
70     public function format(): array
71     {
72         $results = [];
73
74         foreach ($this->list as $item) {
75             $results[] = $this->formatSingle($item);
76         }
77
78         return $results;
79     }
80
81     /**
82      * Format a single entity item to a plain array.
83      */
84     protected function formatSingle(Entity $entity): array
85     {
86         $result = [];
87         $values = (clone $entity)->toArray();
88
89         foreach ($this->fields as $field => $callback) {
90             if (is_string($callback)) {
91                 $field = $callback;
92                 if (!isset($values[$field])) {
93                     continue;
94                 }
95                 $value = $values[$field];
96             } else {
97                 $value = $callback($entity);
98                 if (is_null($value)) {
99                     continue;
100                 }
101             }
102
103             $result[$field] = $value;
104         }
105
106         return $result;
107     }
108 }