Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
broadcast.php
1<?php
2
9namespace Bitrix\Blog;
10
13use Bitrix\Main;
19use Bitrix\Main\Entity\ExpressionField;
20
21Loc::loadMessages(__FILE__);
22
24{
25 protected const ON_CNT = 5;
26 protected const OFF_CNT = 5;
27
28 protected const ON_PERIOD = 'P7D'; // 7 days
29 protected const OFF_PERIOD = 'P7D'; // 7 days
30
31 private static function getValue(): string
32 {
33 return Option::get('blog', 'log_notify_all', 'N');
34 }
35
36 private static function setValue($value = false): void
37 {
38 $value = ($value === true);
39 Option::set('blog', 'log_notify_all', ($value ? 'Y' : 'N'));
40 }
41
42 private static function getOffModeRequested(): bool
43 {
44 return (Option::get('blog', 'log_notify_all_off_requested', false) === 'Y');
45 }
46
47 private static function getOnModeRequested(): bool
48 {
49 return (Option::get('blog', 'log_notify_all_on_requested', false) === 'Y');
50 }
51
52 private static function setOffModeRequested(): void
53 {
54 Option::set('blog', 'log_notify_all_off_requested', 'Y');
55 }
56
57 private static function setOnModeRequested(): void
58 {
59 Option::set('blog', 'log_notify_all_on_requested', 'Y');
60 }
61
62 private static function getCount($period): int
63 {
64 $counter = 0;
65
66 $now = new \DateTime();
67
68 $res = PostTable::getList([
69 'order' => [],
70 'filter' => [
71 '=PostSocnetRights:POST.ENTITY' => 'G2',
72 '=PUBLISH_STATUS' => BLOG_PUBLISH_STATUS_PUBLISH,
73 '>DATE_PUBLISH' => DateTime::createFromUserTime(DateTime::createFromUserTime($now->sub(new \DateInterval($period))->format(DateTime::getFormat()))),
74 ],
75 'group' => [],
76 'select' => [ 'CNT' ],
77 'runtime' => [
78 new ExpressionField('CNT', 'COUNT(*)'),
79 ],
80 'data_doubling' => false,
81 ]);
82 while ($ar = $res->fetch())
83 {
84 $counter = (int)$ar['CNT'];
85 }
86
87 return $counter;
88 }
89
90 private static function onModeNeeded(): bool
91 {
92 $counter = self::getCount(self::ON_PERIOD);
93
94 return ($counter < self::ON_CNT);
95 }
96
97 private static function offModeNeeded(): bool
98 {
99 $counter = self::getCount(self::OFF_PERIOD);
100
101 return ($counter > self::OFF_CNT);
102 }
103
104 public static function getData(): array
105 {
106 $result = [
107 'cnt' => 0,
108 'rate' => 0,
109 ];
110 $value = Option::get('blog', 'log_notify_all_data', false);
111 if ($value)
112 {
113 $value = unserialize($value, ['allowed_classes' => false]);
114 if (
115 is_array($value)
116 && isset($value['cnt'], $value['rate'])
117 )
118 {
119 $result = [
120 'cnt' => (int)$value['cnt'],
121 'rate' => (int)$value['rate'],
122 ];
123 }
124 }
125
126 return $result;
127 }
128
129 public static function setRequestedMode($value): void
130 {
131 $value = ($value === true);
132
133 if ($value)
134 {
135 self::setOnModeRequested();
136 }
137 else
138 {
139 self::setOffModeRequested();
140 }
141 }
142
143 public static function checkMode(): bool
144 {
145 if (ModuleManager::isModuleInstalled('intranet'))
146 {
147 $onModeRequested = self::getOnModeRequested();
148 $offModeRequested = self::getOffModeRequested();
149 $mode = self::getValue();
150
151 if (
152 $onModeRequested
153 && $offModeRequested
154 )
155 {
156 return false;
157 }
158
159 if (
160 $mode === 'N'
161 && !$onModeRequested
162 )
163 {
164 if (self::onModeNeeded())
165 {
166 self::sendRequest(true);
167 }
168
169 }
170 elseif (
171 $mode === 'Y'
172 && !$offModeRequested
173 )
174 {
175 if (self::offModeNeeded())
176 {
177 self::sendRequest(false);
178 }
179 }
180 }
181
182 return true;
183 }
184
185 private static function sendRequest($value, $siteId = SITE_ID): void
186 {
187 $value = ($value === true);
188
189 if (Loader::includeModule('im'))
190 {
191 $str = ($value ? 'ON' : 'OFF');
192 $tag = 'BLOG|BROADCAST_REQUEST|' . ($value ? 'ON' : 'OFF');
193
194 $fields = [
195 'MESSAGE_TYPE' => IM_MESSAGE_SYSTEM,
196 'NOTIFY_TYPE' => IM_NOTIFY_CONFIRM,
197 'NOTIFY_MODULE' => 'blog',
198 'NOTIFY_EVENT' => 'log_notify_all_request',
199 'NOTIFY_SUB_TAG' => $tag,
200 'NOTIFY_MESSAGE' => Loc::getMessage('BLOG_BROADCAST_REQUEST_IM_MESSAGE_' . $str),
201 'NOTIFY_MESSAGE_OUT' => IM_MAIL_SKIP,
202 'NOTIFY_BUTTONS' => [
203 [
204 'TITLE' => Loc::getMessage('BLOG_BROADCAST_REQUEST_IM_BUTTON_' . $str . '_Y'),
205 'VALUE' => 'Y',
206 'TYPE' => 'accept',
207 ],
208 [
209 'TITLE' => Loc::getMessage('BLOG_BROADCAST_REQUEST_IM_BUTTON_' . $str . '_N'),
210 'VALUE' => 'N',
211 'TYPE' => 'cancel',
212 ],
213 ]
214 ];
215
216 $moduleAdminList = array_keys(\Bitrix\Socialnetwork\User::getModuleAdminList([ $siteId, false ]));
217 foreach ($moduleAdminList as $userId)
218 {
219 $fields['TO_USER_ID'] = $userId;
220 $fields['NOTIFY_TAG'] = $tag . '|' . $userId;
221
222 \CIMNotify::add($fields);
223 }
224 }
225
227 }
228
229 public static function send($params): bool
230 {
231 if (
232 !Loader::includeModule('intranet')
233 || !Loader::includeModule('pull')
234 )
235 {
236 return false;
237 }
238
239 if (
240 empty($params['ENTITY_TYPE'])
241 || $params['ENTITY_TYPE'] !== 'POST'
242 || empty($params['ENTITY_ID'])
243 || empty($params['AUTHOR_ID'])
244 || empty($params['URL'])
245 || empty($params['SOCNET_RIGHTS'])
246 || !is_array($params['SOCNET_RIGHTS'])
247 )
248 {
249 return false;
250 }
251
252 if (empty($params['SITE_ID']))
253 {
254 $params['SITE_ID'] = SITE_ID;
255 }
256
257 $res = Main\UserTable::getList([
258 'filter' => [
259 '=ID' => (int)$params['AUTHOR_ID'],
260 ],
261 'select' => [ 'ID', 'PERSONAL_GENDER', 'NAME', 'LAST_NAME', 'SECOND_NAME', 'LOGIN' ],
262 ]);
263
264 if ($author = $res->fetch())
265 {
266 $author['NAME_FORMATTED'] = \CUser::formatName(\CSite::getNameFormat(null, $params['SITE_ID']), $author, true);
267 switch($author['PERSONAL_GENDER'])
268 {
269 case 'M':
270 $authorSuffix = '_M';
271 break;
272 case 'F':
273 $authorSuffix = '_F';
274 break;
275 default:
276 $authorSuffix = '';
277 }
278 }
279 else
280 {
281 return false;
282 }
283
284 $params['SOCNET_RIGHTS'] = array_map(static function ($right) {
285 return ($right === 'G2' ? 'UA' : $right);
286 }, $params['SOCNET_RIGHTS']);
287
288 if (
289 !empty($params['SOCNET_RIGHTS_OLD'])
290 && is_array($params['SOCNET_RIGHTS_OLD'])
291 )
292 {
293 $rightsOld = [];
294 foreach ($params['SOCNET_RIGHTS_OLD'] as $entities)
295 {
296 foreach ($entities as $rightsList)
297 {
298 foreach ($rightsList as $right)
299 {
300 $rightsOld[] = ($right === 'G2' ? 'UA' : $right);
301 }
302 }
303 }
304 $params['SOCNET_RIGHTS'] = array_diff($params['SOCNET_RIGHTS'], $rightsOld);
305 }
306
307 $found = false;
308
309 $userListParams = [
310 'SKIP' => (int)$params['AUTHOR_ID'],
311 'DEPARTMENTS' => [],
312 ];
313
314 foreach ($params['SOCNET_RIGHTS'] as $right)
315 {
316 if (
317 $right === 'UA'
318 || $right === 'G2'
319 )
320 {
321 $userListParams['SITE_ID'] = $params['SITE_ID'];
322 $found = true;
323 }
324 elseif (preg_match('/^DR(\d+)$/', $right, $matches))
325 {
326 $userListParams['DEPARTMENTS'][] = $matches[1];
327 $found = true;
328 }
329 }
330
331 if ($found)
332 {
333 $userList = \Bitrix\Intranet\Util::getEmployeesList($userListParams);
334 }
335
336 if (empty($userList))
337 {
338 return false;
339 }
340
341 if (
342 $params['ENTITY_TYPE'] === 'POST'
343 && ($post = \CBlogPost::getById($params['ENTITY_ID']))
344 && !empty($post['PUBLISH_STATUS'])
345 && ($post['PUBLISH_STATUS'] === BLOG_PUBLISH_STATUS_PUBLISH)
346 )
347 {
348 $titleTmp = str_replace([ "\r\n", "\n" ], ' ', $post['TITLE']);
349 $title = truncateText($titleTmp, 100);
350 $titleEmail = ($post['MICRO'] !== 'Y' ? truncateText($titleTmp, 255) : '');
351
352 $titleEmpty = (trim($title, " \t\n\r\0\x0B\xA0" ) === '');
353
354 $message = Loc::getMessage(
355 'BLOG_BROADCAST_PUSH_POST' . ($titleEmpty ? 'A' : '') . $authorSuffix,
356 [
357 '#author#' => $author['NAME_FORMATTED'],
358 '#title#' => $title,
359 ]
360 );
361
362 $userIdList = array_keys($userList);
363 if (
364 !empty($params['EXCLUDE_USERS'])
365 && is_array($params['EXCLUDE_USERS'])
366 )
367 {
368 $userIdList = array_diff($userIdList, $params['EXCLUDE_USERS']);
369 }
370
371 if (!empty($userIdList))
372 {
373 $userIdListPush = self::filterRecipients($userIdList, \CIMSettings::CLIENT_PUSH);
374
375 \Bitrix\Pull\Push::add($userIdListPush, [
376 'module_id' => 'blog',
377 'push' => [
378 'message' => $message,
379 'params' => [
380 'ACTION' => 'post',
381 'TAG' => 'BLOG|POST|' . $params['ENTITY_ID']
382 ],
383 'tag' => 'BLOG|POST|' . $params['ENTITY_ID'],
384 'send_immediately' => 'Y',
385 ]
386 ]);
387
388 $offlineUserIdList = [];
389
390 $mailRecipients = self::filterRecipients($userIdList, \CIMSettings::CLIENT_MAIL);
391
392 $deviceInfo = \CPushManager::getDeviceInfo($mailRecipients);
393 if (is_array($deviceInfo))
394 {
395 foreach ($deviceInfo as $userId => $info)
396 {
397 if (in_array(
398 $info['mode'],
399 [
400 \CPushManager::SEND_DEFERRED,
401 \CPushManager::RECORD_NOT_FOUND,
402 ],
403 true
404 ))
405 {
406 $offlineUserIdList[] = $userId;
407 }
408 }
409 }
410
411 if (!empty($offlineUserIdList))
412 {
413 $res = Main\UserTable::getList([
414 'filter' => [
415 '=SEND_EMAIL' => 'Y',
416 '@ID' => $offlineUserIdList,
417 ],
418 'runtime' => [
419 new Main\Entity\ExpressionField('SEND_EMAIL', 'CASE WHEN LAST_ACTIVITY_DATE IS NOT NULL AND LAST_ACTIVITY_DATE > ' . Main\Application::getConnection()->getSqlHelper()->addSecondsToDateTime('-' . (60*60*24*90)) . " THEN 'Y' ELSE 'N' END"),
420 ],
421 'select' => [ 'ID' ],
422 ]);
423
424 $offlineUserIdList = [];
425 while ($ar = $res->fetch())
426 {
427 $offlineUserIdList[] = $ar['ID'];
428 }
429 }
430
431 if (!empty($offlineUserIdList))
432 {
433 $serverName = '';
434
435 $res = \CSite::getByID($params['SITE_ID']);
436 if ($site = $res->fetch())
437 {
438 $serverName = $site['SERVER_NAME'];
439 }
440 if (empty($serverName))
441 {
442 $serverName = (
443 defined('SITE_SERVER_NAME')
444 && SITE_SERVER_NAME <> ''
445 ? SITE_SERVER_NAME
446 : Option::get('main', 'server_name', $_SERVER['SERVER_NAME'])
447 );
448 }
449
450 $serverName = (\CMain::isHTTPS() ? 'https' : 'http') . '://' . $serverName;
451
452 $textEmail = $post['DETAIL_TEXT'];
453 if ($post['DETAIL_TEXT_TYPE'] === 'html')
454 {
455 $textEmail = HTMLToTxt($textEmail);
456 }
457
458 $imageList = [];
459
460 $parserBlog = new \blogTextParser();
461 $textEmail = $parserBlog->convert4mail($textEmail, $imageList);
462
463 foreach ($offlineUserIdList as $userId)
464 {
465 if (!empty($userList[$userId]['EMAIL']))
466 {
467 \CEvent::send(
468 'BLOG_POST_BROADCAST',
469 $params['SITE_ID'],
470 [
471 'EMAIL_TO' => (!empty($userList[$userId]['NAME_FORMATTED']) ? '' . $userList[$userId]['NAME_FORMATTED'] . ' <' . $userList[$userId]['EMAIL'] . '>' : $userList[$userId]['EMAIL']),
472 'AUTHOR' => $author['NAME_FORMATTED'],
473 'MESSAGE_TITLE' => $titleEmail,
474 'MESSAGE_TEXT' => $textEmail,
475 'MESSAGE_PATH' => $serverName . $params['URL'],
476 ]
477 );
478 }
479 }
480 }
481 }
482 }
483
484 return false;
485 }
486
487 public function onBeforeConfirmNotify($module, $tag, $value, $params): bool
488 {
489 if ($module === 'blog')
490 {
491 $tagList = explode('|', $tag);
492 if (
493 count($tagList) === 4
494 && $tagList[1] === 'BROADCAST_REQUEST'
495 )
496 {
497 $mode = $tagList[2];
498 if (
499 $value === 'Y'
500 && in_array($mode, [ 'ON', 'OFF' ])
501 )
502 {
503 self::setValue($mode === 'ON');
504 \CIMNotify::deleteBySubTag('BLOG|BROADCAST_REQUEST|' . $mode);
505 }
506
507 return true;
508 }
509 }
510
511 return false;
512 }
513
514 public static function filterRecipients(array $usersId, string $notifyType): array
515 {
516 if (!Loader::includeModule('im'))
517 {
518 return $usersId;
519 }
520
522 {
523 if ($notifyType === \CIMSettings::CLIENT_MAIL)
524 {
525 $notifyType = Notification::MAIL;
526 }
527
528 $notification = new Notification('blog', 'broadcast_post');
529
530 return $notification->filterAllowedUsers($usersId, $notifyType);
531 }
532
533 foreach ($usersId as $key=> $userId)
534 {
535 if (!\CIMSettings::getNotifyAccess(
536 $userId,
537 'blog',
538 'broadcast_post',
539 $notifyType
540 ))
541 {
542 unset($usersId[$key]);
543 }
544 }
545
546 return $usersId;
547 }
548}
onBeforeConfirmNotify($module, $tag, $value, $params)
static send($params)
static filterRecipients(array $usersId, string $notifyType)
static setRequestedMode($value)
static getConnection($name="")
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static isModuleInstalled($moduleName)
static getFormat(Context\Culture $culture=null)
Definition date.php:261
static createFromUserTime($timeString)
Definition datetime.php:180