Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
livefeed.php
1<?php
3
11
13{
17 public function __construct()
18 {
19 parent::__construct();
20 }
21
25 private static function getOrderFields()
26 {
27 return [
28 [
29 'ID' => 'LOG_DATE',
30 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_LOG_DATE')
31 ]
32 ];
33 }
34
39 public static function onBuildSourceListHandler(Main\Event $event)
40 {
42 $selector = $event->getParameter('SELECTOR');
43
44 $siteId = null;
45
46 $restrictions = $selector->getModuleRestrictions('socialnetwork');
47 if (
48 !empty($restrictions)
49 && !empty($restrictions['SITE_ID'])
50 )
51 {
52 $siteId = $restrictions['SITE_ID'];
53 }
54 unset($restrictions);
55
56 $dataSettings = [
57 'ORDER' => self::getOrderFields(),
58 'FIELDS' => [
59 [
60 'ID' => 'TITLE',
61 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_TITLE'),
62 'TYPE' => Landing\Node\Type::TEXT
63 ],
64 [
65 'ID' => 'PREVIEW_TEXT',
66 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_PREVIEW_TEXT'),
67 'TYPE' => Landing\Node\Type::TEXT
68 ],
69 [
70 'ID' => 'DETAIL_TEXT',
71 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_DETAIL_TEXT'),
72 'TYPE' => Landing\Node\Type::TEXT
73 ],
74 [
75 'ID' => 'AUTHOR_NAME_FORMATTED',
76 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_AUTHOR_NAME_FORMATTED'),
77 'TYPE' => Landing\Node\Type::TEXT
78 ],
79 [
80 'ID' => 'LOG_DATE',
81 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_LOG_DATE'),
82 'TYPE' => Landing\Node\Type::TEXT
83 ],
84 [
85 'ID' => 'PICTURE',
86 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_PICTURE'),
87 'TYPE' => Landing\Node\Type::IMAGE
88 ],
89 [
90 'ID' => 'AUTHOR_AVATAR',
91 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_FIELD_AUTHOR_AVATAR'),
92 'TYPE' => Landing\Node\Type::IMAGE
93 ],
94 [
95 'ID' => 'LINK',
96 'NAME' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_ACTIONS'),
97 'TYPE' => Landing\Node\Type::LINK,
98 'ACTIONS' => $selector->getDefaultLinkActions()
99 ]
100 ]
101 ];
102
103 $result = [];
104
105 $result[] = [
106 'SOURCE_ID' => 'livefeed',
107 'TITLE' => Loc::getMessage('SONET_LANDING_DYNAMIC_BLOCK_LIVEFEED_TITLE2'),
108 'TYPE' => Landing\Source\Selector::SOURCE_TYPE_COMPONENT,
109 'SETTINGS' => [
110 'COMPONENT_NAME' => 'bitrix:socialnetwork.landing.livefeed.selector',
111 'COMPONENT_TEMPLATE_NAME' => '.default',
112 'COMPONENT_PARAMS' => [
113 'SITE_ID' => $siteId,
114 ],
115 "USE_UI_TOOLBAR" => "Y", // TODO: remove this key after stable update landing
116 'WRAPPER' => [
117 'USE_PADDING' => false,
118 'PLAIN_VIEW' => false,
119 'USE_UI_TOOLBAR' => 'Y'
120 ]
121 ],
122 'SOURCE_FILTER' => [],
123 'DATA_SETTINGS' => $dataSettings,
124 'DATA_LOADER' => __CLASS__
125 ];
126
127
128 unset($selector);
129
130 return new Main\EventResult(Main\EventResult::SUCCESS, $result, 'socialnetwork');
131 }
132
136 private function getRightsFilter()
137 {
138 global $CACHE_MANAGER;
139
140 $result = [];
141
142 $settingsFilter = $this->getFilter();
143 if (!is_array($settingsFilter))
144 {
145 $settingsFilter = [];
146 }
147
148 foreach ($settingsFilter as $filterField)
149 {
150 if (
151 !empty($filterField['key'])
152 && !empty($filterField['value'])
153 && $filterField['key'] == 'GROUP_ID'
154 && $filterField['value'] != 'all'
155 )
156 {
157 $result[] = $filterField['value'];
158
159 if (defined("BX_COMP_MANAGED_CACHE"))
160 {
161 $CACHE_MANAGER->registerTag("landing_dynamic_filter_".$filterField['value']);
162 }
163 }
164 }
165
166 $groupIdList = array_filter(array_map(function($val) {
167 $res = false;
168 if (preg_match('/^SG(\d+)$/i', $val, $matches))
169 {
170 $res = intval($matches[1]);
171 }
172
173 return $res;
174 }, $result), function ($val) {
175 return ($val > 0);
176 });
177
178 if (empty($groupIdList))
179 {
180 return $result;
181 }
182
183 $result = [];
184 $res = WorkgroupTable::getList([
185 'filter' => [
186 '=LANDING' => 'Y',
187 '=ACTIVE' => 'Y',
188 '@ID' => $groupIdList
189 ],
190 'select' => [ 'ID' ]
191 ]);
192 while ($workgroupFields = $res->fetch())
193 {
194 $result[] = 'SG'.$workgroupFields['ID'];
195 }
196
197 return $result;
198 }
199
203 private function getAuthorFilter()
204 {
205 $result = [];
206
207 $settingsFilter = $this->getFilter();
208 if (!is_array($settingsFilter))
209 {
210 $settingsFilter = [];
211 }
212
213 foreach ($settingsFilter as $filterField)
214 {
215 if (
216 !empty($filterField['key'])
217 && !empty($filterField['value'])
218 && $filterField['key'] == 'AUTHOR_ID'
219 && $filterField['value'] != 'all'
220 )
221 {
222 $result[] = $filterField['value'];
223 }
224 }
225
226 $authorIdList = array_filter(array_map(function($val) {
227 $res = false;
228 if (preg_match('/^U(\d+)$/i', $val, $matches))
229 {
230 $res = intval($matches[1]);
231 }
232
233 return $res;
234 }, $result), function ($val) {
235 return ($val > 0);
236 });
237
238 if (empty($authorIdList))
239 {
240 return $result;
241 }
242
243 $result = [];
244 $res = UserTable::getList([
245 'filter' => [
246 '=ACTIVE' => 'Y',
247 '@ID' => $authorIdList
248 ],
249 'select' => [ 'ID' ]
250 ]);
251 while ($userFields = $res->fetch())
252 {
253 $result[] = $userFields['ID'];
254 }
255
256 return $result;
257 }
258
262 public function getElementListData()
263 {
264 $this->seo->clear();
265
266 $result = [];
267
268 $rightsFilter = $this->getRightsFilter();
269 $authorFilter = $this->getAuthorFilter();
270
271 if (empty($rightsFilter))
272 {
273 return $result;
274 }
275
276 $orderFields = self::getOrderFields();
277 $order = $this->getOrder();
278
279 if (!is_array($order))
280 {
281 $order = [];
282 }
283
284 $livefeedOrder = [];
285
286 if (
287 !empty($order)
288 && !empty($order['by'])
289 && !empty($order['order'])
290 )
291 {
292 foreach($orderFields as $field)
293 {
294 if ($order['by'] == $field['ID'])
295 {
296 $livefeedOrder = [
297 $order['by'] => $order['order']
298 ];
299 }
300 }
301 }
302
303 if (empty($livefeedOrder))
304 {
305 $livefeedOrder = [
306 'LOG_DATE' => 'DESC'
307 ];
308 }
309
310 $livefeedFilter = [
311 'LOG_RIGHTS' => $rightsFilter,
312 'EVENT_ID' => \CSocNetLogTools::findFullSetByEventID('blog_post'),
313 '<=LOG_DATE' => 'NOW',
314 ];
315
316 if (
317 !empty($authorFilter)
318 && is_array($authorFilter)
319 && !empty($authorFilter[0])
320 )
321 {
322 $livefeedFilter['USER_ID'] = intval($authorFilter[0]);
323 }
324
325 $settings = [
326 'order' => $livefeedOrder,
327 'filter' => $livefeedFilter,
328 'limit' => [
329 'nTopCount' => $this->getLimit()
330 ]
331 ];
332
333 $result = $this->getElementsInternal($settings);
334
335 return $result;
336 }
337
342 public function getElementData($element)
343 {
344 $this->seo->clear();
345
346 $result = [];
347 if (!is_string($element) && !is_int($element))
348 return $result;
349 $element = (int)$element;
350 if ($element <= 0)
351 return $result;
352
353 $rightsFilter = $this->getRightsFilter();
354 if (empty($rightsFilter))
355 {
356 return $result;
357 }
358
359 $settings = [
360 'order' => [],
361 'filter' => [
362 'SOURCE_ID' => $element,
363 'LOG_RIGHTS' => $rightsFilter,
364 'EVENT_ID' => \CSocNetLogTools::findFullSetByEventID('blog_post'),
365 '<=LOG_DATE' => 'NOW',
366 ],
367 'limit' => [
368 'nTopCount' => 1
369 ]
370 ];
371
372 $result = $this->getElementsInternal($settings);
373
374 if (!empty($result))
375 {
376 $current = reset($result);
377 if (!empty($current))
378 {
379 $this->seo->setTitle($current['TITLE']);
380 }
381 unset($current);
382 }
383 return $result;
384 }
385
390 private function getElementsInternal(array $settings)
391 {
392 global $CACHE_MANAGER, $USER_FIELD_MANAGER;
393
394 $result = [];
395
396 $pathToSmile = Main\Config\Option::get("socialnetwork", "smile_page", false, SITE_ID);
397 $pathToSmile = ($pathToSmile ? $pathToSmile : "/bitrix/images/socialnetwork/smile/");
398
399 $parserParams = Array(
400 "imageWidth" => 500,
401 "imageHeight" => 500,
402 );
403
404 $allow = [
405 "HTML" => "N",
406 "ANCHOR" => "Y",
407 "BIU" => "Y",
408 "IMG" => "Y",
409 "QUOTE" => "Y",
410 "CODE" => "Y",
411 "FONT" => "Y",
412 "LIST" => "Y",
413 "SMILES" => "Y",
414 "NL2BR" => "N",
415 "VIDEO" => "Y",
416 "USER" => "N",
417 "TAG" => "Y",
418 "SHORT_ANCHOR" => "Y"
419 ];
420 if(Main\Config\Option::get("blog","allow_video", "Y") != "Y")
421 {
422 $allow["VIDEO"] = "N";
423 }
424
425 $iterator = \CSocNetLog::getList(
426 $settings['order'],
427 $settings['filter'],
428 false,
429 $settings['limit'],
430 [ 'SOURCE_ID' ],
431 [
432 'CHECK_RIGHTS' => 'N',
433 'USE_FOLLOW' => 'N',
434 'USE_SUBSCRIBE' => 'N',
435 'USE_FAVORITES' => 'N',
436 ]
437 );
438
439 $blogPostIdList = [];
440 while ($row = $iterator->fetch())
441 {
442 $blogPostIdList[] = $row['SOURCE_ID'];
443 }
444
445 $diskInstalled = Main\Loader::includeModule('disk');
446
447 if (
448 !empty($blogPostIdList)
449 && Main\Loader::includeModule('blog')
450 )
451 {
452 if ($diskInstalled)
453 {
454 $driver = \Bitrix\Disk\Driver::getInstance();
455 $urlManager = $driver->getUrlManager();
456 }
457
458
459 $query = new \Bitrix\Main\Entity\Query(PostTable::getEntity());
460 $query->addOrder('DATE_PUBLISH', 'DESC');
461 $query->addFilter('@ID', $blogPostIdList);
462 $query->addSelect('ID');
463 $query->addSelect('MICRO');
464 $query->addSelect('TITLE');
465 $query->addSelect('DETAIL_TEXT');
466 $query->addSelect('AUTHOR_ID');
467 $query->addSelect('DATE_PUBLISH');
468
469 $query->registerRuntimeField(
470 '',
471 new \Bitrix\Main\Entity\ReferenceField('U',
472 UserTable::getEntity(),
473 array(
474 '=ref.ID' => 'this.AUTHOR_ID'
475 ),
476 array('join_type' => 'INNER')
477 )
478 );
479 $query->addSelect('U.PERSONAL_PHOTO', 'AUTHOR_AVATAR');
480 $query->addSelect('U.NAME', 'AUTHOR_NAME');
481 $query->addSelect('U.LAST_NAME', 'AUTHOR_LAST_NAME');
482 $query->addSelect('U.SECOND_NAME', 'AUTHOR_SECOND_NAME');
483 $query->addSelect('U.LOGIN', 'AUTHOR_LOGIN');
484
485 $iterator = $query->exec();
486 while ($row = $iterator->fetch())
487 {
488 if (defined("BX_COMP_MANAGED_CACHE"))
489 {
490 $CACHE_MANAGER->registerTag("blog_post_".$row['ID']);
491 }
492
493 $attachedFilesList = [];
494
495 if ($diskInstalled)
496 {
497 $res = \Bitrix\Disk\AttachedObject::getList(array(
498 'filter' => array(
499 '=ENTITY_TYPE' => \Bitrix\Disk\Uf\BlogPostConnector::className(),
500 'ENTITY_ID' => $row
501 ),
502 'select' => array('ID', 'OBJECT_ID', 'FILENAME' => 'OBJECT.NAME')
503 ));
504 foreach ($res as $attachedObjectFields)
505 {
506 $attachedObjectFields['URL'] = (\Bitrix\Disk\TypeFile::isImage($attachedObjectFields['FILENAME'])
507 ? $urlManager->getUrlUfController('show', array('attachedId' => $attachedObjectFields['ID']))
508 : ''
509 );
510 $attachedFilesList[] = $attachedObjectFields;
511 }
512 }
513
514 $detailTextInOneString = str_replace("\r\n", "", $row["DETAIL_TEXT"]);
515
516 $inlineAttachmentsList = [];
517 if (preg_match_all('/\[DISK\sFILE\sID=([n]*)(\d+)\]/', $row["DETAIL_TEXT"], $matches))
518 {
519 foreach($matches[2] as $key => $value)
520 {
521 $inlineAttachmentsList[] = [
522 'ID' => $value,
523 'KEY' => ($matches[1][$key] === 'n' ? 'OBJECT_ID' : 'ID'),
524 'POSITION' => mb_strpos($detailTextInOneString, $matches[0][$key])
525 ];
526 }
527 }
528
529 $picture = '';
530 $diskPicturePosition = false;
531 foreach($inlineAttachmentsList as $inlineAttachment)
532 {
533 foreach($attachedFilesList as $attachedFile)
534 {
535 if(
536 $attachedFile[$inlineAttachment['KEY']] == $inlineAttachment['ID']
537 && !empty($attachedFile['URL'])
538 )
539 {
540 $picture = [
541 'alt' => (!empty($attachedFile['FILENAME']) ? $attachedFile['FILENAME'] : ''),
542 'src' => $attachedFile['URL']
543 ];
544 $diskPicturePosition = $inlineAttachment['POSITION'];
545 break;
546 }
547 }
548 if(!empty($picture))
549 {
550 break;
551 }
552 }
553
554 $imgPattern = '/\[IMG\s+WIDTH\s*=\s*\d+\s+HEIGHT\s*=\s*\d+\s*\](.+?)\[\/IMG\]/is'.BX_UTF_PCRE_MODIFIER;
555 $videoPattern = '/\[VIDEO[^\]]*](.+?)\[\/VIDEO\]/is'.BX_UTF_PCRE_MODIFIER;
556 $detailText = \Bitrix\Socialnetwork\Helper\Mention::clear($row['DETAIL_TEXT']);
557
558 if (
559 preg_match_all($imgPattern, $detailText, $matches)
560 && !empty($matches[0])
561 && !empty($matches[0][0])
562 )
563 {
564 if (
565 $diskPicturePosition === false
566 || mb_strpos($detailTextInOneString, $matches[0][0]) < $diskPicturePosition
567 )
568 {
569 $picture = [
570 'alt' => '',
571 'src' => $matches[1][0]
572 ];
573 }
574 }
575
576 $parser = new \blogTextParser(false, $pathToSmile, []);
577 $parser->LAZYLOAD = "N";
578
579 $postFields = $USER_FIELD_MANAGER->getUserFields("BLOG_POST", $row['ID'], LANGUAGE_ID);
580 if (!empty($postFields["UF_BLOG_POST_FILE"]))
581 {
582 $parser->arUserfields = array("UF_BLOG_POST_FILE" => array_merge($postFields["UF_BLOG_POST_FILE"], ["TAG" => "DOCUMENT ID"]));
583 }
584
585 $clearedText = $detailText;
586
587 $clearedText = preg_replace(
588 [ $imgPattern, $videoPattern ],
589 '',
590 $clearedText
591 );
592 $clearedText = preg_replace(
593 '/\[URL(.*?)]([^\]\s]{20,})\[\/URL\]/is'.BX_UTF_PCRE_MODIFIER,
594 '',
595 $clearedText
596 );
597 $clearedText = preg_replace(
598 '/\[URL(.*?)]((?:[^\]\s]{1,19}\s+)+)\[\/URL\]/is'.BX_UTF_PCRE_MODIFIER,
599 '\\2',
600 $clearedText
601 );
602 $clearedText = preg_replace(
603 '/\[URL(.*?)]((?:[^\]\s]{1,19}\s+)+)\[\/URL\]/is'.BX_UTF_PCRE_MODIFIER,
604 '\\2',
605 $clearedText
606 );
607 $clearedText = \blogTextParser::killAllTags($clearedText);
608
609 $title = (
610 $row["MICRO"] == "Y"
611 ? truncateText($clearedText, 100)
612 : htmlspecialcharsEx($row["TITLE"])
613 );
614
615 $authorAvatar = '';
616 $authorName = '';
617 if (intval($row['AUTHOR_AVATAR']) > 0)
618 {
619 $fileRes = FileTable::getById(intval($row['AUTHOR_AVATAR']));
620 if ($fileFields = $fileRes->fetch())
621 {
622 $authorAvatar = [
623 'alt' => '',
624 'src' => \CFile::getFileSrc($fileFields)
625 ];
626 }
627 }
628 if (intval($row['AUTHOR_ID']) > 0)
629 {
630 $authorName = \CUser::formatName(\CSite::getNameFormat(), [
631 "NAME" => $row["AUTHOR_NAME"],
632 "LAST_NAME" => $row["AUTHOR_LAST_NAME"],
633 "SECOND_NAME" => $row["AUTHOR_SECOND_NAME"],
634 "LOGIN" => $row["AUTHOR_LOGIN"],
635 "NAME_LIST_FORMATTED" => "",
636 ]);
637 }
638 if ($row['DATE_PUBLISH'] instanceof \Bitrix\Main\Type\DateTime)
639 {
640 $logDate = $row['DATE_PUBLISH']->format(\Bitrix\Main\Type\Date::getFormat());
641 }
642
643 $result[] = [
644 'ID' => $row['ID'],
645 'TITLE' => $title,
646 'PREVIEW_TEXT' => truncateText($clearedText, 255),
647 'DETAIL_TEXT' => $parser->convert($detailText, false, [], $allow, $parserParams),
648 'PICTURE' => $picture,
649 'AUTHOR_AVATAR' => $authorAvatar,
650 'AUTHOR_NAME_FORMATTED' => $authorName,
651 'LOG_DATE' => $logDate,
652 ];
653 }
654 if (!empty($result))
655 {
656 usort($result, function($a, $b) use ($blogPostIdList) {
657 $keyA = array_search($a['ID'], $blogPostIdList);
658 $keyB = array_search($b['ID'], $blogPostIdList);
659 return ($keyA > $keyB) ? +1 : -1;
660 });
661 }
662 }
663
664 return $result;
665 }
666
671 public static function onSocNetLogRightsAddHandler($code)
672 {
673 global $CACHE_MANAGER;
674
675 if (
676 defined("BX_COMP_MANAGED_CACHE")
677 && $code <> ''
678 && preg_match('/^SG(\d+)$/i', $code, $matches)
679 && Main\ModuleManager::isModuleInstalled('landing')
680 )
681 {
682 $CACHE_MANAGER->clearByTag("landing_dynamic_filter_".$code);
683 }
684 }
685
690 public function normalizeFilter($filter)
691 {
692 if (!is_array($filter))
693 {
694 return [];
695 }
696 if (empty($filter))
697 {
698 return $filter;
699 }
700
701 $result = [];
702 foreach ($filter as $row)
703 {
704 if (empty($row) || !is_array($row))
705 {
706 continue;
707 }
708 if (empty($row['key']) || empty($row['value']))
709 {
710 continue;
711 }
712 $result[] = $row;
713 }
714 unset($row);
715
716 if (!empty($result))
717 {
718 Main\Type\Collection::sortByColumn($result, ['key' => SORT_ASC]);
719 }
720 return $result;
721 }
722}
Definition post.php:33
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29