From 538e212a84873dfa290c594e66a8c038fbf5b382 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 19 Apr 2020 16:33:06 +0000 Subject: [PATCH] Hashtag handling with Diaspora improved --- src/Content/Text/BBCode.php | 2 +- src/Model/Item.php | 5 ++++- src/Model/Tag.php | 34 ++++++++++++++++++++++++++++++++++ src/Protocol/Diaspora.php | 4 ++-- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 334efb32a7..601bf63b25 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -2100,7 +2100,7 @@ class BBCode $ret = []; // Convert hashtag links to hashtags - $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2', $string); + $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2 ', $string); // ignore anything in a code block $string = preg_replace('/\[code.*?\].*?\[\/code\]/sm', '', $string); diff --git a/src/Model/Item.php b/src/Model/Item.php index 1f2faa2698..0e82189298 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -2610,7 +2610,10 @@ class Item // This sorting is important when there are hashtags that are part of other hashtags // Otherwise there could be problems with hashtags like #test and #test2 - rsort($tags); + // Because of this we are sorting from the longest to the shortest tag. + usort($rawtags, function($a, $b) { + return strlen($b) <=> strlen($a); + }); $URLSearchString = "^\[\]"; diff --git a/src/Model/Tag.php b/src/Model/Tag.php index bd1945c480..ac26009033 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -21,7 +21,9 @@ namespace Friendica\Model; +use Friendica\Content\Text\BBCode; use Friendica\Core\Logger; +use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Util\Strings; @@ -87,6 +89,7 @@ class Tag } else { // The contact wasn't found in the system (most likely some dead account) // We ensure that we only store a single entry by overwriting the previous name + Logger::info('Update tag', ['url' => $url, 'name' => $name]); DBA::update('tag', ['name' => substr($name, 0, 96)], ['url' => $url]); } } @@ -148,15 +151,46 @@ class Tag $tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION]; } + Logger::info('Check for tags', ['uri-id' => $uriid, 'hash' => $tags, 'callstack' => System::callstack()]); + if (!preg_match_all("/([" . $tags . "])\[url\=([^\[\]]*)\]([^\[\]]*)\[\/url\]/ism", $body, $result, PREG_SET_ORDER)) { return; } + Logger::info('Found tags', ['uri-id' => $uriid, 'hash' => $tags, 'result' => $result]); + foreach ($result as $tag) { self::storeByHash($uriid, $tag[1], $tag[3], $tag[2]); } } + /** + * Store raw tags (not encapsulated in links) from the body + * This function is needed in the intermediate phase. + * Later we can call item::setHashtags in advance to have all tags converted. + * + * @param integer $uriid URI-Id + * @param string $body Body of the post + */ + public static function storeRawTagsFromBody(int $uriid, string $body) + { + Logger::info('Check for tags', ['uri-id' => $uriid, 'callstack' => System::callstack()]); + + $result = BBCode::getTags($body); + if (empty($result)) { + return; + } + + Logger::info('Found tags', ['uri-id' => $uriid, 'result' => $result]); + + foreach ($result as $tag) { + if (substr($tag, 0, 1) != self::TAG_CHARACTER[self::HASHTAG]) { + continue; + } + self::storeByHash($uriid, substr($tag, 0, 1), substr($tag, 1)); + } + } + /** * Remove tag/mention * diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index d7e8f60a2e..513cd0bcc0 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -1938,7 +1938,7 @@ class Diaspora $datarray["body"] = self::replacePeopleGuid($body, $person["url"]); self::storeMentions($datarray['uri-id'], $text); - Tag::storeFromBody($datarray['uri-id'], $datarray["body"], '#'); + Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray["body"]); self::fetchGuid($datarray); @@ -3015,7 +3015,7 @@ class Diaspora $datarray["body"] = self::replacePeopleGuid($body, $contact["url"]); self::storeMentions($datarray['uri-id'], $text); - Tag::storeFromBody($datarray['uri-id'], $datarray["body"], '#'); + Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray["body"]); if ($provider_display_name != "") { $datarray["app"] = $provider_display_name;