BookStack/app/Api/ListingResponseBuilder.php
2019-12-28 14:58:07 +00:00

83 lines
2.1 KiB
PHP

<?php namespace BookStack\Api;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
class ListingResponseBuilder
{
protected $query;
protected $fields;
/**
* ListingResponseBuilder constructor.
*/
public function __construct(Builder $query, array $fields)
{
$this->query = $query;
$this->fields = $fields;
}
/**
* Get the response from this builder.
*/
public function toResponse()
{
$total = $this->query->count();
$data = $this->fetchData();
return response()->json([
'data' => $data,
'total' => $total,
]);
}
/**
* Fetch the data to return in the response.
*/
protected function fetchData(): Collection
{
$this->applyCountAndOffset($this->query);
$this->applySorting($this->query);
// TODO - Apply filtering
return $this->query->get($this->fields);
}
/**
* Apply sorting operations to the query from given parameters
* otherwise falling back to the first given field, ascending.
*/
protected function applySorting(Builder $query)
{
$defaultSortName = $this->fields[0];
$direction = 'asc';
$sort = request()->get('sort', '');
if (strpos($sort, '-') === 0) {
$direction = 'desc';
}
$sortName = ltrim($sort, '+- ');
if (!in_array($sortName, $this->fields)) {
$sortName = $defaultSortName;
}
$query->orderBy($sortName, $direction);
}
/**
* Apply count and offset for paging, based on params from the request while falling
* back to system defined default, taking the max limit into account.
*/
protected function applyCountAndOffset(Builder $query)
{
$offset = max(0, request()->get('offset', 0));
$maxCount = config('api.max_item_count');
$count = request()->get('count', config('api.default_item_count'));
$count = max(min($maxCount, $count), 1);
$query->skip($offset)->take($count);
}
}