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\Transformers\Chat;
7
8use App\Models\Chat\Channel;
9use App\Models\Chat\Message;
10use App\Models\User;
11use App\Transformers\TransformerAbstract;
12
13class ChannelTransformer extends TransformerAbstract
14{
15 const CONVERSATION_INCLUDES = [
16 'last_message_id',
17 'users',
18 ];
19
20 const LISTING_INCLUDES = [
21 'current_user_attributes',
22 'last_read_id',
23 ...self::CONVERSATION_INCLUDES,
24 ];
25
26 protected array $availableIncludes = [
27 'current_user_attributes',
28 'last_message_id',
29 'last_read_id', // TODO: deprecated
30 'recent_messages', // TODO: deprecated
31 'users',
32 ];
33
34 private $user;
35
36 public static function forUser(?User $user)
37 {
38 $transformer = new static();
39 $transformer->user = $user;
40
41 return $transformer;
42 }
43
44 public function transform(Channel $channel)
45 {
46 return [
47 'channel_id' => $channel->channel_id,
48 'description' => $channel->description,
49 'icon' => $channel->displayIconFor($this->user),
50 'message_length_limit' => $channel->messageLengthLimit(),
51 'moderated' => $channel->moderated,
52 'name' => $channel->displayNameFor($this->user),
53 'type' => $channel->type,
54 'uuid' => $channel->uuid,
55 ];
56 }
57
58 public function includeCurrentUserAttributes(Channel $channel)
59 {
60 $result = $channel->checkCanMessage($this->user);
61
62 return $this->primitive([
63 'can_list_users' => priv_check_user($this->user, 'ChatChannelListUsers', $channel)->can(),
64 'can_message' => $result->can(),
65 'can_message_error' => $result->message(),
66 'last_read_id' => $channel->lastReadIdFor($this->user),
67 ]);
68 }
69
70 public function includeLastMessageId(Channel $channel)
71 {
72 return $this->primitive($channel->last_message_id);
73 }
74
75 public function includeLastReadId(Channel $channel)
76 {
77 return $this->primitive($channel->lastReadIdFor($this->user));
78 }
79
80 public function includeRecentMessages(Channel $channel)
81 {
82 if ($channel->exists) {
83 $messages = Message::filterBacklogs(
84 $channel,
85 $channel
86 ->messages()
87 // assumes sender will be included by the Message transformer
88 ->with('sender')
89 ->orderBy('message_id', 'desc')
90 ->limit(50)
91 ->get()
92 ->reverse(),
93 );
94 } else {
95 $messages = [];
96 }
97
98 return $this->collection($messages, new MessageTransformer());
99 }
100
101 public function includeUsers(Channel $channel)
102 {
103 return $this->primitive($channel->isPM() ? $channel->userIds() : []);
104 }
105
106 public function includeUuid(Channel $channel)
107 {
108 return $this->primitive($channel->uuid);
109 }
110}