I api responses misc methods
This commit is contained in:
parent
e2c663522c
commit
aa51e0aa27
|
|
@ -114,6 +114,143 @@ class MiscService
|
|||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Available content languages for the running app.
|
||||
*
|
||||
* Tries (in order):
|
||||
* 1. config('languages.languages') — Blax convention, list of {code, ...}
|
||||
* 2. config('app.available_locales') — plain array of codes
|
||||
* 3. fall back to [app()->getLocale()]
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function availableLanguages(): array
|
||||
{
|
||||
$configured = config('languages.languages');
|
||||
if (is_array($configured) && $configured) {
|
||||
return collect($configured)
|
||||
->map(fn($l) => is_array($l) ? ($l['code'] ?? $l['lang'] ?? null) : $l)
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
$locales = config('app.available_locales');
|
||||
if (is_array($locales) && $locales) {
|
||||
return array_values($locales);
|
||||
}
|
||||
|
||||
return [app()->getLocale()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard meta block for an API response.
|
||||
*
|
||||
* Every api response in the workkit-shaped envelope carries this block
|
||||
* so consumers always know:
|
||||
* - which URL produced the payload (`url`)
|
||||
* - which locale they got back (`locale`)
|
||||
* - which other locales the same resource is available in (`languages`)
|
||||
*
|
||||
* Pagination keys (current_page, total, total_pages, etc.) are merged in
|
||||
* by `apiPaginated()`; `apiItem()` / `apiCollection()` skip them.
|
||||
*/
|
||||
public static function apiMeta(array $extra = []): array
|
||||
{
|
||||
return array_merge([
|
||||
'url' => optional(request())->fullUrl(),
|
||||
'locale' => app()->getLocale(),
|
||||
'languages' => self::availableLanguages(),
|
||||
], $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginated API envelope. Use for any list/index endpoint.
|
||||
*
|
||||
* Returns:
|
||||
* {
|
||||
* "data": [...resource collection...],
|
||||
* "meta": {
|
||||
* "url", "locale", "languages",
|
||||
* "current_page", "per_page", "from", "to",
|
||||
* "total", "total_pages", "has_more"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public static function apiPaginated(
|
||||
$paginated,
|
||||
string $resource_class,
|
||||
array $extraMeta = []
|
||||
): array {
|
||||
$arr = method_exists($paginated, 'toArray') ? $paginated->toArray() : [];
|
||||
|
||||
$current = $arr['current_page'] ?? 1;
|
||||
$last = $arr['last_page'] ?? null;
|
||||
|
||||
$pagination = [
|
||||
'current_page' => $current,
|
||||
'per_page' => $arr['per_page'] ?? null,
|
||||
'from' => $arr['from'] ?? null,
|
||||
'to' => $arr['to'] ?? null,
|
||||
'total' => $arr['total'] ?? null,
|
||||
'total_pages' => $last,
|
||||
'has_more' => ($last !== null) ? ($current < $last) : false,
|
||||
];
|
||||
|
||||
return [
|
||||
'data' => $resource_class::collection($paginated),
|
||||
'meta' => self::apiMeta(array_merge($pagination, $extraMeta)),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Single-item API envelope. Use for any show endpoint.
|
||||
*/
|
||||
public static function apiItem(
|
||||
$item,
|
||||
?string $resource_class = null,
|
||||
array $extraMeta = []
|
||||
): array {
|
||||
return [
|
||||
'data' => $resource_class ? $resource_class::make($item) : $item,
|
||||
'meta' => self::apiMeta($extraMeta),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-paginated collection envelope. Use only when pagination is
|
||||
* impractical (tiny fixed list like an enum or a child collection of a
|
||||
* parent show response). Most list endpoints should use apiPaginated().
|
||||
*/
|
||||
public static function apiCollection(
|
||||
$items,
|
||||
string $resource_class,
|
||||
array $extraMeta = []
|
||||
): array {
|
||||
$count = is_countable($items) ? count($items) : null;
|
||||
|
||||
return [
|
||||
'data' => $resource_class::collection($items),
|
||||
'meta' => self::apiMeta(array_merge([
|
||||
'total' => $count,
|
||||
], $extraMeta)),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Plain envelope (data + meta) for arbitrary payloads — login responses,
|
||||
* action acknowledgements, etc. Always carries the standard apiMeta block.
|
||||
*/
|
||||
public static function apiResponse(
|
||||
mixed $data = null,
|
||||
array $extraMeta = []
|
||||
): array {
|
||||
return [
|
||||
'data' => $data,
|
||||
'meta' => self::apiMeta($extraMeta),
|
||||
];
|
||||
}
|
||||
|
||||
public static function bytesToHuman($bytes)
|
||||
{
|
||||
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
|
|
|
|||
Loading…
Reference in New Issue