*/
public static function profile($uid)
{
- $accounttype = ['Person', 'Organization', 'Service', 'Group', 'Application'];
-
+ $accounttype = ['Person', 'Organization', 'Service', 'Group', 'Application', 'page-flags'];
$condition = ['uid' => $uid, 'blocked' => false, 'account_expired' => false,
'account_removed' => false, 'verified' => true];
$fields = ['guid', 'nickname', 'pubkey', 'account-type'];
return [];
}
- $fields = ['locality', 'region', 'country-name', 'page-flags'];
+ $fields = ['locality', 'region', 'country-name'];
$profile = DBA::selectFirst('profile', $fields, ['uid' => $uid, 'is-default' => true]);
if (!DBA::isResult($profile)) {
return [];
$data = ['@context' => ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1',
['uuid' => 'http://schema.org/identifier', 'sensitive' => 'as:sensitive',
+ 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
'vcard' => 'http://www.w3.org/2006/vcard/ns#']]];
$data['id'] = $contact['url'];
$data['outbox'] = System::baseUrl() . '/outbox/' . $user['nickname'];
$data['preferredUsername'] = $user['nickname'];
$data['name'] = $contact['name'];
- $data['vcard:hasAddress'] = ['@type' => 'Home', 'vcard:country-name' => $profile['country-name'],
+ $data['vcard:hasAddress'] = ['@type' => 'vcard:Home', 'vcard:country-name' => $profile['country-name'],
'vcard:region' => $profile['region'], 'vcard:locality' => $profile['locality']];
$data['summary'] = $contact['about'];
$data['url'] = $contact['url'];
$data['context'] = $data['conversation'] = $conversation_uri;
$data['actor'] = $item['author-link'];
- $data['to'] = [];
if (!$item['private']) {
- $data['to'][] = 'https://www.w3.org/ns/activitystreams#Public';
+ $data['to'] = 'https://www.w3.org/ns/activitystreams#Public';
}
$data['published'] = DateTimeFormat::utc($item["created"]."+00:00", DateTimeFormat::ATOM);
$data['updated'] = DateTimeFormat::utc($item["edited"]."+00:00", DateTimeFormat::ATOM);
// When it is a delivery to a personal inbox we add that user to the receivers
if (!empty($uid)) {
$owner = User::getOwnerDataById($uid);
- $additional = [$owner['url'] => $uid];
+ $additional = ['uid:' . $uid => $uid];
$receivers = array_merge($receivers, $additional);
}
{
$receivers = [];
- $data = self::fetchContent($actor);
- $followers = defaults($data, 'followers', '');
+ if (!empty($actor)) {
+ $data = self::fetchContent($actor);
+ $followers = defaults($data, 'followers', '');
- logger('Actor: ' . $actor . ' - Followers: ' . $followers, LOGGER_DEBUG);
+ logger('Actor: ' . $actor . ' - Followers: ' . $followers, LOGGER_DEBUG);
+ } else {
+ logger('Empty actor', LOGGER_DEBUG);
+ $followers = '';
+ }
$elements = ['to', 'cc', 'bto', 'bcc'];
foreach ($elements as $element) {
foreach ($activity[$element] as $receiver) {
if ($receiver == self::PUBLIC) {
$receivers['uid:0'] = 0;
+ }
+ if (($receiver == self::PUBLIC) && !empty($actor)) {
// This will most likely catch all OStatus connections to Mastodon
$condition = ['alias' => [$actor, normalise_link($actor)], 'rel' => [Contact::SHARING, Contact::FRIEND]];
$contacts = DBA::select('contact', ['uid'], $condition);
DBA::close($contacts);
}
- if (in_array($receiver, [$followers, self::PUBLIC])) {
+ if (in_array($receiver, [$followers, self::PUBLIC]) && !empty($actor)) {
$condition = ['nurl' => normalise_link($actor), 'rel' => [Contact::SHARING, Contact::FRIEND],
'network' => Protocol::ACTIVITYPUB];
$contacts = DBA::select('contact', ['uid'], $condition);
if (!DBA::isResult($contact)) {
continue;
}
- $receivers['cid:' . $contact['uid']] = $contact['uid'];
+ $receivers['uid:' . $contact['uid']] = $contact['uid'];
}
}
return $receivers;
if (empty($data)) {
logger('Empty content for ' . $object_url . ', check if content is available locally.', LOGGER_DEBUG);
$data = $object_url;
+ $data = $object;
}
} else {
logger('Using original object for url ' . $object_url, LOGGER_DEBUG);
if (($activity['uri'] != $activity['reply-to-uri']) && !Item::exists(['uri' => $activity['reply-to-uri']])) {
logger('Parent ' . $activity['reply-to-uri'] . ' not found. Try to refetch it.');
- self::fetchMissingActivity($activity['reply-to-uri']);
+ self::fetchMissingActivity($activity['reply-to-uri'], $activity);
}
self::postItem($activity, $item, $body);
}
}
- private static function fetchMissingActivity($url)
+ private static function fetchMissingActivity($url, $child)
{
$object = ActivityPub::fetchContent($url);
if (empty($object)) {
$activity['id'] = $object['id'];
$activity['to'] = defaults($object, 'to', []);
$activity['cc'] = defaults($object, 'cc', []);
- $activity['actor'] = $object['attributedTo'];
+ $activity['actor'] = $activity['author'];
$activity['object'] = $object;
$activity['published'] = $object['published'];
$activity['type'] = 'Create';
use Friendica\Model\Queue;
use Friendica\Model\User;
use Friendica\Protocol\DFRN;
+use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\Email;
switch ($contact['network']) {
+ case Protocol::ACTIVITYPUB:
+ self::deliverActivityPub($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
+ break;
+
case Protocol::DFRN:
self::deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
break;
logger('Unknown mode ' . $cmd . ' for ' . $loc);
}
+ /**
+ * @brief Deliver content via ActivityPub
+q *
+ * @param string $cmd Command
+ * @param array $contact Contact record of the receiver
+ * @param array $owner Owner record of the sender
+ * @param array $items Item record of the content and the parent
+ * @param array $target_item Item record of the content
+ * @param boolean $public_message Is the content public?
+ * @param boolean $top_level Is it a thread starter?
+ * @param boolean $followup Is it an answer to a remote post?
+ */
+ private static function deliverActivityPub($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup)
+ {
+ // We don't treat Forum posts as "wall-to-wall" to be able to post them via ActivityPub
+ $walltowall = $top_level && ($owner['id'] != $items[0]['contact-id']) & ($owner['account-type'] != Contact::ACCOUNT_TYPE_COMMUNITY);
+
+ if ($public_message) {
+ $loc = 'public batch ' . $contact['batch'];
+ } else {
+ $loc = $contact['addr'];
+ }
+
+ logger('Deliver ' . $target_item["guid"] . ' via ActivityPub to ' . $loc);
+
+// if (Config::get('system', 'dfrn_only') || !Config::get('system', 'diaspora_enabled')) {
+// return;
+// }
+ if ($cmd == self::MAIL) {
+// ActivityPub::sendMail($target_item, $owner, $contact);
+ return;
+ }
+
+ if ($cmd == self::SUGGESTION) {
+ return;
+ }
+// if (!$contact['pubkey'] && !$public_message) {
+// logger('No public key, no delivery.');
+// return;
+// }
+ if (($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) {
+ // top-level retraction
+ logger('ActivityPub retract: ' . $loc);
+// ActivityPub::sendRetraction($target_item, $owner, $contact, $public_message);
+ return;
+ } elseif ($cmd == self::RELOCATION) {
+// ActivityPub::sendAccountMigration($owner, $contact, $owner['uid']);
+ return;
+ } elseif ($followup) {
+ // send comments and likes to owner to relay
+ logger('ActivityPub followup: ' . $loc);
+ $data = ActivityPub::createActivityFromItem($target_item['id']);
+ $content = json_encode($data);
+ ActivityPub::transmit($content, $contact['notify'], $owner['uid']);
+// ActivityPub::sendFollowup($target_item, $owner, $contact, $public_message);
+ return;
+ } elseif ($target_item['uri'] !== $target_item['parent-uri']) {
+ // we are the relay - send comments, likes and relayable_retractions to our conversants
+ logger('ActivityPub relay: ' . $loc);
+ $data = ActivityPub::createActivityFromItem($target_item['id']);
+ $content = json_encode($data);
+ ActivityPub::transmit($content, $contact['notify'], $owner['uid']);
+// ActivityPub::sendRelay($target_item, $owner, $contact, $public_message);
+ return;
+ } elseif ($top_level && !$walltowall) {
+ // currently no workable solution for sending walltowall
+ logger('ActivityPub status: ' . $loc);
+ $data = ActivityPub::createActivityFromItem($target_item['id']);
+ $content = json_encode($data);
+ ActivityPub::transmit($content, $contact['notify'], $owner['uid']);
+// ActivityPub::sendStatus($target_item, $owner, $contact, $public_message);
+ return;
+ }
+
+ logger('Unknown mode ' . $cmd . ' for ' . $loc);
+ }
+
/**
* @brief Deliver content via mail
*