From 5df5e9521b0db02fedb91bb336b790f28088f823 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 26 Apr 2020 15:24:58 +0000 Subject: [PATCH 01/24] The tag table is now really used --- boot.php | 1 - include/conversation.php | 5 +- src/Model/Tag.php | 94 +++++++++++++++++++++++- src/Model/Term.php | 66 +---------------- src/Module/Profile/Profile.php | 4 +- src/Object/Post.php | 8 +- src/Protocol/ActivityPub/Processor.php | 7 +- src/Protocol/ActivityPub/Transmitter.php | 19 +++-- src/Protocol/Diaspora.php | 10 +-- 9 files changed, 121 insertions(+), 93 deletions(-) diff --git a/boot.php b/boot.php index 0637ff3fea..a070e103ea 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 43eeb9e41c..5d08fd6928 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 cf453f2431..1186602f54 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 13639f7700..a6858d8415 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 6c7f4f14e5..c187281d33 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 76cf6b0367..99ab357bc0 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 7860223432..80b2b0dbab 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 e35d833615..89453735a7 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 fe6c328d9f..0cefb8def6 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 = []; From 7f5f68a9048644ffbc3ce4fb94e56c0dae480d0c Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 26 Apr 2020 16:15:39 +0000 Subject: [PATCH 02/24] More preparations for term to tag transition --- include/api.php | 3 ++- mod/item.php | 15 +++++++-------- mod/network.php | 3 ++- mod/tagger.php | 4 ++-- src/Content/Widget/TagCloud.php | 5 +++-- src/Content/Widget/TrendingTags.php | 1 + src/Model/Item.php | 11 ++++++++--- src/Model/UserItem.php | 3 ++- src/Module/Hashtag.php | 3 ++- src/Module/Profile/Status.php | 3 ++- src/Module/Search/Index.php | 3 ++- 11 files changed, 33 insertions(+), 21 deletions(-) diff --git a/include/api.php b/include/api.php index 36b08f08f8..77dc020da3 100644 --- a/include/api.php +++ b/include/api.php @@ -41,6 +41,7 @@ use Friendica\Model\Item; use Friendica\Model\Mail; use Friendica\Model\Notify; use Friendica\Model\Photo; +use Friendica\Model\Tag; use Friendica\Model\Term; use Friendica\Model\User; use Friendica\Model\UserItem; @@ -1542,7 +1543,7 @@ function api_search($type) $condition = ["`oid` > ? AND (`uid` = 0 OR (`uid` = ? AND NOT `global`)) AND `otype` = ? AND `type` = ? AND `term` = ?", - $since_id, local_user(), Term::OBJECT_TYPE_POST, Term::HASHTAG, $searchTerm]; + $since_id, local_user(), Term::OBJECT_TYPE_POST, Tag::HASHTAG, $searchTerm]; if ($max_id > 0) { $condition[0] .= ' AND `oid` <= ?'; $condition[] = $max_id; diff --git a/mod/item.php b/mod/item.php index 5785954bce..bd28d33899 100644 --- a/mod/item.php +++ b/mod/item.php @@ -29,7 +29,6 @@ */ use Friendica\App; -use Friendica\Content\Pager; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; @@ -396,7 +395,7 @@ function item_post(App $a) { foreach ($tags as $tag) { $tag_type = substr($tag, 0, 1); - if ($tag_type == Term::TAG_CHARACTER[Term::HASHTAG]) { + if ($tag_type == Tag::TAG_CHARACTER[Tag::HASHTAG]) { continue; } @@ -421,9 +420,9 @@ function item_post(App $a) { $tagged[] = $tag; } // When the forum is private or the forum is addressed with a "!" make the post private - if (is_array($success['contact']) && (!empty($success['contact']['prv']) || ($tag_type == Term::TAG_CHARACTER[Term::EXCLUSIVE_MENTION]))) { + if (is_array($success['contact']) && (!empty($success['contact']['prv']) || ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]))) { $private_forum = $success['contact']['prv']; - $only_to_forum = ($tag_type == Term::TAG_CHARACTER[Term::EXCLUSIVE_MENTION]); + $only_to_forum = ($tag_type == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]); $private_id = $success['contact']['id']; $forum_contact = $success['contact']; } elseif (is_array($success['contact']) && !empty($success['contact']['forum']) && @@ -907,7 +906,7 @@ function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network = $r = null; //is it a person tag? - if (Term::isType($tag, Term::MENTION, Term::IMPLICIT_MENTION, Term::EXCLUSIVE_MENTION)) { + if (Term::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) { $tag_type = substr($tag, 0, 1); //is it already replaced? if (strpos($tag, '[url=')) { @@ -1050,7 +1049,7 @@ function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $ if (DI::config()->get('system', 'disable_implicit_mentions')) { // Add a tag if the parent contact is from ActivityPub or OStatus (This will notify them) if (in_array($thread_parent_contact['network'], [Protocol::OSTATUS, Protocol::ACTIVITYPUB])) { - $contact = Term::TAG_CHARACTER[Term::MENTION] . '[url=' . $thread_parent_contact['url'] . ']' . $thread_parent_contact['nick'] . '[/url]'; + $contact = Tag::TAG_CHARACTER[Tag::MENTION] . '[url=' . $thread_parent_contact['url'] . ']' . $thread_parent_contact['nick'] . '[/url]'; if (!stripos(implode($tags), '[url=' . $thread_parent_contact['url'] . ']')) { $tags[] = $contact; } @@ -1060,7 +1059,7 @@ function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $ $thread_parent_contact['url'] => $thread_parent_contact['nick'] ]; - $parent_terms = Term::tagArrayFromItemId($thread_parent_id, [Term::MENTION, Term::IMPLICIT_MENTION]); + $parent_terms = Term::tagArrayFromItemId($thread_parent_id, [Tag::MENTION, Tag::IMPLICIT_MENTION]); foreach ($parent_terms as $parent_term) { $implicit_mentions[$parent_term['url']] = $parent_term['term']; @@ -1068,7 +1067,7 @@ function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $ foreach ($implicit_mentions as $url => $label) { if ($url != \Friendica\Model\Profile::getMyURL() && !stripos(implode($tags), '[url=' . $url . ']')) { - $tags[] = Term::TAG_CHARACTER[Term::IMPLICIT_MENTION] . '[url=' . $url . ']' . $label . '[/url]'; + $tags[] = Tag::TAG_CHARACTER[Tag::IMPLICIT_MENTION] . '[url=' . $url . ']' . $label . '[/url]'; } } } diff --git a/mod/network.php b/mod/network.php index 6c02c4f843..0c2cbccf55 100644 --- a/mod/network.php +++ b/mod/network.php @@ -38,6 +38,7 @@ use Friendica\Model\Contact; use Friendica\Model\Group; use Friendica\Model\Item; use Friendica\Model\Profile; +use Friendica\Model\Tag; use Friendica\Model\Term; use Friendica\Module\Security\Login; use Friendica\Util\DateTimeFormat; @@ -793,7 +794,7 @@ function networkThreadedView(App $a, $update, $parent) STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `item`.`author-id` WHERE `item`.`uid` = 0 AND `item`.$ordering < ? AND `item`.$ordering > ? AND `item`.`gravity` = ? AND NOT `author`.`hidden` AND NOT `author`.`blocked`" . $sql_tag_nets, - local_user(), Term::OBJECT_TYPE_POST, Term::HASHTAG, + local_user(), Term::OBJECT_TYPE_POST, Tag::HASHTAG, $top_limit, $bottom_limit, GRAVITY_PARENT); $data = DBA::toArray($items); diff --git a/mod/tagger.php b/mod/tagger.php index b3ba472eab..f39c37103a 100644 --- a/mod/tagger.php +++ b/mod/tagger.php @@ -183,7 +183,7 @@ EOT; q("INSERT INTO term (oid, otype, type, term, url, uid) VALUE (%d, %d, %d, '%s', '%s', %d)", intval($item['id']), $term_objtype, - Term::HASHTAG, + Tag::HASHTAG, DBA::escape($term), '', intval($owner_uid) @@ -205,7 +205,7 @@ EOT; q("INSERT INTO term (`oid`, `otype`, `type`, `term`, `url`, `uid`) VALUE (%d, %d, %d, '%s', '%s', %d)", intval($original_item['id']), $term_objtype, - Term::HASHTAG, + Tag::HASHTAG, DBA::escape($term), '', intval($owner_uid) diff --git a/src/Content/Widget/TagCloud.php b/src/Content/Widget/TagCloud.php index 5bdf7d8346..63df5a0bd5 100644 --- a/src/Content/Widget/TagCloud.php +++ b/src/Content/Widget/TagCloud.php @@ -25,6 +25,7 @@ use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Item; +use Friendica\Model\Tag; use Friendica\Model\Term; /** @@ -46,7 +47,7 @@ class TagCloud * @return string HTML formatted output. * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function getHTML($uid, $count = 0, $owner_id = 0, $flags = '', $type = Term::HASHTAG) + public static function getHTML($uid, $count = 0, $owner_id = 0, $flags = '', $type = Tag::HASHTAG) { $o = ''; $r = self::tagadelic($uid, $count, $owner_id, $flags, $type); @@ -85,7 +86,7 @@ class TagCloud * @return array Alphabetical sorted array of used tags of an user. * @throws \Exception */ - private static function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = Term::HASHTAG) + private static function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = Tag::HASHTAG) { $sql_options = Item::getPermissionsSQLByUserId($uid); $limit = $count ? sprintf('LIMIT %d', intval($count)) : ''; diff --git a/src/Content/Widget/TrendingTags.php b/src/Content/Widget/TrendingTags.php index 9f935e6de6..053cba09d3 100644 --- a/src/Content/Widget/TrendingTags.php +++ b/src/Content/Widget/TrendingTags.php @@ -23,6 +23,7 @@ namespace Friendica\Content\Widget; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Tag; use Friendica\Model\Term; /** diff --git a/src/Model/Item.php b/src/Model/Item.php index bd8d03359e..6a80765cdb 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -61,7 +61,7 @@ class Item // Field list that is used to display the items const DISPLAY_FIELDLIST = [ - 'uid', 'id', 'parent', 'uri', 'thr-parent', 'parent-uri', 'guid', 'network', 'gravity', + 'uid', 'id', 'parent', 'uri-id', 'uri', 'thr-parent', 'parent-uri', 'guid', 'network', 'gravity', 'commented', 'created', 'edited', 'received', 'verb', 'object-type', 'postopts', 'plink', 'wall', 'private', 'starred', 'origin', 'title', 'body', 'file', 'attach', 'language', 'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object', @@ -77,7 +77,7 @@ class Item ]; // Field list that is used to deliver items via the protocols - const DELIVER_FIELDLIST = ['uid', 'id', 'parent', 'uri', 'thr-parent', 'parent-uri', 'guid', + const DELIVER_FIELDLIST = ['uid', 'id', 'parent', 'uri-id', 'uri', 'thr-parent', 'parent-uri', 'guid', 'parent-guid', 'created', 'edited', 'verb', 'object-type', 'object', 'target', 'private', 'title', 'body', 'location', 'coord', 'app', 'attach', 'tag', 'deleted', 'extid', 'post-type', @@ -1674,6 +1674,11 @@ class Item // Check for hashtags in the body and repair or add hashtag links self::setHashtags($item); + // Store tags from the body if this hadn't been handled previously in the protocol classes + if (!Tag::existsForPost($item['uri-id'])) { + Tag::storeFromBody($item['uri-id'], $item['body']); + } + $item['thr-parent'] = $item['parent-uri']; $notify_type = Delivery::POST; @@ -3558,7 +3563,7 @@ class Item return $ev; } - $tags = Term::populateTagsFromItem($item); + $tags = Tag::populateTagsFromItem($item); $item['tags'] = $tags['tags']; $item['hashtags'] = $tags['hashtags']; diff --git a/src/Model/UserItem.php b/src/Model/UserItem.php index 6a228c098a..f68b5aac82 100644 --- a/src/Model/UserItem.php +++ b/src/Model/UserItem.php @@ -26,6 +26,7 @@ use Friendica\Core\Hook; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Util\Strings; +use Friendica\Model\Tag; use Friendica\Model\Term; class UserItem @@ -207,7 +208,7 @@ class UserItem } // Or the contact is a mentioned forum - $tags = DBA::select('term', ['url'], ['otype' => Term::OBJECT_TYPE_POST, 'oid' => $item['id'], 'type' => Term::MENTION, 'uid' => $uid]); + $tags = DBA::select('term', ['url'], ['otype' => Term::OBJECT_TYPE_POST, 'oid' => $item['id'], 'type' => Tag::MENTION, 'uid' => $uid]); while ($tag = DBA::fetch($tags)) { $condition = ['nurl' => Strings::normaliseLink($tag['url']), 'uid' => $uid, 'notify_new_posts' => true, 'contact-type' => Contact::TYPE_COMMUNITY]; if (DBA::exists('contact', $condition)) { diff --git a/src/Module/Hashtag.php b/src/Module/Hashtag.php index 06c6374e34..8c1dad4afd 100644 --- a/src/Module/Hashtag.php +++ b/src/Module/Hashtag.php @@ -25,6 +25,7 @@ use Friendica\BaseModule; use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Util\Strings; +use Friendica\Model\Tag; use Friendica\Model\Term; /** @@ -44,7 +45,7 @@ class Hashtag extends BaseModule $taglist = DBA::p("SELECT DISTINCT(`term`) FROM `term` WHERE `term` LIKE ? AND `type` = ? ORDER BY `term`", $t . '%', - intval(Term::HASHTAG) + intval(Tag::HASHTAG) ); while ($tag = DBA::fetch($taglist)) { $result[] = ['text' => $tag['term']]; diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php index 8b6734e5cd..d7ed5ca7f4 100644 --- a/src/Module/Profile/Status.php +++ b/src/Module/Profile/Status.php @@ -31,6 +31,7 @@ use Friendica\DI; use Friendica\Model\Item; use Friendica\Model\Profile as ProfileModel; use Friendica\Model\User; +use Friendica\Model\Tag; use Friendica\Model\Term; use Friendica\Module\BaseProfile; use Friendica\Module\Security\Login; @@ -148,7 +149,7 @@ class Status extends BaseProfile if (!empty($hashtags)) { $sql_post_table .= sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", - DBA::escape(Strings::protectSprintf($hashtags)), intval(Term::OBJECT_TYPE_POST), intval(Term::HASHTAG), intval($a->profile['uid'])); + DBA::escape(Strings::protectSprintf($hashtags)), intval(Term::OBJECT_TYPE_POST), intval(Tag::HASHTAG), intval($a->profile['uid'])); } if (!empty($datequery)) { diff --git a/src/Module/Search/Index.php b/src/Module/Search/Index.php index 44407623e9..e5ad5091d9 100644 --- a/src/Module/Search/Index.php +++ b/src/Module/Search/Index.php @@ -33,6 +33,7 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Item; +use Friendica\Model\Tag; use Friendica\Model\Term; use Friendica\Module\BaseSearch; use Friendica\Network\HTTPException; @@ -153,7 +154,7 @@ class Index extends BaseSearch $condition = [ "(`uid` = 0 OR (`uid` = ? AND NOT `global`)) AND `otype` = ? AND `type` = ? AND `term` = ?", - local_user(), Term::OBJECT_TYPE_POST, Term::HASHTAG, $search + local_user(), Term::OBJECT_TYPE_POST, Tag::HASHTAG, $search ]; $params = [ 'order' => ['received' => true], From f5886db3e2fe82437587ab88bb66f9961241bc50 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 27 Apr 2020 20:32:25 +0000 Subject: [PATCH 03/24] New view for searching tags --- static/dbstructure.config.php | 3 ++- static/dbview.config.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 50055f62ae..8b4d1528c6 100755 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -51,7 +51,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1340); + define('DB_UPDATE_VERSION', 1341); } return [ @@ -754,6 +754,7 @@ return [ "icid" => ["icid"], "iaid" => ["iaid"], "psid_wall" => ["psid", "wall"], + "uri-id" => ["uri-id"], ] ], "item-activity" => [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 1d95261a25..47654dfb2b 100755 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -221,6 +221,20 @@ return [ INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid` INNER JOIN `user` ON `register`.`uid` = `user`.`uid`" ], + "tag-search-view" => [ + "fields" => [ + "uri-id" => ["post-tag", "uri-id"], + "uri" => ["item", "uri"], + "guid" => ["item", "guid"], + "uid" => ["item", "uid"], + "private" => ["item", "private"], + "name" => ["tag", "name"], + ], + "query" => "FROM `post-tag` + INNER JOIN `tag` ON `tag`.`id` = `post-tag`.`tid` + INNER JOIN `item` ON `item`.`uri-id` = `post-tag`.`uri-id` + WHERE `post-tag`.`type` = 1" + ], "workerqueue-view" => [ "fields" => [ "pid" => ["process", "pid"], From ce20081d28f56c2fdd9d1f6bf2fae11c61cb082f Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 28 Apr 2020 03:52:07 +0000 Subject: [PATCH 04/24] Fix wrong field name --- src/Protocol/Diaspora.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 0cefb8def6..7e76662d71 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -124,7 +124,7 @@ class Diaspora } // All tags of the current post - $tags = DBA::select('tag-view', ['term'], ['uri-id' => $parent['uri-id'], 'type' => Tag::HASHTAG]); + $tags = DBA::select('tag-view', ['name'], ['uri-id' => $parent['uri-id'], 'type' => Tag::HASHTAG]); $taglist = []; while ($tag = DBA::fetch($tags)) { $taglist[] = $tag['name']; From c2a9b3b9e95260a73c82704620e59f2a08114911 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 28 Apr 2020 11:52:51 +0000 Subject: [PATCH 05/24] Usage of the new tag tables --- src/Model/Tag.php | 50 +++++++++++++++++++++++++++++++++---- src/Module/Hashtag.php | 10 ++------ src/Module/Search/Index.php | 26 +++---------------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 1186602f54..829567fe5f 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -68,7 +68,19 @@ class Tag */ public static function store(int $uriid, int $type, string $name, string $url = '', $probing = true) { - $name = trim($name, "\x00..\x20\xFF#!@"); + if ($type = self::HASHTAG) { + // Remove some common "garbarge" from tags + $name = trim($name, "\x00..\x20\xFF#!@,;.:'/?!^°$%".'"'); + + $tags = explode(self::TAG_CHARACTER[self::HASHTAG], $name); + if (count($tags) > 1) { + foreach ($tags as $tag) { + self::store($uriid, $type, $tag, $url, $probing); + } + return; + } + } + if (empty($name)) { return; } @@ -76,7 +88,7 @@ class Tag $cid = 0; $tagid = 0; - if (in_array($type, [Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION])) { + if (in_array($type, [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION])) { if (empty($url)) { // No mention without a contact url return; @@ -115,7 +127,7 @@ class Tag if (empty($cid)) { $fields = ['name' => substr($name, 0, 96), 'url' => '']; - if (($type != Tag::HASHTAG) && !empty($url) && ($url != $name)) { + if (($type != self::HASHTAG) && !empty($url) && ($url != $name)) { $fields['url'] = strtolower($url); } @@ -135,9 +147,9 @@ class Tag $fields = ['uri-id' => $uriid, 'type' => $type, 'tid' => $tagid, 'cid' => $cid]; - if (in_array($type, [Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION])) { + if (in_array($type, [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION])) { $condition = $fields; - $condition['type'] = [Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION]; + $condition['type'] = [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]; if (DBA::exists('post-tag', $condition)) { Logger::info('Tag already exists', $fields); return; @@ -376,4 +388,32 @@ class Tag return $return; } + /** + * Search posts for given tag + * + * @param string $search + * @param integer $uid + * @param integer $start + * @param integer $limit + * @return array with URI-ID + */ + public static function getURIIdListForTag(string $search, int $uid = 0, int $start = 0, int $limit = 100) + { + $condition = ["`name` = ? AND (NOT `private` OR (`private` AND `uid` = ?))", $search, $uid]; + $params = [ + 'order' => ['uri-id' => true], + 'group_by' => ['uri-id'], + 'limit' => [$start, $limit] + ]; + + $tags = DBA::select('tag-search-view', ['uri-id'], $condition, $params); + + $uriids = []; + while ($tag = DBA::fetch($tags)) { + $uriids[] = $tag['uri-id']; + } + DBA::close($tags); + + return $uriids; + } } diff --git a/src/Module/Hashtag.php b/src/Module/Hashtag.php index 8c1dad4afd..365e77572c 100644 --- a/src/Module/Hashtag.php +++ b/src/Module/Hashtag.php @@ -25,15 +25,12 @@ use Friendica\BaseModule; use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Util\Strings; -use Friendica\Model\Tag; -use Friendica\Model\Term; /** * Hashtag module. */ class Hashtag extends BaseModule { - public static function content(array $parameters = []) { $result = []; @@ -43,12 +40,9 @@ class Hashtag extends BaseModule System::jsonExit($result); } - $taglist = DBA::p("SELECT DISTINCT(`term`) FROM `term` WHERE `term` LIKE ? AND `type` = ? ORDER BY `term`", - $t . '%', - intval(Tag::HASHTAG) - ); + $taglist = DBA::select('tag', ['name'], ["`name` LIKE ?", $t . "%"], ['order' => ['name'], 'limit' => 100]); while ($tag = DBA::fetch($taglist)) { - $result[] = ['text' => $tag['term']]; + $result[] = ['text' => $tag['name']]; } DBA::close($taglist); diff --git a/src/Module/Search/Index.php b/src/Module/Search/Index.php index e5ad5091d9..0aba7a203d 100644 --- a/src/Module/Search/Index.php +++ b/src/Module/Search/Index.php @@ -34,7 +34,6 @@ use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Item; use Friendica\Model\Tag; -use Friendica\Model\Term; use Friendica\Module\BaseSearch; use Friendica\Network\HTTPException; use Friendica\Util\Strings; @@ -150,28 +149,11 @@ class Index extends BaseSearch if ($tag) { Logger::info('Start tag search.', ['q' => $search]); + $uriids = Tag::getURIIdListForTag($search, local_user(), $pager->getStart(), $pager->getItemsPerPage()); - $condition = [ - "(`uid` = 0 OR (`uid` = ? AND NOT `global`)) - AND `otype` = ? AND `type` = ? AND `term` = ?", - local_user(), Term::OBJECT_TYPE_POST, Tag::HASHTAG, $search - ]; - $params = [ - 'order' => ['received' => true], - 'limit' => [$pager->getStart(), $pager->getItemsPerPage()] - ]; - $terms = DBA::select('term', ['oid'], $condition, $params); - - $itemids = []; - while ($term = DBA::fetch($terms)) { - $itemids[] = $term['oid']; - } - - DBA::close($terms); - - if (!empty($itemids)) { - $params = ['order' => ['id' => true]]; - $items = Item::selectForUser(local_user(), [], ['id' => $itemids], $params); + if (!empty($uriids)) { + $params = ['order' => ['id' => true], 'group_by' => ['uri-id']]; + $items = Item::selectForUser(local_user(), [], ['uri-id' => $uriids], $params); $r = Item::inArray($items); } else { $r = []; From 70e5639e2973662705b44e643ac46ce68dd6dade Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 28 Apr 2020 13:33:03 +0000 Subject: [PATCH 06/24] Merge --- mod/msearch.php | 4 +++- src/Core/Worker.php | 1 + src/Database/Database.php | 13 +++++++++---- src/Model/Contact.php | 2 ++ src/Model/GContact.php | 2 ++ src/Model/Process.php | 2 +- src/Model/Search.php | 2 +- src/Model/User.php | 1 + src/Model/UserItem.php | 1 + src/Module/Admin/DBSync.php | 1 + src/Module/Admin/Site.php | 1 + src/Module/Settings/Delegation.php | 1 + src/Protocol/ActivityPub/Transmitter.php | 2 ++ src/Protocol/Diaspora.php | 4 ++++ src/Worker/CronJobs.php | 2 ++ src/Worker/UpdateGContacts.php | 1 + src/Worker/UpdateGServers.php | 1 + 17 files changed, 34 insertions(+), 7 deletions(-) diff --git a/mod/msearch.php b/mod/msearch.php index b02a036ae4..14dfd1ef7c 100644 --- a/mod/msearch.php +++ b/mod/msearch.php @@ -68,7 +68,7 @@ function msearch_post(App $a) $perpage ); - while($search_result = DBA::fetch($search_stmt)) { + while ($search_result = DBA::fetch($search_stmt)) { $results[] = [ 'name' => $search_result['name'], 'url' => DI::baseUrl() . '/profile/' . $search_result['nickname'], @@ -77,6 +77,8 @@ function msearch_post(App $a) ]; } + DBA::close($search_stmt); + $output = ['total' => $total, 'items_page' => $perpage, 'page' => $page, 'results' => $results]; echo json_encode($output); diff --git a/src/Core/Worker.php b/src/Core/Worker.php index 6fb8bd40ff..24febf3bc4 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -614,6 +614,7 @@ class Worker } } } + DBA::close($entries); } /** diff --git a/src/Database/Database.php b/src/Database/Database.php index f86f279965..db906bd01e 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -57,6 +57,7 @@ class Database /** @var PDO|mysqli */ protected $connection; protected $driver; + private $emulate_prepares = false; private $error = false; private $errorno = 0; private $affected_rows = 0; @@ -130,6 +131,8 @@ class Database return false; } + $this->emulate_prepares = (bool)$this->configCache->get('database', 'emulate_prepares'); + if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) { $this->driver = 'pdo'; $connect = "mysql:host=" . $server . ";dbname=" . $db; @@ -428,8 +431,10 @@ class Database { $offset = 0; foreach ($args AS $param => $value) { - if (is_int($args[$param]) || is_float($args[$param])) { + if (is_int($args[$param]) || is_float($args[$param]) || is_bool($args[$param])) { $replace = intval($args[$param]); + } elseif (is_null($args[$param])) { + $replace = 'NULL'; } else { $replace = "'" . $this->escape($args[$param]) . "'"; } @@ -515,8 +520,8 @@ class Database switch ($this->driver) { case 'pdo': // If there are no arguments we use "query" - if (count($args) == 0) { - if (!$retval = $this->connection->query($sql)) { + if ($this->emulate_prepares || count($args) == 0) { + if (!$retval = $this->connection->query($this->replaceParameters($sql, $args))) { $errorInfo = $this->connection->errorInfo(); $this->error = $errorInfo[2]; $this->errorno = $errorInfo[1]; @@ -562,7 +567,7 @@ class Database $can_be_prepared = in_array($command, ['select', 'update', 'insert', 'delete']); // The fallback routine is called as well when there are no arguments - if (!$can_be_prepared || (count($args) == 0)) { + if ($this->emulate_prepares || !$can_be_prepared || (count($args) == 0)) { $retval = $this->connection->query($this->replaceParameters($sql, $args)); if ($this->connection->errno) { $this->error = $this->connection->error; diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 2435b54f9c..becc80c0c3 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2057,6 +2057,7 @@ class Contact Worker::add(PRIORITY_HIGH, 'MergeContact', $first, $duplicate['id'], $uid); } + DBA::close($duplicates); Logger::info('Duplicates handled', ['uid' => $uid, 'nurl' => $nurl]); return true; } @@ -2732,6 +2733,7 @@ class Contact ); } } + DBA::close($contacts); } /** diff --git a/src/Model/GContact.php b/src/Model/GContact.php index 553976296f..becfd61b08 100644 --- a/src/Model/GContact.php +++ b/src/Model/GContact.php @@ -113,6 +113,7 @@ class GContact $gcontacts[] = Contact::getDetailsByURL($result['nurl'], local_user()); } + DBA::close($results); return $gcontacts; } @@ -563,6 +564,7 @@ class GContact PortableContact::loadWorker(0, 0, 0, $base); } } + DBA::close($contacts); } /** diff --git a/src/Model/Process.php b/src/Model/Process.php index 2652929681..18b5f785a1 100644 --- a/src/Model/Process.php +++ b/src/Model/Process.php @@ -85,7 +85,7 @@ class Process self::deleteByPid($process['pid']); } } - + DBA::close($processes); DBA::commit(); } } diff --git a/src/Model/Search.php b/src/Model/Search.php index 9e00bbe308..ca8960ef35 100644 --- a/src/Model/Search.php +++ b/src/Model/Search.php @@ -44,7 +44,7 @@ class Search while ($term = DBA::fetch($termsStmt)) { $tags[] = trim($term['term'], '#'); } - + DBA::close($termsStmt); return $tags; } } diff --git a/src/Model/User.php b/src/Model/User.php index be71bcf645..89574e7609 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1298,6 +1298,7 @@ class User $statistics['active_users_monthly']++; } } + DBA::close($userStmt); return $statistics; } diff --git a/src/Model/UserItem.php b/src/Model/UserItem.php index f68b5aac82..74c5ac4486 100644 --- a/src/Model/UserItem.php +++ b/src/Model/UserItem.php @@ -215,6 +215,7 @@ class UserItem return true; } } + DBA::close($tags); return false; } diff --git a/src/Module/Admin/DBSync.php b/src/Module/Admin/DBSync.php index 8892c29691..dd7febcc59 100644 --- a/src/Module/Admin/DBSync.php +++ b/src/Module/Admin/DBSync.php @@ -102,6 +102,7 @@ class DBSync extends BaseAdmin $failed[] = $upd; } } + DBA::close($configStmt); if (!count($failed)) { $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('admin/dbsync/structure_check.tpl'), [ diff --git a/src/Module/Admin/Site.php b/src/Module/Admin/Site.php index cf3fee31b1..f3086856b3 100644 --- a/src/Module/Admin/Site.php +++ b/src/Module/Admin/Site.php @@ -121,6 +121,7 @@ class Site extends BaseAdmin while ($user = DBA::fetch($usersStmt)) { Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, $user['uid']); } + DBA::close($usersStmt); info("Relocation started. Could take a while to complete."); diff --git a/src/Module/Settings/Delegation.php b/src/Module/Settings/Delegation.php index e70dee8908..e590d6ea77 100644 --- a/src/Module/Settings/Delegation.php +++ b/src/Module/Settings/Delegation.php @@ -125,6 +125,7 @@ class Delegation extends BaseSettings while ($contact = DBA::fetch($contacts)) { $nicknames[] = $contact['nick']; } + DBA::close($contacts); // get user records for all potential page delegates who are not already delegates or managers $potentialDelegateUsers = DBA::selectToArray('user', ['uid', 'username', 'nickname'], ['nickname' => $nicknames]); diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 620894c75e..fd91dca16a 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -96,6 +96,7 @@ class Transmitter while ($contact = DBA::fetch($contacts)) { $list[] = $contact['url']; } + DBA::close($contacts); if (!empty($list)) { $data['next'] = DI::baseUrl() . '/followers/' . $owner['nickname'] . '?page=' . ($page + 1); @@ -145,6 +146,7 @@ class Transmitter while ($contact = DBA::fetch($contacts)) { $list[] = $contact['url']; } + DBA::close($contacts); if (!empty($list)) { $data['next'] = DI::baseUrl() . '/following/' . $owner['nickname'] . '?page=' . ($page + 1); diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 2a7fcc4665..a91c5cdf80 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -122,6 +122,7 @@ class Diaspora while ($server = DBA::fetch($servers)) { $serverlist[$server['url']] = $server['url']; } + DBA::close($servers); // All tags of the current post $tags = DBA::select('tag-view', ['name'], ['uri-id' => $parent['uri-id'], 'type' => Tag::HASHTAG]); @@ -138,6 +139,7 @@ class Diaspora while ($server = DBA::fetch($tagserver)) { $tagserverlist[] = $server['gserver-id']; } + DBA::close($tagserver); } // All adresses with the given id @@ -146,6 +148,7 @@ class Diaspora while ($server = DBA::fetch($servers)) { $serverlist[$server['url']] = $server['url']; } + DBA::close($servers); } } @@ -1718,6 +1721,7 @@ class Diaspora while ($contact = DBA::fetch($contacts)) { Contact::remove($contact["id"]); } + DBA::close($contacts); DBA::delete('gcontact', ['addr' => $author]); diff --git a/src/Worker/CronJobs.php b/src/Worker/CronJobs.php index 2a6c97e842..319a369d1f 100644 --- a/src/Worker/CronJobs.php +++ b/src/Worker/CronJobs.php @@ -128,6 +128,7 @@ class CronJobs while ($user = DBA::fetch($users)) { User::remove($user['uid']); } + DBA::close($users); // delete user records for recently removed accounts $users = DBA::select('user', ['uid'], ["`account_removed` AND `account_expires_on` < UTC_TIMESTAMP() "]); @@ -140,6 +141,7 @@ class CronJobs DBA::delete('user', ['uid' => $user['uid']]); } + DBA::close($users); } /** diff --git a/src/Worker/UpdateGContacts.php b/src/Worker/UpdateGContacts.php index 80c0ef524e..9d9519241b 100644 --- a/src/Worker/UpdateGContacts.php +++ b/src/Worker/UpdateGContacts.php @@ -96,5 +96,6 @@ class UpdateGContacts return; } } + DBA::close($contacts); } } diff --git a/src/Worker/UpdateGServers.php b/src/Worker/UpdateGServers.php index 2200d02e92..5a45138462 100644 --- a/src/Worker/UpdateGServers.php +++ b/src/Worker/UpdateGServers.php @@ -52,5 +52,6 @@ class UpdateGServers return; } } + DBA::close($gservers); } } From 2423831b90acfdee93213f058b0b4a2991fbde55 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 29 Apr 2020 09:12:56 +0000 Subject: [PATCH 07/24] Added todo --- include/api.php | 1 + 1 file changed, 1 insertion(+) diff --git a/include/api.php b/include/api.php index 77dc020da3..97c30e317a 100644 --- a/include/api.php +++ b/include/api.php @@ -1540,6 +1540,7 @@ function api_search($type) $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; if (preg_match('/^#(\w+)$/', $searchTerm, $matches) === 1 && isset($matches[1])) { $searchTerm = $matches[1]; + /// @todo $uriids = Tag::getURIIdListForTag($searchTerm, local_user()); $condition = ["`oid` > ? AND (`uid` = 0 OR (`uid` = ? AND NOT `global`)) AND `otype` = ? AND `type` = ? AND `term` = ?", From 136c6b644e2d0320e38532e53a766e7afcc80eeb Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 29 Apr 2020 10:49:13 +0000 Subject: [PATCH 08/24] Fix: Mentions had been stored as tags --- src/Model/Tag.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 829567fe5f..7e894aca9b 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -68,7 +68,7 @@ class Tag */ public static function store(int $uriid, int $type, string $name, string $url = '', $probing = true) { - if ($type = self::HASHTAG) { + if ($type == self::HASHTAG) { // Remove some common "garbarge" from tags $name = trim($name, "\x00..\x20\xFF#!@,;.:'/?!^°$%".'"'); From 88931e50531bf087fead5bded166bd1586e1f8bc Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 30 Apr 2020 06:09:57 +0000 Subject: [PATCH 09/24] Post update functionality for tags --- src/Database/PostUpdate.php | 130 ++++++++++++++++++++++++++++++++++ static/dbstructure.config.php | 2 +- 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index cd7e8b9462..4a6507ff5f 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -28,7 +28,9 @@ use Friendica\Model\Contact; use Friendica\Model\Item; use Friendica\Model\ItemURI; use Friendica\Model\PermissionSet; +use Friendica\Model\Tag; use Friendica\Model\UserItem; +use Friendica\Util\Strings; /** * These database-intensive post update routines are meant to be executed in the background by the cronjob. @@ -64,6 +66,12 @@ class PostUpdate if (!self::update1329()) { return false; } + if (!self::update1341()) { + return false; + } + if (!self::update1342()) { + return false; + } return true; } @@ -533,4 +541,126 @@ class PostUpdate return false; } + + /** + * Fill the "tag" table with tags and mentions from the body + * + * @return bool "true" when the job is done + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + private static function update1341() + { + // Was the script completed? + if (DI::config()->get('system', 'post_update_version') >= 1341) { + return true; + } + + $id = DI::config()->get('system', 'post_update_version_1341_id', 0); + + Logger::info('Start', ['item' => $id]); + + $start_id = $id; + $rows = 0; + + $items = DBA::p("SELECT `uri-id`,`body` FROM `item-content` WHERE + (`body` LIKE ? OR `body` LIKE ? OR `body` LIKE ?) AND `uri-id` >= ? + ORDER BY `uri-id` LIMIT 100000", '%#%', '%@%', '%!%', $id); + + if (DBA::errorNo() != 0) { + Logger::error('Database error', ['no' => DBA::errorNo(), 'message' => DBA::errorMessage()]); + return false; + } + + while ($item = DBA::fetch($items)) { + Tag::storeFromBody($item['uri-id'], $item['body'], '#!@', false); + $id = $item['uri-id']; + ++$rows; + if ($rows % 1000 == 0) { + DI::config()->set('system', 'post_update_version_1341_id', $id); + } + } + DBA::close($items); + + DI::config()->set('system', 'post_update_version_1341_id', $id); + + Logger::info('Processed', ['rows' => $rows, 'last' => $id]); + + if ($start_id == $id) { + DI::config()->set('system', 'post_update_version', 1341); + Logger::info('Done'); + return true; + } + + return false; + } + + /** + * Fill the "tag" table with tags and mentions from the "term" table + * + * @return bool "true" when the job is done + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + private static function update1342() + { + // Was the script completed? + if (DI::config()->get('system', 'post_update_version') >= 1342) { + return true; + } + + $id = DI::config()->get('system', 'post_update_version_1342_id', 0); + + Logger::info('Start', ['item' => $id]); + + $start_id = $id; + $rows = 0; + + $terms = DBA::p("SELECT `term`.`tid`, `item`.`uri-id`, `term`.`type`, `term`.`term`, `term`.`url`, `item-content`.`body` + FROM `term` + INNER JOIN `item` ON `item`.`id` = `term`.`oid` + INNER JOIN `item-content` ON `item-content`.`uri-id` = `item`.`uri-id` + WHERE term.type IN (?, ?, ?, ?) AND `tid` >= ? ORDER BY `tid` LIMIT 100000", + Tag::HASHTAG, Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION, $id); + + if (DBA::errorNo() != 0) { + Logger::error('Database error', ['no' => DBA::errorNo(), 'message' => DBA::errorMessage()]); + return false; + } + + while ($term = DBA::fetch($terms)) { + if (($term['type'] == Tag::MENTION) && !empty($term['url']) && !strstr($term['body'], $term['url'])) { + $condition = ['nurl' => Strings::normaliseLink($term['url']), 'uid' => 0, 'deleted' => false]; + $contact = DBA::selectFirst('contact', ['url', 'alias'], $condition, ['order' => ['id']]); + if (!DBA::isResult($contact)) { + $ssl_url = str_replace('http://', 'https://', $term['url']); + $condition = ['`alias` IN (?, ?, ?) AND `uid` = ? AND NOT `deleted`', $term['url'], Strings::normaliseLink($term['url']), $ssl_url, 0]; + $contact = DBA::selectFirst('contact', ['url', 'alias'], $condition, ['order' => ['id']]); + } + + if (DBA::isResult($contact) && (!strstr($term['body'], $contact['url']) && (empty($contact['alias']) || !strstr($term['body'], $contact['alias'])))) { + $term['type'] = Tag::IMPLICIT_MENTION; + } + } + + Tag::store($term['uri-id'], $term['type'], $term['term'], $term['url'], false); + + $id = $term['tid']; + ++$rows; + if ($rows % 1000 == 0) { + DI::config()->set('system', 'post_update_version_1342_id', $id); + } + } + DBA::close($terms); + + DI::config()->set('system', 'post_update_version_1342_id', $id); + + Logger::info('Processed', ['rows' => $rows, 'last' => $id]); + + if ($start_id == $id) { + DI::config()->set('system', 'post_update_version', 1342); + Logger::info('Done'); + return true; + } + + return false; + } } diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 8b4d1528c6..72235d2777 100755 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -51,7 +51,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1341); + define('DB_UPDATE_VERSION', 1342); } return [ From bb0d6ce6f60da88c9366628baa96c49d08e8b7e9 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 30 Apr 2020 09:03:05 +0000 Subject: [PATCH 10/24] Better check for finished conversion --- src/Database/PostUpdate.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 4a6507ff5f..c2e96b68c6 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -585,7 +585,9 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows, 'last' => $id]); - if ($start_id == $id) { + // When there are less than 100 items processed this means that we reached the end + // The other entries will then be processed with the regular functionality + if ($rows < 100) { DI::config()->set('system', 'post_update_version', 1341); Logger::info('Done'); return true; @@ -655,7 +657,9 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows, 'last' => $id]); - if ($start_id == $id) { + // When there are less than 100 items processed this means that we reached the end + // The other entries will then be processed with the regular functionality + if ($rows < 100) { DI::config()->set('system', 'post_update_version', 1342); Logger::info('Done'); return true; From 6d4962a57116840fe43cc8d372102865a5071573 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 30 Apr 2020 12:13:13 +0000 Subject: [PATCH 11/24] 1,000 is better than 100 --- src/Database/PostUpdate.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index c2e96b68c6..9ae7691d5f 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -585,9 +585,9 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows, 'last' => $id]); - // When there are less than 100 items processed this means that we reached the end + // When there are less than 1,000 items processed this means that we reached the end // The other entries will then be processed with the regular functionality - if ($rows < 100) { + if ($rows < 1000) { DI::config()->set('system', 'post_update_version', 1341); Logger::info('Done'); return true; @@ -657,9 +657,9 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows, 'last' => $id]); - // When there are less than 100 items processed this means that we reached the end + // When there are less than 1,000 items processed this means that we reached the end // The other entries will then be processed with the regular functionality - if ($rows < 100) { + if ($rows < 1000) { DI::config()->set('system', 'post_update_version', 1342); Logger::info('Done'); return true; From 3b2ae5c4a978ef2e6e104f6827c12c8d1481dd02 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 06:01:22 +0000 Subject: [PATCH 12/24] function names changed --- include/conversation.php | 2 +- src/Model/Item.php | 2 +- src/Model/Tag.php | 6 +++--- src/Object/Post.php | 4 ++-- src/Protocol/ActivityPub/Processor.php | 2 +- src/Protocol/ActivityPub/Transmitter.php | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/conversation.php b/include/conversation.php index 5d08fd6928..a4fe9c00e3 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -526,7 +526,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o $profile_name = $item['author-link']; } - $tags = Tag::populateTagsFromItem($item); + $tags = Tag::populateFromItem($item); $author = ['uid' => 0, 'id' => $item['author-id'], 'network' => $item['author-network'], 'url' => $item['author-link']]; diff --git a/src/Model/Item.php b/src/Model/Item.php index b75abc6ca8..1096c22131 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -3563,7 +3563,7 @@ class Item return $ev; } - $tags = Tag::populateTagsFromItem($item); + $tags = Tag::populateFromItem($item); $item['tags'] = $tags['tags']; $item['hashtags'] = $tags['hashtags']; diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 7e894aca9b..ef962b582c 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -316,7 +316,7 @@ class Tag * @return array * @throws \Exception */ - public static function ArrayFromURIId(int $uri_id, array $type = [self::HASHTAG, self::MENTION, self::IMPLICIT_MENTION, self::EXCLUSIVE_MENTION]) + public static function getByURIId(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); @@ -333,7 +333,7 @@ class 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. * @@ -342,7 +342,7 @@ class Tag * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function populateTagsFromItem(&$item) + public static function populateFromItem(&$item) { $return = [ 'tags' => [], diff --git a/src/Object/Post.php b/src/Object/Post.php index 99ab357bc0..8488df000f 100644 --- a/src/Object/Post.php +++ b/src/Object/Post.php @@ -390,7 +390,7 @@ class Post $buttons["like"] = false; } - $tags = Tag::populateTagsFromItem($item); + $tags = Tag::populateFromItem($item); $ago = Temporal::getRelativeDate($item['created']); $ago_received = Temporal::getRelativeDate($item['received']); @@ -872,7 +872,7 @@ class Post $text = ''; } - $terms = Tag::ArrayFromURIId($item['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); + $terms = Tag::getByURIId($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 80b2b0dbab..43343f1e6b 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1015,7 +1015,7 @@ class Processor return []; } - $parent_terms = Tag::ArrayFromURIId($parent['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); + $parent_terms = Tag::getByURIId($parent['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); $parent_author = Contact::getDetailsByURL($parent['author-link'], 0); diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index fd91dca16a..82bda11698 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -407,7 +407,7 @@ class Transmitter $actor_profile = APContact::getByURL($item['author-link']); } - $terms = Tag::ArrayFromURIId($item['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); + $terms = Tag::getByURIId($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. @@ -1009,7 +1009,7 @@ class Transmitter { $tags = []; - $terms = Tag::ArrayFromURIId($item['uri-id'], [Tag::HASHTAG, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); + $terms = Tag::getByURIId($item['uri-id'], [Tag::HASHTAG, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); foreach ($terms as $term) { if ($term['type'] == Tag::HASHTAG) { $url = DI::baseUrl() . '/search?tag=' . urlencode($term['term']); From 1f64e672baa1b432c1a475b3eaaa8a7d8db95e76 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 07:18:15 +0000 Subject: [PATCH 13/24] Subscribed tags are now based on the tags as well --- mod/network.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mod/network.php b/mod/network.php index 0c2cbccf55..bcdfefdd44 100644 --- a/mod/network.php +++ b/mod/network.php @@ -788,14 +788,13 @@ function networkThreadedView(App $a, $update, $parent) } $items = DBA::p("SELECT `item`.`parent-uri` AS `uri`, 0 AS `item_id`, `item`.$ordering AS `order_date`, `author`.`url` AS `author-link` FROM `item` - STRAIGHT_JOIN (SELECT `oid` FROM `term` WHERE `term` IN - (SELECT SUBSTR(`term`, 2) FROM `search` WHERE `uid` = ? AND `term` LIKE '#%') AND `otype` = ? AND `type` = ? AND `uid` = 0) AS `term` - ON `item`.`id` = `term`.`oid` + STRAIGHT_JOIN (SELECT `uri-id` FROM `tag-search-view` WHERE `name` IN + (SELECT SUBSTR(`term`, 2) FROM `search` WHERE `uid` = ? AND `term` LIKE '#%') AND `uid` = 0) AS `tag-search` + ON `item`.`uri-id` = `tag-search`.`uri-id` STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `item`.`author-id` WHERE `item`.`uid` = 0 AND `item`.$ordering < ? AND `item`.$ordering > ? AND `item`.`gravity` = ? AND NOT `author`.`hidden` AND NOT `author`.`blocked`" . $sql_tag_nets, - local_user(), Term::OBJECT_TYPE_POST, Tag::HASHTAG, - $top_limit, $bottom_limit, GRAVITY_PARENT); + local_user(), $top_limit, $bottom_limit, GRAVITY_PARENT); $data = DBA::toArray($items); From 8602bbb3b9a017004ac42c4b131d687f61d10ace Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 08:02:21 +0000 Subject: [PATCH 14/24] "term" replaced with "tag" --- src/Content/Widget/TagCloud.php | 15 ++++++--------- src/Module/Profile/Status.php | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Content/Widget/TagCloud.php b/src/Content/Widget/TagCloud.php index 63df5a0bd5..49157a5bdd 100644 --- a/src/Content/Widget/TagCloud.php +++ b/src/Content/Widget/TagCloud.php @@ -102,16 +102,13 @@ class TagCloud } // Fetch tags - $tag_stmt = DBA::p("SELECT `term`, COUNT(`term`) AS `total` FROM `term` - LEFT JOIN `item` ON `term`.`oid` = `item`.`id` - WHERE `term`.`uid` = ? AND `term`.`type` = ? - AND `term`.`otype` = ? + $tag_stmt = DBA::p("SELECT `name`, COUNT(`name`) AS `total` FROM `tag-search-view` + LEFT JOIN `item` ON `tag-search-view`.`uri-id` = `item`.`uri-id` + WHERE `tag-search-view`.`uid` = ? AND `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated` $sql_options - GROUP BY `term` ORDER BY `total` DESC $limit", - $uid, - $type, - Term::OBJECT_TYPE_POST + GROUP BY `name` ORDER BY `total` DESC $limit", + $uid ); if (!DBA::isResult($tag_stmt)) { return []; @@ -140,7 +137,7 @@ class TagCloud } foreach ($arr as $rr) { - $tags[$x][0] = $rr['term']; + $tags[$x][0] = $rr['name']; $tags[$x][1] = log($rr['total']); $tags[$x][2] = 0; $min = min($min, $tags[$x][1]); diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php index d7ed5ca7f4..f12889c9f9 100644 --- a/src/Module/Profile/Status.php +++ b/src/Module/Profile/Status.php @@ -148,8 +148,8 @@ class Status extends BaseProfile } if (!empty($hashtags)) { - $sql_post_table .= sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", - DBA::escape(Strings::protectSprintf($hashtags)), intval(Term::OBJECT_TYPE_POST), intval(Tag::HASHTAG), intval($a->profile['uid'])); + $sql_post_table .= sprintf("INNER JOIN (SELECT `uri-id` FROM `tag-search-view` WHERE `name` = '%s' AND `uid` = %d ORDER BY `uri-id` DESC) AS `tag-search` ON `item`.`uri-id` = `tag-search`.`uri-id` ", + DBA::escape(Strings::protectSprintf($hashtags)), intval($a->profile['uid'])); } if (!empty($datequery)) { From 2b8dabcd95c211a52ba25b877829120573564051 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 09:41:17 +0000 Subject: [PATCH 15/24] API search is now done via "tag" as well --- include/api.php | 28 ++++++++++------------------ static/dbstructure.config.php | 2 +- static/dbview.config.php | 1 + 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/include/api.php b/include/api.php index 97c30e317a..beddc5adcb 100644 --- a/include/api.php +++ b/include/api.php @@ -1540,32 +1540,24 @@ function api_search($type) $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; if (preg_match('/^#(\w+)$/', $searchTerm, $matches) === 1 && isset($matches[1])) { $searchTerm = $matches[1]; - /// @todo $uriids = Tag::getURIIdListForTag($searchTerm, local_user()); - $condition = ["`oid` > ? - AND (`uid` = 0 OR (`uid` = ? AND NOT `global`)) - AND `otype` = ? AND `type` = ? AND `term` = ?", - $since_id, local_user(), Term::OBJECT_TYPE_POST, Tag::HASHTAG, $searchTerm]; - if ($max_id > 0) { - $condition[0] .= ' AND `oid` <= ?'; - $condition[] = $max_id; + $condition = ["`iid` > ? AND `name` = ? AND (NOT `private` OR (`private` AND `uid` = ?))", $since_id, $searchTerm, local_user()]; + $tags = DBA::select('tag-search-view', ['uri-id'], $condition); + $uriids = []; + while ($tag = DBA::fetch($tags)) { + $uriids[] = $tag['uri-id']; } - $terms = DBA::select('term', ['oid'], $condition, []); - $itemIds = []; - while ($term = DBA::fetch($terms)) { - $itemIds[] = $term['oid']; - } - DBA::close($terms); + DBA::close($tags); - if (empty($itemIds)) { + if (empty($uriids)) { return api_format_data('statuses', $type, $data); } - $preCondition = ['`id` IN (' . implode(', ', $itemIds) . ')']; + $condition = ['uri-id' => $uriids]; if ($exclude_replies) { - $preCondition[] = '`id` = `parent`'; + $condition['gravity'] = GRAVITY_PARENT; } - $condition = [implode(' AND ', $preCondition)]; + $params['group_by'] = ['uri-id']; } else { $condition = ["`id` > ? " . ($exclude_replies ? " AND `id` = `parent` " : ' ') . " diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 72235d2777..2c3a9fb5fd 100755 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -51,7 +51,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1342); + define('DB_UPDATE_VERSION', 1343); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 59b8686d0b..3be78bf694 100755 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -223,6 +223,7 @@ return [ "tag-search-view" => [ "fields" => [ "uri-id" => ["post-tag", "uri-id"], + "iid" => ["item", "id"], "uri" => ["item", "uri"], "guid" => ["item", "guid"], "uid" => ["item", "uid"], From ac2957c4dda0ec3421f9d47a7d601bdcdd1d9579 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 10:57:32 +0000 Subject: [PATCH 16/24] Some more "term" to "tag" conversion --- mod/item.php | 12 ++-- src/Content/Widget/TrendingTags.php | 5 +- src/Model/Tag.php | 55 +++++++++++++++++ src/Model/Term.php | 91 +---------------------------- src/Module/Admin/Item/Source.php | 4 +- static/dbview.config.php | 4 ++ 6 files changed, 70 insertions(+), 101 deletions(-) diff --git a/mod/item.php b/mod/item.php index bd28d33899..b97f8bbe31 100644 --- a/mod/item.php +++ b/mod/item.php @@ -101,7 +101,7 @@ function item_post(App $a) { $toplevel_item_id = intval($_REQUEST['parent'] ?? 0); $thr_parent_uri = trim($_REQUEST['parent_uri'] ?? ''); - $thread_parent_id = 0; + $thread_parent_uriid = 0; $thread_parent_contact = null; $toplevel_item = null; @@ -123,7 +123,7 @@ function item_post(App $a) { // if this isn't the top-level parent of the conversation, find it if (DBA::isResult($toplevel_item)) { // The URI and the contact is taken from the direct parent which needn't to be the top parent - $thread_parent_id = $toplevel_item['id']; + $thread_parent_uriid = $toplevel_item['uri-id']; $thr_parent_uri = $toplevel_item['uri']; $thread_parent_contact = Contact::getDetailsByURL($toplevel_item["author-link"]); @@ -381,8 +381,8 @@ function item_post(App $a) { $tags = BBCode::getTags($body); - if ($thread_parent_id && !\Friendica\Content\Feature::isEnabled($uid, 'explicit_mentions')) { - $tags = item_add_implicit_mentions($tags, $thread_parent_contact, $thread_parent_id); + if ($thread_parent_uriid && !\Friendica\Content\Feature::isEnabled($uid, 'explicit_mentions')) { + $tags = item_add_implicit_mentions($tags, $thread_parent_contact, $thread_parent_uriid); } $tagged = []; @@ -1044,7 +1044,7 @@ function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network = return ['replaced' => $replaced, 'contact' => $contact]; } -function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $thread_parent_id) +function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $thread_parent_uriid) { if (DI::config()->get('system', 'disable_implicit_mentions')) { // Add a tag if the parent contact is from ActivityPub or OStatus (This will notify them) @@ -1059,7 +1059,7 @@ function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $ $thread_parent_contact['url'] => $thread_parent_contact['nick'] ]; - $parent_terms = Term::tagArrayFromItemId($thread_parent_id, [Tag::MENTION, Tag::IMPLICIT_MENTION]); + $parent_terms = Tag::getByURIId($thread_parent_uriid, [Tag::MENTION, Tag::IMPLICIT_MENTION]); foreach ($parent_terms as $parent_term) { $implicit_mentions[$parent_term['url']] = $parent_term['term']; diff --git a/src/Content/Widget/TrendingTags.php b/src/Content/Widget/TrendingTags.php index 053cba09d3..9c24d1549c 100644 --- a/src/Content/Widget/TrendingTags.php +++ b/src/Content/Widget/TrendingTags.php @@ -24,7 +24,6 @@ namespace Friendica\Content\Widget; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Tag; -use Friendica\Model\Term; /** * Trending tags aside widget for the community pages, handles both local and global scopes @@ -42,9 +41,9 @@ class TrendingTags public static function getHTML($content = 'global', int $period = 24) { if ($content == 'local') { - $tags = Term::getLocalTrendingHashtags($period, 20); + $tags = Tag::getLocalTrendingHashtags($period, 20); } else { - $tags = Term::getGlobalTrendingHashtags($period, 20); + $tags = Tag::getGlobalTrendingHashtags($period, 20); } $tpl = Renderer::getMarkupTemplate('widget/trending_tags.tpl'); diff --git a/src/Model/Tag.php b/src/Model/Tag.php index ef962b582c..0a3e0e8533 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -22,6 +22,7 @@ namespace Friendica\Model; use Friendica\Content\Text\BBCode; +use Friendica\Core\Cache\Duration; use Friendica\Core\Logger; use Friendica\Core\System; use Friendica\Database\DBA; @@ -416,4 +417,58 @@ class Tag return $uriids; } + + /** + * Returns a list of the most frequent global hashtags over the given period + * + * @param int $period Period in hours to consider posts + * @return array + * @throws \Exception + */ + public static function getGlobalTrendingHashtags(int $period, $limit = 10) + { + $tags = DI::cache()->get('global_trending_tags'); + + if (empty($tags)) { + $tagsStmt = DBA::p("SELECT `name` AS `term`, COUNT(*) AS `score` + FROM `tag-search-view` + WHERE `private` = ? AND `received` > DATE_SUB(NOW(), INTERVAL ? HOUR) + GROUP BY `term` ORDER BY `score` DESC LIMIT ?", + Item::PUBLIC, $period, $limit); + + if (DBA::isResult($tagsStmt)) { + $tags = DBA::toArray($tagsStmt); + DI::cache()->set('global_trending_tags', $tags, Duration::HOUR); + } + } + + return $tags ?: []; + } + + /** + * Returns a list of the most frequent local hashtags over the given period + * + * @param int $period Period in hours to consider posts + * @return array + * @throws \Exception + */ + public static function getLocalTrendingHashtags(int $period, $limit = 10) + { + $tags = DI::cache()->get('local_trending_tags'); + + if (empty($tags)) { + $tagsStmt = DBA::p("SELECT `name` AS `term`, COUNT(*) AS `score` + FROM `tag-search-view` + WHERE `private` = ? AND `wall` AND `origin` AND `received` > DATE_SUB(NOW(), INTERVAL ? HOUR) + GROUP BY `term` ORDER BY `score` DESC LIMIT ?", + Item::PUBLIC, $period, $limit); + + if (DBA::isResult($tagsStmt)) { + $tags = DBA::toArray($tagsStmt); + DI::cache()->set('local_trending_tags', $tags, Duration::HOUR); + } + } + + return $tags ?: []; + } } diff --git a/src/Model/Term.php b/src/Model/Term.php index a6858d8415..6f241015f8 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -60,95 +60,6 @@ class Term const OBJECT_TYPE_POST = 1; const OBJECT_TYPE_PHOTO = 2; - /** - * Returns a list of the most frequent global hashtags over the given period - * - * @param int $period Period in hours to consider posts - * @return array - * @throws \Exception - */ - public static function getGlobalTrendingHashtags(int $period, $limit = 10) - { - $tags = DI::cache()->get('global_trending_tags'); - - if (!$tags) { - $tagsStmt = DBA::p("SELECT t.`term`, COUNT(*) AS `score` - FROM `term` t - JOIN `item` i ON i.`id` = t.`oid` AND i.`uid` = t.`uid` - JOIN `thread` ON `thread`.`iid` = i.`id` - WHERE `thread`.`visible` - AND NOT `thread`.`deleted` - AND NOT `thread`.`moderated` - AND `thread`.`private` = ? - AND t.`uid` = 0 - AND t.`otype` = ? - AND t.`type` = ? - AND t.`term` != '' - AND i.`received` > DATE_SUB(NOW(), INTERVAL ? HOUR) - GROUP BY `term` - ORDER BY `score` DESC - LIMIT ?", - Item::PUBLIC, - self::OBJECT_TYPE_POST, - self::HASHTAG, - $period, - $limit - ); - - if (DBA::isResult($tagsStmt)) { - $tags = DBA::toArray($tagsStmt); - DI::cache()->set('global_trending_tags', $tags, Duration::HOUR); - } - } - - return $tags ?: []; - } - - /** - * Returns a list of the most frequent local hashtags over the given period - * - * @param int $period Period in hours to consider posts - * @return array - * @throws \Exception - */ - public static function getLocalTrendingHashtags(int $period, $limit = 10) - { - $tags = DI::cache()->get('local_trending_tags'); - - if (!$tags) { - $tagsStmt = DBA::p("SELECT t.`term`, COUNT(*) AS `score` - FROM `term` t - JOIN `item` i ON i.`id` = t.`oid` AND i.`uid` = t.`uid` - JOIN `thread` ON `thread`.`iid` = i.`id` - WHERE `thread`.`visible` - AND NOT `thread`.`deleted` - AND NOT `thread`.`moderated` - AND `thread`.`private` = ? - AND `thread`.`wall` - AND `thread`.`origin` - AND t.`otype` = ? - AND t.`type` = ? - AND t.`term` != '' - AND i.`received` > DATE_SUB(NOW(), INTERVAL ? HOUR) - GROUP BY `term` - ORDER BY `score` DESC - LIMIT ?", - Item::PUBLIC, - self::OBJECT_TYPE_POST, - self::HASHTAG, - $period, - $limit - ); - - if (DBA::isResult($tagsStmt)) { - $tags = DBA::toArray($tagsStmt); - DI::cache()->set('local_trending_tags', $tags, Duration::HOUR); - } - } - - return $tags ?: []; - } - /** * Generates the legacy item.tag field comma-separated BBCode string from an item ID. * Includes only hashtags, implicit and explicit mentions. @@ -176,7 +87,7 @@ class Term * @return array * @throws \Exception */ - public static function tagArrayFromItemId($item_id, $type = [self::HASHTAG, self::MENTION]) + private static function tagArrayFromItemId($item_id, $type = [self::HASHTAG, self::MENTION]) { $condition = ['otype' => self::OBJECT_TYPE_POST, 'oid' => $item_id, 'type' => $type]; $tags = DBA::select('term', ['type', 'term', 'url'], $condition); diff --git a/src/Module/Admin/Item/Source.php b/src/Module/Admin/Item/Source.php index b8aaff99b8..e35eafd2f2 100644 --- a/src/Module/Admin/Item/Source.php +++ b/src/Module/Admin/Item/Source.php @@ -48,14 +48,14 @@ class Source extends BaseAdmin $item_id = ''; $terms = []; if (!empty($guid)) { - $item = Model\Item::selectFirst(['id', 'guid', 'uri'], ['guid' => $guid]); + $item = Model\Item::selectFirst(['id', 'uri-id', 'guid', 'uri'], ['guid' => $guid]); $conversation = Model\Conversation::getByItemUri($item['uri']); $item_id = $item['id']; $item_uri = $item['uri']; $source = $conversation['source']; - $terms = Model\Term::tagArrayFromItemId($item['id'], [Model\Term::HASHTAG, Model\Term::MENTION, Model\Term::IMPLICIT_MENTION]); + $terms = Model\Tag::getByURIId($item['uri-id'], [Model\Tag::HASHTAG, Model\Tag::MENTION, Model\Tag::IMPLICIT_MENTION]); } $tpl = Renderer::getMarkupTemplate('admin/item/source.tpl'); diff --git a/static/dbview.config.php b/static/dbview.config.php index 3be78bf694..0f0d691085 100755 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -228,6 +228,10 @@ return [ "guid" => ["item", "guid"], "uid" => ["item", "uid"], "private" => ["item", "private"], + "wall" => ["item", "wall"], + "origin" => ["item", "origin"], + "gravity" => ["item", "gravity"], + "received" => ["item", "received"], "name" => ["tag", "name"], ], "query" => "FROM `post-tag` From 029a37906038c3829d8662fc1ec43b430ba9e9bd Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 12:39:41 +0000 Subject: [PATCH 17/24] Move "isType" to Tag.php --- mod/item.php | 2 +- src/Model/Tag.php | 19 +++++++++++++++++++ src/Model/Term.php | 28 ++++------------------------ 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/mod/item.php b/mod/item.php index b97f8bbe31..b044078ae2 100644 --- a/mod/item.php +++ b/mod/item.php @@ -906,7 +906,7 @@ function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network = $r = null; //is it a person tag? - if (Term::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) { + if (Tag::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) { $tag_type = substr($tag, 0, 1); //is it already replaced? if (strpos($tag, '[url=')) { diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 0a3e0e8533..2c5295924a 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -471,4 +471,23 @@ class Tag return $tags ?: []; } + + /** + * Check if the provided tag is of one of the provided term types. + * + * @param string $tag + * @param int ...$types + * @return bool + */ + public static function isType($tag, ...$types) + { + $tag_chars = []; + foreach ($types as $type) { + if (array_key_exists($type, self::TAG_CHARACTER)) { + $tag_chars[] = self::TAG_CHARACTER[$type]; + } + } + + return Strings::startsWith($tag, $tag_chars); + } } diff --git a/src/Model/Term.php b/src/Model/Term.php index 6f241015f8..05314dd601 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -21,7 +21,6 @@ namespace Friendica\Model; -use Friendica\Core\Cache\Duration; use Friendica\Core\Logger; use Friendica\Database\DBA; use Friendica\DI; @@ -202,7 +201,7 @@ class Term } foreach ($tags as $link => $tag) { - if (self::isType($tag, self::HASHTAG)) { + if (Tag::isType($tag, self::HASHTAG)) { // try to ignore #039 or #1 or anything like that if (ctype_digit(substr(trim($tag), 1))) { continue; @@ -216,8 +215,8 @@ class Term $type = self::HASHTAG; $term = substr($tag, 1); $link = ''; - } elseif (self::isType($tag, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION)) { - if (self::isType($tag, self::MENTION, self::EXCLUSIVE_MENTION)) { + } elseif (Tag::isType($tag, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION)) { + if (Tag::isType($tag, self::MENTION, self::EXCLUSIVE_MENTION)) { $type = self::MENTION; } else { $type = self::IMPLICIT_MENTION; @@ -266,7 +265,7 @@ class Term ]); // Search for mentions - if (self::isType($tag, self::MENTION, self::EXCLUSIVE_MENTION) + if (Tag::isType($tag, self::MENTION, self::EXCLUSIVE_MENTION) && ( strpos($link, $profile_base_friendica) !== false || strpos($link, $profile_base_diaspora) !== false @@ -351,23 +350,4 @@ class Term // Clean up all tags DBA::delete('term', ['otype' => self::OBJECT_TYPE_POST, 'oid' => $item_id, 'type' => $type]); } - - /** - * Check if the provided tag is of one of the provided term types. - * - * @param string $tag - * @param int ...$types - * @return bool - */ - public static function isType($tag, ...$types) - { - $tag_chars = []; - foreach ($types as $type) { - if (array_key_exists($type, self::TAG_CHARACTER)) { - $tag_chars[] = self::TAG_CHARACTER[$type]; - } - } - - return Strings::startsWith($tag, $tag_chars); - } } From 2b1fef469a683ce24651564794e839c96040ecde Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 12:41:17 +0000 Subject: [PATCH 18/24] Notification moved to usage of the "tag" table --- src/Model/UserItem.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/UserItem.php b/src/Model/UserItem.php index 74c5ac4486..5e9096f41a 100644 --- a/src/Model/UserItem.php +++ b/src/Model/UserItem.php @@ -51,7 +51,7 @@ class UserItem */ public static function setNotification(int $iid) { - $fields = ['id', 'uid', 'body', 'parent', 'gravity', 'tag', 'contact-id', 'thr-parent', 'parent-uri', 'author-id']; + $fields = ['id', 'uri-id', 'uid', 'body', 'parent', 'gravity', 'tag', 'contact-id', 'thr-parent', 'parent-uri', 'author-id']; $item = Item::selectFirst($fields, ['id' => $iid, 'origin' => false]); if (!DBA::isResult($item)) { return; @@ -208,7 +208,7 @@ class UserItem } // Or the contact is a mentioned forum - $tags = DBA::select('term', ['url'], ['otype' => Term::OBJECT_TYPE_POST, 'oid' => $item['id'], 'type' => Tag::MENTION, 'uid' => $uid]); + $tags = DBA::select('tag-view', ['url'], ['uri-id' => $item['uri-id'], 'type' => [Tag::MENTION, Tag::EXCLUSIVE_MENTION]]); while ($tag = DBA::fetch($tags)) { $condition = ['nurl' => Strings::normaliseLink($tag['url']), 'uid' => $uid, 'notify_new_posts' => true, 'contact-type' => Contact::TYPE_COMMUNITY]; if (DBA::exists('contact', $condition)) { From 70022393b7e32e464b536cb62ce8cdc4fa7ec5c5 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 12:42:22 +0000 Subject: [PATCH 19/24] Fix notice for missing "uri-id" --- src/Protocol/ActivityPub/Transmitter.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 82bda11698..04c7531db2 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -34,6 +34,7 @@ use Friendica\Model\APContact; use Friendica\Model\Contact; use Friendica\Model\Conversation; use Friendica\Model\Item; +use Friendica\Model\ItemURI; use Friendica\Model\Profile; use Friendica\Model\Photo; use Friendica\Model\Tag; @@ -701,6 +702,8 @@ class Transmitter return []; } + $mail['uri-id'] = ItemURI::insert(['uri' => $mail['uri'], 'guid' => $mail['guid']]); + $reply = DBA::selectFirst('mail', ['uri'], ['parent-uri' => $mail['parent-uri'], 'reply' => false]); // Making the post more compatible for Mastodon by: From ede69a86733286c97a931563b1c31bd3e4ba25f9 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 13:13:58 +0000 Subject: [PATCH 20/24] Function renamed --- src/Model/Tag.php | 2 +- src/Module/Search/Index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 2c5295924a..86c93efe8e 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -398,7 +398,7 @@ class Tag * @param integer $limit * @return array with URI-ID */ - public static function getURIIdListForTag(string $search, int $uid = 0, int $start = 0, int $limit = 100) + public static function getURIIdListByTag(string $search, int $uid = 0, int $start = 0, int $limit = 100) { $condition = ["`name` = ? AND (NOT `private` OR (`private` AND `uid` = ?))", $search, $uid]; $params = [ diff --git a/src/Module/Search/Index.php b/src/Module/Search/Index.php index 0aba7a203d..27074fa82a 100644 --- a/src/Module/Search/Index.php +++ b/src/Module/Search/Index.php @@ -149,7 +149,7 @@ class Index extends BaseSearch if ($tag) { Logger::info('Start tag search.', ['q' => $search]); - $uriids = Tag::getURIIdListForTag($search, local_user(), $pager->getStart(), $pager->getItemsPerPage()); + $uriids = Tag::getURIIdListByTag($search, local_user(), $pager->getStart(), $pager->getItemsPerPage()); if (!empty($uriids)) { $params = ['order' => ['id' => true], 'group_by' => ['uri-id']]; From 74081a71ff758ed9ffaad4789c19ae99f19000cd Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 13:26:13 +0000 Subject: [PATCH 21/24] Removed unused "use" --- include/api.php | 2 -- mod/item.php | 1 - mod/network.php | 1 - src/Content/Widget/TagCloud.php | 1 - src/Model/UserItem.php | 1 - src/Module/Profile/Status.php | 1 - 6 files changed, 7 deletions(-) diff --git a/include/api.php b/include/api.php index beddc5adcb..c04174313e 100644 --- a/include/api.php +++ b/include/api.php @@ -41,8 +41,6 @@ use Friendica\Model\Item; use Friendica\Model\Mail; use Friendica\Model\Notify; use Friendica\Model\Photo; -use Friendica\Model\Tag; -use Friendica\Model\Term; use Friendica\Model\User; use Friendica\Model\UserItem; use Friendica\Network\FKOAuth1; diff --git a/mod/item.php b/mod/item.php index b044078ae2..a41bb7c520 100644 --- a/mod/item.php +++ b/mod/item.php @@ -46,7 +46,6 @@ use Friendica\Model\Item; use Friendica\Model\Notify\Type; use Friendica\Model\Photo; use Friendica\Model\Tag; -use Friendica\Model\Term; use Friendica\Network\HTTPException; use Friendica\Object\EMail\ItemCCEMail; use Friendica\Protocol\Activity; diff --git a/mod/network.php b/mod/network.php index bcdfefdd44..9ec8c95b92 100644 --- a/mod/network.php +++ b/mod/network.php @@ -38,7 +38,6 @@ use Friendica\Model\Contact; use Friendica\Model\Group; use Friendica\Model\Item; use Friendica\Model\Profile; -use Friendica\Model\Tag; use Friendica\Model\Term; use Friendica\Module\Security\Login; use Friendica\Util\DateTimeFormat; diff --git a/src/Content/Widget/TagCloud.php b/src/Content/Widget/TagCloud.php index 49157a5bdd..109940a126 100644 --- a/src/Content/Widget/TagCloud.php +++ b/src/Content/Widget/TagCloud.php @@ -26,7 +26,6 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Item; use Friendica\Model\Tag; -use Friendica\Model\Term; /** * TagCloud widget diff --git a/src/Model/UserItem.php b/src/Model/UserItem.php index 5e9096f41a..50e23e1580 100644 --- a/src/Model/UserItem.php +++ b/src/Model/UserItem.php @@ -27,7 +27,6 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Util\Strings; use Friendica\Model\Tag; -use Friendica\Model\Term; class UserItem { diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php index f12889c9f9..685ab4e076 100644 --- a/src/Module/Profile/Status.php +++ b/src/Module/Profile/Status.php @@ -31,7 +31,6 @@ use Friendica\DI; use Friendica\Model\Item; use Friendica\Model\Profile as ProfileModel; use Friendica\Model\User; -use Friendica\Model\Tag; use Friendica\Model\Term; use Friendica\Module\BaseProfile; use Friendica\Module\Security\Login; From 729c6b67aae0f2034c3c7c7c504c816ea77a683a Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 15:18:48 +0000 Subject: [PATCH 22/24] the "term" field now is called "name", workaround removed --- mod/item.php | 2 +- src/Model/Tag.php | 13 +------------ view/templates/admin/item/source.tpl | 2 +- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/mod/item.php b/mod/item.php index a41bb7c520..30b5f5aefa 100644 --- a/mod/item.php +++ b/mod/item.php @@ -1061,7 +1061,7 @@ function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $ $parent_terms = Tag::getByURIId($thread_parent_uriid, [Tag::MENTION, Tag::IMPLICIT_MENTION]); foreach ($parent_terms as $parent_term) { - $implicit_mentions[$parent_term['url']] = $parent_term['term']; + $implicit_mentions[$parent_term['url']] = $parent_term['name']; } foreach ($implicit_mentions as $url => $label) { diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 86c93efe8e..04107f804c 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -320,18 +320,7 @@ class Tag public static function getByURIId(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; + return DBA::selectToArray('tag-view', ['type', 'name', 'url'], $condition); } /** diff --git a/view/templates/admin/item/source.tpl b/view/templates/admin/item/source.tpl index 4f985cbdce..a681d8739f 100644 --- a/view/templates/admin/item/source.tpl +++ b/view/templates/admin/item/source.tpl @@ -45,7 +45,7 @@ {{if $term.type == 8}}Implicit Mention{{/if}} - {{$term.term}} + {{$term.name}} {{$term.url}} From c3ecc19b41b8f4d5bbbd9d46e8323348a080256f Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 15:27:56 +0000 Subject: [PATCH 23/24] Last "term" element renamed --- src/Protocol/ActivityPub/Transmitter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 04c7531db2..16b7b039a9 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -1015,8 +1015,8 @@ class Transmitter $terms = Tag::getByURIId($item['uri-id'], [Tag::HASHTAG, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); foreach ($terms as $term) { if ($term['type'] == Tag::HASHTAG) { - $url = DI::baseUrl() . '/search?tag=' . urlencode($term['term']); - $tags[] = ['type' => 'Hashtag', 'href' => $url, 'name' => '#' . $term['term']]; + $url = DI::baseUrl() . '/search?tag=' . urlencode($term['name']); + $tags[] = ['type' => 'Hashtag', 'href' => $url, 'name' => '#' . $term['name']]; } else { $contact = Contact::getDetailsByURL($term['url']); if (!empty($contact['addr'])) { From 776a1dd7c390ec7ecf15dd1eee832e3f1d798cd4 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 May 2020 15:43:50 +0000 Subject: [PATCH 24/24] Renamed function --- src/Model/Term.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Model/Term.php b/src/Model/Term.php index 05314dd601..5f54024871 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -70,7 +70,7 @@ class Term public static function tagTextFromItemId($item_id) { $tag_list = []; - $tags = self::tagArrayFromItemId($item_id, [self::HASHTAG, self::MENTION, self::IMPLICIT_MENTION]); + $tags = self::getByItemId($item_id, [self::HASHTAG, self::MENTION, self::IMPLICIT_MENTION]); foreach ($tags as $tag) { $tag_list[] = self::TAG_CHARACTER[$tag['type']] . '[url=' . $tag['url'] . ']' . $tag['term'] . '[/url]'; } @@ -86,7 +86,7 @@ class Term * @return array * @throws \Exception */ - private static function tagArrayFromItemId($item_id, $type = [self::HASHTAG, self::MENTION]) + private static function getByItemId($item_id, $type = [self::HASHTAG, self::MENTION]) { $condition = ['otype' => self::OBJECT_TYPE_POST, 'oid' => $item_id, 'type' => $type]; $tags = DBA::select('term', ['type', 'term', 'url'], $condition); @@ -108,7 +108,7 @@ class Term public static function fileTextFromItemId($item_id) { $file_text = ''; - $tags = self::tagArrayFromItemId($item_id, [self::FILE, self::CATEGORY]); + $tags = self::getByItemId($item_id, [self::FILE, self::CATEGORY]); foreach ($tags as $tag) { if ($tag['type'] == self::CATEGORY) { $file_text .= '<' . $tag['term'] . '>';