80 lines
2.6 KiB
PHP
80 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Resources\ArtworkResource;
|
|
use App\Models\Artwork;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Str;
|
|
|
|
class ArtworkNavigationController extends Controller
|
|
{
|
|
/**
|
|
* GET /api/artworks/navigation/{id}
|
|
*
|
|
* Returns prev/next published artworks by the same author.
|
|
*/
|
|
public function neighbors(int $id): JsonResponse
|
|
{
|
|
$artwork = Artwork::published()
|
|
->select(['id', 'user_id', 'title', 'slug'])
|
|
->find($id);
|
|
|
|
if (! $artwork) {
|
|
return response()->json([
|
|
'prev_id' => null, 'next_id' => null,
|
|
'prev_url' => null, 'next_url' => null,
|
|
'prev_slug' => null, 'next_slug' => null,
|
|
]);
|
|
}
|
|
|
|
$scope = Artwork::published()
|
|
->select(['id', 'title', 'slug'])
|
|
->where('user_id', $artwork->user_id);
|
|
|
|
$prev = (clone $scope)->where('id', '<', $id)->orderByDesc('id')->first();
|
|
$next = (clone $scope)->where('id', '>', $id)->orderBy('id')->first();
|
|
|
|
// Infinite loop: wrap around when reaching the first or last artwork
|
|
if (! $prev) {
|
|
$prev = (clone $scope)->where('id', '!=', $id)->orderByDesc('id')->first();
|
|
}
|
|
if (! $next) {
|
|
$next = (clone $scope)->where('id', '!=', $id)->orderBy('id')->first();
|
|
}
|
|
|
|
$prevSlug = $prev ? (Str::slug($prev->slug ?: $prev->title) ?: (string) $prev->id) : null;
|
|
$nextSlug = $next ? (Str::slug($next->slug ?: $next->title) ?: (string) $next->id) : null;
|
|
|
|
return response()->json([
|
|
'prev_id' => $prev?->id,
|
|
'next_id' => $next?->id,
|
|
'prev_url' => $prev ? url('/art/' . $prev->id . '/' . $prevSlug) : null,
|
|
'next_url' => $next ? url('/art/' . $next->id . '/' . $nextSlug) : null,
|
|
'prev_slug' => $prevSlug,
|
|
'next_slug' => $nextSlug,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* GET /api/artworks/{id}/page
|
|
*
|
|
* Returns full artwork resource by numeric ID for client-side (no-reload) navigation.
|
|
*/
|
|
public function pageData(int $id): JsonResponse
|
|
{
|
|
$artwork = Artwork::with(['user.profile', 'categories.contentType', 'categories.parent.contentType', 'tags', 'stats'])
|
|
->published()
|
|
->find($id);
|
|
|
|
if (! $artwork) {
|
|
return response()->json(['error' => 'Not found'], 404);
|
|
}
|
|
|
|
$resource = (new ArtworkResource($artwork))->toArray(request());
|
|
|
|
return response()->json($resource);
|
|
}
|
|
}
|