Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
ReactionMessages.php
1<?php
2
4
7use Bitrix\Im\V2\Common\ContextCustomer;
13
21{
22 use ContextCustomer;
23
24 private bool $withOwnReactions;
25
26 public function __construct(array $messageIds, bool $withOwnReactions = true)
27 {
28 parent::__construct();
29 $this->withOwnReactions = $withOwnReactions;
30
31 if (empty($messageIds))
32 {
33 return;
34 }
35
36 $this->fillCounters($messageIds)->fillUsers()->fillOwnReactions();
37 }
38
39 public static function initFromArray(array $reactionArray, bool $withOwnReactions = true): self
40 {
41 $reactions = new static([], $withOwnReactions);
42
43 foreach ($reactionArray as $reaction)
44 {
45 $reactions->addReactionMessage($reaction);
46 }
47
48 return $reactions;
49 }
50
51 public function addReactionMessage(ReactionMessage $reaction): self
52 {
53 $this[$reaction->getMessageId()] = $reaction;
54
55 return $this;
56 }
57
58 public function getReactionMessage(int $messageId): ReactionMessage
59 {
60 $this[$messageId] ??= new ReactionMessage($messageId);
61
62 return $this[$messageId];
63 }
64
65 private function getMessageIds(): array
66 {
67 $messageIds = [];
68
69 foreach ($this as $reactionMessage)
70 {
71 $messageIds[] = $reactionMessage->getMessageId();
72 }
73
74 return $messageIds;
75 }
76
77 private function getMessageIdsToFillOwnReaction(): array
78 {
79 $messageIds = [];
80
81 foreach ($this as $reactionMessage)
82 {
83 if ($reactionMessage->needToFillOwnReactions())
84 {
85 $messageIds[] = $reactionMessage->getMessageId();
86 }
87 }
88
89 return $messageIds;
90 }
91
92 public static function getRestEntityName(): string
93 {
94 return 'reactions';
95 }
96
97 public function toRestFormat(array $option = []): array
98 {
99 $rest = [];
100 if (!isset($option['WITHOUT_OWN_REACTIONS']))
101 {
102 $option['WITHOUT_OWN_REACTIONS'] = !$this->withOwnReactions;
103 }
104
105 foreach ($this as $reactionMessage)
106 {
107 if ($reactionMessage->haveReactions())
108 {
109 $rest[] = $reactionMessage->toRestFormat($option);
110 }
111 }
112
113 return $rest;
114 }
115
116 public function getUserIds(): array
117 {
118 $userIds = [];
119
120 foreach ($this as $reactionMessage)
121 {
122 foreach ($reactionMessage->getUserIds() as $userId)
123 {
124 $userIds[$userId] = $userId;
125 }
126 }
127
128 return $userIds;
129 }
130
131 public function getPopupData(array $excludedList = []): PopupData
132 {
133 return new PopupData([new UserShortPopupItem($this->getUserIds())], $excludedList);
134 }
135
136 private function fillCounters(array $messageIds): self
137 {
138 $result = ReactionTable::query()
139 ->setSelect(['MESSAGE_ID', 'REACTION', 'COUNT'])
140 ->whereIn('MESSAGE_ID', $messageIds)
141 ->fetchAll()
142 ;
143
144 foreach ($result as $row)
145 {
146 $this->getReactionMessage((int)$row['MESSAGE_ID'])->addCounter($row['REACTION'], (int)$row['COUNT']);
147 }
148
149 return $this;
150 }
151
152 private function fillUsers(): self
153 {
154 $messagesNeedFillUsers = [];
155
156 foreach ($this as $reactionMessage)
157 {
158 if ($reactionMessage->haveDisplayedUsers())
159 {
160 $messagesNeedFillUsers[] = $reactionMessage->getMessageId();
161 }
162 }
163
164 if (empty($messagesNeedFillUsers))
165 {
166 return $this;
167 }
168
169 $derivedQuery = ReactionTable::query()
170 ->setSelect(['MESSAGE_ID', 'REACTION'])
171 ->setGroup(['MESSAGE_ID', 'REACTION'])
172 ->whereIn('MESSAGE_ID', $messagesNeedFillUsers)
173 ->having('COUNT', '<=', ReactionMessage::COUNT_DISPLAYED_USERS)
174 ;
175 $entity = ORM\Entity::getInstanceByQuery($derivedQuery);
176
177 $result = ReactionTable::query()
178 ->setSelect(['MESSAGE_ID', 'REACTION', 'USER_ID'])
179 ->registerRuntimeField(
180 (new ORM\Fields\Relations\Reference(
181 'USERS_GROUP',
182 $entity,
183 ORM\Query\Join::on('this.MESSAGE_ID', 'ref.MESSAGE_ID')
184 ->whereColumn('this.REACTION', 'ref.REACTION')
185 ))->configureJoinType(ORM\Query\Join::TYPE_INNER)
186 )
187 ->exec()
188 ;
189
190 while ($row = $result->fetch())
191 {
192 $reactionMessage = $this->getReactionMessage((int)$row['MESSAGE_ID'])->addUsers($row['REACTION'], [(int)$row['USER_ID']]);
193 if ($this->withOwnReactions && $this->getContext()->getUserId() == (int)$row['USER_ID'])
194 {
195 $reactionMessage->addOwnReaction($row['REACTION']);
196 }
197 }
198
199 return $this;
200 }
201
202 private function fillOwnReactions(): self
203 {
204 if (!$this->withOwnReactions)
205 {
206 return $this;
207 }
208
209 $messageIds = $this->getMessageIdsToFillOwnReaction();
210
211 if (empty($messageIds))
212 {
213 return $this;
214 }
215
216 $result = ReactionTable::query()
217 ->setSelect(['MESSAGE_ID', 'REACTION'])
218 ->whereIn('MESSAGE_ID', $messageIds)
219 ->where('USER_ID', $this->getContext()->getUserId())
220 ->fetchAll()
221 ;
222
223 foreach ($result as $row)
224 {
225 $this->getReactionMessage((int)$row['MESSAGE_ID'])->addOwnReaction($row['REACTION']);
226 }
227
228 return $this;
229 }
230}
__construct(array $messageIds, bool $withOwnReactions=true)
static initFromArray(array $reactionArray, bool $withOwnReactions=true)