New field "network" in "contact-relation"

This commit is contained in:
Michael 2026-03-12 21:11:57 +00:00
commit c4310ffdab
7 changed files with 120 additions and 128 deletions

View file

@ -557,6 +557,7 @@ CREATE TABLE IF NOT EXISTS `config` (
CREATE TABLE IF NOT EXISTS `contact-relation` (
`cid` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact the related contact had interacted with',
`relation-cid` int unsigned NOT NULL DEFAULT 0 COMMENT 'related contact who had interacted with the contact',
`network` char(4) COMMENT 'The network that is used between these contacts',
`last-interaction` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last interaction by relation-cid on cid',
`follow-updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last update of the contact relationship',
`follows` boolean NOT NULL DEFAULT '0' COMMENT 'if true, relation-cid follows cid',
@ -566,7 +567,7 @@ CREATE TABLE IF NOT EXISTS `contact-relation` (
`relation-thread-score` smallint unsigned COMMENT 'score for interactions of relation-cid on threads of cid',
`post-score` smallint unsigned COMMENT 'score for the amount of posts from cid that can be seen by relation-cid',
PRIMARY KEY(`cid`,`relation-cid`),
INDEX `relation-cid` (`relation-cid`),
INDEX `relation-cid-network` (`relation-cid`,`network`),
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`relation-cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Contact relations';
@ -2190,25 +2191,6 @@ CREATE VIEW `channel-post-view` AS SELECT
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread`.`owner-id`
WHERE NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`;
--
-- VIEW contact-relation-view
--
DROP VIEW IF EXISTS `contact-relation-view`;
CREATE VIEW `contact-relation-view` AS SELECT
`contact-relation`.`cid` AS `cid`,
`contact`.`network` AS `network`,
`contact-relation`.`relation-cid` AS `relation-cid`,
`contact-relation`.`last-interaction` AS `last-interaction`,
`contact-relation`.`follow-updated` AS `follow-updated`,
`contact-relation`.`follows` AS `follows`,
`contact-relation`.`score` AS `score`,
`contact-relation`.`relation-score` AS `relation-score`,
`contact-relation`.`thread-score` AS `thread-score`,
`contact-relation`.`relation-thread-score` AS `relation-thread-score`,
`contact-relation`.`post-score` AS `post-score`
FROM `contact-relation`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `contact-relation`.`cid`;
--
-- VIEW system-channel-post-view
--

View file

@ -8,6 +8,7 @@ Contact relations
| --------------------- | ----------------------------------------------------------------------- | ----------------- | ---- | --- | ------------------- | ----- |
| cid | contact the related contact had interacted with | int unsigned | NO | PRI | 0 | |
| relation-cid | related contact who had interacted with the contact | int unsigned | NO | PRI | 0 | |
| network | The network that is used between these contacts | char(4) | YES | | NULL | |
| last-interaction | Date of the last interaction by relation-cid on cid | datetime | NO | | 0001-01-01 00:00:00 | |
| follow-updated | Date of the last update of the contact relationship | datetime | NO | | 0001-01-01 00:00:00 | |
| follows | if true, relation-cid follows cid | boolean | NO | | 0 | |
@ -19,10 +20,10 @@ Contact relations
## Indexes
| Name | Fields |
| ------------ | ----------------- |
| PRIMARY | cid, relation-cid |
| relation-cid | relation-cid |
| Name | Fields |
| -------------------- | --------------------- |
| PRIMARY | cid, relation-cid |
| relation-cid-network | relation-cid, network |
## Foreign keys

View file

@ -75,30 +75,6 @@ final class Activity
return $activity;
}
/**
* Compute a median-like post score for a contact id.
*
* @param int $cid Contact id.
* @param int $divider Divider to compute the median index.
* @param string $network Optional network filter.
* @return int Median post score.
*/
private function getMedianPostScore(int $cid, int $divider, string $network = ''): int
{
$condition = ["`relation-cid` = ? AND `post-score` > ?", $cid, 0];
$condition = $this->setNetworkFilter($condition, $network);
$limit = $this->database->count('contact-relation-view', $condition) / $divider;
$relation = $this->database->selectToArray('contact-relation-view', ['post-score'], $condition, ['order' => ['post-score' => true], 'limit' => [$limit, 1]]);
$score = $relation[0]['post-score'] ?? 0;
if ($score === 0) {
return 0;
}
$this->logger->debug('Calculated median score', ['cid' => $cid, 'network' => $network, 'divider' => $divider, 'median' => $score, 'condition' => $condition]);
return $score;
}
/**
* Compute median comments for a user's wanted languages.
*
@ -116,9 +92,6 @@ final class Activity
$limit = $this->database->count('post-engagement', $condition) / $divider;
$post = $this->database->selectToArray('post-engagement', ['comments'], $condition, ['order' => ['comments' => true], 'limit' => [$limit, 1]]);
$comments = $post[0]['comments'] ?? 0;
if (empty($comments)) {
return 0;
}
$this->logger->debug('Calculated median comments', ['uid' => $uid, 'network' => $network, 'divider' => $divider, 'median' => $comments, 'condition' => $condition]);
return $comments;
@ -132,7 +105,7 @@ final class Activity
* @param string $network Optional network filter.
* @return int Median activities value.
*/
public function getMedianActivities(int $uid, int $divider, string $network = ''): int
private function getMedianActivities(int $uid, int $divider, string $network = ''): int
{
$condition = ["`contact-type` != ? AND `activities` > ?", Contact::TYPE_COMMUNITY, 0];
$condition = $this->channelRepository->addLanguageCondition($uid, $condition);
@ -141,9 +114,6 @@ final class Activity
$limit = $this->database->count('post-engagement', $condition) / $divider;
$post = $this->database->selectToArray('post-engagement', ['activities'], $condition, ['order' => ['activities' => true], 'limit' => [$limit, 1]]);
$activities = $post[0]['activities'] ?? 0;
if (empty($activities)) {
return 0;
}
$this->logger->debug('Calculated median activities', ['uid' => $uid, 'network' => $network, 'divider' => $divider, 'median' => $activities, 'condition' => $condition]);
return $activities;
@ -166,9 +136,6 @@ final class Activity
$limit = $this->database->count('post-engagement', $condition) / $divider;
$post = $this->database->selectToArray('post-engagement', ['views'], $condition, ['order' => ['views' => true], 'limit' => [$limit, 1]]);
$views = $post[0]['views'] ?? 0;
if (empty($views)) {
return 0;
}
$this->logger->debug('Calculated median views', ['uid' => $uid, 'network' => $network, 'divider' => $divider, 'median' => $views, 'condition' => $condition]);
return $views;
@ -187,12 +154,30 @@ final class Activity
$condition = ["`relation-cid` = ? AND `relation-thread-score` > ?", $cid, 0];
$condition = $this->setNetworkFilter($condition, $network);
$limit = $this->database->count('contact-relation-view', $condition) / $divider;
$relation = $this->database->selectToArray('contact-relation-view', ['relation-thread-score'], $condition, ['order' => ['relation-thread-score' => true], 'limit' => [$limit, 1]]);
$limit = $this->database->count('contact-relation', $condition) / $divider;
$relation = $this->database->selectToArray('contact-relation', ['relation-thread-score'], $condition, ['order' => ['relation-thread-score' => true], 'limit' => [$limit, 1]]);
$score = $relation[0]['relation-thread-score'] ?? 0;
if ($score === 0) {
return 0;
}
$this->logger->debug('Calculated median score', ['cid' => $cid, 'network' => $network, 'divider' => $divider, 'median' => $score, 'condition' => $condition]);
return $score;
}
/**
* Compute a median-like post score for a contact id.
*
* @param int $cid Contact id.
* @param int $divider Divider to compute the median index.
* @param string $network Optional network filter.
* @return int Median post score.
*/
private function getMedianPostScore(int $cid, int $divider, string $network = ''): int
{
$condition = ["`relation-cid` = ? AND `post-score` > ?", $cid, 0];
$condition = $this->setNetworkFilter($condition, $network);
$limit = $this->database->count('contact-relation', $condition) / $divider;
$relation = $this->database->selectToArray('contact-relation', ['post-score'], $condition, ['order' => ['post-score' => true], 'limit' => [$limit, 1]]);
$score = $relation[0]['post-score'] ?? 0;
$this->logger->debug('Calculated median score', ['cid' => $cid, 'network' => $network, 'divider' => $divider, 'median' => $score, 'condition' => $condition]);
return $score;
@ -209,23 +194,20 @@ final class Activity
{
switch ($network) {
case '':
$network_condition = ['network' => Protocol::FEDERATED];
case Protocol::DFRN:
$network_condition = ["(`network` IN (?, ?, ?) OR `network` IS NULL)", Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA];
break;
case Protocol::ACTIVITYPUB:
$network_condition = ['network' => [Protocol::ACTIVITYPUB, Protocol::DFRN]];
break;
case Protocol::DFRN:
$network_condition = ['network' => [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA]];
$network_condition = ["(`network` IN (?, ?) OR `network` IS NULL)", Protocol::ACTIVITYPUB, Protocol::DFRN];
break;
case Protocol::DIASPORA:
$network_condition = ['network' => [Protocol::DFRN, Protocol::DIASPORA]];
$network_condition = ["(`network` IN (?, ?) OR `network` IS NULL)", Protocol::DFRN, Protocol::DIASPORA];
break;
default:
$network_condition = ['network' => $network];
$network_condition = ["(`network` = ? OR `network` IS NULL)", $network];
}
return DBA::mergeConditions($condition, $network_condition);

View file

@ -35,27 +35,39 @@ class Relation
/**
* No discovery of followers/followings
*/
const DISCOVERY_NONE = 0;
public const DISCOVERY_NONE = 0;
/**
* Discover followers/followings of local contacts
*/
const DISCOVERY_LOCAL = 1;
public const DISCOVERY_LOCAL = 1;
/**
* Discover followers/followings of local contacts and contacts that visibly interacted on the system
*/
const DISCOVERY_INTERACTOR = 2;
public const DISCOVERY_INTERACTOR = 2;
/**
* Discover followers/followings of all contacts
*/
const DISCOVERY_ALL = 3;
public const DISCOVERY_ALL = 3;
public static function store(int $target, int $actor, string $interaction_date)
/**
* Store an interaction between two contacts. This is used to keep track of followers and followings and to discover new contacts based on interactions.
*
* @param integer $target
* @param integer $actor
* @param string $interaction_date
* @param string $target_network
* @param string $actor_network
* @return void
*/
public static function store(int $target, int $actor, string $interaction_date, string $target_network, string $actor_network)
{
if ($actor == $target) {
return;
}
DBA::insert('contact-relation', ['last-interaction' => $interaction_date, 'cid' => $target, 'relation-cid' => $actor], Database::INSERT_UPDATE);
$network = self::getInteractionNetwork($target_network, $actor_network, $target, $actor);
DBA::insert('contact-relation', ['last-interaction' => $interaction_date, 'cid' => $target, 'relation-cid' => $actor, 'network' => $network], Database::INSERT_UPDATE);
}
/**
@ -387,12 +399,12 @@ class Relation
$cid,
0,
$uid, Contact::FRIEND, Contact::SHARING,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $uid
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $uid,
],
[
'order' => ['last-item' => true],
'limit' => $totallimit,
]
],
);
while ($contact = DBA::fetch($results)) {
@ -420,7 +432,7 @@ class Relation
AND NOT `uri-id` IN (SELECT `uri-id` FROM `account-suggestion` WHERE `uri-id` = `contact`.`uri-id` AND `uid` = ?)",
$cid, 0, $uid, Contact::FRIEND, Contact::SHARING,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $uid],
['order' => ['last-item' => true], 'limit' => $totallimit]
['order' => ['last-item' => true], 'limit' => $totallimit],
);
while ($contact = DBA::fetch($results)) {
@ -443,7 +455,7 @@ class Relation
AND NOT `uri-id` IN (SELECT `uri-id` FROM `account-suggestion` WHERE `uri-id` = `contact`.`uri-id` AND `uid` = ?)",
$uid, Contact::FOLLOWER, 0,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $uid],
['order' => ['last-item' => true], 'limit' => $totallimit]
['order' => ['last-item' => true], 'limit' => $totallimit],
);
while ($contact = DBA::fetch($results)) {
@ -466,7 +478,7 @@ class Relation
AND NOT `uri-id` IN (SELECT `uri-id` FROM `account-suggestion` WHERE `uri-id` = `contact`.`uri-id` AND `uid` = ?)",
$uid, Contact::FRIEND, Contact::SHARING, 0,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $uid],
['order' => ['last-item' => true], 'limit' => $totallimit]
['order' => ['last-item' => true], 'limit' => $totallimit],
);
while ($contact = DBA::fetch($results)) {
@ -620,7 +632,7 @@ class Relation
$condition1 = DBA::mergeConditions($condition, ["`cid` = ? and `follows`", $cid]);
$condition2 = DBA::mergeConditions($condition, ["`relation-cid` = ? and `follows`", $cid]);
$sql1 = "SELECT `contact`.`id` FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `relation-cid` WHERE " . array_shift($condition1);
$sql2 = "SELECT `contact`.`id` FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " .array_shift($condition2);
$sql2 = "SELECT `contact`.`id` FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " . array_shift($condition2);
$union = array_merge($condition1, $condition2);
$sql = $sql1 . " UNION " . $sql2;
@ -649,7 +661,7 @@ class Relation
$condition1 = DBA::mergeConditions($condition, ["`cid` = ? and `follows`", $cid]);
$condition2 = DBA::mergeConditions($condition, ["`relation-cid` = ? and `follows`", $cid]);
$sql1 = "SELECT `contact`.* FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `relation-cid` WHERE " . array_shift($condition1);
$sql2 = "SELECT `contact`.* FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " .array_shift($condition2);
$sql2 = "SELECT `contact`.* FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " . array_shift($condition2);
$union = array_merge($condition1, $condition2);
$sql = $sql1 . " UNION " . $sql2;
if ($count > 0) {
@ -674,7 +686,7 @@ class Relation
$condition1 = DBA::mergeConditions($condition, ["`relation-cid` = ?", $sourceId]);
$condition2 = DBA::mergeConditions($condition, ["`relation-cid` = ?", $targetId]);
$sql1 = "SELECT `contact`.`id` FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " . array_shift($condition1);
$sql2 = "SELECT `contact`.`id` FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " .array_shift($condition2);
$sql2 = "SELECT `contact`.`id` FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " . array_shift($condition2);
$union = array_merge($condition1, $condition2);
$sql = $sql1 . " INTERSECT " . $sql2;
@ -705,7 +717,7 @@ class Relation
$condition1 = DBA::mergeConditions($condition, ["`relation-cid` = ?", $sourceId]);
$condition2 = DBA::mergeConditions($condition, ["`relation-cid` = ?", $targetId]);
$sql1 = "SELECT `contact`.* FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " . array_shift($condition1);
$sql2 = "SELECT `contact`.* FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " .array_shift($condition2);
$sql2 = "SELECT `contact`.* FROM `contact-relation` INNER JOIN `contact` ON `contact`.`id` = `cid` WHERE " . array_shift($condition2);
$union = array_merge($condition1, $condition2);
$sql = $sql1 . " INTERSECT " . $sql2;
if ($count > 0) {
@ -730,7 +742,7 @@ class Relation
$condition,
['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)
AND `id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)',
$sourceId, $targetId]
$sourceId, $targetId],
);
return DI::dba()->count('contact', $condition);
@ -754,14 +766,14 @@ class Relation
$condition,
["`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)
AND `id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)",
$sourceId, $targetId]
$sourceId, $targetId],
);
return DI::dba()->selectToArray(
'contact',
[],
$condition,
['limit' => [$offset, $count], 'order' => [$shuffle ? 'RAND()' : 'name']]
['limit' => [$offset, $count], 'order' => [$shuffle ? 'RAND()' : 'name']],
);
}
@ -780,7 +792,7 @@ class Relation
$condition,
["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)
AND `id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)",
$sourceId, $targetId]
$sourceId, $targetId],
);
return DI::dba()->count('contact', $condition);
@ -804,14 +816,14 @@ class Relation
$condition,
["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)
AND `id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)",
$sourceId, $targetId]
$sourceId, $targetId],
);
return DI::dba()->selectToArray(
'contact',
[],
$condition,
['limit' => [$offset, $count], 'order' => [$shuffle ? 'RAND()' : 'name']]
['limit' => [$offset, $count], 'order' => [$shuffle ? 'RAND()' : 'name']],
);
}
@ -838,7 +850,7 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
DI::logger()->debug('Calculate relation-score', ['uid' => $uid, 'total' => $total['activity']]);
@ -853,10 +865,10 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
while ($interaction = DBA::fetch($interactions)) {
$score = min((int)(($interaction['activity'] / $total['activity']) * 65535), 65535);
$score = min((int) (($interaction['activity'] / $total['activity']) * 65535), 65535);
DBA::update('contact-relation', ['relation-score' => $score, 'follows' => $interaction['follows']], ['relation-cid' => $contact_id, 'cid' => $interaction['author-id']]);
}
DBA::close($interactions);
@ -867,7 +879,7 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
DI::logger()->debug('Calculate relation-thread-score', ['uid' => $uid, 'total' => $total['activity']]);
@ -882,10 +894,10 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
while ($interaction = DBA::fetch($interactions)) {
$score = min((int)(($interaction['activity'] / $total['activity']) * 65535), 65535);
$score = min((int) (($interaction['activity'] / $total['activity']) * 65535), 65535);
DBA::update('contact-relation', ['relation-thread-score' => $score, 'follows' => !empty($interaction['follows'])], ['relation-cid' => $contact_id, 'cid' => $interaction['author-id']]);
}
DBA::close($interactions);
@ -896,7 +908,7 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
DI::logger()->debug('Calculate score', ['uid' => $uid, 'total' => $total['activity']]);
@ -907,10 +919,10 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
while ($interaction = DBA::fetch($interactions)) {
$score = min((int)(($interaction['activity'] / $total['activity']) * 65535), 65535);
$score = min((int) (($interaction['activity'] / $total['activity']) * 65535), 65535);
DBA::update('contact-relation', ['score' => $score], ['relation-cid' => $contact_id, 'cid' => $interaction['author-id']]);
}
DBA::close($interactions);
@ -921,7 +933,7 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
DI::logger()->debug('Calculate thread-score', ['uid' => $uid, 'total' => $total['activity']]);
@ -932,10 +944,10 @@ class Relation
DateTimeFormat::utc('now - ' . $days . ' day'),
$uid,
$contact_id,
$follow
$follow,
);
while ($interaction = DBA::fetch($interactions)) {
$score = min((int)(($interaction['activity'] / $total['activity']) * 65535), 65535);
$score = min((int) (($interaction['activity'] / $total['activity']) * 65535), 65535);
DBA::update('contact-relation', ['thread-score' => $score], ['relation-cid' => $contact_id, 'cid' => $interaction['author-id']]);
}
DBA::close($interactions);
@ -944,7 +956,7 @@ class Relation
"SELECT count(*) AS `posts` FROM `post-thread-user` WHERE EXISTS(SELECT `cid` FROM `contact-relation` WHERE `cid` = `post-thread-user`.`author-id` AND `relation-cid` = ? AND `follows`) AND `uid` = ? AND `created` > ?",
$contact_id,
$uid,
DateTimeFormat::utc('now - ' . $days . ' day')
DateTimeFormat::utc('now - ' . $days . ' day'),
);
DI::logger()->debug('Calculate post-score', ['uid' => $uid, 'total' => $total['posts']]);
@ -953,14 +965,45 @@ class Relation
"SELECT `author-id`, count(*) AS `posts` FROM `post-thread-user` WHERE EXISTS(SELECT `cid` FROM `contact-relation` WHERE `cid` = `post-thread-user`.`author-id` AND `relation-cid` = ? AND `follows`) AND `uid` = ? AND `created` > ? GROUP BY `author-id`",
$contact_id,
$uid,
DateTimeFormat::utc('now - ' . $days . ' day')
DateTimeFormat::utc('now - ' . $days . ' day'),
);
while ($post = DBA::fetch($posts)) {
$score = min((int)(($post['posts'] / $total['posts']) * 65535), 65535);
$score = min((int) (($post['posts'] / $total['posts']) * 65535), 65535);
DBA::update('contact-relation', ['post-score' => $score], ['relation-cid' => $contact_id, 'cid' => $post['author-id']]);
}
DBA::close($posts);
DI::logger()->debug('Calculation - end', ['uid' => $uid]);
}
/**
* Get the network that should be used for interactions between two contacts based on their network.
*
* @param string $target_network The network of the target contact
* @param string $actor_network The network of the actor contact
* @param int $target The contact id of the target contact
* @param int $actor The contact id of the actor contact
* @return string|null The network that should be used for interactions between the two contacts, or null if no suitable network is found
*/
public static function getInteractionNetwork(string $target_network, string $actor_network, int $target, int $actor): ?string
{
$target_network = $target_network === Protocol::DFRN ? Protocol::ACTIVITYPUB : $target_network;
$actor_network = $actor_network === Protocol::DFRN ? Protocol::ACTIVITYPUB : $actor_network;
if (!in_array($target_network, Protocol::FEDERATED)) {
$network = $target_network;
} elseif (!in_array($actor_network, Protocol::FEDERATED)) {
$network = $actor_network;
} elseif ($target_network === $actor_network) {
$network = $actor_network;
} elseif ($actor_network === Protocol::DIASPORA) {
$network = $actor_network;
} elseif ($target_network === Protocol::DIASPORA) {
$network = $target_network;
} else {
$network = null;
DI::logger()->warning('Unhandled network relation', ['target' => $target_network, 'actor' => $actor_network, 'tcid' => $target, 'acid' => $actor]);
}
return $network;
}
}

View file

@ -264,7 +264,7 @@ final class ItemHelper
'uid', 'uri', 'parent-uri', 'id', 'deleted',
'uri-id', 'parent-uri-id', 'restrictions', 'verb',
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
'wall', 'private', 'origin', 'author-id',
'wall', 'private', 'origin', 'author-id', 'network',
];
$uids = $item['verb'] === Activity::VIEW ? [0, $item['uid']] : $item['uid'];
@ -363,7 +363,7 @@ final class ItemHelper
}
// Update the contact relations
Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']);
Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created'], $toplevel_parent['network'], $item['network']);
return $item;
}

