1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Libraries\User;
7
8use App\Exceptions\UserProfilePageLookupException;
9use App\Models\User;
10
11class FindForProfilePage
12{
13 public static function find($id, ?string $type = null, ?bool $assertCanonicalId = null)
14 {
15 $user = static::fromAuth($id, $type) ?? User::lookupWithHistory($id, $type, true);
16
17 if ($user === null || !priv_check('UserShow', $user)->can()) {
18 throw new UserProfilePageLookupException(function () {
19 if (is_json_request()) {
20 abort(404);
21 }
22
23 return ext_view('users.show_not_found', null, null, 404);
24 });
25 }
26
27 if (($assertCanonicalId ?? !is_json_request()) && (string) $user->getKey() !== (string) $id) {
28 $route = \Request::route();
29 $redirectTarget = route(
30 $route->getName(),
31 [
32 ...\Request::query(),
33 ...$route->parameters(),
34 'key' => null,
35 'user' => $user,
36 ],
37 );
38
39 throw new UserProfilePageLookupException(fn () => ujs_redirect($redirectTarget));
40 }
41
42 return $user;
43 }
44
45 private static function fromAuth($requestId, ?string $type): ?User
46 {
47 $user = \Auth::user();
48
49 if ($user === null) {
50 return null;
51 }
52
53 $userId = (string) $user->getKey();
54 $username = $user->username;
55 $isSelf = match ($type) {
56 'id' => $requestId === $userId,
57 'username' => $requestId === $username || $requestId === "@{$username}",
58 default => $requestId === $userId || $requestId === "@{$username}" || (!ctype_digit($username) && $requestId === $username),
59 };
60
61 return $isSelf ? $user : null;
62 }
63}