Files
moonwell-web/app/Http/Controllers/LandingController.php
T

180 lines
7.0 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Exceptions\DuplicateGameAccountException;
use App\Exceptions\InviteCodeException;
use App\Http\Requests\RegisterGameAccountRequest;
use App\Models\News;
use App\Services\AzerothCoreAccountRegistrar;
use App\Services\AzerothCoreAccountService;
use App\Services\InviteCodeService;
use App\Services\NewsService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;
use Throwable;
class LandingController extends Controller
{
public function index(
Request $request,
AzerothCoreAccountService $accounts,
NewsService $news,
): Response {
$realmConfig = config('moonwell.realm');
$rates = $realmConfig['rates'] ?? [];
$user = Auth::user();
$playersOnline = $accounts->onlinePlayerCount();
$realmName = $this->canonicalMoonWellName($realmConfig['realm_name'] ?? null);
$serverName = $this->canonicalMoonWellName($realmConfig['server_name'] ?? null);
$playUrl = $user !== null
? route('cabinet.client')
: '#join';
try {
$posts = $news->listForLanding()
->values()
->map(fn (News $item, int $index): array => [
'id' => $item->id,
'title' => $item->title,
'excerpt' => Str::limit(trim(strip_tags($item->body)), 200),
'date' => $item->created_at?->locale(app()->getLocale())->isoFormat('D MMMM YYYY'),
'tag' => 'Новости',
'tagType' => 'patch',
'image_url' => $item->image_url,
'featured' => $index === 0,
'url' => route('news.show', $item),
])
->all();
} catch (Throwable $exception) {
report($exception);
$posts = [];
}
$bootstrap = [
'realm' => [
'name' => $realmName,
'mode' => sprintf('PvE · %s rate · RU', $rates['experience'] ?? 'x1'),
'realmlist' => $realmConfig['realmlist'],
'online' => $playersOnline !== null,
'players' => $playersOnline,
'uptime' => '99.94%',
'ping' => 38,
'factions' => ['alliance' => 52, 'horde' => 48],
'rates' => $rates,
'client_version' => $realmConfig['client_version'] ?? '3.3.5a',
'tagline' => $realmConfig['tagline'] ?? null,
'server_name' => $serverName,
],
'playUrl' => $playUrl,
'posts' => $posts,
'newsIndexUrl' => route('news.index'),
'tweaks' => [
'variant' => 'forest',
'particles' => true,
'moon' => true,
],
'registerEndpoint' => route('game-account.store'),
'legalUrls' => [
'published' => (bool) config('moonwell.legal.published'),
'offer' => config('moonwell.legal.published') ? route('legal.offer') : null,
'privacy' => config('moonwell.legal.published') ? route('legal.privacy') : null,
],
'inviteRequired' => (bool) config('moonwell.registration.require_invite_code'),
'csrfToken' => csrf_token(),
'auth' => [
'authenticated' => $user !== null,
'is_admin' => $user?->canAccessAdminPanel() ?? false,
'username' => $user?->username,
'login_url' => route('login'),
'cabinet_url' => route('cabinet.index'),
'admin_url' => route('admin.accounts.index'),
],
'flash' => [
'success' => $request->session()->get('registration_success'),
'success_username' => $request->session()->get('registration_username'),
'error' => $request->session()->get('registration_error'),
'errors' => $this->errorBag(),
'old' => $request->session()->getOldInput() ? [
'username' => $request->session()->getOldInput('username'),
'email' => $request->session()->getOldInput('email'),
'invite_code' => $request->session()->getOldInput('invite_code'),
] : [],
],
];
return Inertia::render('Landing/Main', $bootstrap);
}
public function register(
RegisterGameAccountRequest $request,
AzerothCoreAccountRegistrar $registrar,
InviteCodeService $inviteCodes,
): RedirectResponse {
try {
$register = fn (): array => $registrar->register(
$request->string('username')->toString(),
$request->string('email')->toString(),
$request->string('password')->toString(),
);
$result = config('moonwell.registration.require_invite_code')
? $inviteCodes->redeemForRegistration(
$request->string('invite_code')->toString(),
$request->string('username')->toString(),
$register,
)
: $register();
} catch (DuplicateGameAccountException $exception) {
return back()
->withErrors([$exception->field => $exception->getMessage()])
->withInput($request->safe()->only(['username', 'email', 'invite_code']));
} catch (InviteCodeException $exception) {
return back()
->withErrors([$exception->field => $exception->getMessage()])
->withInput($request->safe()->only(['username', 'email', 'invite_code']));
} catch (Throwable $exception) {
report($exception);
return back()
->with('registration_error', 'Не удалось создать аккаунт. Проверь настройки сервера и попробуй снова.')
->withInput($request->safe()->only(['username', 'email', 'invite_code']));
}
return redirect()
->route('landing.index')
->with('registration_success', sprintf('Игровой аккаунт %s успешно создан. Теперь можно входить в клиент WoW.', $result['username']))
->with('registration_username', $result['username']);
}
/**
* @return array<string, array<int, string>>
*/
private function errorBag(): array
{
$errors = session()->get('errors');
if (! $errors) {
return [];
}
$bag = method_exists($errors, 'getBag') ? $errors->getBag('default') : $errors;
return method_exists($bag, 'toArray') ? $bag->toArray() : [];
}
private function canonicalMoonWellName(?string $name): string
{
if ($name === null || strcasecmp($name, 'MoonWell') === 0) {
return 'MoonWell';
}
return $name;
}
}