Files
landing-api/app/Http/Controllers/Api/V1/ApplicationController.php
2026-09-30 19:42:59 +02:00

105 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Enums\ApplicationStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V1\ApplicationRequest;
use App\Http\Resources\ApplicationResource;
use App\Models\Application;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
/**
* The inbox: what people sent from the public site.
*
* Nothing is created here — submissions arrive through the public API — and
* what can be changed is what the panel changes: the status and the private
* notes.
*/
class ApplicationController extends Controller
{
protected const WITH = ['call', 'handler'];
/**
* Filters: status, kind, call_id, search (name, e-mail or organisation), trashed.
*
* Spam stays out unless asked for by `status=spam`, as in the panel.
*/
public function index(Request $request): AnonymousResourceCollection
{
$this->authorize('viewAny', Application::class);
$applications = Application::query()
->with(self::WITH)
->when(
$request->filled('status'),
fn ($q) => $q->where('status', $request->string('status')),
fn ($q) => $q->notSpam(),
)
->when($request->filled('kind'), fn ($q) => $q->where('kind', $request->string('kind')))
->when($request->filled('call_id'), fn ($q) => $q->where('call_id', $request->integer('call_id')))
->when($request->filled('search'), function ($q) use ($request): void {
$term = '%'.$request->string('search').'%';
$q->where(fn ($q) => $q
->where('name', 'like', $term)
->orWhere('email', 'like', $term)
->orWhere('organisation', 'like', $term));
})
->when($request->boolean('trashed'), fn ($q) => $q->onlyTrashed())
->latest()
->paginate(perPage: min($request->integer('per_page', 25), 100))
->withQueryString();
return ApplicationResource::collection($applications);
}
public function show(Application $application): ApplicationResource
{
$this->authorize('view', $application);
return ApplicationResource::make($application->load(self::WITH));
}
public function update(ApplicationRequest $request, Application $application): ApplicationResource
{
$this->authorize('update', $application);
$data = $request->validated();
// Notes are outside the model's fillable list so the public form can
// never reach them; this is the one other place that writes them.
if (array_key_exists('notes', $data)) {
$application->forceFill(['notes' => $data['notes']])->save();
}
if (isset($data['status'])) {
$application->markAs(ApplicationStatus::from($data['status']), $request->user());
}
return ApplicationResource::make($application->load(self::WITH));
}
public function destroy(Application $application): JsonResponse
{
$this->authorize('delete', $application);
$application->delete();
return response()->json(status: 204);
}
public function restore(Application $application): ApplicationResource
{
$this->authorize('restore', $application);
$application->restore();
return ApplicationResource::make($application->load(self::WITH));
}
}