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\Http\Controllers;
7
8use App\Libraries\Search\ScoreSearchParams;
9use App\Models\Beatmap;
10use App\Models\BeatmapPack;
11use App\Transformers\BeatmapPackTransformer;
12
13/**
14 * @group Beatmap Packs
15 */
16class BeatmapPacksController extends Controller
17{
18 private const PER_PAGE = 100;
19
20 public function __construct()
21 {
22 parent::__construct();
23
24 $this->middleware('require-scopes:public');
25 }
26
27 /**
28 * Get Beatmap Packs
29 *
30 * Returns a list of beatmap packs.
31 *
32 * ---
33 *
34 * ### Response format
35 *
36 * Field | Type
37 * ------------- | -----------------------------
38 * beatmap_packs | [BeatmapPack](#beatmappack)[]
39 *
40 * @usesCursor
41 * @queryParam type string [BeatmapPackType](#beatmappacktype) of the beatmap packs to be returned. Defaults to `standard`.
42 */
43 public function index()
44 {
45 $params = request()->all();
46 $type = presence(get_string($params['type'] ?? null)) ?? BeatmapPack::DEFAULT_TYPE;
47 $query = BeatmapPack::getPacks($type);
48 if ($query === null) {
49 abort(404);
50 }
51
52 if (is_api_request()) {
53 $cursorHelper = BeatmapPack::makeDbCursorHelper();
54 [$packs, $hasMore] = $query
55 ->cursorSort($cursorHelper, cursor_from_params($params))
56 ->limit(static::PER_PAGE)
57 ->getWithHasMore();
58
59 return [
60 'beatmap_packs' => json_collection($packs, new BeatmapPackTransformer()),
61 ...cursor_for_response($cursorHelper->next($packs, $hasMore)),
62 ];
63 } else {
64 return ext_view('packs.index', [
65 'packs' => $query->paginate(static::PER_PAGE)->appends(['type' => $type]),
66 'type' => $type,
67 ]);
68 }
69 }
70
71 /**
72 * Get Beatmap Pack
73 *
74 * Gets the beatmap pack for the specified beatmap pack tag.
75 *
76 * ---
77 *
78 * ### Response format
79 *
80 * Returns [BeatmapPack](#beatmappack) object.
81 * The following attributes are always included as well:
82 *
83 * Attribute |
84 * -------------------- |
85 * beatmapsets |
86 * user_completion_data |
87 *
88 * @urlParam pack string required The tag of the beatmap pack to be returned.
89 *
90 * @queryParam legacy_only integer Whether or not to consider lazer scores for user completion data. Defaults to 0. Example: 0
91 */
92 public function show($idOrTag)
93 {
94 $query = BeatmapPack::default();
95
96 if (!is_api_request() && ctype_digit($idOrTag)) {
97 $pack = $query->findOrFail($idOrTag);
98
99 return ujs_redirect(route('packs.show', $pack));
100 }
101
102 $pack = $query->where('tag', $idOrTag)->firstOrFail();
103 $mode = Beatmap::modeStr($pack->playmode ?? 0);
104 $sets = $pack->beatmapsets;
105 $currentUser = \Auth::user();
106 $userCompletionData = $pack->userCompletionData(
107 $currentUser,
108 ScoreSearchParams::showLegacyForUser($currentUser),
109 );
110
111 if (is_api_request()) {
112 return json_item(
113 $pack,
114 new BeatmapPackTransformer($userCompletionData),
115 ['beatmapsets', 'user_completion_data']
116 );
117 }
118
119 $view = request('format') === 'raw' ? 'packs.raw' : 'packs.show';
120
121 return ext_view($view, compact('mode', 'pack', 'sets', 'userCompletionData'));
122 }
123}