17use Bitrix\Socialnetwork\Item\Workgroup\Type;
51 'CLEAR_SMILES' =>
'N',
56 'SHORT_ANCHOR' =>
'N',
80 'p' =>
'ui-typography-paragraph',
81 'b' =>
'ui-typography-text-bold',
82 'i' =>
'ui-typography-text-italic',
83 'u' =>
'ui-typography-text-underline',
84 's' =>
'ui-typography-text-strikethrough',
85 'code' =>
'ui-typography-code',
86 'quote' =>
'ui-typography-quote',
87 'url' =>
'ui-typography-link',
88 'image-container' =>
'ui-typography-image-container',
89 'image' =>
'ui-typography-image',
90 'ol' =>
'ui-typography-ol',
91 'ul' =>
'ui-typography-ul',
92 'li' =>
'ui-typography-li',
93 'table' =>
'ui-typography-table',
94 'td' =>
'ui-typography-table-cell',
95 'tr' =>
'ui-typography-table-row',
96 'th' =>
'ui-typography-table-cell ui-typography-table-cell-header',
97 'mention' =>
'ui-typography-mention',
98 'smiley' =>
'ui-typography-smiley',
99 'hashtag' =>
'ui-typography-hashtag',
124 $this->ajaxPage =
$APPLICATION->GetCurPageParam(
'', [
'bxajaxid',
'logout']);
129 if ($this->anchorSchemes ===
null)
131 static $schemes =
null;
132 if ($schemes ===
null)
134 $schemes = Option::get(
'main',
'~parser_anchor_schemes',
'http|https|news|ftp|aim|mailto|file|tel|callto|skype|viber');
136 $this->anchorSchemes = $schemes;
143 $this->anchorSchemes = $schemes;
148 if (!array_key_exists($this->smilesGallery, self::$repoSmiles))
150 $smiles = CSmile::getByGalleryId(CSmile::TYPE_SMILE, $this->smilesGallery);
154 $arTypings = explode(
' ', $smile[
'TYPING']);
155 foreach ($arTypings as $typing)
157 $arSmiles[] = array_merge($smile, [
159 'IMAGE' => CSmile::PATH_TO_SMILE . $smile[
'SET_ID'] .
'/' . $smile[
'IMAGE'],
160 'DESCRIPTION' => $smile[
'NAME'],
161 'DESCRIPTION_DECODE' =>
'Y',
172 $this->smilePatterns = [];
173 $this->smileReplaces = [];
176 foreach ($this->smiles as $row)
178 if (preg_match(
"/\\w\$/", $row[
'TYPING']))
180 $pre .=
'|' . preg_quote($row[
'TYPING'],
'/');
184 foreach ($this->smiles as $row)
186 if ($row[
'TYPING'] !=
'' && $row[
'IMAGE'] !=
'')
188 $code = str_replace([
"'",
"<",
">"], [
"\\'",
"<",
">"], $row[
"TYPING"]);
189 $patt = preg_quote(
$code,
"/");
190 $code = preg_quote(str_replace([
"\x5C"], [
"\"],
$code));
191 $image = preg_quote(str_replace(
"'",
"\\'", $row[
"IMAGE"]));
194 $patternName =
'pattern' .
count($this->smilePatterns);
196 $this->smilePatterns[] =
"/(?<=^|\\>|[" . $this->wordSeparator .
"\\&]" . $pre .
")(?P<" . $patternName .
">$patt)(?=$|\\<|[" . $this->wordSeparator .
"\\&])/su";
198 $this->smileReplaces[$patternName] = [
202 'width' => intval($row[
'IMAGE_WIDTH']),
203 'height' => intval($row[
'IMAGE_HEIGHT']),
204 'descriptionDecode' => $row[
'DESCRIPTION_DECODE'] ==
'Y',
205 'imageDefinition' => $row[
'IMAGE_DEFINITION'] ?: CSmile::IMAGE_SD,
209 usort($this->smilePatterns,
function(
$a, $b) {
return (mb_strlen(
$a) > mb_strlen($b) ? -1 : 1); });
220 $attributes = is_array($attributes) ? $attributes : [];
222 $text = preg_replace([
"#([?&;])PHPSESSID=([0-9a-zA-Z]{32})#i",
"/\\x{00A0}/u"], [
"\\1PHPSESSID1=",
" "],
$text);
224 $this->defended_urls = [];
226 if ($this->serverName ==
'' && $this->type ==
'rss')
228 $dbSite = CSite::GetByID(
SITE_ID);
229 $arSite = $dbSite->Fetch();
233 if (defined(
'SITE_SERVER_NAME') && SITE_SERVER_NAME !=
'')
239 $serverName = COption::GetOptionString(
'main',
'server_name');
248 $this->preg = [
'counter' => 0,
'pattern' => [],
'replace' => [],
'cache' => []];
250 foreach (
GetModuleEvents(
'main',
'TextParserBefore',
true) as $arEvent)
255 if (($this->allow[
'CODE'] ??
'') ==
'Y')
257 $text = preg_replace_callback(
259 "#(\\[code(?:\\s+[^]]*]|]))(.+?)(\\[/code(?:\\s+[^]]*]|]))#isu",
260 "#(<code(?:\\s+[^>]*>|>))(.+?)(</code(?:\\s+[^>]*>|>))#isu",
262 [$this,
'convertCode'],
266 if (($this->allow[
'HTML'] ??
'') !=
'Y' && ($this->allow[
'NL2BR'] ??
'') ==
'Y')
268 $text = preg_replace(
"#<br(.*?)>#is",
"\n",
$text);
270 if (($this->allow[
'HTML'] ??
'') !=
'Y')
273 if (($this->allow[
'ANCHOR'] ??
'') ==
'Y')
275 $text = preg_replace(
277 "#<a[^>]+href\\s*=\\s*(['\"])(.+?)(?:\\1)[^>]*>(.*?)</a[^>]*>#isu",
278 "#<a[^>]+href(\\s*=\\s*)([^'\">]+)>(.*?)</a[^>]*>#isu",
280 "[url=\\2]\\3[/url]",
$text
283 if (($this->allow[
'BIU'] ??
'') ==
'Y')
288 $text = preg_replace(
289 "/<([busi])[^>a-z]*>(.+?)<\\/(\\1)[^>a-z]*>/isu",
291 $text, -1, $replaced);
293 while ($replaced > 0);
295 if (($this->allow[
'P'] ??
'') ==
'Y')
300 $text = preg_replace(
301 "/<p[^>a-z]*>(.+?)<\\/p[^>a-z]*>/isu",
303 $text, -1, $replaced);
305 while ($replaced > 0);
307 if (($this->allow[
'IMG'] ??
'') ==
'Y')
309 $text = preg_replace(
310 "#<img[^>]+src\\s*=[\\s'\"]*(((http|https|ftp)://[.\\-_:a-z0-9@]+)*(/[-_/=:.a-z0-9@{}&?%]+)+)[\\s'\"]*[^>]*>#isu",
311 "[img]\\1[/img]",
$text
314 if (($this->allow[
'FONT'] ??
'') ==
'Y')
316 $text = preg_replace(
318 "/<font[^>]+size\\s*=[\\s'\"]*([0-9]+)[\\s'\"]*[^>]*>(.+?)<\\/font[^>]*>/isu",
319 "/<font[^>]+color\\s*=[\\s'\"]*(#[a-f0-9]{6})[^>]*>(.+?)<\\/font[^>]*>/isu",
320 "/<font[^>]+face\\s*=[\\s'\"]*([a-z\\s\\-]+)[\\s'\"]*[^>]*>(.+?)<\\/font[^>]*>/isu",
323 "[size=\\1]\\2[/size]",
324 "[color=\\1]\\2[/color]",
325 "[font=\\1]\\2[/font]",
330 if (($this->allow[
'LIST'] ??
'') ==
'Y')
332 $text = preg_replace(
334 "/<ul((\\s[^>]*)|(\\s*))>(.+?)<\\/ul([^>]*)>/isu",
335 "/<ol((\\s[^>]*)|(\\s*))>(.+?)<\\/ol([^>]*)>/isu",
336 "/<li((\\s[^>]*)|(\\s*))>(.+?)<\\/li([^>]*)>/isu",
337 "/<li((\\s[^>]*)|(\\s*))>/isu",
341 "[list=1]\\4[/list]",
348 if (($this->allow[
'TABLE'] ??
'') ==
'Y')
350 $text = preg_replace(
352 "/<table((\\s[^>]*)|(\\s*))>/isu",
353 "/<\\/table([^>]*)>/isu",
354 "/<tr((\\s[^>]*)|(\\s*))>/isu",
355 "/<\\/tr([^>]*)>/isu",
356 "/<td((\\s[^>]*)|(\\s*))>/isu",
357 "/<\\/td([^>]*)>/isu",
358 "/<th((\\s[^>]*)|(\\s*))>/isu",
359 "/<\\/th([^>]*)>/isu",
374 if (($this->allow[
'QUOTE'] ??
'') ==
'Y')
376 $text = preg_replace(
"#<(/?)quote(.*?)>#is",
"[\\1quote]",
$text);
381 $text = preg_replace(
382 "/<cut([^>]*)>(.+?)<\/cut>/isu",
383 "[cut=\\1]\\2[/cut]",
389 if ($this->preg[
'counter'] > 0)
391 $res = mb_strlen((
string)$this->preg[
'counter']);
395 $p[] =
'\d{' . (
$res + 1) .
'}';
397 $text = preg_replace(
398 [
"/<(?!\017#(" . implode(
")|(",
$p) .
")>)/",
"/(?<!<\017#(" . implode(
")|(",
$p) .
"))>/",
"/\"/"],
399 [
"<",
">",
"""],
407 [
"<",
">",
"""],
415 if (($this->allow[
'VIDEO'] ??
'') ==
'Y')
417 $patt[] =
"/\\[video([^\\]]*)\\](.+?)\\[\\/video[\\s]*\\]/isu";
419 if (($this->allow[
'IMG'] ??
'') ==
'Y')
421 $patt[] =
"/\\[img([^\\]]*)\\](.+?)\\[\\/img\\]/isu";
424 foreach (
GetModuleEvents(
'main',
'TextParserBeforeAnchorTags',
true) as $arEvent)
429 if (($this->allow[
'ANCHOR'] ??
'') ==
'Y')
431 $patt[] =
"/\\[url\\](.*?)\\[\\/url\\]/iu";
432 $patt[] =
"/\\[url\\s*=\\s*(
435 |\\[ (?: (?>[^\\[\\]]+) | (?:\\1) )* \\]
437 )\\s*\\](.*?)\\[\\/url\\]/ixsu";
439 $text = preg_replace_callback(
445 if (($this->allow[
'TEXT_ANCHOR'] ??
'Y') ==
'Y')
458 foreach ($boundaries as
$start => $end)
462 $patt[] =
"/(?<=" . preg_quote(
$start) .
")(?<!\\[nomodify\\]|<nomodify>)((((" . $schemes .
"):\\/\\/)|www\\.)[._:a-z0-9@-].*?)(?=" . preg_quote($end) .
")/isu";
466 $patt[] =
"/(?<=^|[" . $this->wordSeparator .
"])(?<!\\[nomodify\\]|<nomodify>)((((" . $schemes .
"):\\/\\/)|www\\.)[._:a-z0-9@-].*?)(?=[\\s\"{}]|"|\$)/isu";
468 $text = preg_replace_callback(
470 fn(
$matches) => $this->preconvertUrl(
$matches, $attributes[
'TEXT_ANCHOR'] ?? []),
477 $text = preg_replace_callback($patt, [$this,
'preconvertAnchor'],
$text);
480 $text = preg_replace(
"/<\\/?nomodify>/iu",
'',
$text);
482 if (($this->allow[
'SPOILER'] ??
'') ===
'Y')
486 $text = preg_replace(
488 "/\\[(cut|spoiler)(([^]])*)]/isu",
489 "/\\[\\/(cut|spoiler)]/isu",
498 while (preg_match(
"/(\001([^\002]*)\002([^\001\002\003]+)\003)/isu",
$text,
$matches))
500 $text = preg_replace_callback(
"/\001([^\002]*)\002([^\001\002\003]+)\003/isu", [ $this,
'convert_spoiler_tag' ],
$text);
503 $text = preg_replace(
505 "/\001([^\002]+)\002/",
519 foreach (
GetModuleEvents(
'main',
'TextParserBeforeTags',
true) as $arEvent)
525 ($this->allow[
'SMILES'] ??
'') ==
'Y'
526 || ($this->allow[
'CLEAR_SMILES'] ??
'') ==
'Y'
529 if (str_contains(
$text,
"<nosmile>"))
531 $text = preg_replace_callback(
532 "/<nosmile>(.*?)<\\/nosmile>/isu",
533 [$this,
"defendTags"],
537 if ($this->smiles ===
null)
541 if (!empty($this->smiles))
543 if ($this->smilePatterns ===
null)
548 if (!empty($this->smilePatterns))
550 $text = preg_replace_callback($this->smilePatterns, [$this,
'convertEmoticon'],
' ' .
$text .
' ');
557 if (!isset($this->allow[
'EMOJI']) || $this->allow[
'EMOJI'] !=
'N')
588 if (str_contains(
$text,
'<nomodify>'))
590 $text = preg_replace_callback(
591 "/<nomodify>(.*?)<\\/nomodify>/isu",
592 [$this,
"defendTags"],
600 $text = preg_replace_callback(
601 "/\\[video([^]]*)](.+?)\\[\\/video\\s*]/isu",
602 [$this,
'convertVideo'],
607 $text = preg_replace_callback(
608 "/\\[img([^]]*)](.+?)\\[\\/img]/isu",
609 [$this,
'convertImage'],
615 "/\\[url\\](.*?)\\[\\/url\\]/iu",
619 |\\[ (?: (?>[^\\[\\]]+) | (?:\\1) )* \\]
621 )\\s*\\](.*?)\\[\\/url\\]/ixsu",
624 if (($this->allow[
'CUT_ANCHOR'] ??
'') !=
'Y')
626 $text = preg_replace_callback(
634 $text = preg_replace($arUrlPatterns,
'',
$text);
641 $text = preg_replace_callback(
642 "/\\[([busi])](.*?)\\[\\/(\\1)]/isu",
645 $className = $this->useTypography ?
' class="' . $this->tagClasses[$tag] .
'"' :
'';
647 return "<$tag$className>" .
$matches[2].
"</$tag>";
654 while ($replaced > 0);
660 $text = preg_replace_callback(
661 "/\\[p](.*?)\\[\\/p](([ \r\t]*)\n?)/isu",
663 $className = $this->useTypography ?
' class="' . $this->tagClasses[
'p'] .
'"' :
'';
665 return "<p$className>". self::trimLineBreaks(
$matches[1]) .
'</p>';
672 while ($replaced > 0);
675 $olClassName = $this->useTypography ?
' class="' . $this->tagClasses[
'ol'] .
'"' :
'';
676 $ulClassName = $this->useTypography ?
' class="' . $this->tagClasses[
'ul'] .
'"' :
'';
677 $liClassName = $this->useTypography ?
' class="' . $this->tagClasses[
'li'] .
'"' :
'';
679 while (preg_match(
"/\\[list\\s*=\\s*([1a])\\s*](.+?)\\[\\/list]/isu",
$text))
681 $text = preg_replace(
683 "/\\[list\\s*=\\s*1\\s*](\\s*)(.+?)\\[\\/list](([\040\\r\\t]*)\\n?)/isu",
684 "/\\[list\\s*=\\s*a\\s*](\\s*)(.+?)\\[\\/list](([\040\\r\\t]*)\\n?)/isu",
688 "<ol$olClassName>\\2</ol>",
689 "<ol type=\"a\"$olClassName>\\2</ol>",
695 while (preg_match(
"/\\[list](.+?)\\[\\/list](([\\040\\r\\t]*)\\n?)/isu",
$text))
697 $text = preg_replace(
699 "/\\[list](\\s*)(.+?)\\[\\/list](([\\040\\r\\t]*)\\n?)/isu",
703 "<ul$ulClassName>\\2</ul>",
711 while (preg_match(
"/\\[size\\s*=\\s*([^]]+)](.*?)\\[\\/size]/isu",
$text))
713 $text = preg_replace_callback(
714 "/\\[size\\s*=\\s*([^]]+)](.*?)\\[\\/size]/isu",
715 [$this,
'convertFontSize'],
719 while (preg_match(
"/\\[font\\s*=\\s*([^]]+)](.*?)\\[\\/font]/isu",
$text))
721 $text = preg_replace_callback(
722 "/\\[font\\s*=\\s*([^]]+)](.*?)\\[\\/font]/isu",
723 [$this,
'convertFont'],
727 while (preg_match(
"/\\[color\\s*=\\s*([^]]+)](.*?)\\[\\/color]/isu",
$text))
729 $text = preg_replace_callback(
730 "/\\[color\\s*=\\s*([^]]+)](.*?)\\[\\/color]/isu",
731 [$this,
'convertFontColor'],
737 while (preg_match(
"/\\[table]/isu",
$text))
739 $tagToCheckList = [
'td',
'th',
'tr',
'table'];
740 foreach ($tagToCheckList as $tagToCheck)
742 preg_match_all(
"/\\[" . $tagToCheck .
"]/isu",
$text,
$matches);
745 preg_match_all(
"/\\[\\/" . $tagToCheck .
"]/is",
$text,
$matches);
748 $unclosed = $opentags - $closetags;
751 $text .= str_repeat(
'[/' . $tagToCheck .
']', $unclosed);
755 $tableClass = $this->useTypography ? $this->tagClasses[
'table'] :
'data-table';
758 ?
"<div style=\"overflow-x: auto;\"><table class=\"$tableClass\">"
759 :
"<table class=\"$tableClass\">"
767 $trClass = $this->useTypography ?
' class="' . $this->tagClasses[
'tr'] .
'"' :
'';
768 $tdClass = $this->useTypography ?
' class="' . $this->tagClasses[
'td'] .
'"' :
'';
769 $thClass = $this->useTypography ?
' class="' . $this->tagClasses[
'th'] .
'"' :
'';
771 $text = preg_replace(
774 "/\\[\\/table](?:(?:[\\040\\r\\t]*)\\n?)/isu",
775 "/(\\s*?)\\[tr]/isu",
776 "/\\[\\/tr](\\s*?)/isu",
777 "/(\\s*?)\\[td]/isu",
778 "/\\[\\/td](\\s*?)/isu",
779 "/(\\s*?)\\[th]/isu",
780 "/\\[\\/th](\\s*?)/isu",
797 $paragraph =
"<p class=\"{$this->tagClasses['p']}\">\\1</p>";
802 $text = preg_replace(
804 "/\\[left](.*?)\\[\\/left](([\\040\\r\\t]*)\\n?)/isu",
805 "/\\[right](.*?)\\[\\/right](([\\040\\r\\t]*)\\n?)/isu",
806 "/\\[center](.*?)\\[\\/center](([\\040\\r\\t]*)\\n?)/isu",
807 "/\\[justify](.*?)\\[\\/justify](([\\040\\r\\t]*)\\n?)/isu",
810 $this->useTypography ? $paragraph :
"<div align=\"left\">\\1</div>",
811 $this->useTypography ? $paragraph :
"<div align=\"right\">\\1</div>",
812 $this->useTypography ? $paragraph :
"<div align=\"center\">\\1</div>",
813 $this->useTypography ? $paragraph :
"<div align=\"justify\">\\1</div>",
820 while ($replaced > 0);
823 while (preg_match(
"/\\[quote[^]]*](.*?)\\[\\/quote[^]]*]/isu",
$text))
825 $text = preg_replace_callback(
826 "/\\[quote[^]]*](.*?)\\[\\/quote[^]]*](([\\040\\r\\t]*)\\n?)/isu",
827 [$this,
'convertQuote'],
837 $text = preg_replace(
839 "/\[cut(([^]])*)]/isu",
849 $text = preg_replace_callback(
850 "/(\001([^\002]*)\002([^\001\002\003]+)\003)/isu",
857 $text = preg_replace(
859 "/\001([^\002]+)\002/",
872 if (str_contains(
$text,
'<nomodify>'))
874 $text = preg_replace_callback(
875 "/<nomodify>(.*?)<\\/nomodify>/isu",
876 [$this,
'defendTags'],
881 if (isset($this->allow[
'USERFIELDS']) && is_array($this->allow[
'USERFIELDS']))
883 foreach ($this->allow[
'USERFIELDS'] as
$userField)
893 case 'webdav_element' :
903 method_exists(
$userField[
'USER_TYPE'][
'CLASS_NAME'],
'GetPublicViewHTML') )
907 $text = preg_replace_callback(
909 [$this,
'convert_userfields'],
916 if (!isset($this->allow[
'USER']) || $this->allow[
'USER'] !=
'N')
920 $textOriginal =
$text;
921 $text = preg_replace_callback(
922 "/\[user\s*=\s*([^]]*)]((?:(?!\[user\s*=\s*[^]]*]).)+?)\[\/user]/isu",
923 [$this,
'convert_user'],
927 while ($textOriginal !==
$text);
930 if (!isset($this->allow[
'PROJECT']) || $this->allow[
'PROJECT'] !==
'N')
932 $text = preg_replace_callback(
933 "/\[project\s*=\s*([^]]*)](.+?)\[\/project]/isu",
934 [ $this,
'convert_project' ],
939 if (!isset($this->allow[
'DEPARTMENT']) || $this->allow[
'DEPARTMENT'] !==
'N')
941 $text = preg_replace_callback(
942 "/\[department\s*=\s*([^]]*)](.+?)\[\/department]/isu",
943 [ $this,
'convert_department' ],
948 if (isset($this->allow[
'TAG']) && $this->allow[
'TAG'] ==
'Y')
950 $text = preg_replace_callback(
952 [$this,
'convert_tag'],
957 foreach (
GetModuleEvents(
'main',
'TextParserAfterTags',
true) as $arEvent)
962 if (($this->allow[
'HTML'] ??
'') !=
'Y' || ($this->allow[
'NL2BR'] ??
'') ==
'Y')
964 $text = str_replace([
"\r\n",
"\n"],
"<br />",
$text);
965 $text = preg_replace(
967 "/<br \\/>[\\t\\s]*(<\\/table[^>]*>)/isu",
968 "/<br \\/>[\\t\\s]*(<thead[^>]*>)/isu",
969 "/<br \\/>[\\t\\s]*(<\\/thead[^>]*>)/isu",
970 "/<br \\/>[\\t\\s]*(<tfoot[^>]*>)/isu",
971 "/<br \\/>[\\t\\s]*(<\\/tfoot[^>]*>)/isu",
972 "/<br \\/>[\\t\\s]*(<tbody[^>]*>)/isu",
973 "/<br \\/>[\\t\\s]*(<\\/tbody[^>]*>)/isu",
974 "/<br \\/>[\\t\\s]*(<tr[^>]*>)/isu",
975 "/<br \\/>[\\t\\s]*(<\\/tr[^>]*>)/isu",
976 "/<br \\/>[\\t\\s]*(<td[^>]*>)/isu",
977 "/<br \\/>[\\t\\s]*(<\\/td[^>]*>)/isu",
987 "(tm)",
"(TM)",
"(Tm)",
"(tM)",
992 "™",
"™",
"™",
"™",
998 if (($this->allow[
'HTML'] ??
'') !=
'Y')
1000 if ($this->maxStringLen > 0)
1002 $text = preg_replace(
"/(&#\\d{1,3};)/isu",
"<\019\\1>",
$text);
1003 $text = preg_replace_callback(
"/(?<=^|>)([^<>\\[]+?)(?=<|\\[|$)/isu", [$this,
"partWords"],
$text);
1004 $text = preg_replace(
"/(<\019((&#\\d{1,3};))>)/isu",
"\\2",
$text);
1006 $text = preg_replace_callback(
"/(?<=^|>)([^<>\\[]+?)(?=<|\\[|$)/isu", [$this,
"parseSpaces"],
$text);
1009 foreach (
GetModuleEvents(
'main',
'TextParserBeforePattern',
true) as $arEvent)
1014 if ($this->preg[
'counter'] > 0)
1016 $text = str_replace(array_reverse($this->preg[
'pattern']), array_reverse($this->preg[
'replace']),
$text);
1019 foreach (
GetModuleEvents(
'main',
'TextParserAfter',
true) as $arEvent)
1038 if ((
$k = array_search(
$text, $this->preg[
'replace'])) !==
false)
1043 $this->preg[
"pattern"][] =
"<\017#" . $this->preg[
"counter"] .
">";
1044 $this->preg[
"replace"][] =
$text;
1045 $text =
"<\017#" . $this->preg[
"counter"] .
">";
1046 $this->preg[
"counter"]++;
1063 $arPattern[] =
"/\\[(code|quote)(.*?)\\]/isu";
1064 $arReplace[] =
"\n>================== \\1 ===================\n";
1066 $arPattern[] =
"/\\[\\/(code|quote)(.*?)\\]/isu";
1067 $arReplace[] =
"\n>===========================================\n";
1069 $arPattern[] =
"/\\<WBR[\\s\\/]?\\>/isu";
1072 $arPattern[] =
"/\\[\\*\\]/isu";
1073 $arReplace[] =
"- ";
1075 $arPattern[] =
"/^(\r|\n)+?(.*)$/";
1076 $arReplace[] =
"\\2";
1078 $arPattern[] =
"/\\[b\\](.+?)\\[\\/b\\]/isu";
1079 $arReplace[] =
"\\1";
1081 $arPattern[] =
"/\\[p\\](.*?)\\[\\/p\\]/isu";
1082 $arReplace[] =
"\\1";
1084 $arPattern[] =
"/\\[i\\](.+?)\\[\\/i\\]/isu";
1085 $arReplace[] =
"\\1";
1087 $arPattern[] =
"/\\[u\\](.+?)\\[\\/u\\]/isu";
1088 $arReplace[] =
"_\\1_";
1090 $arPattern[] =
"/\\[s\\](.+?)\\[\\/s\\]/isu";
1091 $arReplace[] =
"_\\1_";
1093 $arPattern[] =
"/\\[(\\/?)(color|font|size|left|right|center)([^\\]]*)\\]/isu";
1096 $arPattern[] =
"/\\[url\\](\\S+?)\\[\\/url\\]/isu";
1097 $arReplace[] =
"(URL: \\1 )";
1099 $arPattern[] =
"/\\[url\\s*=\\s*(\\S+?)\\s*\\](.*?)\\[\\/url\\]/isu";
1100 $arReplace[] =
"\\2 (URL: \\1 )";
1102 $arPattern[] =
"/\\[img([^\\]]*)\\](.+?)\\[\\/img\\]/isu";
1103 $arReplace[] =
"(IMAGE: \\2)";
1105 $arPattern[] =
"/\\[video([^\\]]*)\\](.+?)\\[\\/video[\\s]*\\]/isu";
1106 $arReplace[] =
"(VIDEO: \\2)";
1108 $arPattern[] =
"/\\[(\\/?)list(.*?)\\]/isu";
1109 $arReplace[] =
"\n";
1111 $arPattern[] =
"/\\[user([^\\]]*)\\](.+?)\\[\\/user\\]/isu";
1112 $arReplace[] =
"\\2";
1114 $arPattern[] =
"/\\[project([^\\]]*)\\](.+?)\\[\\/project\\]/isu";
1115 $arReplace[] =
"\\2";
1117 $arPattern[] =
"/\\[department([^\\]]*)\\](.+?)\\[\\/department\\]/isu";
1118 $arReplace[] =
"\\2";
1120 $arPattern[] =
"/\\[DOCUMENT([^\\]]*)\\]/isu";
1123 $arPattern[] =
"/\\[DISK(.+?)\\]/isu";
1126 $arPattern[] =
"/\\[(table)(.*?)\\]/isu";
1127 $arReplace[] =
"\n>================== \\1 ===================";
1129 $arPattern[] =
"/\\[\\/table(.*?)\\]/isu";
1130 $arReplace[] =
"\n>===========================================\n";
1132 $arPattern[] =
"/\\[tr\\]\\s*/isu";
1133 $arReplace[] =
"\n";
1135 $arPattern[] =
"/\\[(\\/?)(tr|td)\\]/isu";
1138 $text = preg_replace($arPattern, $arReplace,
$text);
1141 if (preg_match(
"/\[cut(([^]])*)]/isu",
$text))
1143 $text = preg_replace(
1145 "/\[cut(([^]])*)]/isu",
1154 while (preg_match(
"/(\001([^\002]*)\002([^\001\002\003]+)\003)/isu",
$text))
1156 $text = preg_replace(
1157 "/(\001([^\002]*)\002([^\001\002\003]+)\003)/isu",
1158 "\n>================== CUT ===================\n\\3\n>==========================================\n",
1162 $text = preg_replace(
1164 "/\001([^\002]+)\002/",
1177 static $replacements = [
1212 preg_match(
"/height=([0-9]+)/isu",
$params, $height);
1214 preg_match(
"/preview='([^']+)'/isu",
$params, $preview);
1215 if (empty($preview))
1217 preg_match(
"/preview=\"([^\"]+)\"/isu",
$params, $preview);
1220 preg_match(
"/type=(YOUTUBE|RUTUBE|VIMEO|VK|FACEBOOK|INSTAGRAM)/isu",
$params,
$provider);
1225 $height = intval($height[1] ?? 0);
1226 $height = ($height > 0 ? $height : 300);
1227 $preview = trim($preview[1] ??
'');
1228 $preview = ($preview !=
'' ? $preview :
'');
1235 'HEIGHT' => $height,
1236 'PREVIEW' => $preview,
1238 'MIME_TYPE' =>
$type,
1239 'PARSER_OBJECT' => $this,
1242 foreach (
GetModuleEvents(
'main',
'TextParserVideoConvert',
true) as $arEvent)
1263 $trustedProviders = [
1274 if ($this->type ==
'mail')
1278 ?><a href=
"<?=$pathEncoded?>"><?=$pathEncoded?></a><?
1283 if (str_starts_with(
$arParams[
'PATH'],
'//'))
1288 if (UrlPreview::isHostTrusted(
$uri) ||
$uri->getHost() == Application::getInstance()->getContext()->getServer()->getServerName())
1297 ?><iframe
class=
"bx-mobile-video-frame" src=
"<?=$pathEncoded?>" allowfullscreen=
"" frameborder=
"0" height=
"100%" width=
"100%" style=
"max-width: 600px; min-height: 300px;"></iframe><?
1301 ?><iframe src=
"<?=$pathEncoded?>" allowfullscreen=
"" frameborder=
"0" height=
"<?=intval($arParams["HEIGHT
"])?>" width=
"<?=intval($arParams["WIDTH
"])?>" style=
"max-width: 100%;"></iframe><?
1308 $playerParams[
'TYPE'] =
$arParams[
'MIME_TYPE'];
1309 $playerComponent =
'bitrix:player';
1312 $playerComponent =
'bitrix:mobile.player';
1316 $playerComponent,
'', $playerParams,
1319 'HIDE_ICONS' =>
'Y',
1324 return ob_get_clean();
1329 $array = array_intersect_key($this->smileReplaces,
$matches);
1330 $replacement = reset($array);
1331 if (!empty($replacement))
1333 if (($this->allow[
'CLEAR_SMILES'] ??
'') ==
'Y')
1340 $replacement[
'code'],
1341 $replacement[
'image'],
1342 $replacement[
'description'],
1343 $replacement[
'width'],
1344 $replacement[
'height'],
1345 $replacement[
'descriptionDecode'],
1346 $replacement[
'imageDefinition']
1355 if (
$code ==
'' || $image ==
'')
1361 $image = stripslashes($image);
1363 $height = intval($height);
1364 if ($descriptionDecode)
1369 $html =
'<img src="' .
htmlspecialcharsbx($this->serverName) . $this->pathToSmile . $image .
'"'
1371 .
' data-code="' .
$code .
'"'
1372 .
' data-definition="' . $imageDefinition .
'"'
1373 .
' alt="' .
$code .
'"'
1374 .
' style="' . (
$width > 0 ?
'width:' .
$width .
'px;' :
'') . ($height > 0 ?
'height:' . $height .
'px;' :
'') .
'"'
1376 .
' class="' . ($this->useTypography ? $this->tagClasses[
'smiley'] :
'bx-smile') .
'" />';
1377 $cacheKey = md5($html);
1378 if (!isset($this->preg[
'cache'][$cacheKey]))
1380 $this->preg[
'cache'][$cacheKey] = $this->
defended_tags($html);
1383 return $this->preg[
'cache'][$cacheKey];
1395 $text = str_replace(
1396 [
"[nomodify]",
"[/nomodify]",
"[",
"]",
"&",
"<",
">",
"\\r",
"\\n",
"\\\"",
"\\",
"[",
"]",
" ",
"\t"],
1397 [
"",
"",
"[",
"]",
"&",
"<",
">",
"\r",
"\n",
'\"',
"\",
"[",
"]",
" ",
" "],
1402 $text = $this->useTypography ? self::trimLineBreaks(
$text) :
"<pre>" .
$text .
"</pre>";
1421 if ($this->useTypography)
1431 if (is_array(
$text))
1443 if ($this->type ===
'mail')
1472 '<details class="ui-typography-spoiler ui-icon-set__scope">' .
1474 '<div class="ui-typography-spoiler-content" data-spoiler-content="true">' .
1475 self::trimLineBreaks(
$text) .
1483 ?><table
class=
"forum-spoiler"><?
1484 ?><thead onclick=
"if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><?
1491 ?><tbody
class=
"forum-spoiler" style=
"display:none;"><?
1493 ?><td><?=self::trimLineBreaks(
$text)?></td><?
1498 return ob_get_clean();
1503 $marker = (mb_strtolower($marker) ==
'code' ?
'code' :
'quote');
1505 $this->{$marker .
'_open'}++;
1506 if ($this->type ==
'rss')
1508 return "\n====" . $marker .
"====\n";
1511 if ($this->useTypography)
1515 ?
'<blockquote class="' . $this->tagClasses[
'quote'] .
'">'
1516 :
'<code class="' . $this->tagClasses[
'code'] .
'">'
1520 return "<div class='" . $marker .
"'><table class='" . $marker .
"'><tr><td>";
1525 $marker = (mb_strtolower($marker) ==
'code' ?
'code' :
'quote');
1527 if ($this->{$marker .
'_open'} == 0)
1529 $this->{$marker .
'_error'}++;
1532 $this->{$marker .
'_closed'}++;
1534 if ($this->type ==
'rss')
1536 return "\n=============\n";
1539 if ($this->useTypography)
1548 return '</td></tr></table></div>';
1565 preg_match(
"/height=([0-9]+)/isu",
$params, $height);
1567 $height = intval($height[1] ?? 0);
1570 if (!preg_match(
"/^(http|https|ftp|\\/)/iu",
$url))
1578 return '[img]' .
$url .
'[/img]';
1584 if (
$width > $this->imageWidth)
1586 $height = intval($height * ($this->imageWidth /
$width));
1592 if ($height > $this->imageHeight)
1594 $width = intval(
$width * ($this->imageHeight / $height));
1600 $strPar =
" width=\"" .
$width .
"\"";
1604 $strPar .=
" height=\"" . $height .
"\"";
1608 if ($this->useTypography)
1611 if ($this->serverName ==
'' || preg_match(
"/^(http|https|ftp):\\/\\//iu",
$url))
1616 $attrs =
' loading="lazy"';
1619 $attrs .=
" width=\"" .
$width .
"\"";
1622 $attrs .=
' style="aspect-ratio: ' . (
$width / $height) .
'"';
1627 '<span class="' . $this->tagClasses[
'image-container'] .
'">' .
1628 '<img src="' . $src .
'" class="' . $this->tagClasses[
'image'] .
'"'. $attrs .
'>' .
1636 if ($this->serverName ==
'' || preg_match(
"/^(http|https|ftp):\\/\\//iu",
$url))
1638 $image =
'<img src="' .
$url .
'" border="0"' . $strPar .
' data-bx-image="' .
$url .
'" data-bx-onload="Y" />';
1660 return preg_replace(
'|[[/!]*?[^\\[\\]]*?]|i',
'',
$text);
1677 if ($attr ==
'size')
1679 if (mb_strlen($value) > 2 && str_ends_with($value,
'pt'))
1681 $value = intval(substr($value, 0, -2));
1686 return '<span class="bx-font" style="font-size:' . $value .
'pt; line-height: normal;">' .
$text .
'</span>';
1694 $value = intval($value >
$count ? (
$count - 1) : $value);
1695 if (!isset($this->arFontSize[$value]))
1701 $size = (is_numeric($this->arFontSize[$value])? $this->arFontSize[$value] .
'%' : $this->arFontSize[$value]);
1702 return '<span class="bx-font" style="font-size:' . $size .
';">' .
$text .
'</span>';
1704 elseif ($attr ==
'color')
1706 $value = preg_replace(
"/[^\\w#]/",
"" , $value);
1707 return '<span class="bx-font" style="color:' . $value .
'">' .
$text .
'</span>';
1711 $value = preg_replace(
"/[^\\w\\s\\-,()]/",
"" , $value);
1712 return '<span class="bx-font" style="font-family:' . $value .
'">' .
$text .
'</span>';
1719 $vars = get_object_vars($this);
1720 $vars[
'TEMPLATE'] = ($this->bMobile ?
'mobile' :
$this->type);
1727 foreach (
GetModuleEvents(
'main',
'TextParserUserField',
true) as $arEvent)
1732 if (
$userField[
'USER_TYPE'][
'USER_TYPE_ID'] ==
'disk_file' || in_array($id,
$userField[
'VALUE']))
1734 if (defined(
'BX_COMP_MANAGED_CACHE'))
1740 return call_user_func_array(
1741 [
$userField[
'USER_TYPE'][
'CLASS_NAME'],
'GetPublicViewHTML'],
1750 static $userTypeList = [];
1769 if (isset($userTypeList[
$userId]))
1775 if (Loader::includeModule(
'intranet'))
1784 !empty($this->userPath)
1797 $classAdditional =
' blog-p-user-name-extranet';
1800 $classAdditional =
' blog-p-user-name-email';
1803 $this->pathToUserEntityType && $this->pathToUserEntityType !=
''
1804 && (
int)$this->pathToUserEntityId > 0
1807 $pathToUser .= (!str_contains(
$pathToUser,
'?') ?
'?' :
'&') .
'entityType=' . $this->pathToUserEntityType .
'&entityId=' . intval($this->pathToUserEntityId);
1811 $classAdditional =
' blog-p-user-name-collaber';
1814 $classAdditional =
'';
1818 'CLASS_ADDITIONAL' => $classAdditional,
1826 && !empty($this->pathToUserEntityType)
1827 && !empty($this->pathToUserEntityId)
1831 'entityType' => $this->pathToUserEntityType,
1832 'entityId' => (
int)$this->pathToUserEntityId,
1844 $classAdditional = (!empty(
$fields[
'CLASS_ADDITIONAL']) ?
$fields[
'CLASS_ADDITIONAL'] :
'');
1849 $className = $this->useTypography ? $this->tagClasses[
'mention'] :
'blog-p-user-name';
1852 return "<span class=\"{$className}\">{$userName}</span>";
1855 return '<a class="'. $className . $classAdditional .
'"'
1856 .
' href="' . CComponentEngine::MakePathFromTemplate(
$pathToUser, [
"user_id" =>
$userId]) .
'"'
1857 .
' bx-tooltip-user-id="' . (!$this->bMobile ?
$userId :
'') .
'"'
1864 static $projectTypeList = [];
1865 static $extranetProjectIdList =
null;
1871 'PROJECT_ID' => $projectId,
1872 'PROJECT_NAME' => $projectName,
1877 if ($extranetProjectIdList ===
null)
1879 $extranetSiteId = (Loader::includeModule(
'extranet') ? CExtranet::getExtranetSiteId() :
'');
1880 if (!empty($extranetSiteId))
1882 $res = \Bitrix\Socialnetwork\WorkgroupSiteTable::getList([
1884 '=SITE_ID' => $extranetSiteId,
1886 'select' => [
'GROUP_ID' ],
1889 while ($projectSiteFields =
$res->fetch())
1891 $extranetProjectIdList[] = (int)$projectSiteFields[
'GROUP_ID'];
1898 if (isset($projectTypeList[$projectId]))
1900 $type = $projectTypeList[$projectId];
1904 if (!empty($extranetProjectIdList) && in_array($projectId, $extranetProjectIdList,
true))
1906 $type = $this->getExternalGroupType($projectId);
1909 $projectTypeList[$projectId] =
$type;
1912 $pathToProject = $this->getGroupPath($projectId, (
array)$extranetProjectIdList);
1917 $classAdditional =
' blog-p-user-name-extranet';
1920 $classAdditional =
' blog-p-user-name-collab';
1923 $classAdditional =
'';
1926 $renderParams[
'CLASS_ADDITIONAL'] = $classAdditional;
1927 $renderParams[
'PATH_TO_PROJECT'] = $pathToProject;
1937 $classAdditional = (
$fields[
'CLASS_ADDITIONAL'] ??
'');
1938 $pathToProject = (
$fields[
'PATH_TO_PROJECT'] ??
'');
1939 $projectId = (int)(
$fields[
'PROJECT_ID'] ?? 0);
1940 $projectName = (string)(
$fields[
'PROJECT_NAME'] ??
'');
1942 $className = $this->useTypography ? $this->tagClasses[
'mention'] :
'blog-p-user-name';
1943 if ($projectId <= 0)
1945 return "<span class=\"{$className}\">{$projectName}</span>";
1948 return '<a class="' . $className . $classAdditional .
'" href="' . CComponentEngine::MakePathFromTemplate($pathToProject, [
'group_id' => $projectId ]) .
'" >' . $projectName .
'</a>';
1953 static $pathToDepartment =
null;
1959 'DEPARTMENT_ID' => $departmentId,
1960 'DEPARTMENT_NAME' => $departmentName,
1963 if ($departmentId > 0)
1965 if ($pathToDepartment ===
null)
1968 $pathToDepartment = Option::get(
'main',
'TOOLTIP_PATH_TO_CONPANY_DEPARTMENT',
SITE_DIR .
'company/structure.php?set_filter_structure=Y&structure_UF_DEPARTMENT=#ID#',
SITE_ID);
1971 $renderParams[
'PATH_TO_DEPARTMENT'] = $pathToDepartment;
1981 $pathToDepartment = (
$fields[
'PATH_TO_DEPARTMENT'] ??
'');
1982 $departmentId = (int)(
$fields[
'DEPARTMENT_ID'] ?? 0);
1983 $departmentName = (string)(
$fields[
'DEPARTMENT_NAME'] ??
'');
1985 $className = $this->useTypography ? $this->tagClasses[
'mention'] :
'blog-p-user-name';
1986 if ($departmentId <= 0)
1988 return "<span class=\"{$className}\">{$departmentName}</span>";
1991 return '<a class="' . $className .
'" href="' . CComponentEngine::MakePathFromTemplate($pathToDepartment, [
'ID' => $departmentId ]) .
'" >' . $departmentName .
'</a>';
1996 return $this->tagPattern .
'u';
2001 return trim(html_entity_decode(str_replace(
' ',
' ', $tag), (ENT_COMPAT | ENT_HTML401),
SITE_CHARSET));
2022 function($tag) {
return $tag !=
''; }
2049 $className = $this->useTypography ? $this->tagClasses[
'hashtag'] :
'bx-inline-tag';
2050 $res =
'<span class="' . $className .
'" bx-tag-value="' .
$res .
'">#' .
$res .
'</span>';
2052 return $tag[1].$this->defended_tags(
$res);
2058 if ($this->maxStringLen > 0 && !empty(
$text))
2060 $text = str_replace([chr(11), chr(12), chr(34), chr(39)], [
"",
"", chr(11), chr(12)],
$text);
2061 $text = preg_replace_callback(
"/(?<=^|>)([^<]+)(?=<|$)/isu", [$this,
"partWords"],
$text);
2062 $text = str_replace([chr(11), chr(12)], [chr(34), chr(39)],
$text);
2075 if (($this->maxStringLen > 0) && (trim(
$str) !=
''))
2078 [chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8),
2079 "&",
"<",
">",
""",
" ",
"©",
"®",
"™",
2082 [
"",
"",
"",
"",
"",
"",
"",
"",
2083 chr(1),
"<",
">", chr(2), chr(3), chr(4), chr(5), chr(6),
2088 $str = preg_replace_callback(
2089 "/(?<=[" . $word_separator .
"]|^)(([^" . $word_separator .
"]+))(?=[" . $word_separator .
"]|$)/isu",
2090 [$this,
"cutWords"],
2094 [chr(1),
"<",
">", chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8),
"<WBR/>",
"<WBR>",
"&shy;"],
2095 [
"&",
"<",
">",
""",
" ",
"©",
"®",
"™", chr(34), chr(39),
"<WBR/>",
"<WBR/>",
"­"],
2109 if (($this->maxStringLen > 0) && (
$str !=
''))
2111 $str = preg_replace(
"/([^ \n\r\t\x01]{" . $this->maxStringLen .
"})/isu",
"\\1<WBR/>­",
$str);
2120 return preg_replace(
"/\x20{2}/",
"\x20 ",
$matches[1]);
2132 $url = trim(str_replace([
'[nomodify]',
'[/nomodify]'],
'',
$url));
2133 $text = trim(str_replace([
'[nomodify]',
'[/nomodify]'],
'',
$text));
2137 $bShortUrl = (($this->allow[
'SHORT_ANCHOR'] ??
'') ==
'Y');
2144 $postfix = $match[1];
2149 $url = preg_replace(
2153 "/[" . chr(12) .
"']/u",
2159 "java script: ",
2171 $text = preg_replace(
2172 [
"/&/iu",
"/javascript:/iu"],
2173 [
"&",
"javascript: "],
2178 mb_strlen(
$text) > $this->maxAnchorLength &&
2183 $text = $uri_type .
'://' . (mb_strlen($stripped) > $this->maxAnchorLength ?
2184 mb_substr($stripped, 0, $this->maxAnchorLength - 10) .
'...' . mb_substr($stripped, -10) :
2189 if ($this->anchorType ===
'bbcode')
2193 $link =
'[URL]' .
$url .
'[/URL]';
2197 $link =
'[URL=' .
$url .
']' .
$text .
'[/URL]';
2204 if (!str_contains(
$text,
"<\017"))
2210 $noFollowAttribute = $this->parser_nofollow ==
'Y'?
' rel="nofollow"':
'';
2212 $className = $this->useTypography ?
' class="' . $this->tagClasses[
'url'] .
'"' :
'';
2214 $link =
'<a' . $className .
' href="' .
$url .
'" target="' . $this->link_target .
'"' . $noFollowAttribute . $this->
convertAttributes($attributes) .
' >' .
$text .
'</a>';
2216 if ($noFollowAttribute)
2218 $link =
'<noindex>' . $link .
'</noindex>';
2222 return $link . $postfix;
2228 if (!is_array($attributes))
2233 foreach ($attributes as
$key => $value)
2235 if (preg_match(
'#[^a-zA-Z\d-]#',
$key))
2246 private function preconvertUrl(
$matches, $attributes = [])
2258 if (stripos(
$str,
'[url') !== 0)
2264 $url = str_replace([
'[',
']'], [
'%5B',
'%5D'],
$url);
2272 if (isset($this->defended_urls[
$url]))
2274 return $this->defended_urls[
$url];
2279 $this->defended_urls[
$url] = $tag;
2287 if (!empty($this->defended_urls))
2289 return str_replace(array_reverse(array_values($this->defended_urls)), array_reverse(array_keys($this->defended_urls)),
$str);
2298 $ar = preg_split(
"/(<.*?>|\\s+)/s", $string, -1, PREG_SPLIT_DELIM_CAPTURE);
2299 foreach (
$ar as
$i => $s)
2301 if (!str_starts_with($s,
'<'))
2312 if (isset($splice_pos))
2314 array_splice(
$ar, $splice_pos+1);
2315 return implode(
'',
$ar);
2322 preg_match_all(
"#<([a-z0-9]+)([^>]*)(?<!/)>#iu", $html,
$result);
2323 $openedtags = array_map(
'strtolower',
$result[1]);
2325 preg_match_all(
"#</([a-z0-9]+)>#iu", $html,
$result);
2326 $closedtags = array_map(
'strtolower',
$result[1]);
2328 $len_opened =
count($openedtags);
2330 if (
count($closedtags) == $len_opened)
2335 $openedtags = array_reverse($openedtags);
2337 static $tagsWithoutClose = [
'input'=>1,
'img'=>1,
'br'=>1,
'hr'=>1,
'meta'=>1,
'area'=>1,
'base'=>1,
'col'=>1,
'embed'=>1,
'keygen'=>1,
'link'=>1,
'param'=>1,
'source'=>1,
'track'=>1,
'wbr'=>1];
2339 for (
$i = 0;
$i < $len_opened;
$i++)
2341 if (isset($tagsWithoutClose[$openedtags[
$i]]))
2345 if (!in_array($openedtags[
$i], $closedtags))
2347 $html .=
'</' . $openedtags[
$i] .
'>';
2351 unset($closedtags[array_search($openedtags[
$i], $closedtags)]);
2366 if (mb_stripos(
$text,
'<cut') !==
false || mb_stripos(
$text,
'[cut') !==
false)
2368 $text = preg_replace([
2369 "/^(.+?)<cut(.*?)>/isu",
2370 "/^(.+?)\\[cut(.*?)]/isu",
2373 if (mb_stripos(
$text,
'[quote') !==
false)
2375 while (preg_match(
"/\\[(?:quote)(?:.*?)](.*?)\\[\\/quote(.*?)]/isu",
$text))
2377 $text = preg_replace(
2379 "/\\[quote(?:.*?)](.*?)\\[\\/quote(.*?)]/isu",
2380 "/<quote(?:.*?)>(.*?)<\\/quote(.*?)>/isu",
2388 $text = preg_replace(
"/\\[url\\s*=\\s*(\\S+?)\\s*](.*?)\\[\\/url]/isu",
"\\2",
$text);
2393 $arPattern[] =
"/\\<WBR[\\s\\/]?\\>/isu";
2396 $arPattern[] =
"/^(\r|\n)+?(.*)$/";
2397 $arReplace[] =
"\\2";
2399 $arPattern[] =
"/\\<(\\/?)(code|font|color|video)(.*?)\\>/isu";
2401 $arPattern[] =
"/\\[\\/td(.*?)\\]\\[td(.*?)\\]/isu";
2403 $arPattern[] =
"/\\[(\\/?)(p|b|i|u|s|list|code|quote|size|font|color|url|img|video|td|tr|table|file|document id|disk file id|user|project|left|right|center|justify|\\*)(.*?)\\]/isu";
2406 return preg_replace($arPattern, $arReplace,
$text);
2411 $symbols = strip_tags($html);
2412 $symbols_len = mb_strlen($symbols);
2414 if ($symbols_len < mb_strlen($html))
2418 if ($symbols_len > $size)
2420 $strip_text = $strip_text .
'...';
2423 $final_text = $this->closetags($strip_text);
2425 elseif ($symbols_len > $size)
2427 $final_text = mb_substr($html, 0, $size) .
'...';
2431 $final_text = $html;
2444 $handler =
AddEventHandler(
'main',
'TextParserBeforeTags', [
'CTextParser',
'TextParserHTMLToBBHack']);
2446 $this->allow = array_merge(
2467 $html = preg_replace(
"/<br\s*\\/*>/isu",
"\n", $html);
2468 $html = preg_replace(
"/ /isu",
'', $html);
2478 $TextParser->allow = [
2485 private static function trimLineBreaks(
string $text): string
2487 return preg_replace(
"/^\r?\n|\r?\n$/",
'',
$text);
2490 private function getExternalGroupType(
int $groupId): string
2493 !Loader::includeModule(
'socialnetwork')
2494 || !class_exists(GroupProvider::class)
2500 return GroupProvider::getInstance()->getGroupType($groupId) === Type::Collab ?
'collab' :
'extranet';
2503 private function getGroupPath(
int $groupId,
array $extranetGroupIds): string
2505 $path = Option::get(
'socialnetwork',
'group_path_template',
SITE_DIR .
'workgroups/group/#group_id#/',
SITE_ID);
2508 !Loader::includeModule(
'socialnetwork')
2509 || !class_exists(UrlManager::class)
2515 if (!in_array($groupId, $extranetGroupIds,
true))
2520 $type = GroupProvider::getInstance()->getGroupType($groupId);
2521 if (
$type !== Type::Collab)
2526 $chatId = Workgroup::getChatData([
'group_id' => $groupId])[$groupId] ??
null;
2528 return UrlManager::getCollabUrlById($groupId, [
'chatId' => $chatId]);
if(!Loader::includeModule('messageservice')) $provider
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static encode($data, $options=null)
wrap_long_words($text='')
convert_spoiler_tag($text, $title='')
setAnchorSchemes($schemes)
convert_department(array $matches)
convert_open_tag($marker='quote')
convertFontColor($matches)
convertEmoticon($matches)
convert_emoticon($code='', $image='', $description='', $width='', $height='', $descriptionDecode=false, $imageDefinition=CSmile::IMAGE_SD)
static TextParserHTMLToBBHack($text, $TextParser)
defended_tags($text, $tag='replace')
pre_convert_anchor_tag($url, $text='', $str='', $attributes=[])
convert_project(array $matches)
convert_anchor_tag($url, $text, $attributes=[])
convert_user($userId=0, $userName='')
post_convert_anchor_tag($str)
convertAnchor($matches, $attributes=[])
convert_userfields($matches)
convertText($text, $attributes=[])
convertFontSize($matches)
convert_cut_tag($text, $title='')
convert_quote_tag($text='')
static renderSpoiler($text, $title='', $useTypography=false)
convertHTMLToBB($html='', $allow=null)
strip_words($string, $count)
convert_close_tag($marker='quote')
render_department($fields)
preconvertAnchor($matches, $attributes=[])
convert_image_tag($url='', $params='')
convertAttributes($attributes)
static clearAllTags($text)
convert_font_attr($attr, $value="", $text="")
hidden PROPERTY[<?=$propertyIndex?>][CODE]<?=htmlspecialcharsEx( $propertyCode)?> height
bx popup label bx width30 PAGE_NEW_MENU_NAME text width
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
if(file_exists($_SERVER['DOCUMENT_ROOT'] . "/urlrewrite.php")) $uri
const SITE_DIR(!defined('LANG'))
ExecuteModuleEventEx($arEvent, $arParams=[])
htmlspecialcharsback($str)
AddEventHandler($FROM_MODULE_ID, $MESSAGE_ID, $CALLBACK, $SORT=100, $FULL_PATH=false)
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
RemoveEventHandler($FROM_MODULE_ID, $MESSAGE_ID, $iEventHandlerKey)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
if(!Loader::includeModule('sale')) $pattern