Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
usercollector.php
1<?php
2
4
5use Bitrix\Main\Entity\ExpressionField;
12
14{
15 public const PUBLIC_ACCESS_CODES = ['AU', 'G2'];
16
17 private int $userId;
18 private array $sonetLogGroups = [];
19 private array|null $userAccessCodes = null;
20
21 private static array $instances = [];
22
23 public static function getInstance(int $userId)
24 {
25 if (!array_key_exists($userId, self::$instances))
26 {
27 self::$instances[$userId] = new self($userId);
28 }
29
30 return self::$instances[$userId];
31 }
32
33 private function __construct(int $userId)
34 {
35 $this->userId = $userId;
36 }
37
38 public function recount(string $counter, array $sonetLogIds = []): array
39 {
40 if (!$this->userId)
41 {
42 return [];
43 }
44
45 if (empty($sonetLogIds))
46 {
47 return [];
48 }
49
50 $sonetLogIds = array_unique($sonetLogIds);
51 sort($sonetLogIds);
52
53 $counters = [];
54
55 switch ($counter)
56 {
58 $counters = $this->recountPosts($sonetLogIds);
59 break;
61 $counters = $this->recountComments($sonetLogIds);
62 break;
63 default:
64 break;
65 }
66
67 return $counters;
68 }
69
70 private function recountPosts(array $sonetLogIds): array
71 {
72 $counters = [];
73
74 foreach ($sonetLogIds as $logId)
75 {
76 $logItem = Log::getById($logId);
77 if (!$logItem)
78 {
79 continue;
80 }
81
82 $logItemFields = $logItem->getFields();
83 // skip if the current user is an author of the post
84 if ((int)$logItemFields['USER_ID'] === $this->userId)
85 {
86 continue;
87 }
88
89 if (!in_array($logItemFields['ENTITY_TYPE'], \CSocNetAllowed::GetAllowedEntityTypes(), true))
90 {
91 continue;
92 }
93
94 if (!$this->isItemForEveryOne($logId) && !$this->userHasAccess($logId))
95 {
96 continue;
97 }
98
99 $params = [
100 'RATING_ENTITY_ID' => $logItemFields['RATING_ENTITY_ID'],
101 'RATING_TYPE_ID' => $logItemFields['RATING_TYPE_ID'],
102 ];
103 if (!$this->isItemSeenByUser($params))
104 {
105 foreach ($this->findGroupsByLogIdAndUser($logId) as $groupId)
106 {
107 $counters[] = [
108 'USER_ID' => $this->userId,
109 'SONET_LOG_ID' => $logId,
110 'GROUP_ID' => $groupId,
112 'VALUE' => 1
113 ];
114 }
115 }
116 }
117
118 return $counters;
119 }
120
121 private function recountComments(array $sonetLogIds): array
122 {
123 $counters = [];
124
125 foreach ($sonetLogIds as $logId)
126 {
127 $logItem = Log::getById($logId);
128 if (!$logItem)
129 {
130 continue;
131 }
132
133 $logItemFields = $logItem->getFields();
134 if (!in_array($logItemFields['ENTITY_TYPE'], \CSocNetAllowed::GetAllowedEntityTypes(), true))
135 {
136 continue;
137 }
138
139 if (!$this->isItemForEveryOne($logId) && !$this->userHasAccess($logId))
140 {
141 continue;
142 }
143
144 $params = [
145 'RATING_ENTITY_ID' => $logItemFields['RATING_ENTITY_ID'],
146 'RATING_TYPE_ID' => $logItemFields['RATING_TYPE_ID'],
147 ];
148 $commentsCount = $this->isItemSeenByUser($params)
149 ? $this->getCountCommentsByLogItemAndLastDateSeen($logId, $params)
150 : $this->getCountCommentsByLogItem($logId);
151
152 if ($commentsCount > 0)
153 {
154 foreach ($this->findGroupsByLogIdAndUser($logId) as $groupId)
155 {
156 $counters[] = [
157 'USER_ID' => $this->userId,
158 'SONET_LOG_ID' => $logId,
159 'GROUP_ID' => $groupId,
161 'VALUE' => $commentsCount
162 ];
163 }
164 }
165 }
166
167 return $counters;
168 }
169
170 private function getCountCommentsByLogItemAndLastDateSeen(int $logId, array $params): int
171 {
172 $lastTimeSeen = $this->getContentViewByItem($params);
173 if (!isset($lastTimeSeen['DATE_VIEW']))
174 {
175 return 0;
176 }
177
179 'select' => ['CNT'],
180 'filter' => [
181 '=LOG_ID' => $logId,
182 '!USER_ID' => $this->userId,
183 '>LOG_DATE' => $lastTimeSeen['DATE_VIEW']
184 ],
185 'runtime' => [
186 new ExpressionField('CNT', 'COUNT(*)'),
187 ]
188 ])->fetch();
189
190 return $res['CNT'] ?? 0;
191 }
192
193 private function getCountCommentsByLogItem(int $logId): int
194 {
196 'select' => ['CNT'],
197 'filter' => [
198 '=LOG_ID' => $logId,
199 '!USER_ID' => $this->userId,
200 ],
201 'runtime' => [
202 new ExpressionField('CNT', 'COUNT(*)'),
203 ]
204 ])->fetch();
205
206 return $res['CNT'] ?? 0;
207 }
208
209 private function isItemSeenByUser(array $params): bool
210 {
211 return (bool)$this->getContentViewByItem($params);
212 }
213
214 private function getContentViewByItem(array $params): array|false
215 {
216 return UserContentViewTable::getList([
217 'select' => ['DATE_VIEW'],
218 'filter' => [
219 '=USER_ID' => $this->userId,
220 '=RATING_ENTITY_ID' => $params['RATING_ENTITY_ID'],
221 '=RATING_TYPE_ID' => $params['RATING_TYPE_ID']
222 ]
223 ])->fetch();
224 }
225
226 private function isItemForEveryOne(int $logItemId): bool
227 {
228 foreach (LogRight::get($logItemId) as $logAccessRight)
229 {
230 if (in_array($logAccessRight, self::PUBLIC_ACCESS_CODES, true))
231 {
232 return true;
233 }
234 }
235
236 return false;
237 }
238
239 private function userHasAccess(int $logItemId): bool
240 {
241 $rights = LogRight::get($logItemId);
242
243 if ($this->userAccessCodes === null && $rights)
244 {
245 $this->userAccessCodes = [];
246 $res = UserAccessTable::getList([
247 'select' => ['ACCESS_CODE'],
248 'filter' => [
249 '=USER_ID' => $this->userId,
250 '=ACCESS_CODE' => $rights,
251 ]
252 ])->fetchAll();
253
254 foreach ($res as $access)
255 {
256 if (isset($access['ACCESS_CODE']))
257 {
258 $this->userAccessCodes[] = $access['ACCESS_CODE'];
259 }
260 }
261 }
262
263 foreach ($rights as $logRight)
264 {
265 if (in_array($logRight, $this->userAccessCodes, true))
266 {
267 return true;
268 }
269 }
270
271 return false;
272 }
273
274 private function findGroupsByLogIdAndUser(int $sonetLogId): array
275 {
276 if (!empty($this->sonetLogGroups[$sonetLogId]))
277 {
278 return $this->sonetLogGroups[$sonetLogId];
279 }
280
281 $this->sonetLogGroups[$sonetLogId] = [];
282 $sonetLogRights = LogRight::get($sonetLogId);
283 $userAccessCodes = array_merge(self::PUBLIC_ACCESS_CODES, ['U' . $this->userId]);
284 foreach ($sonetLogRights as $logRight)
285 {
286 if (in_array($logRight, $userAccessCodes))
287 {
288 // append common group
289 $commonGroupId = 0;
290 $this->sonetLogGroups[$sonetLogId][$commonGroupId] = $commonGroupId;
291 break;
292 }
293 }
294
295 $query = UserAccessTable::query()
296 ->setDistinct()
297 ->setSelect([
298 'ACCESS_CODE',
299 ])
300 ->where('USER_ID', '=', $this->userId)
301 ->where('PROVIDER_ID', '=', 'socnetgroup')
302 ->whereIn('ACCESS_CODE', $sonetLogRights)
303 ->exec();
304
305 foreach ($query->fetchAll() as $group)
306 {
307 $matches = [];
308 preg_match('/SG([0-9]+)/m', $group['ACCESS_CODE'], $matches);
309 if (isset($matches[1]))
310 {
311 $groupId = (int)$matches[1];
312 $this->sonetLogGroups[$sonetLogId][$groupId] = $groupId;
313 }
314 }
315
316 return $this->sonetLogGroups[$sonetLogId];
317 }
318}
static getList(array $parameters=array())