mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-30 12:43:43 +08:00
108 lines
2.8 KiB
PHP
108 lines
2.8 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace BookStack\Api;
|
||
|
|
||
|
use BookStack\Entities\Models\Entity;
|
||
|
|
||
|
class ApiEntityListFormatter
|
||
|
{
|
||
|
/**
|
||
|
* The list to be formatted.
|
||
|
* @var Entity[]
|
||
|
*/
|
||
|
protected $list = [];
|
||
|
|
||
|
/**
|
||
|
* The fields to show in the formatted data.
|
||
|
* Can be a plain string array item for a direct model field (If existing on model).
|
||
|
* If the key is a string, with a callable value, the return value of the callable
|
||
|
* will be used for the resultant value. A null return value will omit the property.
|
||
|
* @var array<string|int, string|callable>
|
||
|
*/
|
||
|
protected $fields = [
|
||
|
'id', 'name', 'slug', 'book_id', 'chapter_id',
|
||
|
'draft', 'template', 'created_at', 'updated_at',
|
||
|
];
|
||
|
|
||
|
public function __construct(array $list)
|
||
|
{
|
||
|
$this->list = $list;
|
||
|
|
||
|
// Default dynamic fields
|
||
|
$this->withField('url', fn(Entity $entity) => $entity->getUrl());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a field to be used in the formatter, with the property using the given
|
||
|
* name and value being the return type of the given callback.
|
||
|
*/
|
||
|
public function withField(string $property, callable $callback): self
|
||
|
{
|
||
|
$this->fields[$property] = $callback;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Show the 'type' property in the response reflecting the entity type.
|
||
|
* EG: page, chapter, bookshelf, book
|
||
|
* To be included in results with non-pre-determined types.
|
||
|
*/
|
||
|
public function withType(): self
|
||
|
{
|
||
|
$this->withField('type', fn(Entity $entity) => $entity->getType());
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Include tags in the formatted data.
|
||
|
*/
|
||
|
public function withTags(): self
|
||
|
{
|
||
|
$this->withField('tags', fn(Entity $entity) => $entity->tags);
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Format the data and return an array of formatted content.
|
||
|
* @return array[]
|
||
|
*/
|
||
|
public function format(): array
|
||
|
{
|
||
|
$results = [];
|
||
|
|
||
|
foreach ($this->list as $item) {
|
||
|
$results[] = $this->formatSingle($item);
|
||
|
}
|
||
|
|
||
|
return $results;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Format a single entity item to a plain array.
|
||
|
*/
|
||
|
protected function formatSingle(Entity $entity): array
|
||
|
{
|
||
|
$result = [];
|
||
|
$values = (clone $entity)->toArray();
|
||
|
|
||
|
foreach ($this->fields as $field => $callback) {
|
||
|
if (is_string($callback)) {
|
||
|
$field = $callback;
|
||
|
if (!isset($values[$field])) {
|
||
|
continue;
|
||
|
}
|
||
|
$value = $values[$field];
|
||
|
} else {
|
||
|
$value = $callback($entity);
|
||
|
if (is_null($value)) {
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$result[$field] = $value;
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
}
|