403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/im/lib/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/im/lib/text.php
<?php
namespace Bitrix\Im;

use Bitrix\Im\Integration\Socialnetwork\Extranet;
use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);

class Text
{
	private static $replacements = Array();
	private static $parsers = Array();

	private static $emojiList = [
		"file" => ':f09f938e:',
		"image" => ':f09f96bc:',
		"audio" => ':f09f9488:',
		"video" => ':f09f93ba:',
		"code" => ':f09f9384:',
		"call" => ':f09f939e:',
		"attach" => ':f09fa7a9:',
		"quote" => ':f09f92ac:',
	];

	public static function parse($text, $params = Array())
	{
		$linkParam = $params['LINK'] ?? null;
		$smilesParam = $params['SMILES'] ?? null;
		$linkLimitParam = $params['LINK_LIMIT'] ?? null;
		$textLimitParam = $params['TEXT_LIMIT'] ?? null;
		$cutStrikeParam = $params['CUT_STRIKE'] ?? null;

		$parseId = md5($linkParam.$smilesParam.$linkLimitParam.$textLimitParam);
		if (isset(self::$parsers[$parseId]))
		{
			$parser = self::$parsers[$parseId];
		}
		else
		{
			$parser = new \CTextParser();
			$parser->serverName = Common::getPublicDomain();
			$parser->maxStringLen = intval($textLimitParam);

			$parser->anchorType = 'bbcode';
			$parser->maxAnchorLength = intval($linkLimitParam)? $linkLimitParam: 55;

			foreach ($parser->allow as $tag => $value)
			{
				$parser->allow[$tag] = 'N';
			}
			$parser->allow['EMOJI'] = 'Y';
			$parser->allow['HTML'] = 'Y';
			$parser->allow['ANCHOR'] = 'Y';
			$parser->allow['TEXT_ANCHOR'] = 'Y';

			self::$parsers[$parseId] = $parser;
		}

		$text = preg_replace_callback("/\[CODE\](.*?)\[\/CODE\]/si", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[PUT(?:=(.+?))?\](.+?)?\[\/PUT\]/i", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[SEND(?:=(.+?))?\](.+?)?\[\/SEND\]/i", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[USER=([0-9]{1,})\]\[\/USER\]/i", Array('\Bitrix\Im\Text', 'modifyShortUserTag'), $text);

		if ($cutStrikeParam === 'Y')
		{
			$text = preg_replace("/\[s\].*?\[\/s\]/i", "", $text);
		}

		$text = $parser->convertText($text);

		$text = str_replace(['<br />', '#BR#', '[br]'], "\n", $text);
		$text = str_replace(["&#169;", "&#153;", "&#174;"], ["(c)", "(tm)", "(r)"], $text);
		$text = str_replace("&nbsp;", " ", $text);
		$text = str_replace("&quot;", "\"", $text);
		$text = str_replace("&#092;", "\\", $text);
		$text = str_replace("&#036;", "\$", $text);
		$text = str_replace("&#33;", "!", $text);
		$text = str_replace("&#91;", "[", $text);
		$text = str_replace("&#93;", "]", $text);
		$text = str_replace("&#39;", "'", $text);
		$text = str_replace("&lt;", "<", $text);
		$text = str_replace("&gt;", ">", $text);
		$text = str_replace("&#124;", '|', $text);
		$text = str_replace("&amp;", "&", $text);

		$text = self::recoverReplacements($text);

		return $text;
	}

	public static function parseLegacyFormat($text, $params = Array())
	{
		if (!$text)
		{
			return '';
		}

		$safeParam = $params['SAFE'] ?? null;
		$linkParam = $params['LINK'] ?? null;
		$fontParam = $params['FONT'] ?? null;
		$smilesParam = $params['SMILES'] ?? null;
		$textAnchorParam = $params['TEXT_ANCHOR'] ?? null;
		$linkLimitParam = $params['LINK_LIMIT'] ?? null;
		$textLimitParam = $params['TEXT_LIMIT'] ?? null;
		$linkTargetSelfParam = $params['LINK_TARGET_SELF'] ?? null;
		$cutStrikeParam = $params['CUT_STRIKE'] ?? null;

		if (!$safeParam || $safeParam === 'Y')
		{
			$text = htmlspecialcharsbx($text);
		}

		$allowTags = [
			'HTML' => 'N',
			'USER' => 'N',
			'ANCHOR' => $linkParam === 'N' ? 'N' : 'Y',
			'BIU' => 'Y',
			'IMG' => 'N',
			'QUOTE' => 'N',
			'CODE' => 'N',
			'FONT' => $fontParam === 'Y' ? 'Y' : 'N',
			'LIST' => 'N',
			'SPOILER' => 'N',
			'SMILES' => $smilesParam === 'N' ? 'N' : 'Y',
			'EMOJI' => 'Y',
			'NL2BR' => 'Y',
			'VIDEO' => 'N',
			'TABLE' => 'N',
			'CUT_ANCHOR' => 'N',
			'SHORT_ANCHOR' => 'N',
			'ALIGN' => 'N',
			'TEXT_ANCHOR' => $textAnchorParam === 'N' ? 'N' : 'Y',
		];

		$parseId = md5('legacy'.$linkParam.$smilesParam.$linkLimitParam.$textLimitParam.$linkTargetSelfParam);
		if (isset(self::$parsers[$parseId]))
		{
			$parser = self::$parsers[$parseId];
		}
		else
		{
			$parser = new \CTextParser();
			$parser->serverName = Common::getPublicDomain();
			$parser->maxAnchorLength = intval($linkLimitParam)? $linkLimitParam: 55;
			$parser->maxStringLen = intval($textLimitParam);
			$parser->allow = $allowTags;
			if ($linkTargetSelfParam === 'Y')
			{
				$parser->link_target = "_self";
			}

			self::$parsers[$parseId] = $parser;
		}

		$text = preg_replace_callback("/\[PUT(?:=(.+?))?\](.+?)?\[\/PUT\]/i", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[SEND(?:=(.+?))?\](.+?)?\[\/SEND\]/i", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[CODE\](.*?)\[\/CODE\]/si", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[USER=([0-9]{1,})\]\[\/USER\]/i", Array('\Bitrix\Im\Text', 'modifyShortUserTag'), $text);

		if ($cutStrikeParam === 'Y')
		{
			$text = preg_replace("/\[s\].*?\[\/s\]/i", "", $text);
		}

		$text = $parser->convertText($text);

		$text = str_replace(array('#BR#', '[br]', '[BR]'), '<br/>', $text);

		$text = self::recoverReplacements($text);

		return $text;
	}

	public static function getReplaceMap($text)
	{
		$replaces = [];

		$dates = self::getDateConverterParams($text);
		foreach ($dates as $result)
		{
			$replaces[] = [
				'TYPE' => 'DATE',
				'TEXT' => $result->getText(),
				'VALUE' => $result->getDate(),
				'START' => $result->getTextPosition(),
				'END' => $result->getTextPosition()+$result->getTextLength(),
			];
		}

		return self::resolveIntersect($replaces);
	}

	private static function resolveIntersect(array $segments): array
	{
		usort($segments, fn(array $segmentA, array $segmentB) => $segmentA['START'] <=> $segmentB['START']);

		$result = [];
		$maxEnd = -1;

		foreach ($segments as $segment)
		{
			if ($segment['START'] > $maxEnd)
			{
				$result[] = $segment;
				$maxEnd = $segment['END'];
			}
		}

		return array_reverse($result);
	}

	/**
	 * @param $text
	 * @return \Bitrix\Main\Text\DateConverterResult[]
	 */
	public static function getDateConverterParams($text)
	{
		if ($text == '')
			return Array();

		$text = preg_replace_callback("/\[PUT(?:=(.+?))?\](.+?)?\[\/PUT\]/i", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback("/\[SEND(?:=(.+?))?\](.+?)?\[\/SEND\]/i", Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback('/\[URL\=([^\]]*)\]([^\]]*)\[\/URL\]/i', Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback('/(https?):\/\/(([a-z0-9$_\.\+!\*\'\(\),;\?&=-]|%[0-9a-f]{2})+(:([a-z0-9$_\.\+!\*\'\(\),;\?&=-]|%[0-9a-f]{2})+)?@)?(?#)((([a-z0-9]\.|[a-z0-9][a-z0-9-]*[a-z0-9]\.)*[a-z][a-z0-9-]*[a-z0-9]|((\d|[1-9]\d|1\d{2}|2[0-4][0-9]|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4][0-9]|25[0-5]))(:\d+)?)(((\/+([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)*(\?([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)?)?)?(#([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)?/im', Array('\Bitrix\Im\Text', 'setReplacement'), $text);
		$text = preg_replace_callback('#\-{54}(.+?)\-{54}#s', Array('\Bitrix\Im\Text', 'setReplacement'), $text);

		return \Bitrix\Main\Text\DateConverter::decode($text, 1000);
	}

	public static function isOnlyEmoji($text)
	{
		$total = 0;
		$count = 0;

		$pattern = '%(?:
				\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
				| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
				| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
			)%xs';
		$text = preg_replace_callback($pattern, function () {return "";}, $text, 4-$total, $count);
		$total += $count;

		if ($total > 3)
		{
			return false;
		}

		if ($total <= 0)
		{
			return false;
		}

		$text = trim($text);

		return !$text;
	}

	public static function setReplacement($match)
	{
		$code = '####REPLACEMENT_MARK_'.count(self::$replacements).'####';

		self::$replacements[$code] = $match[0];

		return $code;
	}

	public static function recoverReplacements($text)
	{
		if (empty(self::$replacements))
		{
			return $text;
		}

		foreach(self::$replacements as $code => $value)
		{
			$text = str_replace($code, $value, $text);
		}

		if (mb_strpos($text, '####REPLACEMENT_MARK_') !== false)
		{
			$text = self::recoverReplacements($text);
		}

		self::$replacements = Array();

		return $text;
	}

	public static function modifyShortUserTag($matches)
	{
		$userId = $matches[1];
		$userName = \Bitrix\Im\User::getInstance($userId)->getFullName(false);
		return '[USER='.$userId.' REPLACE]'.$userName.'[/USER]';
	}

	public static function removeBbCodes($text, $withFile = false, $attachValue = false)
	{
		if ($attachValue)
		{
			if ($attachValue === true || preg_match('/^(\d+)$/', $attachValue))
			{
				$text .= " [".Loc::getMessage('IM_MESSAGE_ATTACH')."]";
			}
			else
			{
				$text .= ' '. $attachValue;
			}
		}

		$text = preg_replace("/\[s\](.*?)\[\/s\]/i", "", $text);
		$text = preg_replace("/\[[buis]\](.*?)\[\/[buis]\]/i", "$1", $text);
		$text = preg_replace("/\[url\](.*?)\[\/url\]/iu", "$1", $text);
		$text = preg_replace("/\[url\\s*=\\s*((?:[^\\[\\]]++|\\[ (?: (?>[^\\[\\]]+) | (?:\\1) )* \\])+)\\s*\\](.*?)\\[\\/url\\]/ixsu", "$2", $text);
		$text = preg_replace("/\[RATING=([1-5]{1})\]/i", " [".Loc::getMessage('IM_MESSAGE_RATING')."] ", $text);
		$text = preg_replace("/\[ATTACH=([0-9]{1,})\]/i", " [".Loc::getMessage('IM_MESSAGE_ATTACH')."] ", $text);
		$text = preg_replace_callback("/\[USER=([0-9]{1,})\]\[\/USER\]/i", Array('\Bitrix\Im\Text', 'modifyShortUserTag'), $text);
		$text = preg_replace("/\[USER=([0-9]+)( REPLACE)?](.*?)\[\/USER]/i", "$3", $text);
		$text = preg_replace("/\[dialog=(chat\d+|\d+:\d)(?: message=(\d+))?](.*?)\[\/dialog]/i", "$3", $text);
		$text = preg_replace("/\[context=(chat\d+|\d+:\d+)\/(\d+)](.*?)\[\/context]/i", "$3", $text);
		$text = preg_replace("/\[CHAT=([0-9]{1,})\](.*?)\[\/CHAT\]/i", "$2", $text);
		$text = preg_replace("/\[SEND(?:=(.+?))?\](.+?)?\[\/SEND\]/i", "$2", $text);
		$text = preg_replace("/\[PUT(?:=(.+?))?\](.+?)?\[\/PUT\]/i", "$2", $text);
		$text = preg_replace("/\[CALL(?:=(.+?))?\](.+?)?\[\/CALL\]/i", "$2", $text);
		$text = preg_replace("/\[PCH=([0-9]{1,})\](.*?)\[\/PCH\]/i", "$2", $text);
		$text = preg_replace("/\[size=(\d+)](.*?)\[\/size]/i", "$2", $text);
		$text = preg_replace("/\[color=#([0-9a-f]{3}|[0-9a-f]{6})](.*?)\[\/color]/i", "$2", $text);
		$text = preg_replace_callback("/\[ICON\=([^\]]*)\]/i", Array('\Bitrix\Im\Text', 'modifyIcon'), $text);
		$text = preg_replace('#\-{54}.+?\-{54}#s', " [".Loc::getMessage('IM_QUOTE')."] ", str_replace(array("#BR#"), Array(" "), $text));
		$text = trim($text);

		if ($withFile)
		{
			$text .= " [".Loc::getMessage('IM_MESSAGE_FILE')."]";
		}

		$text = trim($text);

		if ($text == '')
		{
			$text = Loc::getMessage('IM_MESSAGE_DELETE');
		}

		return $text;
	}

	public static function populateUserBbCode(string $text): string
	{
		return preg_replace_callback("/\[USER=([0-9]{1,})\]\[\/USER\]/i", static function($matches){
			$userId = $matches[1];
			$userName = \Bitrix\Im\User::getInstance($userId)->getFullName(false);
			return '[USER='.$userId.' REPLACE]'.$userName.'[/USER]';
		}, $text);
	}

	public static function encodeEmoji($text)
	{
		return \Bitrix\Main\Text\Emoji::encode($text);
	}

	public static function decodeEmoji($text)
	{
		return \Bitrix\Main\Text\Emoji::decode($text);
	}

	public static function getEmoji($code, $fallbackText = '')
	{
		if (!isset(self::$emojiList[$code]))
		{
			return $fallbackText;
		}

		return self::decodeEmoji(self::$emojiList[$code]);
	}

	public static function getEmojiList(): ?array
	{
		return array_map(fn ($element) => self::decodeEmoji($element), self::$emojiList);
	}

	public static function convertHtmlToBbCode($html)
	{
		if (!is_string($html))
		{
			return $html;
		}

		$html = str_replace('&nbsp;', ' ', $html);
		$html = str_replace('<hr>', '------[BR]', $html);
		$html = str_replace('#BR#', '[BR]', $html);

		$replaced = 0;
		do
		{
			$html = preg_replace(
				"/<([busi])[^>a-z]*>(.+?)<\\/(\\1)[^>a-z]*>/isu",
				"[\\1]\\2[/\\1]",
				$html, -1, $replaced
			);
		}
		while($replaced > 0);

		$html = preg_replace("/\\<br\s*\\/*\\>/isu","[br]", $html);
		$html = preg_replace(
			[
				"#<a[^>]+href\\s*=\\s*('|\")(.+?)(?:\\1)[^>]*>(.*?)</a[^>]*>#isu",
				"#<a[^>]+href(\\s*=\\s*)([^'\">]+)>(.*?)</a[^>]*>#isu"
			],
			"[url=\\2]\\3[/url]", $html
		);
		$html = preg_replace(
			["/<font[^>]+color\s*=[\s'\"]*#([0-9a-f]{3}|[0-9a-f]{6})[\s'\"]*>(.+?)<\/font[^>]*>/iu"],
			["[color=#\\1]\\2[/color]"],
			$html
		);
		$html = preg_replace(
			["/<span[^>]+color\s*=[\s'\"]*#([0-9a-f]{3}|[0-9a-f]{6})[\s'\"]*>(.+?)<\/span[^>]*>/iu"],
			["[color=#\\1]\\2[/color]"],
			$html
		);
		$html = preg_replace(
			["/<font[^>]+size\s*=[\s'\"]*(\d+)[\s'\"]*>(.+?)<\/font[^>]*>/iu"],
			["[size=\\1]\\2[/size]"],
			$html
		);

		$replaced = 0;
		do
		{
			$html = preg_replace(
				"/<div(?:.*?)>(.*?)<\/div>/iu",
				"\\1",
				$html, -1, $replaced
			);
		}
		while($replaced > 0);

		$replaced = 0;
		do
		{
			$html = preg_replace(
				"/<span(?:.*?)>(.*?)<\/span>/iu",
				"\\1",
				$html, -1, $replaced
			);
		}
		while($replaced > 0);

		$html = preg_replace(
			"/<font(?:.*?)>(.*?)<\/font>/iu",
			"\\1",
			$html
		);

		return $html;
	}

	public static function modifyIcon($params)
	{
		$text = $params[1];

		$title = Loc::getMessage('IM_MESSAGE_ICON');

		preg_match('/title\=(.*[^\s\]])/i', $text, $match);
		if ($match)
		{
			$title = $match[1];
			if (mb_strpos($title, 'width=') !== false)
			{
				$title = mb_substr($title, 0, mb_strpos($title, 'width='));
			}
			if (mb_strpos($title, 'height=') !== false)
			{
				$title = mb_substr($title, 0, mb_strpos($title, 'height='));
			}
			if (mb_strpos($title, 'size=') !== false)
			{
				$title = mb_substr($title, 0, mb_strpos($title, 'size='));
			}
			$title = trim($title);
		}

		return '('.$title.')';
	}

	public static function modifySendPut($params)
	{
		$code = mb_strpos(mb_strtoupper($params[0]), '[SEND') === 0? 'SEND': 'PUT';
		return preg_replace("/\[$code(?:=(.+))?\](.+?)?\[\/$code\]/i", "$2", $params[0]);
	}

	public static function getSaveModificator()
	{
		return [
			[__CLASS__, 'extendedEncodeEmoji']
		];
	}

	public static function getFetchModificator()
	{
		return [
			[__CLASS__, 'extendedDecodeEmoji']
		];
	}

	public static function extendedEncodeEmoji($text)
	{
		return isset($text) ? self::encodeEmoji($text) : null;
	}

	public static function extendedDecodeEmoji($text)
	{
		return isset($text) ? self::decodeEmoji($text) : null;
	}

	public static function convertSymbolsAfterJsonDecode($data)
	{
		$search = ["\\n", "\\t", '\\"', "\\\\"];
		$replace = ["\n", "\t", '"', "\\"];

		if (is_string($data))
		{
			return str_replace($search, $replace, $data);
		}

		if (is_array($data))
		{
			foreach ($data as $key => $value)
			{
				$data[$key] = self::convertSymbolsAfterJsonDecode($value);
			}
		}

		return $data;
	}

	public static function filterUserBbCodes(string $text, int $currentUserId): string
	{
		$pattern = "/\[USER=(\d+)(?: REPLACE)?](.*?)\[\/USER]/is";

		do
		{
			$previousText = $text;
			$text = preg_replace_callback($pattern, function ($matches) use($currentUserId) {
				return self::replaceUserBbCodeByAccess($matches, $currentUserId);
			}, $text);
		}
		while ($previousText !== $text);

		return $text;
	}

	private static function replaceUserBbCodeByAccess($matches, int $currentUserId): string
	{
		$userId = $matches[1];

		$currentUser = \Bitrix\Im\V2\Entity\User\User::getInstance($currentUserId);
		$result = $currentUser->checkAccess((int)$userId);

		if ($result->isSuccess())
		{
			return $matches[0] ?? '';
		}

		return $matches[2] ?? '';
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit