X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FTerm.php;h=868f2bf0532380ee8bef06655f8e5e8bd6a594df;hb=7b7132971a64a92a685a5fd860fe4709dce1765a;hp=36876368dfabb1f468d30b7465fba681dba81ba4;hpb=67aa1888309e83648be62988b10e757c14a2e2a9;p=friendica.git diff --git a/src/Model/Term.php b/src/Model/Term.php index 36876368df..868f2bf053 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -1,13 +1,39 @@ . + * */ + namespace Friendica\Model; -use Friendica\Core\System; +use Friendica\Core\Cache\Duration; +use Friendica\Core\Logger; use Friendica\Database\DBA; +use Friendica\DI; use Friendica\Util\Strings; +/** + * Class Term + * + * This Model class handles term table interactions. + * This tables stores relevant terms related to posts, photos and searches, like hashtags, mentions and + * user-applied categories. + */ class Term { const UNKNOWN = 0; @@ -18,7 +44,13 @@ class Term const FILE = 5; const SAVEDSEARCH = 6; const CONVERSATION = 7; + /** + * An implicit mention is a mention in a comment body that is redundant with the threading information. + */ const IMPLICIT_MENTION = 8; + /** + * An exclusive mention transfers the ownership of the post to the target account, usually a forum. + */ const EXCLUSIVE_MENTION = 9; const TAG_CHARACTER = [ @@ -31,6 +63,95 @@ 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, + Term::OBJECT_TYPE_POST, + Term::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, + Term::OBJECT_TYPE_POST, + Term::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. @@ -103,9 +224,9 @@ class Term */ public static function insertFromTagFieldByItemId($item_id, $tag_str) { - $profile_base = System::baseUrl(); + $profile_base = DI::baseUrl(); $profile_data = parse_url($profile_base); - $profile_path = defaults($profile_data, 'path', ''); + $profile_path = $profile_data['path'] ?? ''; $profile_base_friendica = $profile_data['host'] . $profile_path . '/profile/'; $profile_base_diaspora = $profile_data['host'] . $profile_path . '/u/'; @@ -320,7 +441,7 @@ class Term 'implicit_mentions' => [], ]; - $searchpath = System::baseUrl() . "/search?tag="; + $searchpath = DI::baseUrl() . "/search?tag="; $taglist = DBA::select( 'term', @@ -342,13 +463,13 @@ class Term $item['body'] = str_replace($orig_tag, $tag['url'], $item['body']); } - $return['hashtags'][] = $prefix . '' . $tag['term'] . ''; - $return['tags'][] = $prefix . '' . $tag['term'] . ''; + $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 . '' . $tag['term'] . ''; - $return['tags'][] = $prefix . '' . $tag['term'] . ''; + $return['mentions'][] = $prefix . '' . htmlspecialchars($tag['term']) . ''; + $return['tags'][] = $prefix . '' . htmlspecialchars($tag['term']) . ''; break; case self::IMPLICIT_MENTION: $return['implicit_mentions'][] = $prefix . $tag['term']; @@ -388,7 +509,7 @@ class Term { $tag_chars = []; foreach ($types as $type) { - if (isset(self::TAG_CHARACTER[$type])) { + if (array_key_exists($type, self::TAG_CHARACTER)) { $tag_chars[] = self::TAG_CHARACTER[$type]; } }