1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
functions.php
См. документацию.
1<?php
2##############################################
3# Bitrix Site Manager Forum #
4# Copyright (c) 2002-2007 Bitrix #
5# https://www.bitrixsoft.com #
6# mailto:admin@bitrixsoft.com #
7##############################################
9function Error($error)
10{
11 global $MESS;
12 require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/forum/lang/".LANGUAGE_ID."/errors.php");
13 $msg = $MESS[$error["MSG"]];
14 echo "Error: ".$msg;
15}
16
18{
19 /* @deprecated */ var $image_params = array();
20 /* @deprecated */ var $pathToUser = "";
21 public $imageWidth = 300;
22 public $imageHeight = 300;
23 public $maxStringLen = 60;
24 public $imageHtmlWidth = 0;
25 public $imageHtmlHeight = 0;
26 public $imageTemplate = "popup_image";
27 public $component = null;
28 public $smilesGallery = 0;
30 public $MaxStringLen = null;
31
32 function __construct($lang = false, $pathToSmiles = '', $type=false, $mode = 'full')
33 {
34 parent::__construct();
35 $this->arFiles = array();
36 $this->arFilesParsed = array();
37
38 $this->arUserfields = array();
39 $this->ajaxPage = $GLOBALS["APPLICATION"]->GetCurPageParam("", array("bxajaxid", "logout"));
40 $this->userPath = "";
41 $this->userNameTemplate = str_replace(array("#NOBR#","#/NOBR#"), "", CSite::GetDefaultNameFormat());
42 $this->smilesGallery = \COption::GetOptionInt("forum", "smile_gallery_id", 0);
43
44 if ($mode == 'full')
45 {
46 AddEventHandler("main", "TextParserAfterTags", Array(&$this, "ParserFile"));
47 }
48 }
49
50 public static function GetFeatures($arForum)
51 {
52 static $arFeatures = [
53 "HTML", "ANCHOR", "BIU", "IMG",
54 "VIDEO", "LIST", "QUOTE", "CODE",
55 "FONT", "UPLOAD", "NL2BR", "SMILES",
56 "TABLE", "ALIGN"];
57 $result = array();
58 if (is_array($arForum))
59 {
60 foreach ($arFeatures as $feature)
61 {
62 $result[$feature] = ((isset($arForum['ALLOW_'.$feature]) && $arForum['ALLOW_'.$feature] == 'Y') ? 'Y' : 'N');
63 }
64 }
65 return $result;
66 }
67
68 public static function GetEditorButtons($arParams)
69 {
70 $result = array();
71 $arEditorFeatures = array(
72 "ALLOW_QUOTE" => array('Quote'),
73 'ALLOW_ANCHOR' => array('CreateLink'),
74 "ALLOW_VIDEO" => array('InputVideo'),
75 "ALLOW_UPLOAD" => array('UploadFile'),
76 "ALLOW_MENTION" => array('MentionUser')
77 );
78 if (isset($arParams['forum']) && is_array($arParams['forum']))
79 {
80 $res = array_intersect_key($arParams['forum'], $arEditorFeatures);
81 foreach ($res as $featureName => $val)
82 {
83 if ($val != 'N')
84 $result = array_merge($result, $arEditorFeatures[$featureName]);
85 }
86 }
87 return $result;
88 }
89
90 public static function GetEditorToolbar($arParams)
91 {
92 static $arEditorFeatures = array(
93 "ALLOW_BIU" => array('Bold', 'Italic', 'Underline', 'Strike', 'Spoiler'),
94 "ALLOW_FONT" => array('ForeColor','FontList', 'FontSizeList'),
95 "ALLOW_QUOTE" => array('Quote'),
96 "ALLOW_CODE" => array('Code'),
97 'ALLOW_ANCHOR' => array('CreateLink', 'DeleteLink'),
98 "ALLOW_IMG" => array('Image'),
99 "ALLOW_VIDEO" => array('InputVideo'),
100 "ALLOW_TABLE" => array('Table'),
101 "ALLOW_ALIGN" => array('Justify'),
102 "ALLOW_LIST" => array('InsertOrderedList', 'InsertUnorderedList'),
103 "ALLOW_SMILES" => array('SmileList'),
104 //"ALLOW_UPLOAD" => array('UploadFile'),
105 //"ALLOW_NL2BR" => array(''),
106 );
107 $result = array();
108
109 if (isset($arParams['mode']) && ($arParams['mode'] == 'full'))
110 {
111 foreach ($arEditorFeatures as $featureName => $toolbarIcons)
112 {
113 $result = array_merge($result, $toolbarIcons);
114 }
115 }
116 elseif (isset($arParams['forum']))
117 {
118 foreach ($arEditorFeatures as $featureName => $toolbarIcons)
119 {
120 if (isset($arParams['forum'][$featureName]) && ($arParams['forum'][$featureName] == 'Y'))
121 $result = array_merge($result, $toolbarIcons);
122 }
123 }
124
125 $result = array_merge($result, array('MentionUser', 'UploadFile', 'RemoveFormat', 'Source'));
126 if (LANGUAGE_ID == 'ru')
127 $result[] = 'Translit';
128
129 return $result;
130 }
131
132 function convert($text, $allow = array(), $type = "html", $arFiles = false, $attributes = [])
133 {
134 $text = str_replace(array("\013", "\014"), "", $text);
135
136 $this->imageWidth = (isset($this->image_params["width"]) && $this->image_params["width"] > 0 ? $this->image_params["width"] : ($this->imageWidth > 0 ? $this->imageWidth : 300));
137 $this->imageHeight = (isset($this->image_params["height"]) && $this->image_params["height"] > 0 ? $this->image_params["height"] : ($this->imageHeight > 0 ? $this->imageHeight : 300));
138
139 $this->userPath = str_replace(array("#UID#", "#uid#"), "#user_id#", (empty($this->userPath) && !empty($this->pathToUser) ? $this->pathToUser : $this->userPath));
140
141 $this->type = $type;
142
143 $allow = (is_array($allow) ? $allow : array());
144 if (!empty($this->arUserfields))
145 $allow["USERFIELDS"] = $this->arUserfields;
146
147 if (sizeof($allow)>0)
148 {
149 if (!isset($allow['TABLE']))
150 $allow['TABLE']=$allow['BIU'];
151
152 $this->allow = array_merge((is_array($this->allow) ? $this->allow : array()), $allow);
153 }
154 $this->parser_nofollow = COption::GetOptionString("forum", "parser_nofollow", "Y");
155 $this->link_target = COption::GetOptionString("forum", "parser_link_target", "_blank");
156
157 if ($arFiles !== false)
158 $this->arFiles = is_array($arFiles) ? $arFiles : array($arFiles);
159 $this->arFilesIDParsed = array();
160
161 $text = str_replace(array("\013", "\014"), array(chr(34), chr(39)), $this->convertText($text, $attributes));
162 return $text;
163 }
164
165 function convert4mail($text, $files = false, $allow = array(), $params = array())
166 {
167 $this->arFiles = (is_array($files) ? $files : ($files ? array($files) : array()));
168 $this->arFilesIDParsed = array();
169
170 if (!empty($params))
171 {
172 $mail = array(
173 "RECIPIENT_ID" => intval($params["RECIPIENT_ID"]),
174 "SITE_ID" => ($params["SITE_ID"] ?: SITE_ID)
175 );
176 $allow = array_merge(((is_array($allow) ? $allow : array()) + array(
177 "HTML" => "N",
178 "ANCHOR" => "Y",
179 "BIU" => "Y",
180 "IMG" => "Y",
181 "QUOTE" => "Y",
182 "CODE" => "Y",
183 "FONT" => "Y",
184 "LIST" => "Y",
185 "NL2BR" => "N",
186 "TABLE" => "Y"
187 )), array("SMILES" => "N"));
188
189 $this->RECIPIENT_ID = $mail["RECIPIENT_ID"];
190 $this->SITE_ID = $mail["SITE_ID"];
191
192 if (is_array($this->arUserfields))
193 {
194 foreach ($this->arUserfields as &$f)
195 {
196 $f += $mail;
197 }
198 }
199 return $this->convert($text, $allow, "mail");
200 }
201 else
202 {
203 $text = parent::convert4mail($text);
204 if (!empty($this->arFiles))
205 $this->ParserFile($text, $this, "mail");
206 if (preg_match("/\\[cut(([^\\]])*)\\]/isu", $text, $matches))
207 {
208 $text = preg_replace(
209 array("/\\[cut(([^\\]])*)\\]/isu",
210 "/\\[\\/cut\\]/isu"),
211 array("\001\\1\002",
212 "\003"),
213 $text);
214 while (preg_match("/(\001([^\002]*)\002([^\001\002\003]+)\003)/isu", $text, $arMatches))
215 $text = preg_replace(
216 "/(\001([^\002]*)\002([^\001\002\003]+)\003)/isu",
217 "\n>================== CUT ===================\n\\3\n>==========================================\n",
218 $text);
219 $text = preg_replace(
220 array("/\001([^\002]+)\002/",
221 "/\001\002/",
222 "/\003/"),
223 array("[cut\\1]",
224 "[cut]",
225 "[/cut]"),
226 $text);
227 }
228 }
229 return $text;
230 }
231
232 function ParserFile(&$text, &$obj, $type="html")
233 {
234 if (method_exists($obj, "convert_attachment"))
235 {
236 $tmpType = $obj->type;
237 $obj->type = $type;
238 $text = preg_replace_callback("/\[file([^\]]*)id\s*=\s*([0-9]+)([^\]]*)\]/isu", array($this, "convert_attachment"), $text);
239 $obj->type = $tmpType;
240 }
241 }
242
243 function convert_open_tag($marker = "quote")
244 {
245 $marker = (mb_strtolower($marker) == "code" ? "code" : "quote");
246
247 $this->{$marker."_open"}++;
248 if ($this->type == "rss")
249 return "\n====".$marker."====\n";
250 else if ($this->type == "mail")
251 return ($marker == "code" ? "<code>" : "<blockquote>");
252 else if ($this->bMobile)
253 return "<div class='blog-post-".$marker."' title=\"".($marker == "quote" ? GetMessage("FRM_QUOTE") : GetMessage("FRM_CODE"))."\"><table class='blog".$marker."'><tr><td>";
254 else
255 return '<div class="entry-'.$marker.'"><table class="forum-'.$marker.'"><thead><tr><th>'.($marker == "quote" ? GetMessage("FRM_QUOTE") : GetMessage("FRM_CODE")).'</th></tr></thead><tbody><tr><td>';
256 }
257
258 function convert_close_tag($marker = "quote")
259 {
260 $marker = (mb_strtolower($marker) == "code" ? "code" : "quote");
261
262 if ($this->{$marker."_open"} == 0)
263 {
264 $this->{$marker."_error"}++;
265 return "";
266 }
267 $this->{$marker."_closed"}++;
268
269 if ($this->type == "rss")
270 return "\n=============\n";
271 else if ($this->type == "mail")
272 return ($marker == "code" ? "</code>" : "</blockquote>");
273 else if ($this->bMobile)
274 return "</td></tr></table></div>";
275 else
276 return "</td></tr></tbody></table></div>";
277
278 }
279
280 function convert_image_tag($url = "", $params="")
281 {
282 $url = trim($url);
283 if (empty($url)) return "";
284 $type = (mb_strtolower($this->type) == "rss" ? "rss" : "html");
285
286 $bErrorIMG = !preg_match("/^(http|https|ftp|\/)/iu", $url);
287
288 $url = str_replace(array("<", ">", "\""), array("%3C", "%3E", "%22"), $url);
289 // to secure from XSS [img]http://ya.ru/[url]http://onmouseover=prompt(/XSS/)//[/url].jpg[/img]
290
291 if ($bErrorIMG)
292 return "[img]".$url."[/img]";
293
294 if ($type != "html")
295 return '<img src="'.$url.'" alt="'.GetMessage("FRM_IMAGE_ALT").'" border="0" />';
296
297 $width = 0; $height = 0;
298 if (preg_match_all("/width\=(?P<width>\d+)|height\=(?P<height>\d+)/isu", $params, $matches)):
299 $width = intval(!empty($matches["width"][0]) ? $matches["width"][0] : $matches["width"][1]);
300 $height = intval(!empty($matches["height"][0]) ? $matches["height"][0] : $matches["height"][1]);
301 endif;
302 $result = $GLOBALS["APPLICATION"]->IncludeComponent(
303 "bitrix:forum.interface",
304 $this->imageTemplate,
305 Array(
306 "URL" => $url,
307 "SIZE" => array("width" => $width, "height" => $height),
308 "MAX_SIZE" => array("width" => $this->imageWidth, "height" => $this->imageHeight),
309 "HTML_SIZE"=> array("width" => $this->imageHtmlWidth, "height" => $this->imageHtmlHeight),
310 "CONVERT" => "N",
311 "FAMILY" => "FORUM",
312 "RETURN" => "Y"
313 ),
314 $this->component,
315 array("HIDE_ICONS" => "Y"));
316 return $this->defended_tags($result, 'replace');
317 }
318
319 function convert_attachment($fileID = "", $p = "", $type = "", $text = "")
320 {
321 if (is_array($fileID))
322 {
323 $text = $fileID[0];
324 $p = $fileID[3];
325 $fileID = $fileID[2];
326 }
327
328 $fileID = intval($fileID);
329 $type = mb_strtolower(empty($type)? $this->type : $type);
330 $type = (in_array($type, array("html", "mail", "bbcode", "rss")) ? $type : "html");
331
332 $this->arFiles = (is_array($this->arFiles) ? $this->arFiles : array($this->arFiles));
333 if ($fileID <= 0 || (!array_key_exists($fileID, $this->arFiles) && !in_array($fileID, $this->arFiles)))
334 return $text;
335
336 if (!array_key_exists($fileID, $this->arFiles) && in_array($fileID, $this->arFiles)): // array(fileID10, fileID12, fileID14)
337 unset($this->arFiles[array_search($fileID, $this->arFiles)]);
338 $this->arFiles[$fileID] = $fileID; // array(fileID10 => fileID10, fileID12 => fileID12, fileID14 => fileID14)
339 endif;
340
341 if (!is_array($this->arFiles[$fileID]))
342 $this->arFiles[$fileID] = CFile::GetFileArray($fileID); // array(fileID10 => array about file, ....)
343
344 if (!is_array($this->arFiles[$fileID])): // if file does not exist
345 unset($this->arFiles[$fileID]);
346 return $text;
347 endif;
348
349 if (!array_key_exists($fileID, $this->arFilesParsed) || empty($this->arFilesParsed[$fileID][$type]))
350 {
351 $arFile = $this->arFiles[$fileID];
352 if ($type == "html" || $type == "rss")
353 {
354 $width = 0; $height = 0;
355 if (preg_match_all("/width\=(?P<width>\d+)|height\=(?P<height>\d+)/isu", $p, $matches)):
356 $width = intval(!empty($matches["width"][0]) ? $matches["width"][0] : $matches["width"][1]);
357 $height = intval(!empty($matches["height"][0]) ? $matches["height"][0] : $matches["height"][1]);
358 endif;
359 $arFile[$type] = $GLOBALS["APPLICATION"]->IncludeComponent(
360 "bitrix:forum.interface",
361 "show_file",
362 Array(
363 "FILE" => $arFile,
364 "SHOW_MODE" => ($type == "html" ? "THUMB" : "RSS"),
365 "SIZE" => array("width" => $width, "height" => $height),
366 "MAX_SIZE" => array("width" => $this->imageWidth, "height" => $this->imageHeight),
367 "HTML_SIZE"=> array("width" => $this->imageHtmlWidth, "height" => $this->imageHtmlHeight),
368 "CONVERT" => "N",
369 "NAME_TEMPLATE" => $this->userNameTemplate,
370 "FAMILY" => "FORUM",
371 "SINGLE" => "Y",
372 "RETURN" => "Y"),
373 $this->component,
374 array("HIDE_ICONS" => "Y"));
375 }
376 else
377 {
378 $path = '/bitrix/components/bitrix/forum.interface/show_file.php?fid='.$arFile["ID"];
379 $bIsImage = (CFile::CheckImageFile(CFile::MakeFileArray($fileID)) === null);
380// $path = ($bIsImage && !empty($arFile["SRC"]) ? $arFile["SRC"] : !$bIsImage && !empty($arFile["URL"]) ? $arFile["URL"] : $path);
381 $path = preg_replace("'(?<!:)/+'s", "/", (mb_substr($path, 0, 1) == "/" ? CHTTP::URN2URI($path, $this->serverName) : $path));
382 switch ($type)
383 {
384 case "bbcode":
385 $arFile["bbcode"] = ($bIsImage ? '[IMG]'.$path.'[/IMG]' : '[URL='.$path.']'.$arFile["ORIGINAL_NAME"].'[/URL]');
386 break;
387 case "mail":
388 $arFile["mail"] = $arFile["ORIGINAL_NAME"].($bIsImage ? " (IMAGE: ".$path.")" : " (URL: ".$path.")");
389 break;
390 }
391 }
392 $this->arFilesParsed[$fileID] = $arFile;
393 }
394 $this->arFilesIDParsed[] = $fileID;
395 return $this->arFilesParsed[$fileID][$type];
396 }
397
399 $text,
400 $arImages = Array(),
401 $arAllow = Array())
402 {
403 if (empty($arAllow))
404 $arAllow = array(
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 "TABLE" => "Y"
416 );
417 $text = preg_replace(
418 array(
419 "#^(.+?)<cut[\s]*(/>|>).*?$#isu",
420 "#^(.+?)\[cut[\s]*(/\]|\]).*?$#isu"),
421 "\\1", $text);
422
423 return $this->convert($text, $arAllow, "rss", $arImages);
424 }
425
427 {
428 $classAdditional = (!empty($fields['CLASS_ADDITIONAL']) ? $fields['CLASS_ADDITIONAL'] : '');
429 $pathToUser = (!empty($fields['PATH_TO_USER']) ? $fields['PATH_TO_USER'] : '');
430 $userId = (!empty($fields['USER_ID']) ? $fields['USER_ID'] : '');
431 $userName = (!empty($fields['USER_NAME']) ? $fields['USER_NAME'] : '');
432
433 if (empty($userId))
434 {
435 return "<span class=\"blog-p-user-name\">{$userName}</span>";
436 }
437
438 $anchorId = RandString(8);
439
440 return '<a class="blog-p-user-name'.$classAdditional.'" id="bp_'.$anchorId.'" href="'.CComponentEngine::MakePathFromTemplate($pathToUser, array("user_id" => $userId)).'" bx-tooltip-user-id="'.(!$this->bMobile ? $userId : '').'">'.$userName.'</a>';
441 }
442}
443
444/***
445 * @deprecated
446 */
448 public function killAllTags($text)
449 {
450 return parent::clearAllTags($text);
451 }
452}
453
455{
456 private $data;
457 private $parse_search_needle = '/([^\[]*)(?:\[(.*)\])*/iu';
458 private $parse_tag = "/<(?<closing>\/?)(?<tag>[a-z]+)(?<params>.*?)(?<selfclosing>\/?)>/ismu";
459 private $parse_params = '/([a-z\-]+)\s*=\s*(?:([^\s]*)|(?:[\'"]([^\'"])[\'"]))/imu';
460 private $lastError = '';
461 private $preg = array(
462 "counter" => 0,
463 "pattern" => array(),
464 "replace" => array()
465 );
466
467 function __construct ($data)
468 {
469 $this->data = $this->prepare($data);
470 }
471
475 private function prepare(string $text): string
476 {
477 $text = preg_replace_callback(
478 "/<pre>(.+?)<\\/pre>/isu",
479 [$this, "defendTags"],
480 $text
481 );
482 $text = str_replace(["\r\n", "\n", "\t"], "", $text);
483 $text = str_replace($this->preg["pattern"], $this->preg["replace"], $text);
484 $this->preg["pattern"] = array();
485 $this->preg["replace"] = array();
486 return $text;
487 }
488
493 public function defendTags($matches)
494 {
495 $text = "<\017#".(++$this->preg["counter"]).">";
496 $this->preg["pattern"][] = $text;
497 $this->preg["replace"][] = $matches[0];
498 return $text;
499 }
500
501 function findTagStart($needle) // needle = input[name=input;class=red]
502 {
503 $offset = 0;
504
505 $search = array();
506 if (preg_match($this->parse_search_needle, $needle, $matches ) == 0)
507 return '';
508 if (sizeof($matches) > 1)
509 {
510 $search['TAG'] = trim($matches[1]);
511 }
512 if (sizeof($matches) > 2)
513 {
514 $arAttr = explode(';', $matches[2]);
515 foreach($arAttr as $attr)
516 {
517 list($attr_name, $attr_value) = explode('=', $attr);
518 $search[mb_strtoupper(trim($attr_name))] = trim($attr_value);
519 }
520 }
522 // skip special tags
523 while ($skip = $this->skipTags($tmp))
524 {
525 $offset += $skip;
526 $tmp = mb_substr($tmp, $skip);
527 }
528 while ($tmp <> '' && preg_match($this->parse_tag, $tmp, $matches) > 0)
529 {
530 $tag_name = $matches['tag'];
531 $localOffset = mb_strpos($tmp, $matches[0]) + mb_strlen($matches[0]);
532
533 if (mb_strlen($matches['closing']) <= 0 && $tag_name == $search['TAG']) // tag has been found
534 {
535 // parse params
536 $params = $matches['params'];
537 if (preg_match_all($this->parse_params, $params, $arParams, PREG_SET_ORDER ) > 0)
538 {
539 // store tag params
540 $arTagParams = array();
541 foreach($arParams as $arParam)
542 $arTagParams[mb_strtoupper(trim($arParam[1]))] = trim(trim($arParam[2]), '"\'');
543 // compare all search params
544 $found = true;
545 foreach($search as $key => $value)
546 {
547 if ($key == 'TAG') continue;
548 if (!( isset($arTagParams[$key]) && $arTagParams[$key] == $value))
549 {
550 $found = false;
551 break;
552 }
553 }
554 if ($found)
555 {
556 return $offset;
557 }
558 }
559 }
560
561 $offset += $localOffset;
562 $tmp = mb_substr($tmp, $localOffset);
563
564 // skip special tags
565 while ($skip = $this->skipTags($tmp))
566 {
567 $offset += $skip;
568 $tmp = mb_substr($tmp, $skip);
569 }
570 }
571 return false;
572 }
573
574 function skipTags($tmp)
575 {
576 static $tags_open = array('<!--', '<script');
577 static $tags_close = array('-->', '</script>');
578 static $n_tags = 2;
579 static $tags_quoted;
580
581 if (!is_array($tags_quoted))
582 for ($i=0; $i<$n_tags;$i++)
583 $tags_quoted[$i] = array('open' => preg_quote($tags_open[$i]), 'close' => preg_quote($tags_close[$i]));
584
585 for ($i=0; $i<$n_tags;$i++)
586 {
587 if (preg_match('#^\s*'.$tags_quoted[$i]['open'].'#iu', $tmp) < 1) continue;
588 if (preg_match('#('.$tags_quoted[$i]['close'].'[^<]*)#imu', $tmp, $matches) > 0)
589 {
590 $endpos = mb_strpos($tmp, $matches[1]);
591 $offset = $endpos + mb_strlen($matches[1]);
592 return $offset;
593 }
594 }
595 return false;
596 }
597
598 function setError($msg)
599 {
600 $this->lastError = $msg;
601 return false;
602 }
603
604 function findTagEnd($startIndex)
605 {
606 if ($startIndex === false || (intval($startIndex) == 0 && $startIndex !== 0))
607 return $this->setError('E_PARSE_INVALID_INDEX');
608 $tmp = mb_substr($this->data, $startIndex);
609
610 $this->lastError = '';
611 $arStack = [];
612 $offset = 0;
613 $closeMistmatch = 2;
614 $tag_id = 0;
615
616 while ($tmp <> '' && preg_match($this->parse_tag, $tmp, $matches) > 0)
617 {
618 $tag_id++;
619 $tag_name = mb_strtoupper($matches['tag']);
620 $localOffset = mb_strpos($tmp, $matches[0]) + mb_strlen($matches[0]);
621
622 if ($matches['closing'] == '/') // close tag
623 {
624 if (end($arStack) == $tag_name)
625 {
626 array_pop($arStack);
627 }
628 else // lost close tag somewhere
629 {
630 $fixed = false;
631 for ($i=2;$i<=$closeMistmatch+1;$i++)
632 {
633 if (sizeof($arStack) > $i && $arStack[sizeof($arStack)-$i] == $tag_name)
634 {
635 $arStack = array_slice($arStack, 0, -$i);
636 $fixed = true;
637 }
638 }
639 if (!$fixed)
640 {
641 return $this->setError('E_PARSE_INVALID_DOM_2');
642 }
643 }
644 }
645 else if ($matches['selfclosing'] == '/') // self close tag
646 {
647 // do nothing
648 }
649 else if ($tag_name == 'LI' && end($arStack) == 'LI') // oh
650 {
651 // do nothing
652 }
653 else // open tag
654 {
655 $arStack[] = $tag_name;
656 }
657 if (sizeof($arStack) > 300)
658 {
659 return $this->setError('E_PARSE_TOO_BIG_DOM_3'); // too big DOM
660 }
661 else if (sizeof($arStack) == 0) // done !
662 {
663 return $offset + $localOffset;
664 }
665 else // continue
666 {
667 $offset += $localOffset;
668 $tmp = mb_substr($tmp, $localOffset);
669 }
670 // skip special tags
671 while ($skip = $this->skipTags($tmp))
672 {
673 $offset += $skip;
674 $tmp = mb_substr($tmp, $skip);
675 }
676 }
677 return $this->setError('E_PARSE_INVALID_DOM_4'); // not enough data in $data ?
678 }
679
680 function getTagHTML($search)
681 {
682 $messagePost = '';
683 $messageStart = $this->findTagStart($search);
684 if ($messageStart === false) return '';
685 $messageEnd = $this->findTagEnd($messageStart);
686 if ($messageEnd !== false)
687 $messagePost = mb_substr($this->data, $messageStart, $messageEnd);
688 return trim($messagePost);
689 }
690
691 function getInnerHTML($startLabel, $endLabel, $multiple=false)
692 {
693 $startPos = mb_strpos($this->data, $startLabel);
694 if ($startPos === false) return '';
695 $startPos += mb_strlen($startLabel);
696 $endPos = mb_strpos($this->data, $endLabel, $startPos);
697 if ($endPos === false) return '';
698 return trim(mb_substr($this->data, $startPos, $endPos - $startPos));
699 }
700}
701
703{
704 public function __construct()
705 {
706 if(defined("BX_COMP_MANAGED_CACHE"))
707 {
708 AddEventHandler("forum", "onAfterMessageDelete", array(&$this, "OnMessageDelete"));
709 AddEventHandler("forum", "onAfterMessageUpdate", array(&$this, "OnMessageUpdate"));
710 AddEventHandler("forum", "onAfterMessageAdd", array(&$this, "OnMessageAdd"));
711
712 AddEventHandler("forum", "onAfterTopicAdd", array(&$this, "OnTopicAdd"));
713 AddEventHandler("forum", "onAfterTopicUpdate", array(&$this, "OnTopicUpdate"));
714 AddEventHandler("forum", "onTopicOpen", array(&$this, "OnTopicUpdate"));
715 AddEventHandler("forum", "onTopicClose", array(&$this, "OnTopicUpdate"));
716 AddEventHandler("forum", "onAfterTopicDelete", array(&$this, "OnTopicDelete"));
717
718 //AddEventHandler("forum", "onAfterForumAdd", array(&$this, "OnForumAdd"));
719 AddEventHandler("forum", "onAfterForumUpdate", array(&$this, "OnForumUpdate"));
720 //AddEventHandler("forum", "OnAfterForumDelete", array(&$this, "OnForumDelete"));
721
722 AddEventHandler("main", "OnAddRatingVote", Array(&$this, "OnRate"));
723 AddEventHandler("main", "OnCancelRatingVote", Array(&$this, "OnRate"));
724 }
725 }
726
727 public static function Compress($arDictCollection)
728 {
729 if (
730 is_array($arDictCollection) &&
731 (sizeof($arDictCollection) > 9)
732 )
733 {
734 reset($arDictCollection);
735 $arFirst = current($arDictCollection);
736 $arKeys = array_keys($arFirst);
737 $i = 0;
738
739 foreach($arDictCollection as &$arDictionary)
740 {
741 if ($i++ === 0)
742 continue;
743
744 foreach($arKeys as $k)
745 {
746 if (isset($arDictionary[$k]) && ($arDictionary[$k] === $arFirst[$k]))
747 unset($arDictionary[$k]);
748 }
749 }
750 }
751 return $arDictCollection;
752 }
753
754 public static function Expand($arDictCollection)
755 {
756 if (
757 is_array($arDictCollection) &&
758 (sizeof($arDictCollection) > 9) &&
759 is_array($arDictCollection[0])
760 )
761 {
762
763 $arFirst =& $arDictCollection[0];
764 $arKeys = array_keys($arFirst);
765 $i = 0;
766
767 foreach($arDictCollection as &$arDictionary)
768 {
769 if ($i++ === 0)
770 continue;
771
772 foreach($arKeys as $k)
773 {
774 if (!isset($arDictionary[$k]))
775 {
776 $arDictionary[$k] = $arFirst[$k];
777 }
778 }
779 }
780 }
781 return $arDictCollection;
782 }
783
784 public static function SetTag($path, $tags)
785 {
786 global $CACHE_MANAGER;
787 if (! defined("BX_COMP_MANAGED_CACHE"))
788 return false;
789 $CACHE_MANAGER->StartTagCache($path);
790 if (is_array($tags))
791 {
792 foreach ($tags as $tag)
793 $CACHE_MANAGER->RegisterTag($tag);
794 }
795 else
796 {
797 $CACHE_MANAGER->RegisterTag($tags);
798 }
799 $CACHE_MANAGER->EndTagCache();
800 return true;
801 }
802
803 public static function ClearTag($type, $ID=0)
804 {
805 global $CACHE_MANAGER;
806 static $forum = "forum_";
807 static $topic = "forum_topic_";
808
809 if ($type === "F" && $ID > 0)
810 {
811 $CACHE_MANAGER->ClearByTag($forum.$ID);
812 }
813 elseif ($type === "T" && $ID > 0)
814 {
815 $CACHE_MANAGER->ClearByTag($topic.$ID);
816 }
817 else if ($type !== "F" && $type !== "T")
818 {
819 $CACHE_MANAGER->ClearByTag($type);
820 }
821 }
822
823 public function OnRate($rateID, $arData)
824 {
825 if (!isset($arData['ENTITY_TYPE_ID']) ||
826 !isset($arData['ENTITY_ID']) ||
827 ($arData['ENTITY_TYPE_ID'] !== 'FORUM_POST' && $arData['ENTITY_TYPE_ID'] !== 'FORUM_TOPIC'))
828 return false;
829
830 if ($arData['ENTITY_TYPE_ID'] === 'FORUM_POST')
831 {
832 $arMessage = CForumMessage::GetByID($arData['ENTITY_ID']);
833 if ($arMessage)
834 $this->ClearTag("T", $arMessage['TOPIC_ID']);
835 }
836 else if ($arData['ENTITY_TYPE_ID'] === 'FORUM_TOPIC')
837 {
838 $arTopic = CForumTopic::GetByID($arData['ENTITY_ID']);
839 if ($arTopic)
840 $this->ClearTag("F", $arTopic['FORUM_ID']);
841 $this->ClearTag("T", $arData['ENTITY_ID']);
842 }
843 return true;
844 }
845
846 public function OnMessageAdd($ID, $arFields)
847 {
848 self::ClearTag("T", isset($arFields["FORUM_TOPIC_ID"]) ? $arFields["FORUM_TOPIC_ID"] : $arFields["TOPIC_ID"]);
849 self::ClearTag("forum_msg_count".$arFields["FORUM_ID"]);
850 }
851
852 public function OnMessageUpdate($ID, $arFields, $arMessage = array())
853 {
854 $arMessage = (is_array($arMessage) ? $arMessage : array());
855 if ($topic_id = $arFields["FORUM_TOPIC_ID"] ?? $arFields["TOPIC_ID"] ?? $arMessage["TOPIC_ID"] ?? 0)
856 {
857 $this->ClearTag("T", $topic_id);
858 }
859 if ($forum_id = $arFields["FORUM_ID"] ?? $arMessage["FORUM_ID"] ?? 0)
860 {
861 $this->ClearTag("forum_msg_count" . $forum_id);
862 }
863 }
864
865 public function OnMessageDelete($ID, $arMessage)
866 {
867 self::ClearTag("T", isset($arMessage["FORUM_TOPIC_ID"]) ? $arMessage["FORUM_TOPIC_ID"] : $arMessage["TOPIC_ID"]);
868 self::ClearTag("forum_msg_count".$arMessage["FORUM_ID"]);
869 }
870
871 public function OnTopicAdd($ID, $arFields)
872 {
873 self::ClearTag("F", $arFields["FORUM_ID"]);
874 }
875
876 public function OnTopicUpdate($ID, $arFields)
877 {
878 if (count($arFields) == 1 && array_key_exists("VIEWS", $arFields))
879 {
880 return;
881 }
882 self::ClearTag("T", $ID);
883 self::ClearTag("F", $arFields["FORUM_ID"] ?? 0);
884 }
885
886 public function OnTopicDelete(&$ID, $arTopic)
887 {
888 self::ClearTag("T", $ID);
889 self::ClearTag("F", $arTopic["FORUM_ID"]);
890 }
891
892 //public function OnForumAdd(&$ID, &$arFields)
893 //{
894 //}
895
896 public function OnForumUpdate($ID, $arFields)
897 {
898 self::ClearTag("F", $arFields["FORUM_ID"] ?? null);
899 }
900
901 //public function OnForumDelete($ID)
902 //{
903 //}
904}
905
907{
908 private static $instance;
909 private $as;
910
911 public function __construct()
912 {
913 echo CJSCore::Init(array('autosave'), true);
914 $this->as = new CAutoSave();
915 }
916
917 public static function GetInstance()
918 {
919 if (!$GLOBALS['USER']->IsAuthorized())
920 return false;
921 if (COption::GetOptionString("forum", "USE_AUTOSAVE", "Y") === "N")
922 return false;
923
924 if (!isset(self::$instance))
925 {
926 $c = __CLASS__;
927 self::$instance = new $c;
928 }
929
930 return self::$instance;
931 }
932
933 public function LoadScript($arParams)
934 {
935 if (!is_array($arParams))
936 $arParams = array("formID" => $arParams);
937 if (!isset($arParams['recoverMessage']))
938 $arParams['recoverMessage'] = GetMessage('F_MESSAGE_RECOVER');
939
940 $jsParams = CUtil::PhpToJSObject($arParams);
941 $id = $this->as->GetID();
942 ob_start();
943?>
944 <script>
945 window.autosave_<?=$id?>_func = function() { ForumFormAutosave(<?=$jsParams?>); window.autosave_<?=$id?>.Prepare(); };
946 if (!!window["ForumFormAutosave"])
947 window.autosave_<?=$id?>_func();
948 else
949 {
950 BX.addCustomEvent(window, 'onScriptForumAutosaveLoaded', window.autosave_<?=$id?>_func);
951 BX.loadScript("<?=CUtil::GetAdditionalFileURL("/bitrix/js/forum/autosave.js")?>");
952 }
953 </script>
954<?
955 ob_end_flush();
956 }
957
958 public function Init()
959 {
960 return $this->as->Init(false);
961 }
962
963 public function Reset()
964 {
965 return $this->as->Reset();
966 }
967}
968?>
$arParams
Определения access_dialog.php:21
$path
Определения access_edit.php:21
$type
Определения options.php:106
$jsParams
Определения catalog_reindex.php:168
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static GetByID($ID, $arAddParams=array())
Определения message.php:591
static GetByID($ID, $arAddParams=array())
Определения topic.php:431
Определения undo.php:238
Определения functions.php:907
__construct()
Определения functions.php:911
static GetInstance()
Определения functions.php:917
Init()
Определения functions.php:958
Reset()
Определения functions.php:963
LoadScript($arParams)
Определения functions.php:933
__construct()
Определения functions.php:704
static ClearTag($type, $ID=0)
Определения functions.php:803
OnRate($rateID, $arData)
Определения functions.php:823
static SetTag($path, $tags)
Определения functions.php:784
OnTopicUpdate($ID, $arFields)
Определения functions.php:876
OnMessageAdd($ID, $arFields)
Определения functions.php:846
OnForumUpdate($ID, $arFields)
Определения functions.php:896
OnTopicDelete(&$ID, $arTopic)
Определения functions.php:886
OnTopicAdd($ID, $arFields)
Определения functions.php:871
OnMessageUpdate($ID, $arFields, $arMessage=array())
Определения functions.php:852
static Compress($arDictCollection)
Определения functions.php:727
static Expand($arDictCollection)
Определения functions.php:754
OnMessageDelete($ID, $arMessage)
Определения functions.php:865
findTagStart($needle)
Определения functions.php:501
setError($msg)
Определения functions.php:598
defendTags($matches)
Определения functions.php:493
__construct($data)
Определения functions.php:467
getTagHTML($search)
Определения functions.php:680
findTagEnd($startIndex)
Определения functions.php:604
getInnerHTML($startLabel, $endLabel, $multiple=false)
Определения functions.php:691
skipTags($tmp)
Определения functions.php:574
static URN2URI($urn, $server_name='')
Определения http.php:39
static Init($arExt=array(), $bReturn=false)
Определения jscore.php:66
Определения textparser.php:21
defended_tags($text, $tag='replace')
Определения textparser.php:1032
convertText($text, $attributes=[])
Определения textparser.php:213
$type
Определения textparser.php:22
$allow
Определения textparser.php:40
Определения functions.php:18
$pathToUser
Определения functions.php:20
convert_attachment($fileID="", $p="", $type="", $text="")
Определения functions.php:319
static GetFeatures($arForum)
Определения functions.php:50
$component
Определения functions.php:27
render_user($fields)
Определения functions.php:426
$MaxStringLen
Определения functions.php:30
$imageTemplate
Определения functions.php:26
ParserFile(&$text, &$obj, $type="html")
Определения functions.php:232
convert4mail($text, $files=false, $allow=array(), $params=array())
Определения functions.php:165
convert_image_tag($url="", $params="")
Определения functions.php:280
static GetEditorButtons($arParams)
Определения functions.php:68
convert_close_tag($marker="quote")
Определения functions.php:258
$imageHtmlWidth
Определения functions.php:24
$imageHeight
Определения functions.php:22
static GetEditorToolbar($arParams)
Определения functions.php:90
convert_to_rss( $text, $arImages=Array(), $arAllow=Array())
Определения functions.php:398
convert_open_tag($marker="quote")
Определения functions.php:243
$image_params
Определения functions.php:19
__construct($lang=false, $pathToSmiles='', $type=false, $mode='full')
Определения functions.php:32
$arFilesIDParsed
Определения functions.php:29
$maxStringLen
Определения functions.php:23
$imageHtmlHeight
Определения functions.php:25
$smilesGallery
Определения functions.php:28
$imageWidth
Определения functions.php:21
convert($text, $allow=array(), $type="html", $arFiles=false, $attributes=[])
Определения functions.php:132
Определения functions.php:447
killAllTags($text)
Определения functions.php:448
global $CACHE_MANAGER
Определения clear_component_cache.php:7
$f
Определения component_props.php:52
if(!is_array($prop["VALUES"])) $tmp
Определения component_props.php:203
$arFields
Определения dblapprove.php:5
$data['IS_AVAILABLE']
Определения .description.php:13
</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
Error($error)
Определения functions.php:9
$result
Определения get_property_values.php:14
if($ajaxMode) $ID
Определения get_user.php:27
$p
Определения group_list_element_edit.php:23
global $MESS
Определения bill.php:2
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
endif
Определения csv_new_setup.php:990
if(!defined('SITE_ID')) $lang
Определения include.php:91
AddEventHandler($FROM_MODULE_ID, $MESSAGE_ID, $CALLBACK, $SORT=100, $FULL_PATH=false)
Определения tools.php:5165
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
$arFiles
Определения options.php:60
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$text
Определения template_pdf.php:79
$i
Определения factura.php:643
else $userName
Определения order_form.php:75
</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."%"
Определения waybill.php:936
$width
Определения html.php:68
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$val
Определения options.php:1793
$matches
Определения index.php:22
$arFeatures
Определения options.php:54
const SITE_ID
Определения sonet_set_content_view.php:12
$error
Определения subscription_card_product.php:20
$k
Определения template_pdf.php:567
$GLOBALS['_____370096793']
Определения update_client.php:1
$url
Определения iframe.php:7
$fields
Определения yandex_run.php:501