X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FActivityPub%2FTransmitter.php;h=7f5f51c38aedcde640271d4f8bfba59250606102;hb=e4e9a20ac8a8a7896c3d2e4136237d399c664dd6;hp=dae783bd74d4edb5ac70de55ab89c4eef6c64923;hpb=178455928a87b549cea8f1936baa5776b214b8bc;p=friendica.git diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index dae783bd74..7f5f51c38a 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -37,13 +37,14 @@ use Friendica\Model\Item; use Friendica\Model\ItemURI; use Friendica\Model\Profile; use Friendica\Model\Photo; +use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; use Friendica\Protocol\Activity; use Friendica\Protocol\ActivityPub; +use Friendica\Protocol\Relay; use Friendica\Util\DateTimeFormat; use Friendica\Util\HTTPSignature; -use Friendica\Util\Images; use Friendica\Util\JsonLD; use Friendica\Util\LDSignature; use Friendica\Util\Map; @@ -67,7 +68,7 @@ class Transmitter * @param array $inboxes * @return array inboxes with added relay servers */ - public static function addRelayServerInboxes(array $inboxes) + public static function addRelayServerInboxes(array $inboxes = []) { $contacts = DBA::select('apcontact', ['inbox'], ["`type` = ? AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))", @@ -80,6 +81,27 @@ class Transmitter return $inboxes; } + /** + * Add relay servers to the list of inboxes + * + * @param array $inboxes + * @return array inboxes with added relay servers + */ + public static function addRelayServerInboxesForItem(int $item_id, array $inboxes = []) + { + $relays = Relay::getList($item_id, [], [Protocol::ACTIVITYPUB]); + if (empty($relays)) { + return $inboxes; + } + + foreach ($relays as $relay) { + if (!in_array($relay['batch'], $inboxes)) { + $inboxes[] = $relay['batch']; + } + } + return $inboxes; + } + /** * Subscribe to a relay * @@ -88,15 +110,16 @@ class Transmitter */ public static function sendRelayFollow(string $url) { - $contact_id = Contact::getIdForURL($url); - if (!$contact_id) { + $contact = Contact::getByURL($url); + if (empty($contact)) { return false; } - $activity_id = ActivityPub\Transmitter::activityIDFromContact($contact_id); + $activity_id = ActivityPub\Transmitter::activityIDFromContact($contact['id']); $success = ActivityPub\Transmitter::sendActivity('Follow', $url, 0, $activity_id); if ($success) { - DBA::update('contact', ['rel' => Contact::FRIEND], ['id' => $contact_id]); + $rel = $contact['rel'] == Contact::SHARING ? Contact::FRIEND : Contact::FOLLOWER; + DBA::update('contact', ['rel' => $rel], ['id' => $contact['id']]); } return $success; @@ -105,19 +128,21 @@ class Transmitter /** * Unsubscribe from a relay * - * @param string $url Subscribe actor url + * @param string $url Subscribe actor url + * @param bool $force Set the relay status as non follower even if unsubscribe hadn't worked * @return bool success */ - public static function sendRelayUndoFollow(string $url) + public static function sendRelayUndoFollow(string $url, bool $force = false) { - $contact_id = Contact::getIdForURL($url); - if (!$contact_id) { + $contact = Contact::getByURL($url); + if (empty($contact)) { return false; } - $success = self::sendContactUndo($url, $contact_id, 0); - if ($success) { - DBA::update('contact', ['rel' => Contact::SHARING], ['id' => $contact_id]); + $success = self::sendContactUndo($url, $contact['id'], 0); + if ($success || $force) { + $rel = $contact['rel'] == Contact::FRIEND ? Contact::SHARING : Contact::NOTHING; + DBA::update('contact', ['rel' => $rel], ['id' => $contact['id']]); } return $success; @@ -143,7 +168,8 @@ class Transmitter 'deleted' => false, 'hidden' => false, 'archive' => false, - 'pending' => false + 'pending' => false, + 'blocked' => false, ]; $condition = DBA::buildCondition($parameters); @@ -406,7 +432,12 @@ class Transmitter $activity = json_decode($conversation['source'], true); $actor = JsonLD::fetchElement($activity, 'actor', 'id'); - $profile = APContact::getByURL($actor); + if (!empty($actor)) { + $permissions['to'][] = $actor; + $profile = APContact::getByURL($actor); + } else { + $profile = []; + } $item_profile = APContact::getByURL($item['author-link']); $exclude[] = $item['author-link']; @@ -415,8 +446,6 @@ class Transmitter $exclude[] = $item['owner-link']; } - $permissions['to'][] = $actor; - foreach (['to', 'cc', 'bto', 'bcc'] as $element) { if (empty($activity[$element])) { continue; @@ -459,14 +488,12 @@ class Transmitter } $always_bcc = false; - $isforum = false; // Check if we should always deliver our stuff via BCC if (!empty($item['uid'])) { $profile = User::getOwnerDataById($item['uid']); if (!empty($profile)) { $always_bcc = $profile['hide-friends']; - $isforum = $profile['account-type'] == User::ACCOUNT_TYPE_COMMUNITY; } } @@ -474,7 +501,7 @@ class Transmitter $always_bcc = true; } - if ((self::isAnnounce($item) && !$isforum) || DI::config()->get('debug', 'total_ap_delivery')) { + if (self::isAnnounce($item) || DI::config()->get('debug', 'total_ap_delivery')) { // Will be activated in a later step $networks = Protocol::FEDERATED; } else { @@ -528,10 +555,6 @@ class Transmitter continue; } - if ($isforum && DBA::isResult($contact) && ($contact['dfrn'] == Protocol::DFRN)) { - continue; - } - if (!empty($profile = APContact::getByURL($contact['url'], false))) { $data['to'][] = $profile['url']; } @@ -544,10 +567,6 @@ class Transmitter continue; } - if ($isforum && DBA::isResult($contact) && ($contact['dfrn'] == Protocol::DFRN)) { - continue; - } - if (!empty($profile = APContact::getByURL($contact['url'], false))) { if ($contact['hidden'] || $always_bcc) { $data['bcc'][] = $profile['url']; @@ -651,7 +670,7 @@ class Transmitter * * @return boolean "true" if inbox is archived */ - private static function archivedInbox($url) + public static function archivedInbox($url) { return DBA::exists('inbox-status', ['url' => $url, 'archive' => true]); } @@ -687,7 +706,7 @@ class Transmitter $networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS]; } - $condition = ['uid' => $uid, 'archive' => false, 'pending' => false]; + $condition = ['uid' => $uid, 'archive' => false, 'pending' => false, 'blocked' => false]; if (!empty($uid)) { $condition['rel'] = [Contact::FOLLOWER, Contact::FRIEND]; @@ -703,7 +722,7 @@ class Transmitter continue; } - if ($isforum && ($contact['dfrn'] == Protocol::DFRN)) { + if ($isforum && ($contact['network'] == Protocol::DFRN)) { continue; } @@ -836,7 +855,6 @@ class Transmitter $mail['gravity'] = ($mail['reply'] ? GRAVITY_COMMENT: GRAVITY_PARENT); $mail['event-type'] = ''; - $mail['attach'] = ''; $mail['parent'] = 0; @@ -855,6 +873,9 @@ class Transmitter public static function createActivityFromMail($mail_id, $object_mode = false) { $mail = self::ItemArrayFromMail($mail_id); + if (empty($mail)) { + return []; + } $object = self::createNote($mail); if (!$object_mode) { @@ -999,11 +1020,19 @@ class Transmitter if (!empty($author['nurl'])) { $self = Contact::selectFirst(['uid'], ['nurl' => $author['nurl'], 'self' => true]); if (!empty($self['uid'])) { - $item = Item::selectFirst([], ['uri-id' => $item['uri-id'], 'uid' => $self['uid']]); + $forum_item = Item::selectFirst([], ['uri-id' => $item['uri-id'], 'uid' => $self['uid']]); + if (DBA::isResult($item)) { + $item = $forum_item; + } } } } + if (empty($item['uri-id'])) { + Logger::warning('Item without uri-id', ['item' => $item]); + return false; + } + if (empty($type)) { $condition = ['item-uri' => $item['uri'], 'protocol' => Conversation::PARCEL_ACTIVITYPUB]; $conversation = DBA::selectFirst('conversation', ['source'], $condition); @@ -1224,57 +1253,22 @@ class Transmitter $attachments[] = $attachment; } */ - $arr = explode('[/attach],', $item['attach']); - if (count($arr)) { - foreach ($arr as $r) { - $matches = false; - $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|', $r, $matches); - if ($cnt) { - $attributes = ['type' => 'Document', - 'mediaType' => $matches[3], - 'url' => $matches[1], - 'name' => null]; - - if (trim($matches[4]) != '') { - $attributes['name'] = trim($matches[4]); - } - - $attachments[] = $attributes; - } - } + foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT, Post\Media::UNKNOWN]) as $attachment) { + $attachments[] = ['type' => 'Document', + 'mediaType' => $attachment['mimetype'], + 'url' => $attachment['url'], + 'name' => $attachment['description']]; } if ($type != 'Note') { return $attachments; } - // Simplify image codes - $body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $item['body']); - - // Grab all pictures without alternative descriptions and create attachments out of them - if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures)) { - foreach ($pictures[1] as $picture) { - $imgdata = Images::getInfoFromURLCached($picture); - if ($imgdata) { - $attachments[] = ['type' => 'Document', - 'mediaType' => $imgdata['mime'], - 'url' => $picture, - 'name' => null]; - } - } - } - - // Grab all pictures with alternative description and create attachments out of them - if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) { - foreach ($pictures as $picture) { - $imgdata = Images::getInfoFromURLCached($picture[1]); - if ($imgdata) { - $attachments[] = ['type' => 'Document', - 'mediaType' => $imgdata['mime'], - 'url' => $picture[1], - 'name' => $picture[2]]; - } - } + foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]) as $attachment) { + $attachments[] = ['type' => 'Document', + 'mediaType' => $attachment['mimetype'], + 'url' => $attachment['url'], + 'name' => $attachment['description']]; } return $attachments; @@ -1293,12 +1287,12 @@ class Transmitter return ''; } - $data = Contact::getByURL($match[1], false, ['url', 'nick']); + $data = Contact::getByURL($match[1], false, ['url', 'alias', 'nick']); if (empty($data['nick'])) { return $match[0]; } - return '@[url=' . $data['url'] . ']' . $data['nick'] . '[/url]'; + return '[url=' . ($data['alias'] ?: $data['url']) . ']@' . $data['nick'] . '[/url]'; } /** @@ -1458,16 +1452,16 @@ class Transmitter $body = $item['body']; - if (empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions')) { - $body = self::prependMentions($body, $item['uri-id']); - } - if ($type == 'Note') { - $body = self::removePictures($body); + $body = $item['raw-body'] ?? self::removePictures($body); } elseif (($type == 'Article') && empty($data['summary'])) { $data['summary'] = BBCode::toPlaintext(Plaintext::shorten(self::removePictures($body), 1000)); } + if (empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions')) { + $body = self::prependMentions($body, $item['uri-id'], $item['author-link']); + } + if ($type == 'Event') { $data = array_merge($data, self::createEvent($item)); } else { @@ -2013,7 +2007,7 @@ class Transmitter return HTTPSignature::transmit($signed, $profile['inbox'], $uid); } - private static function prependMentions($body, int $uriid) + private static function prependMentions($body, int $uriid, string $authorLink) { $mentions = []; @@ -2023,6 +2017,7 @@ class Transmitter && $profile['contact-type'] != Contact::TYPE_COMMUNITY && !strstr($body, $profile['addr']) && !strstr($body, $tag['url']) + && $tag['url'] !== $authorLink ) { $mentions[] = '@[url=' . $tag['url'] . ']' . $profile['nick'] . '[/url]'; }