View file

@ -602,6 +602,7 @@ return [
"fields" => [
"cid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "primary" => "1", "comment" => "contact the related contact had interacted with"],
"relation-cid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "primary" => "1", "comment" => "related contact who had interacted with the contact"],
"network" => ["type" => "char(4)", "comment" => "The network that is used between these contacts"],
"last-interaction" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last interaction by relation-cid on cid"],
"follow-updated" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last update of the contact relationship"],
"follows" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "if true, relation-cid follows cid"],
@ -612,8 +613,8 @@ return [
"post-score" => ["type" => "smallint unsigned", "comment" => "score for the amount of posts from cid that can be seen by relation-cid"],
],
"indexes" => [
"PRIMARY" => ["cid", "relation-cid"],
"relation-cid" => ["relation-cid"],
"PRIMARY" => ["cid", "relation-cid"],
"relation-cid-network" => ["relation-cid", "network"],
],
],
"conv" => [

View file

@ -76,23 +76,6 @@ return [
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread`.`owner-id`
WHERE NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`",
],
"contact-relation-view" => [
"fields" => [
"cid" => ["contact-relation", "cid"],
"network" => ["contact", "network"],
"relation-cid" => ["contact-relation", "relation-cid"],
"last-interaction" => ["contact-relation", "last-interaction"],
"follow-updated" => ["contact-relation", "follow-updated"],
"follows" => ["contact-relation", "follows"],
"score" => ["contact-relation", "score"],
"relation-score" => ["contact-relation", "relation-score"],
"thread-score" => ["contact-relation", "thread-score"],
"relation-thread-score" => ["contact-relation", "relation-thread-score"],
"post-score" => ["contact-relation", "post-score"],
],
"query" => "FROM `contact-relation`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `contact-relation`.`cid`",
],
"system-channel-post-view" => [
"fields" => [
"channel" => ["system-channel-post", "channel"],