1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
usercollector.php
См. документацию.
1<?php
2
3namespace Bitrix\Socialnetwork\Internals\LiveFeed\Counter\Collector;
4
5use Bitrix\Main\Entity\ExpressionField;
6use Bitrix\Main\Type\DateTime;
7use Bitrix\Main\UserAccessTable;
8use Bitrix\Socialnetwork\Item\Log;
9use Bitrix\Socialnetwork\Item\LogRight;
10use Bitrix\Socialnetwork\Livefeed\Provider;
11use Bitrix\Socialnetwork\LogCommentTable;
12use Bitrix\Socialnetwork\UserContentViewTable;
13use Bitrix\Socialnetwork\Internals\LiveFeed\Counter\CounterDictionary;
14
16{
17 public const PUBLIC_ACCESS_CODES = ['AU', 'G2'];
18
19 private int $userId;
20 private array $sonetLogGroups = [];
21 private array|null $userAccessCodes = null;
22
23 private static array $instances = [];
24
25 public static function getInstance(int $userId)
26 {
27 if (!array_key_exists($userId, self::$instances))
28 {
29 self::$instances[$userId] = new self($userId);
30 }
31
32 return self::$instances[$userId];
33 }
34
35 private function __construct(int $userId)
36 {
37 $this->userId = $userId;
38 }
39
40 public function recount(string $counter, array $sonetLogIds = []): array
41 {
42 if (!$this->userId)
43 {
44 return [];
45 }
46
47 if (empty($sonetLogIds))
48 {
49 return [];
50 }
51
52 $sonetLogIds = array_unique($sonetLogIds);
53 sort($sonetLogIds);
54
55 $counters = [];
56
57 switch ($counter)
58 {
60 $counters = $this->recountPosts($sonetLogIds);
61 break;
63 $counters = $this->recountComments($sonetLogIds);
64 break;
65 default:
66 break;
67 }
68
69 return $counters;
70 }
71
72 public function add(string $counter, array $sonetLogIds = []): array
73 {
74 if (!$this->userId)
75 {
76 return [];
77 }
78
79 if (empty($sonetLogIds))
80 {
81 return [];
82 }
83
84 $sonetLogIds = array_unique($sonetLogIds);
85 sort($sonetLogIds);
86
87 $counters = [];
88
89 switch ($counter)
90 {
92 $counters = $this->addPost($sonetLogIds);
93 break;
95 $counters = $this->addComment($sonetLogIds);
96 break;
97 default:
98 break;
99 }
100
101 return $counters;
102 }
103
104 private function recountPosts(array $sonetLogIds): array
105 {
106 $counters = [];
107
108 foreach ($sonetLogIds as $logId)
109 {
110 $logItem = Log::getById($logId);
111 if (!$logItem)
112 {
113 continue;
114 }
115
116 $logItemFields = $logItem->getFields();
117 // skip if the current user is an author of the post
118 if ((int)($logItemFields['USER_ID'] ?? 0) === $this->userId)
119 {
120 continue;
121 }
122
123 if (!in_array($logItemFields['ENTITY_TYPE'] ?? null, \CSocNetAllowed::GetAllowedEntityTypes(), true))
124 {
125 continue;
126 }
127
128 if (!$this->isItemForEveryOne($logId) && !$this->userHasAccess($logId))
129 {
130 continue;
131 }
132
133 if (!$this->isItemSeenByUser($logItemFields))
134 {
135 foreach ($this->findGroupsByLogIdAndUser($logId) as $groupId)
136 {
137 $counters[] = [
138 'USER_ID' => $this->userId,
139 'SONET_LOG_ID' => $logId,
140 'GROUP_ID' => $groupId,
142 'VALUE' => 1
143 ];
144 }
145 }
146 }
147
148 return $counters;
149 }
150
151 private function recountComments(array $sonetLogIds): array
152 {
153 $counters = [];
154
155 foreach ($sonetLogIds as $logId)
156 {
157 $logItem = Log::getById($logId);
158 if (!$logItem)
159 {
160 continue;
161 }
162
163 $logItemFields = $logItem->getFields();
164 if (!in_array($logItemFields['ENTITY_TYPE'] ?? null, \CSocNetAllowed::GetAllowedEntityTypes(), true))
165 {
166 continue;
167 }
168
169 if (!$this->isItemForEveryOne($logId) && !$this->userHasAccess($logId))
170 {
171 continue;
172 }
173
174 $commentsCount = $this->isItemSeenByUser($logItemFields)
175 ? $this->getCountCommentsByLogItemAndLastDateSeen($logId, $logItemFields)
176 : $this->getCountCommentsByLogItem($logId);
177
178 if ($commentsCount > 0)
179 {
180 foreach ($this->findGroupsByLogIdAndUser($logId) as $groupId)
181 {
182 $counters[] = [
183 'USER_ID' => $this->userId,
184 'SONET_LOG_ID' => $logId,
185 'GROUP_ID' => $groupId,
187 'VALUE' => $commentsCount
188 ];
189 }
190 }
191 }
192
193 return $counters;
194 }
195
196 private function addPost(array $sonetLogIds): array
197 {
198 $counters = [];
199
200 foreach ($sonetLogIds as $logId)
201 {
202 $logItem = Log::getById($logId);
203 if (!$logItem)
204 {
205 continue;
206 }
207
208 $logItemFields = $logItem->getFields();
209 // skip if the current user is an author of the post
210 if ((int)($logItemFields['USER_ID'] ?? 0) === $this->userId)
211 {
212 continue;
213 }
214
215 foreach ($this->findGroupsByLogIdAndUser($logId) as $groupId)
216 {
217 if ($this->isFeedSeenByUser($groupId, new DateTime($logItemFields['LOG_DATE'])))
218 {
219 return [];
220 }
221
222 $counters[] = [
223 'USER_ID' => $this->userId,
224 'SONET_LOG_ID' => $logId,
225 'GROUP_ID' => $groupId,
227 'VALUE' => 1
228 ];
229 }
230 }
231
232 return $counters;
233 }
234
235 private function addComment(array $sonetLogIds): array
236 {
237 $counters = [];
238
239 foreach ($sonetLogIds as $logId)
240 {
241 foreach ($this->findGroupsByLogIdAndUser($logId) as $groupId)
242 {
243 $lastTimeFeedSeen = $this->getLastTimeFeedSeen($groupId);
244 $filter = $lastTimeFeedSeen
245 ? ['=LOG_ID' => $logId, '!USER_ID' => $this->userId, '>LOG_DATE' => $lastTimeFeedSeen]
246 : ['=LOG_ID' => $logId, '!USER_ID' => $this->userId, ]
247 ;
248 $commentsCount = LogCommentTable::getCount([
249 $filter
250 ]);
251
252 $counters[] = [
253 'USER_ID' => $this->userId,
254 'SONET_LOG_ID' => $logId,
255 'GROUP_ID' => $groupId,
257 'VALUE' => $commentsCount
258 ];
259 }
260 }
261
262 return $counters;
263 }
264
265 private function getCountCommentsByLogItemAndLastDateSeen(int $logId, array $logItemFields): int
266 {
267 $lastTimeSeen = $this->getContentViewByItem($logItemFields);
268 if (!isset($lastTimeSeen['DATE_VIEW']))
269 {
270 return 0;
271 }
272
274 'select' => ['CNT'],
275 'filter' => [
276 '=LOG_ID' => $logId,
277 '!USER_ID' => $this->userId,
278 '>LOG_DATE' => $lastTimeSeen['DATE_VIEW']
279 ],
280 'runtime' => [
281 new ExpressionField('CNT', 'COUNT(*)'),
282 ]
283 ])->fetch();
284
285 return $res['CNT'] ?? 0;
286 }
287
288 private function getCountCommentsByLogItem(int $logId): int
289 {
291 'select' => ['CNT'],
292 'filter' => [
293 '=LOG_ID' => $logId,
294 '!USER_ID' => $this->userId,
295 ],
296 'runtime' => [
297 new ExpressionField('CNT', 'COUNT(*)'),
298 ]
299 ])->fetch();
300
301 return $res['CNT'] ?? 0;
302 }
303
304 private function isItemSeenByUser(array $logItemFields): bool
305 {
306 return (bool)$this->getContentViewByItem($logItemFields);
307 }
308
309 private function getContentViewByItem(array $logItemFields): array|false
310 {
311 $ratingTypeId = null;
312 $ratingEntityId = null;
313
314 if (!empty($logItemFields['RATING_ENTITY_ID']) && !empty($logItemFields['RATING_TYPE_ID']))
315 {
316 $ratingTypeId = $logItemFields['RATING_TYPE_ID'];
317 $ratingEntityId = $logItemFields['RATING_ENTITY_ID'];
318 }
319 else
320 {
321 $logItemFields['LOG_ID'] = $logItemFields['ID'];
322 $content = Provider::getContentId($logItemFields);
323 $ratingTypeId = $content['ENTITY_TYPE'] ?? null;
324 $ratingEntityId = $content['ENTITY_ID'] ?? null;
325 }
326
327 return UserContentViewTable::getList([
328 'select' => ['DATE_VIEW'],
329 'filter' => [
330 '=USER_ID' => $this->userId,
331 '=RATING_ENTITY_ID' => $ratingEntityId,
332 '=RATING_TYPE_ID' => $ratingTypeId
333 ]
334 ])->fetch();
335 }
336
337 private function isItemForEveryOne(int $logItemId): bool
338 {
339 foreach (LogRight::get($logItemId) as $logAccessRight)
340 {
341 if (in_array($logAccessRight, self::PUBLIC_ACCESS_CODES, true))
342 {
343 return true;
344 }
345 }
346
347 return false;
348 }
349
350 private function userHasAccess(int $logItemId): bool
351 {
352 $rights = LogRight::get($logItemId);
353
354 if ($this->userAccessCodes === null && $rights)
355 {
356 $this->userAccessCodes = [];
357 $res = UserAccessTable::getList([
358 'select' => ['ACCESS_CODE'],
359 'filter' => [
360 '=USER_ID' => $this->userId,
361 '=ACCESS_CODE' => $rights,
362 ]
363 ])->fetchAll();
364
365 foreach ($res as $access)
366 {
367 if (isset($access['ACCESS_CODE']))
368 {
369 $this->userAccessCodes[] = $access['ACCESS_CODE'];
370 }
371 }
372 }
373
374 foreach ($rights as $logRight)
375 {
376 if (in_array($logRight, $this->userAccessCodes, true))
377 {
378 return true;
379 }
380 }
381
382 return false;
383 }
384
385 private function findGroupsByLogIdAndUser(int $sonetLogId): array
386 {
387 if (!empty($this->sonetLogGroups[$sonetLogId]))
388 {
389 return $this->sonetLogGroups[$sonetLogId];
390 }
391
392 $this->sonetLogGroups[$sonetLogId] = [];
393 $sonetLogRights = LogRight::get($sonetLogId);
394 $userAccessCodes = array_merge(self::PUBLIC_ACCESS_CODES, ['U' . $this->userId]);
395 foreach ($sonetLogRights as $logRight)
396 {
397 if (in_array($logRight, $userAccessCodes))
398 {
399 // append common group
400 $commonGroupId = 0;
401 $this->sonetLogGroups[$sonetLogId][$commonGroupId] = $commonGroupId;
402 break;
403 }
404 }
405
406 $query = UserAccessTable::query()
407 ->setDistinct()
408 ->setSelect([
409 'ACCESS_CODE',
410 ])
411 ->where('USER_ID', '=', $this->userId)
412 ->where('PROVIDER_ID', '=', 'socnetgroup')
413 ->whereIn('ACCESS_CODE', $sonetLogRights)
414 ->exec();
415
416 foreach ($query->fetchAll() as $group)
417 {
418 $matches = [];
419 preg_match('/SG([0-9]+)/m', $group['ACCESS_CODE'], $matches);
420 if (isset($matches[1]))
421 {
422 $groupId = (int)$matches[1];
423 $this->sonetLogGroups[$sonetLogId][$groupId] = $groupId;
424 }
425 }
426
427 return $this->sonetLogGroups[$sonetLogId];
428 }
429
430 private function isFeedSeenByUser(int $groupId, DateTime $logDate): bool
431 {
432 $lastTimeSeen = $this->getLastTimeFeedSeen($groupId);
433 if ($lastTimeSeen && $lastTimeSeen > $logDate)
434 {
435 return true;
436 }
437
438 return false;
439 }
440
441 private function getLastTimeFeedSeen(int $groupId): DateTime|null
442 {
443 $contentSeen = UserContentViewTable::getList([
444 'select' => ['DATE_VIEW', 'USER_ID', 'RATING_ENTITY_ID', 'RATING_TYPE_ID'],
445 'filter' => [
446 '=USER_ID' => $this->userId,
447 '=RATING_ENTITY_ID' => $groupId,
448 '=RATING_TYPE_ID' => Provider::DATA_ENTITY_TYPE_LIVE_FEED_VIEW,
449 ]
450 ])->fetch();
451
452 return isset($contentSeen['DATE_VIEW'])
453 ? new DateTime($contentSeen['DATE_VIEW'])
454 : null;
455 }
456}
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getList(array $parameters=array())
Определения datamanager.php:431
static getCount($filter=array(), array $cache=array())
Определения datamanager.php:516
add(string $counter, array $sonetLogIds=[])
Определения usercollector.php:72
recount(string $counter, array $sonetLogIds=[])
Определения usercollector.php:40
$content
Определения commerceml.php:144
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$query
Определения get_search.php:11
$filter
Определения iblock_catalog_list.php:54
if(!is_array($deviceNotifyCodes)) $access
Определения options.php:174
$counter
Определения options.php:5
return false
Определения prolog_main_admin.php:185
$matches
Определения index.php:22
$counters
Определения options.php:100
$rights
Определения options.php:4