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
6declare(strict_types=1);
7
8namespace App\Libraries\Opengraph;
9
10use App\Models\Beatmap;
11use App\Models\User;
12
13class UserOpengraph implements OpengraphInterface
14{
15 public static function escapeForTitle(string $username)
16 {
17 return blade_safe(str_replace(' ', ' ', e($username)));
18 }
19
20 public function __construct(private User $user, private string $page, private ?string $ruleset = null)
21 {
22 }
23
24 public function get(): array
25 {
26 return [
27 // none for multiplayer, playlist counts seems...not useful?
28 'description' => $this->page === 'modding' ? $this->moddingDescription() : $this->showDescription(),
29 'image' => $this->user->user_avatar,
30 'title' => static::escapeForTitle($this->user->username),
31 ];
32 }
33
34 private function moddingDescription(): string
35 {
36 static $statuses = ['ranked', 'loved', 'pending', 'graveyard'];
37
38 $countsText = [];
39 foreach ($statuses as $status) {
40 $count = $this->user->profileBeatmapsetCountByGroupedStatus($status);
41 if ($count > 0) {
42 $countsText[] = osu_trans("beatmapsets.show.status.{$status}").' '.number_format($count);
43 }
44 }
45
46 return empty($countsText)
47 ? osu_trans('users.ogp.modding_description_empty')
48 : osu_trans('users.ogp.modding_description', [
49 'counts' => implode(' | ', $countsText),
50 ]);
51 }
52
53 private function showDescription(): string
54 {
55 static $rankTypes = ['country', 'global'];
56
57 $ruleset = $this->ruleset ?? $this->user->playmode;
58 $stats = $this->user->statistics($ruleset);
59
60 $replacements['ruleset'] = $ruleset;
61
62 foreach ($rankTypes as $type) {
63 $method = "{$type}Rank";
64 $replacements[$type] = osu_trans("users.ogp.description.{$type}", [
65 'rank' => format_rank($stats?->$method()),
66 ]);
67
68 $variants = Beatmap::VARIANTS[$ruleset] ?? [];
69
70 $variantsTexts = null;
71 foreach ($variants as $variant) {
72 $variantRank = $this->user->statistics($ruleset, false, $variant)?->$method();
73 if ($variantRank !== null) {
74 $variantsTexts[] = $variant.' '.format_rank($variantRank);
75 }
76 }
77
78 if (!empty($variantsTexts)) {
79 $replacements[$type] .= ' ('.implode(', ', $variantsTexts).')';
80 }
81 }
82
83 return osu_trans('users.ogp.description._', $replacements);
84 }
85}