namespace Friendica\Protocol\ActivityPub;
+use Friendica\Content\PageInfo;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\Logger;
foreach ($activity['attachments'] as $attach) {
switch ($attach['type']) {
case 'link':
- // Only one [attachment] tag is allowed
- $existingAttachmentPos = strpos($item['body'], '[attachment');
- if ($existingAttachmentPos !== false) {
- $linkTitle = $attach['title'] ?: $attach['url'];
- // Additional link attachments are prepended before the existing [attachment] tag
- $item['body'] = substr_replace($item['body'], "\n[bookmark=" . $attach['url'] . ']' . $linkTitle . "[/bookmark]\n", $existingAttachmentPos, 0);
- } else {
- $item['body'] .= "\n[attachment type='link' url='" . $attach['url'] . "' title='" . ($attach['title'] ?? '') . "' image='" . ($attach['image'] ?? '') . "']" . ($attach['desc'] ?? '') . '[/attachment]';
- }
+ $data = [
+ 'url' => $attach['url'],
+ 'type' => $attach['type'],
+ 'title' => $attach['title'] ?? '',
+ 'text' => $attach['desc'] ?? '',
+ 'image' => $attach['image'] ?? '',
+ 'images' => [],
+ 'keywords' => [],
+ ];
+ $item['body'] = PageInfo::appendDataToBody($item['body'], $data);
break;
default:
$filetype = strtolower(substr($attach['mediaType'], 0, strpos($attach['mediaType'], '/')));
continue 2;
}
+ $item['body'] .= "\n";
+
+ // image is the preview/thumbnail URL
+ if (!empty($attach['image'])) {
+ $item['body'] .= '[url=' . $attach['url'] . ']';
+ $attach['url'] = $attach['image'];
+ }
+
if (empty($attach['name'])) {
- $item['body'] .= "\n[img]" . $attach['url'] . '[/img]';
+ $item['body'] .= '[img]' . $attach['url'] . '[/img]';
} else {
- $item['body'] .= "\n[img=" . $attach['url'] . ']' . $attach['name'] . '[/img]';
+ $item['body'] .= '[img=' . $attach['url'] . ']' . $attach['name'] . '[/img]';
+ }
+
+ if (!empty($attach['image'])) {
+ $item['body'] .= '[/url]';
}
} elseif ($filetype == 'audio') {
if (!empty($activity['source']) && strpos($activity['source'], $attach['url'])) {
$item = Item::selectFirst(['uri', 'uri-id', 'thr-parent', 'gravity'], ['uri' => $activity['id']]);
if (!DBA::isResult($item)) {
Logger::warning('No existing item, item will be created', ['uri' => $activity['id']]);
- self::createItem($activity);
+ $item = self::createItem($activity);
+ self::postItem($activity, $item);
return;
}
* Prepares data for a message
*
* @param array $activity Activity array
+ * @return array Internal item
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
$item['diaspora_signed_text'] = $activity['diaspora:comment'] ?? '';
- self::postItem($activity, $item);
+ /// @todo What to do with $activity['context']?
+ if (empty($activity['directmessage']) && ($item['gravity'] != GRAVITY_PARENT) && !Item::exists(['uri' => $item['thr-parent']])) {
+ Logger::info('Parent not found, message will be discarded.', ['thr-parent' => $item['thr-parent']]);
+ return [];
+ }
+
+ $item['network'] = Protocol::ACTIVITYPUB;
+ $item['author-link'] = $activity['author'];
+ $item['author-id'] = Contact::getIdForURL($activity['author'], 0, false);
+ $item['owner-link'] = $activity['actor'];
+ $item['owner-id'] = Contact::getIdForURL($activity['actor'], 0, false);
+
+ if (in_array(0, $activity['receiver']) && !empty($activity['unlisted'])) {
+ $item['private'] = Item::UNLISTED;
+ } elseif (in_array(0, $activity['receiver'])) {
+ $item['private'] = Item::PUBLIC;
+ } else {
+ $item['private'] = Item::PRIVATE;
+ }
+
+ if (!empty($activity['raw'])) {
+ $item['source'] = $activity['raw'];
+ $item['protocol'] = Conversation::PARCEL_ACTIVITYPUB;
+ $item['conversation-href'] = $activity['context'] ?? '';
+ $item['conversation-uri'] = $activity['conversation'] ?? '';
+
+ if (isset($activity['push'])) {
+ $item['direction'] = $activity['push'] ? Conversation::PUSH : Conversation::PULL;
+ }
+ }
+
+ $item['isForum'] = false;
+
+ if (!empty($activity['thread-completion'])) {
+ // Store the original actor in the "causer" fields to enable the check for ignored or blocked contacts
+ $item['causer-link'] = $item['owner-link'];
+ $item['causer-id'] = $item['owner-id'];
+
+ Logger::info('Ignoring actor because of thread completion.', ['actor' => $item['owner-link']]);
+ $item['owner-link'] = $item['author-link'];
+ $item['owner-id'] = $item['author-id'];
+ } else {
+ $actor = APContact::getByURL($item['owner-link'], false);
+ $item['isForum'] = ($actor['type'] == 'Group');
+ }
+
+ $item['uri'] = $activity['id'];
+
+ $item['created'] = DateTimeFormat::utc($activity['published']);
+ $item['edited'] = DateTimeFormat::utc($activity['updated']);
+ $guid = $activity['sc:identifier'] ?: self::getGUIDByURL($item['uri']);
+ $item['guid'] = $activity['diaspora:guid'] ?: $guid;
+
+ $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
+
+ $item = self::processContent($activity, $item);
+ if (empty($item)) {
+ return [];
+ }
+
+ $item['plink'] = $activity['alternate-url'] ?? $item['uri'];
+
+ $item = self::constructAttachList($activity, $item);
+
+ return $item;
}
/**
{
$owner = Contact::getIdForURL($activity['actor']);
- Logger::log('Deleting item ' . $activity['object_id'] . ' from ' . $owner, Logger::DEBUG);
+ Logger::info('Deleting item', ['object' => $activity['object_id'], 'owner' => $owner]);
Item::markForDeletion(['uri' => $activity['object_id'], 'owner-id' => $owner]);
}
*/
public static function createActivity($activity, $verb)
{
- $item = [];
+ $item = self::createItem($activity);
$item['verb'] = $verb;
$item['thr-parent'] = $activity['object_id'];
$item['gravity'] = GRAVITY_ACTIVITY;
}
$event_id = Event::store($event);
- Logger::log('Event '.$event_id.' was stored', Logger::DEBUG);
+ Logger::info('Event was stored', ['id' => $event_id]);
}
/**
Logger::warning('Unknown parent item.', ['uri' => $item['thr-parent']]);
return false;
}
- if ($item_private && ($parent['private'] == Item::PRIVATE)) {
+ if ($item_private && ($parent['private'] != Item::PRIVATE)) {
Logger::warning('Item is private but the parent is not. Dropping.', ['item-uri' => $item['uri'], 'thr-parent' => $item['thr-parent']]);
return false;
}
$item['location'] = $activity['location'];
- if (!empty($item['latitude']) && !empty($item['longitude'])) {
- $item['coord'] = $item['latitude'] . ' ' . $item['longitude'];
+ if (!empty($activity['latitude']) && !empty($activity['longitude'])) {
+ $item['coord'] = $activity['latitude'] . ' ' . $activity['longitude'];
}
$item['app'] = $activity['generator'];
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- private static function postItem($activity, $item)
+ public static function postItem(array $activity, array $item)
{
- /// @todo What to do with $activity['context']?
- if (empty($activity['directmessage']) && ($item['gravity'] != GRAVITY_PARENT) && !Item::exists(['uri' => $item['thr-parent']])) {
- Logger::info('Parent not found, message will be discarded.', ['thr-parent' => $item['thr-parent']]);
- return;
- }
-
- $item['network'] = Protocol::ACTIVITYPUB;
- $item['author-link'] = $activity['author'];
- $item['author-id'] = Contact::getIdForURL($activity['author'], 0, true);
- $item['owner-link'] = $activity['actor'];
- $item['owner-id'] = Contact::getIdForURL($activity['actor'], 0, true);
-
- if (in_array(0, $activity['receiver']) && !empty($activity['unlisted'])) {
- $item['private'] = Item::UNLISTED;
- } elseif (in_array(0, $activity['receiver'])) {
- $item['private'] = Item::PUBLIC;
- } else {
- $item['private'] = Item::PRIVATE;
- }
-
- if (!empty($activity['raw'])) {
- $item['source'] = $activity['raw'];
- $item['protocol'] = Conversation::PARCEL_ACTIVITYPUB;
- $item['conversation-href'] = $activity['context'] ?? '';
- $item['conversation-uri'] = $activity['conversation'] ?? '';
-
- if (isset($activity['push'])) {
- $item['direction'] = $activity['push'] ? Conversation::PUSH : Conversation::PULL;
- }
- }
-
- $isForum = false;
-
- if (!empty($activity['thread-completion'])) {
- // Store the original actor in the "causer" fields to enable the check for ignored or blocked contacts
- $item['causer-link'] = $item['owner-link'];
- $item['causer-id'] = $item['owner-id'];
-
- Logger::info('Ignoring actor because of thread completion.', ['actor' => $item['owner-link']]);
- $item['owner-link'] = $item['author-link'];
- $item['owner-id'] = $item['author-id'];
- } else {
- $actor = APContact::getByURL($item['owner-link'], false);
- $isForum = ($actor['type'] == 'Group');
- }
-
- $item['uri'] = $activity['id'];
-
- $item['created'] = DateTimeFormat::utc($activity['published']);
- $item['edited'] = DateTimeFormat::utc($activity['updated']);
- $item['guid'] = $activity['diaspora:guid'] ?: $activity['sc:identifier'] ?: self::getGUIDByURL($item['uri']);
-
- $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
-
- $item = self::processContent($activity, $item);
if (empty($item)) {
return;
}
- $item['plink'] = $activity['alternate-url'] ?? $item['uri'];
-
- $item = self::constructAttachList($activity, $item);
-
$stored = false;
foreach ($activity['receiver'] as $receiver) {
$item['uid'] = $receiver;
- if ($isForum) {
- $item['contact-id'] = Contact::getIdForURL($activity['actor'], $receiver, true);
+ if ($item['isForum'] ?? false) {
+ $item['contact-id'] = Contact::getIdForURL($activity['actor'], $receiver, false);
} else {
- $item['contact-id'] = Contact::getIdForURL($activity['author'], $receiver, true);
+ $item['contact-id'] = Contact::getIdForURL($activity['author'], $receiver, false);
}
if (($receiver != 0) && empty($item['contact-id'])) {
- $item['contact-id'] = Contact::getIdForURL($activity['author'], 0, true);
+ $item['contact-id'] = Contact::getIdForURL($activity['author'], 0, false);
}
if (!empty($activity['directmessage'])) {
if (DI::pConfig()->get($receiver, 'system', 'accept_only_sharer', false) && ($receiver != 0) && ($item['gravity'] == GRAVITY_PARENT)) {
$skip = !Contact::isSharingByURL($activity['author'], $receiver);
- if ($skip && (($activity['type'] == 'as:Announce') || $isForum)) {
+ if ($skip && (($activity['type'] == 'as:Announce') || ($item['isForum'] ?? false))) {
$skip = !Contact::isSharingByURL($activity['actor'], $receiver);
}
$author = APContact::getByURL($item['owner-link'], false);
// We send automatic follow requests for reshared messages. (We don't need though for forum posts)
if ($author['type'] != 'Group') {
- Logger::log('Send follow request for ' . $item['uri'] . ' (' . $stored . ') to ' . $item['author-link'], Logger::DEBUG);
+ Logger::info('Send follow request', ['uri' => $item['uri'], 'stored' => $stored, 'to' => $item['author-link']]);
ActivityPub\Transmitter::sendFollowObject($item['uri'], $item['author-link']);
}
}
* @return string fetched message URL
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function fetchMissingActivity($url, $child = [])
+ public static function fetchMissingActivity(string $url, array $child = [])
{
if (!empty($child['receiver'])) {
$uid = ActivityPub\Receiver::getFirstUserFromReceivers($child['receiver']);
$result = Contact::addRelationship($owner, $contact, $item, false, $note);
if ($result === true) {
- ActivityPub\Transmitter::sendContactAccept($item['author-link'], $item['author-id'], $owner['uid']);
+ ActivityPub\Transmitter::sendContactAccept($item['author-link'], $activity['id'], $owner['uid']);
}
$cid = Contact::getIdForURL($activity['actor'], $uid);
return;
}
- Logger::log('Updating profile for ' . $activity['object_id'], Logger::DEBUG);
+ Logger::info('Updating profile', ['object' => $activity['object_id']]);
Contact::updateFromProbeByURL($activity['object_id'], true);
}
public static function deletePerson($activity)
{
if (empty($activity['object_id']) || empty($activity['actor'])) {
- Logger::log('Empty object id or actor.', Logger::DEBUG);
+ Logger::info('Empty object id or actor.');
return;
}
if ($activity['object_id'] != $activity['actor']) {
- Logger::log('Object id does not match actor.', Logger::DEBUG);
+ Logger::info('Object id does not match actor.');
return;
}
}
DBA::close($contacts);
- Logger::log('Deleted contact ' . $activity['object_id'], Logger::DEBUG);
+ Logger::info('Deleted contact', ['object' => $activity['object_id']]);
}
/**
$cid = Contact::getIdForURL($activity['actor'], $uid);
if (empty($cid)) {
- Logger::log('No contact found for ' . $activity['actor'], Logger::DEBUG);
+ Logger::info('No contact found', ['actor' => $activity['actor']]);
return;
}
$condition = ['id' => $cid];
DBA::update('contact', $fields, $condition);
- Logger::log('Accept contact request from contact ' . $cid . ' for user ' . $uid, Logger::DEBUG);
+ Logger::info('Accept contact request', ['contact' => $cid, 'user' => $uid]);
}
/**
$cid = Contact::getIdForURL($activity['actor'], $uid);
if (empty($cid)) {
- Logger::log('No contact found for ' . $activity['actor'], Logger::DEBUG);
+ Logger::info('No contact found', ['actor' => $activity['actor']]);
return;
}
if (DBA::exists('contact', ['id' => $cid, 'rel' => Contact::SHARING])) {
Contact::remove($cid);
- Logger::log('Rejected contact request from contact ' . $cid . ' for user ' . $uid . ' - contact had been removed.', Logger::DEBUG);
+ Logger::info('Rejected contact request - contact removed', ['contact' => $cid, 'user' => $uid]);
} else {
- Logger::log('Rejected contact request from contact ' . $cid . ' for user ' . $uid . '.', Logger::DEBUG);
+ Logger::info('Rejected contact request', ['contact' => $cid, 'user' => $uid]);
}
}
$cid = Contact::getIdForURL($activity['actor'], $uid);
if (empty($cid)) {
- Logger::log('No contact found for ' . $activity['actor'], Logger::DEBUG);
+ Logger::info('No contact found', ['actor' => $activity['actor']]);
return;
}
}
Contact::removeFollower($owner, $contact);
- Logger::log('Undo following request from contact ' . $cid . ' for user ' . $uid, Logger::DEBUG);
+ Logger::info('Undo following request', ['contact' => $cid, 'user' => $uid]);
}
/**
{
$parent_terms = Tag::getByURIId($parent['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]);
- $parent_author = Contact::getDetailsByURL($parent['author-link'], 0);
+ $parent_author = Contact::getByURL($parent['author-link'], false, ['url', 'nurl', 'alias']);
$implicit_mentions = [];
- if (empty($parent_author)) {
+ if (empty($parent_author['url'])) {
Logger::notice('Author public contact unknown.', ['author-link' => $parent['author-link'], 'item-id' => $parent['id']]);
} else {
$implicit_mentions[] = $parent_author['url'];
}
foreach ($parent_terms as $term) {
- $contact = Contact::getDetailsByURL($term['url'], 0);
- if (!empty($contact)) {
+ $contact = Contact::getByURL($term['url'], false, ['url', 'nurl', 'alias']);
+ if (!empty($contact['url'])) {
$implicit_mentions[] = $contact['url'];
$implicit_mentions[] = $contact['nurl'];
$implicit_mentions[] = $contact['alias'];