mirror of
https://github.com/friendica/friendica
synced 2026-04-19 18:27:21 +02:00
New field "network" in "contact-relation"
This commit is contained in:
parent
0a3d3ed8dd
commit
c4310ffdab
7 changed files with 120 additions and 128 deletions
22
database.sql
22
database.sql
|
|
@ -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
|
||||
--
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" => [
|
||||
|
|
|
|||
|
|
@ -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"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue