- Adds Character model with survival needs (hunger, thirst, energy) and state machine - Implements city:tick world ticker for offline progression every minute - Adds city territory expansion and building construction system - Introduces job economy, inventory, and transaction audit trail - Adds social graph (friends, marriage, children) and character chat - Implements admin approval workflow for new registrations - Adds hospital admission system for traffic accidents - Includes comprehensive feature tests and world seeders
121 lines
3.6 KiB
PHP
Executable File
121 lines
3.6 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Http\Controllers\Web;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\ConsentRequest;
|
|
use App\Models\LegalDocument;
|
|
use App\Models\UserConsent;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\View\View;
|
|
|
|
/**
|
|
* Web controllers for legal documents and consent management.
|
|
*
|
|
* Renders the Terms of Use, Privacy Policy and Cookie Policy and records
|
|
* the auditable acceptance required by the Brazilian LGPD before the
|
|
* user can access the main platform features.
|
|
*/
|
|
class LegalController extends Controller
|
|
{
|
|
/**
|
|
* Show the current version of a legal document.
|
|
*/
|
|
public function show(string $type): View
|
|
{
|
|
$document = LegalDocument::query()
|
|
->where('type', $type)
|
|
->where('is_current', true)
|
|
->firstOrFail();
|
|
|
|
$locale = app()->getLocale();
|
|
|
|
return view('legal.show', [
|
|
'document' => $document,
|
|
'title' => $document->title[$locale] ?? ($document->title['pt_BR'] ?? $document->type),
|
|
'body' => $document->body[$locale] ?? ($document->body['pt_BR'] ?? ''),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Show the first-access terms acceptance screen.
|
|
*/
|
|
public function acceptForm(Request $request): View|RedirectResponse
|
|
{
|
|
$user = $request->user();
|
|
|
|
$current = LegalDocument::query()->where('is_current', true)->orderBy('type')->get();
|
|
|
|
if ($current->isEmpty()) {
|
|
return redirect()->route('dashboard');
|
|
}
|
|
|
|
$acceptedIds = $user->consents()->pluck('legal_document_id');
|
|
$pending = $current->reject(fn (LegalDocument $doc) => $acceptedIds->contains($doc->id));
|
|
|
|
if ($pending->isEmpty()) {
|
|
return redirect()->route('dashboard');
|
|
}
|
|
|
|
$locale = app()->getLocale();
|
|
|
|
$documents = $pending->map(fn (LegalDocument $doc): array => [
|
|
'type' => $doc->type,
|
|
'version' => $doc->version,
|
|
'title' => $doc->title[$locale] ?? ($doc->title['pt_BR'] ?? $doc->type),
|
|
'body' => $doc->body[$locale] ?? ($doc->body['pt_BR'] ?? ''),
|
|
])->values();
|
|
|
|
return view('legal.accept', [
|
|
'documents' => $documents,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Record the acceptance of all current legal documents.
|
|
*/
|
|
public function accept(ConsentRequest $request): RedirectResponse
|
|
{
|
|
$user = $request->user();
|
|
|
|
$documents = LegalDocument::query()->where('is_current', true)->get();
|
|
|
|
DB::transaction(function () use ($user, $documents, $request): void {
|
|
foreach ($documents as $document) {
|
|
UserConsent::updateOrCreate(
|
|
[
|
|
'user_id' => $user->id,
|
|
'legal_document_id' => $document->id,
|
|
],
|
|
[
|
|
'accepted_at' => now(),
|
|
'ip_address' => $request->ip(),
|
|
'user_agent' => (string) $request->userAgent(),
|
|
'source' => 'web_form',
|
|
],
|
|
);
|
|
}
|
|
});
|
|
|
|
return redirect()->route('dashboard')->with('status', __('legal.accepted'));
|
|
}
|
|
|
|
/**
|
|
* Display the consent audit history of the authenticated user.
|
|
*/
|
|
public function history(Request $request): View
|
|
{
|
|
$history = $request->user()
|
|
->consents()
|
|
->with('document:id,type,version')
|
|
->orderByDesc('accepted_at')
|
|
->get();
|
|
|
|
return view('legal.history', [
|
|
'history' => $history,
|
|
]);
|
|
}
|
|
}
|