2020-06-07 19:04:43 +03:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
namespace openvk\Web\Models\Entities\Traits;
|
2022-12-10 22:33:13 +03:00
|
|
|
use openvk\Web\Models\Repositories\{Users, Clubs};
|
2021-12-14 14:46:51 +03:00
|
|
|
use Wkhooy\ObsceneCensorRus;
|
2020-06-07 19:04:43 +03:00
|
|
|
|
|
|
|
trait TRichText
|
|
|
|
{
|
|
|
|
private function formatEmojis(string $text): string
|
|
|
|
{
|
2021-11-17 22:41:44 +03:00
|
|
|
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
|
|
|
if(iconv_strlen($this->getRecord()->{$contentColumn}) > OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["emojiProcessingLimit"])
|
2020-08-20 15:58:40 +03:00
|
|
|
return $text;
|
|
|
|
|
2020-06-26 11:36:56 +03:00
|
|
|
$emojis = \Emoji\detect_emoji($text);
|
2020-08-20 15:58:40 +03:00
|
|
|
$replaced = []; # OVK-113
|
2020-06-07 19:04:43 +03:00
|
|
|
foreach($emojis as $emoji) {
|
2020-08-20 15:58:40 +03:00
|
|
|
$point = explode("-", strtolower($emoji["hex_str"]))[0];
|
|
|
|
if(in_array($point, $replaced))
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
$replaced[] = $point;
|
|
|
|
|
2020-06-26 12:30:15 +03:00
|
|
|
$image = "https://abs.twimg.com/emoji/v2/72x72/$point.png";
|
2020-06-07 19:04:43 +03:00
|
|
|
$image = "<img src='$image' alt='$emoji[emoji]' ";
|
2020-06-26 12:30:15 +03:00
|
|
|
$image .= "style='max-height:12px; padding-left: 2pt; padding-right: 2pt; vertical-align: bottom;' />";
|
2020-06-07 19:04:43 +03:00
|
|
|
|
|
|
|
$text = str_replace($emoji["emoji"], $image, $text);
|
|
|
|
}
|
|
|
|
|
2020-08-20 15:58:40 +03:00
|
|
|
return $text;
|
2020-06-07 19:04:43 +03:00
|
|
|
}
|
2021-11-17 22:41:44 +03:00
|
|
|
|
|
|
|
private function formatLinks(string &$text): string
|
|
|
|
{
|
|
|
|
return preg_replace_callback(
|
2022-01-16 14:15:08 +03:00
|
|
|
"%(([A-z]++):\/\/(\S*?\.\S*?))([\s)\[\]{},\"\'<]|\.\s|$)%",
|
2021-11-17 22:41:44 +03:00
|
|
|
(function (array $matches): string {
|
|
|
|
$href = str_replace("#", "#", $matches[1]);
|
2023-02-25 19:08:17 +03:00
|
|
|
$href = rawurlencode(str_replace(";", ";", $href));
|
2021-11-17 22:41:44 +03:00
|
|
|
$link = str_replace("#", "#", $matches[3]);
|
2024-11-01 14:46:41 +03:00
|
|
|
# this string breaks ampersands
|
2023-02-25 19:07:29 +03:00
|
|
|
$link = str_replace(";", ";", $link);
|
2021-11-17 22:41:44 +03:00
|
|
|
$rel = $this->isAd() ? "sponsored" : "ugc";
|
2024-11-01 14:46:41 +03:00
|
|
|
|
|
|
|
$server_domain = str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']);
|
|
|
|
if(str_contains($link, $server_domain)) {
|
|
|
|
$replaced_link = str_replace(':' . $_SERVER['SERVER_PORT'], '', $link);
|
|
|
|
$replaced_link = str_replace($server_domain, '', $replaced_link);
|
|
|
|
|
|
|
|
return "<a href='$replaced_link' rel='$rel'>$link</a>" . htmlentities($matches[4]);
|
|
|
|
}
|
|
|
|
|
|
|
|
$link = htmlentities(urldecode($link));
|
2021-11-17 22:41:44 +03:00
|
|
|
|
2022-09-05 18:57:41 +03:00
|
|
|
return "<a href='/away.php?to=$href' rel='$rel' target='_blank'>$link</a>" . htmlentities($matches[4]);
|
2021-11-17 22:41:44 +03:00
|
|
|
}),
|
|
|
|
$text
|
|
|
|
);
|
|
|
|
}
|
2020-06-07 19:04:43 +03:00
|
|
|
|
|
|
|
private function removeZalgo(string $text): string
|
|
|
|
{
|
2023-02-25 19:08:17 +03:00
|
|
|
return preg_replace("%\p{M}{3,}%Xu", "", $text);
|
2020-06-07 19:04:43 +03:00
|
|
|
}
|
|
|
|
|
2022-12-10 22:33:13 +03:00
|
|
|
function resolveMentions(array $skipUsers = []): \Traversable
|
|
|
|
{
|
|
|
|
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
|
|
|
$text = $this->getRecord()->{$contentColumn};
|
|
|
|
$text = preg_replace("%@([A-Za-z0-9]++) \(((?:[\p{L&}\p{Lo} 0-9]\p{Mn}?)++)\)%Xu", "[$1|$2]", $text);
|
|
|
|
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
|
|
|
|
|
|
|
$resolvedUsers = $skipUsers;
|
|
|
|
$resolvedClubs = [];
|
|
|
|
preg_match_all("%\[([A-Za-z0-9]++)\|((?:[\p{L&}\p{Lo} 0-9@]\p{Mn}?)++)\]%Xu", $text, $links, PREG_PATTERN_ORDER);
|
|
|
|
foreach($links[1] as $link) {
|
|
|
|
if(preg_match("%^id([0-9]++)$%", $link, $match)) {
|
|
|
|
$uid = (int) $match[1];
|
|
|
|
if(in_array($uid, $resolvedUsers))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
$resolvedUsers[] = $uid;
|
|
|
|
$maybeUser = (new Users)->get($uid);
|
|
|
|
if($maybeUser)
|
|
|
|
yield $maybeUser;
|
|
|
|
} else if(preg_match("%^(?:club|public|event)([0-9]++)$%", $link, $match)) {
|
|
|
|
$cid = (int) $match[1];
|
|
|
|
if(in_array($cid, $resolvedClubs))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
$resolvedClubs[] = $cid;
|
|
|
|
$maybeClub = (new Clubs)->get($cid);
|
|
|
|
if($maybeClub)
|
|
|
|
yield $maybeClub;
|
|
|
|
} else {
|
|
|
|
$maybeUser = (new Users)->getByShortURL($link);
|
|
|
|
if($maybeUser) {
|
|
|
|
$uid = $maybeUser->getId();
|
|
|
|
if(in_array($uid, $resolvedUsers))
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
$resolvedUsers[] = $uid;
|
|
|
|
|
|
|
|
yield $maybeUser;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$maybeClub = (new Clubs)->getByShortURL($link);
|
|
|
|
if($maybeClub) {
|
|
|
|
$cid = $maybeClub->getId();
|
|
|
|
if(in_array($cid, $resolvedClubs))
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
$resolvedClubs[] = $cid;
|
|
|
|
|
|
|
|
yield $maybeClub;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-07 19:04:43 +03:00
|
|
|
function getText(bool $html = true): string
|
|
|
|
{
|
2021-11-17 22:39:22 +03:00
|
|
|
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
|
|
|
|
2022-04-18 19:22:36 +03:00
|
|
|
$text = htmlspecialchars($this->getRecord()->{$contentColumn}, ENT_DISALLOWED | ENT_XHTML);
|
2021-11-17 22:39:22 +03:00
|
|
|
$proc = iconv_strlen($this->getRecord()->{$contentColumn}) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["processingLimit"];
|
2020-06-07 19:04:43 +03:00
|
|
|
if($html) {
|
2020-08-20 15:58:40 +03:00
|
|
|
if($proc) {
|
2020-08-24 14:37:47 +03:00
|
|
|
$text = $this->formatLinks($text);
|
2022-04-18 19:22:36 +03:00
|
|
|
$text = preg_replace("%@([A-Za-z0-9]++) \(((?:[\p{L&}\p{Lo} 0-9]\p{Mn}?)++)\)%Xu", "[$1|$2]", $text);
|
2021-12-22 17:01:39 +03:00
|
|
|
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
2022-04-18 19:22:36 +03:00
|
|
|
$text = preg_replace("%\[([A-Za-z0-9]++)\|((?:[\p{L&}\p{Lo} 0-9@]\p{Mn}?)++)\]%Xu", "<a href='/$1'>$2</a>", $text);
|
2022-04-18 19:33:44 +03:00
|
|
|
$text = preg_replace_callback("%([\n\r\s]|^)(\#([\p{L}_0-9][\p{L}_0-9\(\)\-\']+[\p{L}_0-9\(\)]|[\p{L}_0-9]{1,2}))%Xu", function($m) {
|
|
|
|
$slug = rawurlencode($m[3]);
|
|
|
|
|
2024-10-25 16:28:35 +03:00
|
|
|
return "$m[1]<a href='/search?section=posts&q=%23$slug'>$m[2]</a>";
|
2022-04-18 19:33:44 +03:00
|
|
|
}, $text);
|
|
|
|
|
2020-08-20 15:58:40 +03:00
|
|
|
$text = $this->formatEmojis($text);
|
|
|
|
}
|
|
|
|
|
2020-06-07 19:04:43 +03:00
|
|
|
$text = $this->removeZalgo($text);
|
|
|
|
$text = nl2br($text);
|
2022-07-21 09:40:42 +03:00
|
|
|
} else {
|
|
|
|
$text = str_replace("\r\n","\n", $text);
|
2020-06-07 19:04:43 +03:00
|
|
|
}
|
|
|
|
|
2021-12-14 14:46:51 +03:00
|
|
|
if(OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["christian"])
|
2021-12-14 14:55:11 +03:00
|
|
|
ObsceneCensorRus::filterText($text);
|
2021-12-14 14:46:51 +03:00
|
|
|
|
2020-06-07 19:04:43 +03:00
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
}
|