Manage redirects, missing URLs, repositories and settings through the API
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
95
app/Http/Controllers/Api/V1/MissingUrlController.php
Normal file
95
app/Http/Controllers/Api/V1/MissingUrlController.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user