use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\Post;
+use Friendica\Model\Tag;
use Friendica\Model\Verb;
use Friendica\Protocol\Activity;
+use Friendica\Protocol\Relay;
use Friendica\Util\DateTimeFormat;
// Channel
class Engagement
{
+ /**
+ * Store engagement data from an item array
+ *
+ * @param array $item
+ * @return void
+ */
public static function storeFromItem(array $item)
{
- if (!in_array($item['network'], Protocol::FEDERATED)) {
- Logger::debug('No federated network', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'network' => $item['network']]);
+ if (in_array($item['verb'], [Activity::FOLLOW, Activity::VIEW, Activity::READ])) {
+ Logger::debug('Technical activities are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'verb' => $item['verb']]);
return;
}
- if ($item['gravity'] == Item::GRAVITY_PARENT) {
- Logger::debug('Parent posts are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id']]);
- return;
- }
+ $parent = Post::selectFirst(['created', 'owner-id', 'uid', 'private', 'contact-contact-type', 'language'], ['uri-id' => $item['parent-uri-id']]);
- if (($item['uid'] != 0) && ($item['gravity'] == Item::GRAVITY_COMMENT)) {
- Logger::debug('Non public comments are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
+ if ($parent['created'] < DateTimeFormat::utc('now - ' . DI::config()->get('channel', 'engagement_hours') . ' hour')) {
+ Logger::debug('Post is too old', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'created' => $parent['created']]);
return;
}
- if (in_array($item['verb'], [Activity::FOLLOW, Activity::VIEW, Activity::READ])) {
- Logger::debug('Technical activities are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'verb' => $item['verb']]);
- return;
+ $store = ($item['gravity'] != Item::GRAVITY_PARENT);
+
+ if (!$store) {
+ $store = Contact::hasFollowers($parent['owner-id']);
}
- $parent = Post::selectFirst(['created', 'author-id', 'uid', 'private', 'contact-contact-type'], ['uri-id' => $item['parent-uri-id']]);
- if ($parent['private'] != Item::PUBLIC) {
- Logger::debug('Non public posts are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $parent['uid'], 'private' => $parent['private']]);
- return;
+ if (!$store) {
+ $tagList = Relay::getSubscribedTags();
+ foreach (array_column(Tag::getByURIId($item['parent-uri-id'], [Tag::HASHTAG]), 'name') as $tag) {
+ if (in_array($tag, $tagList)) {
+ $store = true;
+ break;
+ }
+ }
}
- if ($parent['created'] < DateTimeFormat::utc('now - ' . DI::config()->get('channel', 'engagement_hours') . ' hour')) {
- Logger::debug('Post is too old', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'created' => $parent['created']]);
- return;
+ $mediatype = self::getMediaType($item['parent-uri-id']);
+
+ if (!$store) {
+ $mediatype = !empty($mediatype);
}
$engagement = [
'uri-id' => $item['parent-uri-id'],
- 'author-id' => $parent['author-id'],
+ 'owner-id' => $parent['owner-id'],
'contact-type' => $parent['contact-contact-type'],
+ 'media-type' => $mediatype,
+ 'language' => $parent['language'],
'created' => $parent['created'],
+ 'restricted' => !in_array($item['network'], Protocol::FEDERATED) || ($parent['private'] != Item::PUBLIC),
'comments' => DBA::count('post', ['parent-uri-id' => $item['parent-uri-id'], 'gravity' => Item::GRAVITY_COMMENT]),
'activities' => DBA::count('post', [
"`parent-uri-id` = ? AND `gravity` = ? AND NOT `vid` IN (?, ?, ?)",
Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW), Verb::getID(Activity::READ)
])
];
- if (($engagement['comments'] == 0) && ($engagement['activities'] == 0)) {
- Logger::debug('No comments nor activities. Engagement not stored', ['fields' => $engagement]);
+ if (!$store && ($engagement['comments'] == 0) && ($engagement['activities'] == 0)) {
+ Logger::debug('No media, follower, subscribed tags, comments or activities. Engagement not stored', ['fields' => $engagement]);
return;
}
$ret = DBA::insert('post-engagement', $engagement, Database::INSERT_UPDATE);
Logger::debug('Engagement stored', ['fields' => $engagement, 'ret' => $ret]);
}
+ private static function getMediaType(int $uri_id): int
+ {
+ $media = Post\Media::getByURIId($uri_id);
+ $type = 0;
+ foreach ($media as $entry) {
+ if ($entry['type'] == Post\Media::IMAGE) {
+ $type = $type | 1;
+ } elseif ($entry['type'] == Post\Media::VIDEO) {
+ $type = $type | 2;
+ } elseif ($entry['type'] == Post\Media::AUDIO) {
+ $type = $type | 4;
+ }
+ }
+ return $type;
+ }
+
+ /**
+ * Expire old engagement data
+ *
+ * @return void
+ */
public static function expire()
{
DBA::delete('post-engagement', ["`created` < ?", DateTimeFormat::utc('now - ' . DI::config()->get('channel', 'engagement_hours') . ' hour')]);