mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-19 01:35:12 +00:00
addressing refactor
This commit is contained in:
parent
806b7a65b0
commit
9067a31939
4 changed files with 117 additions and 158 deletions
|
@ -447,7 +447,7 @@ function contact_remove($channel_id, $abook_id, $atoken_sync = false)
|
|||
|
||||
Hook::call('connection_remove', $x);
|
||||
|
||||
$archive = get_pconfig($channel_id, 'system', 'archive_removed_contacts');
|
||||
$archive = get_pconfig($channel_id, 'system', 'archive_removed_contacts', true);
|
||||
if ($archive) {
|
||||
q(
|
||||
"update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d",
|
||||
|
|
|
@ -145,6 +145,10 @@ define ( 'CLIENT_MODE_UPDATE', 0x0002);
|
|||
define ('AUDIENCE_SENDER', 0x0001);
|
||||
define ('AUDIENCE_CONVERSATION', 0x0002);
|
||||
define ('AUDIENCE_FOLLOWERS', 0x0004);
|
||||
define ('AUDIENCE_PUBLIC', 0x0008);
|
||||
define ('AUDIENCE_UNLISTED', 0x0010);
|
||||
define ('AUDIENCE_MENTIONS', 0x0020);
|
||||
define ('AUDIENCE_SERVER', 0x0040);
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -2636,6 +2636,11 @@ function ids_to_querystr($arr, $idx = 'id', $quote = false)
|
|||
return(implode(',', $t));
|
||||
}
|
||||
|
||||
function array_merge_clean($array1, $array2)
|
||||
{
|
||||
return array_values(array_unique(array_merge($array1, $array2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief array_elm_to_str($arr,$elm,$delim = ',') extract unique individual elements from an array of arrays and return them as a string separated by a delimiter
|
||||
* similar to ids_to_querystr, but allows a different delimiter instead of a db-quote option
|
||||
|
|
|
@ -951,12 +951,6 @@ class Activity
|
|||
$activity['inReplyTo'] = set_activity_mid($item['thr_parent']);
|
||||
}
|
||||
|
||||
// @FIXME FEP-5624 set for comment approvals but not event approvals
|
||||
// For comment approvals and rejections
|
||||
// if (in_array($activity['type'], ['Accept','Reject']) && is_string($item['obj']) && strlen($item['obj'])) {
|
||||
// $activity['inReplyTo'] = $item['thr_parent'];
|
||||
// }
|
||||
|
||||
$cnv = get_iconfig($item['parent'], 'activitypub', 'context');
|
||||
if (!$cnv) {
|
||||
$cnv = $item['parent_mid'];
|
||||
|
@ -1087,89 +1081,7 @@ class Activity
|
|||
}
|
||||
}
|
||||
|
||||
// addressing madness
|
||||
|
||||
$audience = self::getAudienceFromItem($item);
|
||||
$mentions = self::map_mentions($item);
|
||||
|
||||
if ($activitypub) {
|
||||
$parent_i = [];
|
||||
$public = !$item['item_private'];
|
||||
$top_level = ($item['mid'] === $item['parent_mid']);
|
||||
$activity['to'] = [];
|
||||
$activity['cc'] = [];
|
||||
|
||||
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
|
||||
if ($recips) {
|
||||
$parent_i['to'] = $recips['to'];
|
||||
$parent_i['cc'] = $recips['cc'];
|
||||
}
|
||||
|
||||
if ($public) {
|
||||
$activity['to'] = [ACTIVITY_PUBLIC_INBOX];
|
||||
if (isset($parent_i['to']) && is_array($parent_i['to'])) {
|
||||
$activity['to'] = array_values(array_unique(array_merge($activity['to'], $parent_i['to'])));
|
||||
}
|
||||
if ($item['item_origin']) {
|
||||
$activity['cc'] = [z_root() . '/followers/' . substr($item['author']['xchan_addr'], 0, strpos($item['author']['xchan_addr'], '@'))];
|
||||
}
|
||||
if (isset($parent_i['cc']) && is_array($parent_i['cc'])) {
|
||||
$activity['cc'] = array_values(array_unique(array_merge($activity['cc'], $parent_i['cc'])));
|
||||
}
|
||||
} else {
|
||||
// private activity
|
||||
if ($top_level) {
|
||||
$activity['to'] = self::map_acl($item);
|
||||
if (isset($parent_i['to']) && is_array($parent_i['to'])) {
|
||||
$activity['to'] = array_values(array_unique(array_merge($activity['to'], $parent_i['to'])));
|
||||
}
|
||||
} elseif ((int)$item['item_private'] === 1) {
|
||||
if (($audience & AUDIENCE_FOLLOWERS) && $item['item_origin']) {
|
||||
$activity['to'] = [z_root() . '/followers/' . substr($item['author']['xchan_addr'], 0, strpos($item['author']['xchan_addr'], '@'))];
|
||||
}
|
||||
else {
|
||||
$activity['cc'] = self::map_acl($item);
|
||||
if (isset($parent_i['cc']) && is_array($parent_i['cc'])) {
|
||||
$activity['cc'] = array_values(array_unique(array_merge($activity['cc'], $parent_i['cc'])));
|
||||
}
|
||||
|
||||
$d = q(
|
||||
"select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d and hubloc_deleted = 0 order by hubloc_id desc limit 1",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
if ($d) {
|
||||
if ($d[0]['hubloc_network'] === 'activitypub') {
|
||||
$addr = $d[0]['hubloc_hash'];
|
||||
} else {
|
||||
$addr = $d[0]['hubloc_id_url'];
|
||||
}
|
||||
$activity['cc'][] = $addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($mentions) > 0) {
|
||||
if (!$activity['to']) {
|
||||
$activity['to'] = $mentions;
|
||||
} else {
|
||||
$activity['cc'] = array_values(array_unique(array_merge($activity['cc'], $mentions)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cc = [];
|
||||
if ($activity['cc'] && is_array($activity['cc'])) {
|
||||
foreach ($activity['cc'] as $e) {
|
||||
if (!is_array($activity['to'])) {
|
||||
$cc[] = $e;
|
||||
} elseif (!in_array($e, $activity['to'])) {
|
||||
$cc[] = $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
$activity['cc'] = $cc;
|
||||
$activity = self::encodeAddressing($activity, $item);
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
@ -1462,91 +1374,113 @@ class Activity
|
|||
}
|
||||
}
|
||||
|
||||
// addressing madness
|
||||
$activity = self::encodeAddressing($activity, $item);
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
public static function encodeAddressing($activity,$item)
|
||||
{
|
||||
/*
|
||||
* addressing madness
|
||||
*
|
||||
* For what it's worth, Mastodon’s visibility scopes are a custom thing and this is generally how they map:
|
||||
* public = to: [public], cc: [followers, mentions]
|
||||
* unlisted = cc: [public, followers, mentions]
|
||||
* followers-only = to: [followers], cc: [mentions]
|
||||
* direct = to: [mentions]
|
||||
*
|
||||
* This software does not normally use the same mappings - and doesn't even require mappings;
|
||||
* but the Mastodon mappings may need to be considered so that private audiences are not mis-identified
|
||||
* when communicating with people using that software.
|
||||
*/
|
||||
|
||||
$channel = Channel::from_id($item['uid']); // needed in future for nomadic follower addressing
|
||||
$audience = self::getAudienceFromItem($item);
|
||||
$mentions = self::map_mentions($item);
|
||||
$followers = [z_root() . '/followers/' . substr($item['author']['xchan_addr'], 0, strpos($item['author']['xchan_addr'], '@'))];
|
||||
|
||||
if ($activitypub) {
|
||||
$parent_i = [];
|
||||
$activity['to'] = [];
|
||||
$activity['cc'] = [];
|
||||
$parent_i = [];
|
||||
$activity['to'] = [];
|
||||
$activity['cc'] = [];
|
||||
|
||||
$public = !$item['item_private'];
|
||||
$top_level = $item['mid'] === $item['parent_mid'];
|
||||
$public = !$item['item_private'];
|
||||
$top_level = $item['mid'] === $item['parent_mid'];
|
||||
|
||||
if (!$top_level) {
|
||||
if (intval($item['parent'])) {
|
||||
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
|
||||
if (!$top_level) {
|
||||
if (intval($item['parent'])) {
|
||||
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
|
||||
} else {
|
||||
// if we are encoding this item prior to storage there won't be a parent.
|
||||
$p = q(
|
||||
"select parent from item where parent_mid = '%s' and uid = %d",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
if ($p) {
|
||||
$recips = get_iconfig($p[0]['parent'], 'activitypub', 'recips');
|
||||
}
|
||||
}
|
||||
if ($recips) {
|
||||
$parent_i['to'] = $recips['to'];
|
||||
$parent_i['cc'] = $recips['cc'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($public) {
|
||||
$activity['to'] = [ACTIVITY_PUBLIC_INBOX];
|
||||
if (isset($parent_i['to']) && is_array($parent_i['to'])) {
|
||||
$activity['to'] = array_merge_clean($activity['to'], $parent_i['to']);
|
||||
}
|
||||
if ($item['item_origin']) {
|
||||
$activity['cc'] = $followers;
|
||||
}
|
||||
if (isset($parent_i['cc']) && is_array($parent_i['cc'])) {
|
||||
$activity['cc'] = array_merge_clean($activity['cc'], $parent_i['cc']);
|
||||
}
|
||||
} else {
|
||||
// private activity
|
||||
if ($top_level) {
|
||||
$activity['to'] = self::map_acl($item);
|
||||
if (isset($parent_i['to']) && is_array($parent_i['to'])) {
|
||||
$activity['to'] = array_merge_clean($activity['to'], $parent_i['to']);
|
||||
}
|
||||
} elseif ((int)$item['item_private'] === 1) {
|
||||
if (($audience & AUDIENCE_FOLLOWERS) && $item['item_origin']) {
|
||||
$activity['to'] = $followers;
|
||||
} else {
|
||||
// if we are encoding this item prior to storage there won't be a parent.
|
||||
$p = q(
|
||||
"select parent from item where parent_mid = '%s' and uid = %d",
|
||||
$activity['cc'] = self::map_acl($item);
|
||||
if (isset($parent_i['cc']) && is_array($parent_i['cc'])) {
|
||||
$activity['cc'] = array_merge_clean($activity['cc'], $parent_i['cc']);
|
||||
}
|
||||
|
||||
$d = q(
|
||||
"select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d and hubloc_deleted = 0 order by hubloc_id desc limit 1",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
if ($p) {
|
||||
$recips = get_iconfig($p[0]['parent'], 'activitypub', 'recips');
|
||||
}
|
||||
}
|
||||
if ($recips) {
|
||||
$parent_i['to'] = $recips['to'];
|
||||
$parent_i['cc'] = $recips['cc'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($public) {
|
||||
$activity['to'] = [ACTIVITY_PUBLIC_INBOX];
|
||||
if (isset($parent_i['to']) && is_array($parent_i['to'])) {
|
||||
$activity['to'] = array_values(array_unique(array_merge($activity['to'], $parent_i['to'])));
|
||||
}
|
||||
if ($item['item_origin']) {
|
||||
$activity['cc'] = [z_root() . '/followers/' . substr($item['author']['xchan_addr'], 0, strpos($item['author']['xchan_addr'], '@'))];
|
||||
}
|
||||
if (isset($parent_i['cc']) && is_array($parent_i['cc'])) {
|
||||
$activity['cc'] = array_values(array_unique(array_merge($activity['cc'], $parent_i['cc'])));
|
||||
}
|
||||
} else {
|
||||
// private activity
|
||||
|
||||
if ($top_level) {
|
||||
$activity['to'] = self::map_acl($item);
|
||||
if (isset($parent_i['to']) && is_array($parent_i['to'])) {
|
||||
$activity['to'] = array_values(array_unique(array_merge($activity['to'], $parent_i['to'])));
|
||||
}
|
||||
} elseif ((int)$item['item_private'] === 1) {
|
||||
if (($audience & AUDIENCE_FOLLOWERS) && $item['item_origin']) {
|
||||
$activity['to'] = [z_root() . '/followers/' . substr($item['author']['xchan_addr'], 0, strpos($item['author']['xchan_addr'], '@'))];
|
||||
}
|
||||
else {
|
||||
$activity['cc'] = self::map_acl($item);
|
||||
if (isset($parent_i['cc']) && is_array($parent_i['cc'])) {
|
||||
$activity['cc'] = array_values(array_unique(array_merge($activity['cc'], $parent_i['cc'])));
|
||||
}
|
||||
|
||||
$d = q(
|
||||
"select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.parent_mid = '%s' and item.uid = %d and hubloc_deleted = 0 order by hubloc_id desc limit 1",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
|
||||
if ($d) {
|
||||
if ($d[0]['hubloc_network'] === 'activitypub') {
|
||||
$addr = $d[0]['hubloc_hash'];
|
||||
} else {
|
||||
$addr = $d[0]['hubloc_id_url'];
|
||||
}
|
||||
$activity['cc'][] = $addr;
|
||||
if ($d) {
|
||||
if (in_array($d[0]['hubloc_network'], ['activitypub', 'apnomadic'])) {
|
||||
$addr = $d[0]['hubloc_hash'];
|
||||
} else {
|
||||
$addr = $d[0]['hubloc_id_url'];
|
||||
}
|
||||
$activity['cc'][] = $addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($mentions) > 0) {
|
||||
// Delivery is controlled by parent ACL when AUDIENCE_CONVERSATION is in effect -
|
||||
// and mentions are ignored.
|
||||
|
||||
if ((!$audience) || !($audience & AUDIENCE_CONVERSATION)) {
|
||||
if (count($mentions)) {
|
||||
if (!$activity['to']) {
|
||||
$activity['to'] = $mentions;
|
||||
} else {
|
||||
$activity['cc'] = array_values(array_unique(array_merge($activity['to'], $mentions)));
|
||||
} elseif ((int)$item['item_private'] !== 2) {
|
||||
$activity['cc'] = array_merge_clean($activity['cc'], $mentions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1570,6 +1504,8 @@ class Activity
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Returns an array of URLS for any mention tags found in the item array $i.
|
||||
|
||||
public static function map_mentions($i)
|
||||
|
@ -5221,10 +5157,15 @@ class Activity
|
|||
return $item;
|
||||
}
|
||||
|
||||
public static function getPostOpts($item)
|
||||
{
|
||||
return explode(',', $item['postopts']);
|
||||
}
|
||||
|
||||
public static function getAudienceFromItem($item)
|
||||
{
|
||||
$audience = 0;
|
||||
$postopts = explode(',', $item['postopts']);
|
||||
$postopts = self::getPostOpts($item);
|
||||
if (in_array('sender', $postopts)) {
|
||||
$audience += AUDIENCE_SENDER;
|
||||
}
|
||||
|
@ -5234,6 +5175,15 @@ class Activity
|
|||
if (in_array('followers', $postopts)) {
|
||||
$audience += AUDIENCE_FOLLOWERS;
|
||||
}
|
||||
if (in_array('public', $postopts)) {
|
||||
$audience += AUDIENCE_PUBLIC;
|
||||
}
|
||||
if (in_array('unlisted', $postopts)) {
|
||||
$audience += AUDIENCE_UNLISTED;
|
||||
}
|
||||
if (in_array('mentions', $postopts)) {
|
||||
$audience += AUDIENCE_MENTIONS;
|
||||
}
|
||||
return $audience;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue