X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FActivityPub%2FTransmitter.php;h=ce23e6db209910d7530ccb1376ffe58132d66ac1;hb=2788995ab0c44b9f4e680e2adbab2b175f0293a6;hp=f5953e7c5fcdab1e5bc54aba944b48d0440d53ee;hpb=75728430832633407c78a49d47481e97bbd9e00e;p=friendica.git diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index f5953e7c5f..ce23e6db20 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -5,6 +5,7 @@ namespace Friendica\Protocol\ActivityPub; use Friendica\BaseObject; +use Friendica\Content\Feature; use Friendica\Database\DBA; use Friendica\Core\Config; use Friendica\Core\Logger; @@ -19,6 +20,7 @@ use Friendica\Model\Term; use Friendica\Model\User; use Friendica\Util\DateTimeFormat; use Friendica\Content\Text\BBCode; +use Friendica\Content\Text\Plaintext; use Friendica\Util\JsonLD; use Friendica\Util\LDSignature; use Friendica\Model\Profile; @@ -151,7 +153,7 @@ class Transmitter $condition = ['uid' => 0, 'contact-id' => $public_contact, 'author-id' => $public_contact, 'private' => false, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], - 'deleted' => false, 'visible' => true]; + 'deleted' => false, 'visible' => true, 'moderated' => false]; $count = DBA::count('item', $condition); $data = ['@context' => ActivityPub::CONTEXT]; @@ -302,15 +304,16 @@ class Transmitter /** * Creates an array of permissions from an item thread * - * @param array $item - * @param boolean $blindcopy - * @param boolean $last_id + * @param array $item Item array + * @param boolean $blindcopy addressing via "bcc" or "cc"? + * @param integer $last_id Last item id for adding receivers + * @param boolean $forum_mode "true" means that we are sending content to a forum * * @return array with permission data * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function createPermissionBlockForItem($item, $blindcopy, $last_id = 0) + private static function createPermissionBlockForItem($item, $blindcopy, $last_id = 0, $forum_mode = false) { if ($last_id == 0) { $last_id = $item['id']; @@ -342,7 +345,7 @@ class Transmitter $actor_profile = APContact::getByURL($item['author-link']); } - $terms = Term::tagArrayFromItemId($item['id'], TERM_MENTION); + $terms = Term::tagArrayFromItemId($item['id'], [Term::MENTION, Term::IMPLICIT_MENTION]); if (!$item['private']) { $data = array_merge($data, self::fetchPermissionBlockFromConversation($item)); @@ -398,7 +401,7 @@ class Transmitter } } else { // Public thread parent post always are directed to the followes - if (!$item['private']) { + if (!$item['private'] && !$forum_mode) { $data['cc'][] = $actor_profile['followers']; } } @@ -514,18 +517,18 @@ class Transmitter /** * Fetches an array of inboxes for the given item and user * - * @param array $item - * @param integer $uid User ID - * @param boolean $personal fetch personal inboxes - * @param integer $last_id Last item id for adding receivers - * + * @param array $item Item array + * @param integer $uid User ID + * @param boolean $personal fetch personal inboxes + * @param integer $last_id Last item id for adding receivers + * @param boolean $forum_mode "true" means that we are sending content to a forum * @return array with inboxes * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function fetchTargetInboxes($item, $uid, $personal = false, $last_id = 0) + public static function fetchTargetInboxes($item, $uid, $personal = false, $last_id = 0, $forum_mode = false) { - $permissions = self::createPermissionBlockForItem($item, true, $last_id); + $permissions = self::createPermissionBlockForItem($item, true, $last_id, $forum_mode); if (empty($permissions)) { return []; } @@ -658,7 +661,7 @@ class Transmitter return false; } - if ($item['wall']) { + if ($item['wall'] && ($item['uri'] == $item['parent-uri'])) { $owner = User::getOwnerDataById($item['uid']); if (($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) && ($item['author-link'] != $owner['url'])) { $type = 'Announce'; @@ -696,7 +699,12 @@ class Transmitter $data['id'] = $item['uri'] . '#' . $type; $data['type'] = $type; - $data['actor'] = $item['owner-link']; + + if (Item::isForumPost($item) && ($type != 'Announce')) { + $data['actor'] = $item['author-link']; + } else { + $data['actor'] = $item['owner-link']; + } $data['published'] = DateTimeFormat::utc($item['created'] . '+00:00', DateTimeFormat::ATOM); @@ -806,12 +814,12 @@ class Transmitter { $tags = []; - $terms = Term::tagArrayFromItemId($item['id']); + $terms = Term::tagArrayFromItemId($item['id'], [Term::HASHTAG, Term::MENTION, Term::IMPLICIT_MENTION]); foreach ($terms as $term) { - if ($term['type'] == TERM_HASHTAG) { + if ($term['type'] == Term::HASHTAG) { $url = System::baseUrl() . '/search?tag=' . urlencode($term['term']); $tags[] = ['type' => 'Hashtag', 'href' => $url, 'name' => '#' . $term['term']]; - } elseif ($term['type'] == TERM_MENTION) { + } elseif ($term['type'] == Term::MENTION || $term['type'] == Term::IMPLICIT_MENTION) { $contact = Contact::getDetailsByURL($term['url']); if (!empty($contact['addr'])) { $mention = '@' . $contact['addr']; @@ -891,12 +899,12 @@ class Transmitter private static function mentionCallback($match) { if (empty($match[1])) { - return; + return ''; } $data = Contact::getDetailsByURL($match[1]); - if (empty($data) || empty($data['nick'])) { - return; + if (empty($data['nick'])) { + return $match[0]; } return '@[url=' . $data['url'] . ']' . $data['nick'] . '[/url]'; @@ -1013,7 +1021,7 @@ class Transmitter return $data; } - $data['summary'] = null; // Ignore by now + $data['summary'] = BBCode::toPlaintext(BBCode::getAbstract($item['body'], Protocol::ACTIVITYPUB)); if ($item['uri'] != $item['thr-parent']) { $data['inReplyTo'] = $item['thr-parent']; @@ -1037,10 +1045,18 @@ class Transmitter $data['name'] = BBCode::toPlaintext($item['title'], false); } + $permission_block = self::createPermissionBlockForItem($item, false); + $body = $item['body']; + if (empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions')) { + $body = self::prependMentions($body, $permission_block); + } + if ($type == 'Note') { $body = self::removePictures($body); + } elseif (($type == 'Article') && empty($data['summary'])) { + $data['summary'] = BBCode::toPlaintext(Plaintext::shorten(self::removePictures($body), 1000)); } if ($type == 'Event') { @@ -1069,7 +1085,7 @@ class Transmitter $data['generator'] = ['type' => 'Application', 'name' => $item['app']]; } - $data = array_merge($data, self::createPermissionBlockForItem($item, false)); + $data = array_merge($data, $permission_block); return $data; } @@ -1202,6 +1218,16 @@ class Transmitter { $owner = User::getOwnerDataById($uid); + if (empty($owner)) { + Logger::error('No owner data found, the deletion message cannot be processed.', ['user' => $uid]); + return false; + } + + if (empty($owner['uprvkey'])) { + Logger::error('No private key for owner found, the deletion message cannot be processed.', ['user' => $uid]); + return false; + } + $data = ['@context' => ActivityPub::CONTEXT, 'id' => System::baseUrl() . '/activity/' . System::createGUID(), 'type' => 'Delete', @@ -1310,6 +1336,13 @@ class Transmitter $uid = $first_user['uid']; } + $condition = ['verb' => ACTIVITY_FOLLOW, 'uid' => 0, 'parent-uri' => $object, + 'author-id' => Contact::getPublicIdByUserId($uid)]; + if (Item::exists($condition)) { + Logger::log('Follow for ' . $object . ' for user ' . $uid . ' does already exist.', Logger::DEBUG); + return false; + } + $owner = User::getOwnerDataById($uid); $data = ['@context' => ActivityPub::CONTEXT, @@ -1422,4 +1455,28 @@ class Transmitter $signed = LDSignature::sign($data, $owner); HTTPSignature::transmit($signed, $profile['inbox'], $uid); } + + private static function prependMentions($body, array $permission_block) + { + if (Config::get('system', 'disable_implicit_mentions')) { + return $body; + } + + $mentions = []; + + foreach ($permission_block['to'] as $profile_url) { + $profile = Contact::getDetailsByURL($profile_url); + if (!empty($profile['addr']) + && $profile['contact-type'] != Contact::TYPE_COMMUNITY + && !strstr($body, $profile['addr']) + && !strstr($body, $profile_url) + ) { + $mentions[] = '@[url=' . $profile_url . ']' . $profile['nick'] . '[/url]'; + } + } + + $mentions[] = $body; + + return implode(' ', $mentions); + } }