X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FTag.php;h=0e891f9c6f27870e314aa75a7b8e74329f3e94ff;hb=31693c2d1f749d744964eee0b0fe79db589fac2c;hp=c7dbbb336b42c637f9564f403c69cfe4c5919d44;hpb=2f3705f47101fceeb340bfbe1ab415edbfe441fe;p=friendica.git diff --git a/src/Model/Tag.php b/src/Model/Tag.php index c7dbbb336b..0e891f9c6f 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -1,6 +1,6 @@ $url]); if (!empty($tag)) { if ($tag['name'] != substr($name, 0, 96)) { - DBA::update('tag', ['name' => substr($name, 0, 96)], ['url' => $url]); + DBA::update('tag', ['name' => substr($name, 0, 96)], ['url' => $url, 'type' => $tag['type']]); } if (!empty($target) && ($tag['type'] != $target)) { DBA::update('tag', ['type' => $target], ['url' => $url]); @@ -156,7 +157,7 @@ class Tag DBA::insert('post-tag', $fields, Database::INSERT_IGNORE); - Logger::info('Stored tag/mention', ['uri-id' => $uriId, 'tag-id' => $tagid, 'contact-id' => $cid, 'name' => $name, 'type' => $type, 'callstack' => System::callstack(8)]); + Logger::debug('Stored tag/mention', ['uri-id' => $uriId, 'tag-id' => $tagid, 'contact-id' => $cid, 'name' => $name, 'type' => $type, 'callstack' => System::callstack(8)]); } /** @@ -217,7 +218,7 @@ class Tag * Get a tag id for a given tag name and URL * * @param string $name Name of tag - * @param string $url URL + * @param string $url * @param int $type Type of tag * @return int Tag id */ @@ -243,9 +244,8 @@ class Tag return $tid; } - // Also log type and tag id + // Also log type $fields['type'] = $type; - $fields['tid'] = $tid; Logger::error('No tag id created', $fields); return 0; @@ -254,21 +254,20 @@ class Tag /** * Store tag/mention elements * - * @param integer $uriId URI id - * @param string $hash Hash - * @param string $name Name - * @param string $url URL - * @param boolean $probing Whether probing is active + * @param integer $uriId + * @param string $hash + * @param string $name + * @param string $url * @return void */ - public static function storeByHash(int $uriId, string $hash, string $name, string $url = '', bool $probing = true) + public static function storeByHash(int $uriId, string $hash, string $name, string $url = '') { $type = self::getTypeForHash($hash); if ($type == self::UNKNOWN) { return; } - self::store($uriId, $type, $name, $url, $probing); + self::store($uriId, $type, $name, $url); } /** @@ -298,34 +297,39 @@ class Tag * @param integer $uriId URI-Id * @param string $body Body of the post * @param string $tags Accepted tags - * @param boolean $probing Perform a probing for contacts, adding them if needed * @return void */ - public static function storeFromBody(int $uriId, string $body, string $tags = null, bool $probing = true) + public static function storeFromBody(int $uriId, string $body, string $tags = null) + { + $item = ['uri-id' => $uriId, 'body' => $body, 'quote-uri-id' => null]; + self::storeFromArray($item, $tags); + } + + /** + * Store tags and mentions from the item array + * + * @param array $item Item array + * @param string $tags Accepted tags + * @return void + */ + public static function storeFromArray(array $item, string $tags = null) { - Logger::info('Check for tags', ['uri-id' => $uriId, 'hash' => $tags, 'callstack' => System::callstack()]); + Logger::info('Check for tags', ['uri-id' => $item['uri-id'], 'hash' => $tags, 'callstack' => System::callstack()]); if (is_null($tags)) { $tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION]; } - // Only remove the shared data from "real" reshares - $shared = BBCode::fetchShareAttributes($body); - if (!empty($shared['guid'])) { - if (preg_match("/\s*\[share .*?\](.*?)\[\/share\]\s*/ism", $body, $matches)) { - $share_body = $matches[1]; - } - $body = preg_replace("/\s*\[share .*?\].*?\[\/share\]\s*/ism", '', $body); + foreach (self::getFromBody($item['body'], $tags) as $tag) { + self::storeByHash($item['uri-id'], $tag[1], $tag[3], $tag[2]); } - foreach (self::getFromBody($body, $tags) as $tag) { - self::storeByHash($uriId, $tag[1], $tag[3], $tag[2], $probing); - } + $shared = DI::contentItem()->getSharedPost($item, ['uri-id']); // Search for hashtags in the shared body (but only if hashtags are wanted) - if (!empty($share_body) && (strpos($tags, self::TAG_CHARACTER[self::HASHTAG]) !== false)) { - foreach (self::getFromBody($share_body, self::TAG_CHARACTER[self::HASHTAG]) as $tag) { - self::storeByHash($uriId, $tag[1], $tag[3], $tag[2], $probing); + if (!empty($shared) && (strpos($tags, self::TAG_CHARACTER[self::HASHTAG]) !== false)) { + foreach (self::getByURIId($shared['post']['uri-id'], [self::HASHTAG]) as $tag) { + self::store($item['uri-id'], $tag['type'], $tag['name'], $tag['url']); } } } @@ -372,7 +376,7 @@ class Tag /** * Remove tag/mention * - * @param integer $uriId URI id + * @param integer $uriId * @param integer $type Type * @param string $name Name * @param string $url URL @@ -390,17 +394,17 @@ class Tag return; } - Logger::info('Removing tag/mention', ['uri-id' => $uriId, 'tid' => $tag['tid'], 'name' => $name, 'url' => $url, 'callstack' => System::callstack(8)]); + Logger::debug('Removing tag/mention', ['uri-id' => $uriId, 'tid' => $tag['tid'], 'name' => $name, 'url' => $url, 'callstack' => System::callstack(8)]); DBA::delete('post-tag', ['uri-id' => $uriId, 'type' => $type, 'tid' => $tag['tid'], 'cid' => $tag['cid']]); } /** * Remove tag/mention * - * @param integer $uriId URI id - * @param string $hash Hash - * @param string $name Name - * @param string $url URL + * @param integer $uriId + * @param string $hash + * @param string $name + * @param string $url * @return void */ public static function removeByHash(int $uriId, string $hash, string $name, string $url = '') @@ -416,7 +420,7 @@ class Tag /** * Get the type for the given hash * - * @param string $hash Hash + * @param string $hash * @return integer Tag type */ private static function getTypeForHash(string $hash): int @@ -437,8 +441,8 @@ class Tag /** * Create implicit mentions for a given post * - * @param integer $uriId URI Id - * @param integer $parentUriId Parent URI id + * @param integer $uriId + * @param integer $parentUriId * @return void */ public static function createImplicitMentions(int $uriId, int $parentUriId) @@ -461,7 +465,7 @@ class Tag /** * Retrieves the terms from the provided type(s) associated with the provided item ID. * - * @param int $uriId URI id + * @param int $uriId * @param array $type Tag type(s) * @return array|bool Array on success, false on error * @throws \Exception @@ -472,10 +476,30 @@ class Tag return DBA::selectToArray('tag-view', ['type', 'name', 'url', 'tag-type'], $condition); } + /** + * Checks if the given url is mentioned in the post + * + * @param integer $uriId + * @param string $url + * @param array $type + * + * @return boolean + */ + public static function isMentioned(int $uriId, string $url, array $type = [self::MENTION, self::EXCLUSIVE_MENTION]): bool + { + $tags = self::getByURIId($uriId, $type); + foreach ($tags as $tag) { + if (Strings::compareLink($url, $tag['url'])) { + return true; + } + } + return false; + } + /** * Return a string with all tags and mentions * - * @param integer $uriId URI id + * @param integer $uriId * @param array $type Tag type(s) * @return string tags and mentions * @throws \Exception @@ -510,8 +534,11 @@ class Tag $searchpath = DI::baseUrl() . '/search?tag='; - $taglist = DBA::select('tag-view', ['type', 'name', 'url', 'cid'], - ['uri-id' => $item['uri-id'], 'type' => [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]); + $taglist = DBA::select( + 'tag-view', + ['type', 'name', 'url', 'cid'], + ['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']); @@ -520,7 +547,7 @@ class Tag $orig_tag = $tag['url']; $prefix = self::TAG_CHARACTER[$tag['type']]; - switch($tag['type']) { + switch ($tag['type']) { case self::HASHTAG: if ($orig_tag != $tag['url']) { $item['body'] = str_replace($orig_tag, $tag['url'], $item['body']); @@ -546,7 +573,7 @@ class Tag break; default: - Logger:warning('Unknown tag type found', $tag); + Logger::warning('Unknown tag type found', $tag); } } DBA::close($taglist); @@ -565,15 +592,8 @@ class Tag { $condition = ["`name` = ? AND (`uid` = ? OR (`uid` = ? AND NOT `global`)) AND (`network` IN (?, ?, ?, ?) OR (`uid` = ? AND `uid` != ?))", - $search, - 0, - $uid, - Protocol::ACTIVITYPUB, - Protocol::DFRN, - Protocol::DIASPORA, - Protocol::OSTATUS, - $uid, - 0, + $search, 0, $uid, + Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, $uid, 0, ]; return DBA::count('tag-search-view', $condition); @@ -593,15 +613,8 @@ class Tag { $condition = ["`name` = ? AND (`uid` = ? OR (`uid` = ? AND NOT `global`)) AND (`network` IN (?, ?, ?, ?) OR (`uid` = ? AND `uid` != ?))", - $search, - 0, - $uid, - Protocol::ACTIVITYPUB, - Protocol::DFRN, - Protocol::DIASPORA, - Protocol::OSTATUS, - $uid, - 0, + $search, 0, $uid, + Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, $uid, 0, ]; if (!empty($last_uriid)) { @@ -629,17 +642,17 @@ class Tag * * @param int $period Period in hours to consider posts * @param int $limit Number of returned tags + * @param int $offset Page offset in results * @return array * @throws \Exception */ - public static function getGlobalTrendingHashtags(int $period, $limit = 10): array + public static function getGlobalTrendingHashtags(int $period, int $limit = 10, int $offset = 0): array { - $tags = DI::cache()->get('global_trending_tags-' . $period . '-' . $limit); - if (!empty($tags)) { - return $tags; - } else { - return self::setGlobalTrendingHashtags($period, $limit); + $tags = DI::cache()->get("global_trending_tags-$period"); + if (empty($tags)) { + $tags = self::setGlobalTrendingHashtags($period, 1000); } + return array_slice($tags, $offset, $limit); } /** @@ -655,7 +668,9 @@ class Tag } $blocked = explode(',', $blocked_txt); - array_walk($blocked, function(&$value) { $value = "'" . DBA::escape(trim($value)) . "'";}); + array_walk($blocked, function (&$value) { + $value = "'" . DBA::escape(trim($value)) . "'"; + }); return ' AND NOT `name` IN (' . implode(',', $blocked) . ')'; } @@ -673,8 +688,11 @@ class Tag * Get a uri-id that is at least X hours old. * We use the uri-id in the query for the hash tags since this is much faster */ - $post = Post::selectFirstThread(['uri-id'], ["`uid` = ? AND `received` < ?", 0, DateTimeFormat::utc('now - ' . $period . ' hour')], - ['order' => ['received' => true]]); + $post = Post::selectFirstThread( + ['uri-id'], + ["`uid` = ? AND `received` < ?", 0, DateTimeFormat::utc('now - ' . $period . ' hour')], + ['order' => ['received' => true]] + ); if (empty($post['uri-id'])) { return []; @@ -682,7 +700,8 @@ class Tag $block_sql = self::getBlockedSQL(); - $tagsStmt = DBA::p("SELECT `name` AS `term`, COUNT(*) AS `score`, COUNT(DISTINCT(`author-id`)) as `authors` + $tagsStmt = DBA::p( + "SELECT `name` AS `term`, COUNT(*) AS `score`, COUNT(DISTINCT(`author-id`)) as `authors` FROM `tag-search-view` WHERE `private` = ? AND `uid` = ? AND `uri-id` > ? $block_sql GROUP BY `term` ORDER BY `authors` DESC, `score` DESC LIMIT ?", @@ -694,7 +713,7 @@ class Tag if (DBA::isResult($tagsStmt)) { $tags = DBA::toArray($tagsStmt); - DI::cache()->set('global_trending_tags-' . $period . '-' . $limit, $tags, Duration::DAY); + DI::cache()->set("global_trending_tags-$period", $tags, Duration::HOUR); return $tags; } @@ -706,17 +725,17 @@ class Tag * * @param int $period Period in hours to consider posts * @param int $limit Number of returned tags + * @param int $offset Page offset in results * @return array * @throws \Exception */ - public static function getLocalTrendingHashtags(int $period, $limit = 10): array + public static function getLocalTrendingHashtags(int $period, $limit = 10, int $offset = 0): array { - $tags = DI::cache()->get('local_trending_tags-' . $period . '-' . $limit); - if (!empty($tags)) { - return $tags; - } else { - return self::setLocalTrendingHashtags($period, $limit); + $tags = DI::cache()->get("local_trending_tags-$period"); + if (empty($tags)) { + $tags = self::setLocalTrendingHashtags($period, 1000); } + return array_slice($tags, $offset, $limit); } /** @@ -731,15 +750,19 @@ class Tag { // Get a uri-id that is at least X hours old. // We use the uri-id in the query for the hash tags since this is much faster - $post = Post::selectFirstThread(['uri-id'], ["`uid` = ? AND `received` < ?", 0, DateTimeFormat::utc('now - ' . $period . ' hour')], - ['order' => ['received' => true]]); + $post = Post::selectFirstThread( + ['uri-id'], + ["`uid` = ? AND `received` < ?", 0, DateTimeFormat::utc('now - ' . $period . ' hour')], + ['order' => ['received' => true]] + ); if (empty($post['uri-id'])) { return []; } $block_sql = self::getBlockedSQL(); - $tagsStmt = DBA::p("SELECT `name` AS `term`, COUNT(*) AS `score`, COUNT(DISTINCT(`author-id`)) as `authors` + $tagsStmt = DBA::p( + "SELECT `name` AS `term`, COUNT(*) AS `score`, COUNT(DISTINCT(`author-id`)) as `authors` FROM `tag-search-view` WHERE `private` = ? AND `wall` AND `origin` AND `uri-id` > ? $block_sql GROUP BY `term` ORDER BY `authors` DESC, `score` DESC LIMIT ?", @@ -750,7 +773,7 @@ class Tag if (DBA::isResult($tagsStmt)) { $tags = DBA::toArray($tagsStmt); - DI::cache()->set('local_trending_tags-' . $period . '-' . $limit, $tags, Duration::DAY); + DI::cache()->set("local_trending_tags-$period", $tags, Duration::HOUR); return $tags; } @@ -797,7 +820,7 @@ class Tag /** * Fetch user who subscribed to the tags of the given item * - * @param integer $uriId URI Id + * @param integer $uriId * @return array User list */ public static function getUIDListByURIId(int $uriId): array