diff --git a/boot.php b/boot.php
index 0637ff3fe..a070e103e 100644
--- a/boot.php
+++ b/boot.php
@@ -33,7 +33,6 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Notify;
-use Friendica\Model\Term;
use Friendica\Util\BasePath;
use Friendica\Util\DateTimeFormat;
diff --git a/include/conversation.php b/include/conversation.php
index 43eeb9e41..5d08fd692 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -22,7 +22,6 @@
use Friendica\App;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
-use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
@@ -34,7 +33,7 @@ use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\Profile;
-use Friendica\Model\Term;
+use Friendica\Model\Tag;
use Friendica\Object\Post;
use Friendica\Object\Thread;
use Friendica\Protocol\Activity;
@@ -527,7 +526,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
$profile_name = $item['author-link'];
}
- $tags = Term::populateTagsFromItem($item);
+ $tags = Tag::populateTagsFromItem($item);
$author = ['uid' => 0, 'id' => $item['author-id'],
'network' => $item['author-network'], 'url' => $item['author-link']];
diff --git a/src/Model/Tag.php b/src/Model/Tag.php
index cf453f243..1186602f5 100644
--- a/src/Model/Tag.php
+++ b/src/Model/Tag.php
@@ -25,6 +25,7 @@ use Friendica\Content\Text\BBCode;
use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Database\DBA;
+use Friendica\DI;
use Friendica\Util\Strings;
/**
@@ -221,6 +222,17 @@ class Tag
}
}
+ /**
+ * Checks for stored hashtags and mentions for the given post
+ *
+ * @param integer $uriid
+ * @return bool
+ */
+ public static function existsForPost(int $uriid)
+ {
+ return DBA::exists('post-tag', ['uri-id' => $uriid, 'type' => [self::HASHTAG, self::MENTION, self::IMPLICIT_MENTION, self::EXCLUSIVE_MENTION]]);
+ }
+
/**
* Remove tag/mention
*
@@ -282,6 +294,86 @@ class Tag
} else {
return self::UNKNOWN;
}
-
}
+
+ /**
+ * Retrieves the terms from the provided type(s) associated with the provided item ID.
+ *
+ * @param int $item_id
+ * @param int|array $type
+ * @return array
+ * @throws \Exception
+ */
+ public static function ArrayFromURIId(int $uri_id, array $type = [self::HASHTAG, self::MENTION, self::IMPLICIT_MENTION, self::EXCLUSIVE_MENTION])
+ {
+ $condition = ['uri-id' => $uri_id, 'type' => $type];
+ $tags = DBA::select('tag-view', ['type', 'name', 'url'], $condition);
+ if (!DBA::isResult($tags)) {
+ return [];
+ }
+
+ $tag_list = [];
+ while ($tag = DBA::fetch($tags)) {
+ $tag['term'] = $tag['name']; /// @todo Remove this line when all occurrences of "term" had been replaced with "name"
+ $tag_list[] = $tag;
+ }
+
+ return $tag_list;
+ }
+
+ /**
+ * Sorts an item's tags into mentions, hashtags and other tags. Generate personalized URLs by user and modify the
+ * provided item's body with them.
+ *
+ * @param array $item
+ * @return array
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws \ImagickException
+ */
+ public static function populateTagsFromItem(&$item)
+ {
+ $return = [
+ 'tags' => [],
+ 'hashtags' => [],
+ 'mentions' => [],
+ 'implicit_mentions' => [],
+ ];
+
+ $searchpath = DI::baseUrl() . "/search?tag=";
+
+ $taglist = DBA::select('tag-view', ['type', 'name', 'url'],
+ ['uri-id' => $item['uri-id'], 'type' => [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]);
+ while ($tag = DBA::fetch($taglist)) {
+ if ($tag['url'] == '') {
+ $tag['url'] = $searchpath . rawurlencode($tag['name']);
+ }
+
+ $orig_tag = $tag['url'];
+
+ $prefix = self::TAG_CHARACTER[$tag['type']];
+ switch($tag['type']) {
+ case self::HASHTAG:
+ if ($orig_tag != $tag['url']) {
+ $item['body'] = str_replace($orig_tag, $tag['url'], $item['body']);
+ }
+
+ $return['hashtags'][] = $prefix . '' . htmlspecialchars($tag['name']) . '';
+ $return['tags'][] = $prefix . '' . htmlspecialchars($tag['name']) . '';
+ break;
+ case self::MENTION:
+ case self::EXCLUSIVE_MENTION:
+ $tag['url'] = Contact::magicLink($tag['url']);
+ $return['mentions'][] = $prefix . '' . htmlspecialchars($tag['name']) . '';
+ $return['tags'][] = $prefix . '' . htmlspecialchars($tag['name']) . '';
+ break;
+ case self::IMPLICIT_MENTION:
+ $return['implicit_mentions'][] = $prefix . $tag['name'];
+ break;
+ }
+ }
+ DBA::close($taglist);
+
+ return $return;
+ }
+
}
diff --git a/src/Model/Term.php b/src/Model/Term.php
index 13639f770..a6858d841 100644
--- a/src/Model/Term.php
+++ b/src/Model/Term.php
@@ -89,8 +89,8 @@ class Term
ORDER BY `score` DESC
LIMIT ?",
Item::PUBLIC,
- Term::OBJECT_TYPE_POST,
- Term::HASHTAG,
+ self::OBJECT_TYPE_POST,
+ self::HASHTAG,
$period,
$limit
);
@@ -134,8 +134,8 @@ class Term
ORDER BY `score` DESC
LIMIT ?",
Item::PUBLIC,
- Term::OBJECT_TYPE_POST,
- Term::HASHTAG,
+ self::OBJECT_TYPE_POST,
+ self::HASHTAG,
$period,
$limit
);
@@ -424,64 +424,6 @@ class Term
}
}
- /**
- * Sorts an item's tags into mentions, hashtags and other tags. Generate personalized URLs by user and modify the
- * provided item's body with them.
- *
- * @param array $item
- * @return array
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
- */
- public static function populateTagsFromItem(&$item)
- {
- $return = [
- 'tags' => [],
- 'hashtags' => [],
- 'mentions' => [],
- 'implicit_mentions' => [],
- ];
-
- $searchpath = DI::baseUrl() . "/search?tag=";
-
- $taglist = DBA::select(
- 'term',
- ['type', 'term', 'url'],
- ['otype' => self::OBJECT_TYPE_POST, 'oid' => $item['id'], 'type' => [self::HASHTAG, self::MENTION, self::IMPLICIT_MENTION]],
- ['order' => ['tid']]
- );
- while ($tag = DBA::fetch($taglist)) {
- if ($tag['url'] == '') {
- $tag['url'] = $searchpath . rawurlencode($tag['term']);
- }
-
- $orig_tag = $tag['url'];
-
- $prefix = self::TAG_CHARACTER[$tag['type']];
- switch($tag['type']) {
- case self::HASHTAG:
- if ($orig_tag != $tag['url']) {
- $item['body'] = str_replace($orig_tag, $tag['url'], $item['body']);
- }
-
- $return['hashtags'][] = $prefix . '' . htmlspecialchars($tag['term']) . '';
- $return['tags'][] = $prefix . '' . htmlspecialchars($tag['term']) . '';
- break;
- case self::MENTION:
- $tag['url'] = Contact::magicLink($tag['url']);
- $return['mentions'][] = $prefix . '' . htmlspecialchars($tag['term']) . '';
- $return['tags'][] = $prefix . '' . htmlspecialchars($tag['term']) . '';
- break;
- case self::IMPLICIT_MENTION:
- $return['implicit_mentions'][] = $prefix . $tag['term'];
- break;
- }
- }
- DBA::close($taglist);
-
- return $return;
- }
-
/**
* Delete tags of the specific type(s) from an item
*
diff --git a/src/Module/Profile/Profile.php b/src/Module/Profile/Profile.php
index 6c7f4f14e..c187281d3 100644
--- a/src/Module/Profile/Profile.php
+++ b/src/Module/Profile/Profile.php
@@ -35,7 +35,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Profile as ProfileModel;
-use Friendica\Model\Term;
+use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Module\BaseProfile;
use Friendica\Module\Security\Login;
@@ -184,7 +184,7 @@ class Profile extends BaseProfile
foreach (explode(',', $a->profile['pub_keywords']) as $tag_label) {
$tags[] = [
'url' => '/search?tag=' . $tag_label,
- 'label' => Term::TAG_CHARACTER[Term::HASHTAG] . $tag_label,
+ 'label' => Tag::TAG_CHARACTER[Tag::HASHTAG] . $tag_label,
];
}
diff --git a/src/Object/Post.php b/src/Object/Post.php
index 76cf6b036..99ab357bc 100644
--- a/src/Object/Post.php
+++ b/src/Object/Post.php
@@ -33,7 +33,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Item;
-use Friendica\Model\Term;
+use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Protocol\Activity;
use Friendica\Util\Crypto;
@@ -390,7 +390,7 @@ class Post
$buttons["like"] = false;
}
- $tags = Term::populateTagsFromItem($item);
+ $tags = Tag::populateTagsFromItem($item);
$ago = Temporal::getRelativeDate($item['created']);
$ago_received = Temporal::getRelativeDate($item['received']);
@@ -860,7 +860,7 @@ class Post
return '';
}
- $item = Item::selectFirst(['author-addr'], ['id' => $this->getId()]);
+ $item = Item::selectFirst(['author-addr', 'uri-id'], ['id' => $this->getId()]);
if (!DBA::isResult($item) || empty($item['author-addr'])) {
// Should not happen
return '';
@@ -872,7 +872,7 @@ class Post
$text = '';
}
- $terms = Term::tagArrayFromItemId($this->getId(), [Term::MENTION, Term::IMPLICIT_MENTION]);
+ $terms = Tag::ArrayFromURIId($item['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]);
foreach ($terms as $term) {
$profile = Contact::getDetailsByURL($term['url']);
if (!empty($profile['addr']) && ((($profile['contact-type'] ?? '') ?: Contact::TYPE_UNKNOWN) != Contact::TYPE_COMMUNITY) &&
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 786022343..80b2b0dba 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -35,7 +35,6 @@ use Friendica\Model\Item;
use Friendica\Model\ItemURI;
use Friendica\Model\Mail;
use Friendica\Model\Tag;
-use Friendica\Model\Term;
use Friendica\Model\User;
use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
@@ -1016,7 +1015,7 @@ class Processor
return [];
}
- $parent_terms = Term::tagArrayFromItemId($parent['id'], [Term::MENTION, Term::IMPLICIT_MENTION]);
+ $parent_terms = Tag::ArrayFromURIId($parent['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]);
$parent_author = Contact::getDetailsByURL($parent['author-link'], 0);
@@ -1084,8 +1083,8 @@ class Processor
foreach ($activity_tags as $index => $tag) {
if (in_array($tag['href'], $potential_mentions)) {
$activity_tags[$index]['name'] = preg_replace(
- '/' . preg_quote(Term::TAG_CHARACTER[Term::MENTION], '/') . '/',
- Term::TAG_CHARACTER[Term::IMPLICIT_MENTION],
+ '/' . preg_quote(Tag::TAG_CHARACTER[Tag::MENTION], '/') . '/',
+ Tag::TAG_CHARACTER[Tag::IMPLICIT_MENTION],
$activity_tags[$index]['name'],
1
);
diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php
index e35d83361..89453735a 100644
--- a/src/Protocol/ActivityPub/Transmitter.php
+++ b/src/Protocol/ActivityPub/Transmitter.php
@@ -36,7 +36,7 @@ use Friendica\Model\Conversation;
use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Model\Photo;
-use Friendica\Model\Term;
+use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
@@ -405,7 +405,7 @@ class Transmitter
$actor_profile = APContact::getByURL($item['author-link']);
}
- $terms = Term::tagArrayFromItemId($item['id'], [Term::MENTION, Term::IMPLICIT_MENTION]);
+ $terms = Tag::ArrayFromURIId($item['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]);
if ($item['private'] != Item::PRIVATE) {
// Directly mention the original author upon a quoted reshare.
@@ -1007,12 +1007,12 @@ class Transmitter
{
$tags = [];
- $terms = Term::tagArrayFromItemId($item['id'], [Term::HASHTAG, Term::MENTION, Term::IMPLICIT_MENTION]);
+ $terms = Tag::ArrayFromURIId($item['uri-id'], [Tag::HASHTAG, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]);
foreach ($terms as $term) {
- if ($term['type'] == Term::HASHTAG) {
+ if ($term['type'] == Tag::HASHTAG) {
$url = DI::baseUrl() . '/search?tag=' . urlencode($term['term']);
$tags[] = ['type' => 'Hashtag', 'href' => $url, 'name' => '#' . $term['term']];
- } elseif ($term['type'] == Term::MENTION || $term['type'] == Term::IMPLICIT_MENTION) {
+ } else {
$contact = Contact::getDetailsByURL($term['url']);
if (!empty($contact['addr'])) {
$mention = '@' . $contact['addr'];
@@ -1211,15 +1211,14 @@ class Transmitter
/**
* Returns if the post contains sensitive content ("nsfw")
*
- * @param integer $item_id
+ * @param integer $uri_id
*
* @return boolean
* @throws \Exception
*/
- private static function isSensitive($item_id)
+ private static function isSensitive($uri_id)
{
- $condition = ['otype' => Term::OBJECT_TYPE_POST, 'oid' => $item_id, 'type' => Term::HASHTAG, 'term' => 'nsfw'];
- return DBA::exists('term', $condition);
+ return DBA::exists('tag-view', ['uri-id' => $uri_id, 'name' => 'nsfw']);
}
/**
@@ -1301,7 +1300,7 @@ class Transmitter
$data['url'] = $item['plink'];
$data['attributedTo'] = $item['author-link'];
- $data['sensitive'] = self::isSensitive($item['id']);
+ $data['sensitive'] = self::isSensitive($item['uri-id']);
$data['context'] = self::fetchContextURLForItem($item);
if (!empty($item['title'])) {
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index fe6c328d9..0cefb8def 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -38,9 +38,7 @@ use Friendica\Model\Item;
use Friendica\Model\ItemURI;
use Friendica\Model\ItemDeliveryData;
use Friendica\Model\Mail;
-use Friendica\Model\Profile;
use Friendica\Model\Tag;
-use Friendica\Model\Term;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Util\Crypto;
@@ -114,7 +112,7 @@ class Diaspora
if (DI::config()->get("system", "relay_directly", false)) {
// We distribute our stuff based on the parent to ensure that the thread will be complete
- $parent = Item::selectFirst(['parent'], ['id' => $item_id]);
+ $parent = Item::selectFirst(['uri-id'], ['id' => $item_id]);
if (!DBA::isResult($parent)) {
return;
}
@@ -126,12 +124,12 @@ class Diaspora
}
// All tags of the current post
- $condition = ['otype' => Term::OBJECT_TYPE_POST, 'type' => Term::HASHTAG, 'oid' => $parent['parent']];
- $tags = DBA::select('term', ['term'], $condition);
+ $tags = DBA::select('tag-view', ['term'], ['uri-id' => $parent['uri-id'], 'type' => Tag::HASHTAG]);
$taglist = [];
while ($tag = DBA::fetch($tags)) {
- $taglist[] = $tag['term'];
+ $taglist[] = $tag['name'];
}
+ DBA::close($tags);
// All servers who wants content with this tag
$tagserverlist = [];