96 lines
3.1 KiB
PHP
96 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api\V1;
|
|
|
|
use App\Enums\MissingUrlStatus;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Api\V1\MissingUrlRedirectRequest;
|
|
use App\Http\Resources\MissingUrlResource;
|
|
use App\Http\Resources\RedirectResource;
|
|
use App\Models\MissingUrl;
|
|
use App\Models\Redirect;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
/**
|
|
* Addresses the public site was asked for and could not find, reported by the
|
|
* frontend. What can be done with one is what the panel does: ignore it, or
|
|
* give it a destination.
|
|
*/
|
|
class MissingUrlController extends Controller
|
|
{
|
|
/**
|
|
* Filters: status (pending by default), locale, search (path).
|
|
*/
|
|
public function index(Request $request): AnonymousResourceCollection
|
|
{
|
|
$this->authorize('viewAny', MissingUrl::class);
|
|
|
|
$missing = MissingUrl::query()
|
|
->where('status', $request->string('status', MissingUrlStatus::Pending->value))
|
|
->when($request->filled('locale'), fn ($q) => $q->where('locale', $request->string('locale')))
|
|
->when($request->filled('search'), fn ($q) => $q->where('path', 'like', '%'.$request->string('search').'%'))
|
|
->orderByDesc('hits')
|
|
->orderByDesc('last_seen_at')
|
|
->paginate(perPage: min($request->integer('per_page', 25), 100))
|
|
->withQueryString();
|
|
|
|
return MissingUrlResource::collection($missing);
|
|
}
|
|
|
|
public function show(MissingUrl $missingUrl): MissingUrlResource
|
|
{
|
|
$this->authorize('view', $missingUrl);
|
|
|
|
return MissingUrlResource::make($missingUrl);
|
|
}
|
|
|
|
/**
|
|
* Only between pending and ignored: `resolved` is what writing a redirect
|
|
* makes it, and claiming it without one would be a lie the next sighting
|
|
* undoes anyway.
|
|
*/
|
|
public function update(Request $request, MissingUrl $missingUrl): MissingUrlResource
|
|
{
|
|
$this->authorize('update', $missingUrl);
|
|
|
|
$data = $request->validate([
|
|
'status' => ['required', Rule::in([MissingUrlStatus::Pending->value, MissingUrlStatus::Ignored->value])],
|
|
]);
|
|
|
|
$missingUrl->update($data);
|
|
|
|
return MissingUrlResource::make($missingUrl);
|
|
}
|
|
|
|
public function destroy(MissingUrl $missingUrl): JsonResponse
|
|
{
|
|
$this->authorize('delete', $missingUrl);
|
|
|
|
$missingUrl->delete();
|
|
|
|
return response()->json(status: 204);
|
|
}
|
|
|
|
/**
|
|
* Give the address a destination. The report is marked resolved by the
|
|
* redirect being created, as from anywhere else.
|
|
*/
|
|
public function redirect(MissingUrlRedirectRequest $request, MissingUrl $missingUrl): JsonResponse
|
|
{
|
|
$this->authorize('redirect', $missingUrl);
|
|
|
|
$redirect = Redirect::create([
|
|
'from' => $missingUrl->path,
|
|
'is_enabled' => true,
|
|
...$request->validated(),
|
|
])->refresh();
|
|
|
|
return RedirectResource::make($redirect)->response()->setStatusCode(201);
|
|
}
|
|
}
|