X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FActivityPub%2FTransmitter.php;h=38482d3ec95f83dab1191745305e794b49b824dc;hb=0d3aa681b4bec50c72e426c60cc5a22e4736d9e9;hp=ecd18431855713b3bc940d3db9179a0d5c13ee56;hpb=f9bf2424b1ebaa16c817e8c8d525989e382aed66;p=friendica.git diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index ecd1843185..38482d3ec9 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -59,7 +59,6 @@ class Transmitter { const CACHEKEY_FEATURED = 'transmitter:getFeatured:'; const CACHEKEY_CONTACTS = 'transmitter:getContacts:'; - const CACHEKEY_OUTBOX = 'transmitter:getOutbox:'; /** * Add relay servers to the list of inboxes @@ -251,14 +250,6 @@ class Transmitter */ public static function getOutbox(array $owner, int $page = null, string $requester = '', bool $nocache = false): array { - if (empty($page)) { - $cachekey = self::CACHEKEY_OUTBOX . $owner['uid']; - $result = DI::cache()->get($cachekey); - if (!$nocache && !is_null($result)) { - return $result; - } - } - $condition = ['private' => [Item::PUBLIC, Item::UNLISTED]]; if (!empty($requester)) { @@ -283,12 +274,12 @@ class Transmitter 'visible' => true ]); - $count = Post::count($condition); + $apcontact = APContact::getByURL($owner['url']); $data = ['@context' => ActivityPub::CONTEXT]; $data['id'] = DI::baseUrl() . '/outbox/' . $owner['nickname']; $data['type'] = 'OrderedCollection'; - $data['totalItems'] = $count; + $data['totalItems'] = $apcontact['statuses_count'] ?? 0; if (!empty($page)) { $data['id'] .= '?' . http_build_query(['page' => $page]); @@ -316,15 +307,17 @@ class Transmitter $data['next'] = DI::baseUrl() . '/outbox/' . $owner['nickname'] . '?page=' . ($page + 1); } + // Fix the cached total item count when it is lower than the real count + $total = (($page - 1) * 20) + $data['totalItems']; + if ($total > $data['totalItems']) { + $data['totalItems'] = $total; + } + $data['partOf'] = DI::baseUrl() . '/outbox/' . $owner['nickname']; $data['orderedItems'] = $list; } - if (!empty($cachekey)) { - DI::cache()->set($cachekey, $data, Duration::DAY); - } - return $data; } @@ -655,7 +648,7 @@ class Transmitter } $parent = Post::selectFirst(['causer-link', 'post-reason'], ['id' => $item['parent']]); - if (($parent['post-reason'] == Item::PR_ANNOUNCEMENT) && !empty($parent['causer-link'])) { + if (!empty($parent) && ($parent['post-reason'] == Item::PR_ANNOUNCEMENT) && !empty($parent['causer-link'])) { $profile = APContact::getByURL($parent['causer-link'], false); $is_forum_thread = isset($profile['type']) && $profile['type'] == 'Group'; } else { @@ -772,7 +765,7 @@ class Transmitter $data['to'][] = $profile['url']; } else { $data['cc'][] = $profile['url']; - if (($item['private'] != Item::PRIVATE) && !empty($actor_profile['followers'])&& !$is_forum_thread) { + if (($item['private'] != Item::PRIVATE) && !empty($actor_profile['followers']) && (!$exclusive || !$is_forum_thread)) { $data['cc'][] = $actor_profile['followers']; } } @@ -1192,9 +1185,9 @@ class Transmitter * @return array|false activity or false on failure * @throws \Exception */ - public static function createCachedActivityFromItem(int $item_id, bool $force = false) + public static function createCachedActivityFromItem(int $item_id, bool $force = false, bool $object_mode = false) { - $cachekey = 'APDelivery:createActivity:' . $item_id; + $cachekey = 'APDelivery:createActivity:' . $item_id . ':' . (int)$object_mode; if (!$force) { $data = DI::cache()->get($cachekey); @@ -1203,7 +1196,7 @@ class Transmitter } } - $data = self::createActivityFromItem($item_id); + $data = self::createActivityFromItem($item_id, $object_mode); DI::cache()->set($cachekey, $data, Duration::QUARTER_HOUR); return $data; @@ -1362,11 +1355,12 @@ class Transmitter /** * Returns a tag array for a given item array * - * @param array $item Item array + * @param array $item Item array + * @param string $quote_url Url of the attached quote link * @return array of tags * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function createTagList(array $item): array + private static function createTagList(array $item, string $quote_url): array { $tags = []; @@ -1396,6 +1390,17 @@ class Transmitter $tags[] = ['type' => 'Mention', 'href' => $announce['actor']['url'], 'name' => '@' . $announce['actor']['addr']]; } + // @see https://codeberg.org/fediverse/fep/src/branch/main/feps/fep-e232.md + if (!empty($quote_url)) { + // Currently deactivated because of compatibility issues with Pleroma + //$tags[] = [ + // 'type' => 'Link', + // 'mediaType' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + // 'href' => $quote_url, + // 'name' => '♲ ' . BBCode::convertForUriId($item['uri-id'], $quote_url, BBCode::ACTIVITYPUB) + //]; + } + return $tags; } @@ -1403,51 +1408,39 @@ class Transmitter * Adds attachment data to the JSON document * * @param array $item Data of the item that is to be posted - * @param string $type Object type * * @return array with attachment data * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function createAttachmentList(array $item, string $type): array + private static function createAttachmentList(array $item): array { $attachments = []; - $uriids = [$item['uri-id']]; - $shared = BBCode::fetchShareAttributes($item['body']); - if (!empty($shared['guid'])) { - $shared_item = Post::selectFirst(['uri-id'], ['guid' => $shared['guid']]); - if (!empty($shared_item['uri-id'])) { - $uriids[] = $shared_item['uri-id']; - } - } - $urls = []; - foreach ($uriids as $uriid) { - foreach (Post\Media::getByURIId($uriid, [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO, Post\Media::DOCUMENT, Post\Media::TORRENT]) as $attachment) { - if (in_array($attachment['url'], $urls)) { - continue; - } - $urls[] = $attachment['url']; - - $attach = ['type' => 'Document', - 'mediaType' => $attachment['mimetype'], - 'url' => $attachment['url'], - 'name' => $attachment['description']]; + foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO, Post\Media::DOCUMENT, Post\Media::TORRENT]) as $attachment) { + if (in_array($attachment['url'], $urls)) { + continue; + } + $urls[] = $attachment['url']; - if (!empty($attachment['height'])) { - $attach['height'] = $attachment['height']; - } + $attach = ['type' => 'Document', + 'mediaType' => $attachment['mimetype'], + 'url' => $attachment['url'], + 'name' => $attachment['description']]; - if (!empty($attachment['width'])) { - $attach['width'] = $attachment['width']; - } + if (!empty($attachment['height'])) { + $attach['height'] = $attachment['height']; + } - if (!empty($attachment['preview'])) { - $attach['image'] = $attachment['preview']; - } + if (!empty($attachment['width'])) { + $attach['width'] = $attachment['width']; + } - $attachments[] = $attach; + if (!empty($attachment['preview'])) { + $attach['image'] = $attachment['preview']; } + + $attachments[] = $attach; } return $attachments; @@ -1617,7 +1610,10 @@ class Transmitter $data['url'] = $link ?? $item['plink']; $data['attributedTo'] = $item['author-link']; $data['sensitive'] = self::isSensitive($item['uri-id']); - $data['conversation'] = $data['context'] = $item['conversation']; + + if (!empty($item['conversation']) && ($item['conversation'] != './')) { + $data['conversation'] = $data['context'] = $item['conversation']; + } if (!empty($item['title'])) { $data['name'] = BBCode::toPlaintext($item['title'], false); @@ -1666,6 +1662,12 @@ class Transmitter $body = BBCode::setMentionsToNicknames($body); + $shared = BBCode::fetchShareAttributes($body); + if (!empty($shared['link']) && !empty($shared['guid']) && !empty($shared['comment'])) { + $body = self::replaceSharedData($body); + $data['quoteUrl'] = $shared['link']; + } + $data['content'] = BBCode::convertForUriId($item['uri-id'], $body, BBCode::ACTIVITYPUB); } @@ -1675,6 +1677,12 @@ class Transmitter $language = self::getLanguage($item); if (!empty($language)) { $richbody = BBCode::setMentionsToNicknames($item['body'] ?? ''); + + $shared = BBCode::fetchShareAttributes($richbody); + if (!empty($shared['link']) && !empty($shared['guid']) && !empty($shared['comment'])) { + $richbody = self::replaceSharedData($richbody); + } + $richbody = BBCode::removeAttachment($richbody); $data['contentMap'][$language] = BBCode::convertForUriId($item['uri-id'], $richbody, BBCode::EXTERNAL); @@ -1686,8 +1694,8 @@ class Transmitter $data['diaspora:comment'] = $item['signed_text']; } - $data['attachment'] = self::createAttachmentList($item, $type); - $data['tag'] = self::createTagList($item); + $data['attachment'] = self::createAttachmentList($item); + $data['tag'] = self::createTagList($item, $data['quoteUrl'] ?? ''); if (empty($data['location']) && (!empty($item['coord']) || !empty($item['location']))) { $data['location'] = self::createLocation($item); @@ -1702,6 +1710,22 @@ class Transmitter return $data; } + /** + * Replace the share block with a link + * + * @param string $body + * @return string + */ + private static function replaceSharedData(string $body): string + { + return BBCode::convertShare( + $body, + function (array $attributes) { + return '♲ ' . $attributes['link']; + } + ); + } + /** * Fetches the language from the post, the user or the system. *