if (in_array($mode, ['community', 'contacts'])) {
$writable = true;
} else {
- $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], [Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
+ $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
}
if (!local_user()) {
foreach ($items as $index => $item) {
if ($item['uid'] == 0) {
- $items[$index]['writable'] = in_array($item['network'], [Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
+ $items[$index]['writable'] = in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
}
}
}
if ((($cid == 0) || ($rel == Contact::FOLLOWER)) &&
- in_array($item['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) {
+ in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) {
$menu[L10n::t('Connect/Follow')] = 'follow?url=' . urlencode($item['author-link']);
}
} else {
$relation_text = '';
}
- if (!in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) {
+ if (!in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) {
$relation_text = "";
}
}
$lblsuggest = (($contact['network'] === Protocol::DFRN) ? L10n::t('Suggest friends') : '');
- $poll_enabled = in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
+ $poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
$nettype = L10n::t('Network type: %s', ContactSelector::networkToName($contact['network'], $contact["url"]));
$profiledata = Contact::getDetailsByURL($contact["url"]);
if (local_user()) {
- if (in_array($profiledata["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
+ if (in_array($profiledata["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
$profiledata["remoteconnect"] = System::baseUrl()."/follow?url=".urlencode($profiledata["url"]);
}
}
$profiledata = Contact::getDetailsByURL($contact["url"]);
if (local_user()) {
- if (in_array($profiledata["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
+ if (in_array($profiledata["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
$profiledata["remoteconnect"] = System::baseUrl()."/follow?url=".urlencode($profiledata["url"]);
}
}
*/
function contact_actions($contact)
{
- $poll_enabled = in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
+ $poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
$contact_actions = [];
// Provide friend suggestion only for Friendica contacts
if ((valid_email($search) && Network::isEmailDomainValid($search)) ||
(substr(normalise_link($search), 0, 7) == "http://")) {
$user_data = Probe::uri($search);
- $discover_user = (in_array($user_data["network"], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA]));
+ $discover_user = (in_array($user_data["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA]));
}
}
public static function networkToName($s, $profile = "")
{
$nets = [
- Protocol::DFRN => L10n::t('Friendica'),
- Protocol::OSTATUS => L10n::t('OStatus'),
- Protocol::FEED => L10n::t('RSS/Atom'),
- Protocol::MAIL => L10n::t('Email'),
- Protocol::DIASPORA => L10n::t('Diaspora'),
- Protocol::ZOT => L10n::t('Zot!'),
- Protocol::LINKEDIN => L10n::t('LinkedIn'),
- Protocol::XMPP => L10n::t('XMPP/IM'),
- Protocol::MYSPACE => L10n::t('MySpace'),
- Protocol::GPLUS => L10n::t('Google+'),
- Protocol::PUMPIO => L10n::t('pump.io'),
- Protocol::TWITTER => L10n::t('Twitter'),
- Protocol::DIASPORA2 => L10n::t('Diaspora Connector'),
- Protocol::STATUSNET => L10n::t('GNU Social Connector'),
- Protocol::PNUT => L10n::t('pnut'),
+ Protocol::DFRN => L10n::t('Friendica'),
+ Protocol::OSTATUS => L10n::t('OStatus'),
+ Protocol::FEED => L10n::t('RSS/Atom'),
+ Protocol::MAIL => L10n::t('Email'),
+ Protocol::DIASPORA => L10n::t('Diaspora'),
+ Protocol::ZOT => L10n::t('Zot!'),
+ Protocol::LINKEDIN => L10n::t('LinkedIn'),
+ Protocol::XMPP => L10n::t('XMPP/IM'),
+ Protocol::MYSPACE => L10n::t('MySpace'),
+ Protocol::GPLUS => L10n::t('Google+'),
+ Protocol::PUMPIO => L10n::t('pump.io'),
+ Protocol::TWITTER => L10n::t('Twitter'),
+ Protocol::DIASPORA2 => L10n::t('Diaspora Connector'),
+ Protocol::STATUSNET => L10n::t('GNU Social Connector'),
+ Protocol::ACTIVITYPUB => L10n::t('ActivityPub'),
+ Protocol::PNUT => L10n::t('pnut'),
];
Addon::callHooks('network_to_name', $nets);
$networkname = str_replace($search, $replace, $s);
- if ((in_array($s, [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) && ($profile != "")) {
+ if ((in_array($s, [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) && ($profile != "")) {
$r = DBA::fetchFirst("SELECT `gserver`.`platform` FROM `gcontact`
INNER JOIN `gserver` ON `gserver`.`nurl` = `gcontact`.`server_url`
WHERE `gcontact`.`nurl` = ? AND `platform` != ''", normalise_link($profile));
$nets = array();
while ($rr = DBA::fetch($r)) {
- /// @TODO If 'network' is not there, this triggers an E_NOTICE
- if ($rr['network']) {
- $nets[] = array('ref' => $rr['network'], 'name' => ContactSelector::networkToName($rr['network']), 'selected' => (($selected == $rr['network']) ? 'selected' : '' ));
- }
+ $nets[] = array('ref' => $rr['network'], 'name' => ContactSelector::networkToName($rr['network']), 'selected' => (($selected == $rr['network']) ? 'selected' : '' ));
}
DBA::close($r);
}
if ((empty($profile["addr"]) || empty($profile["name"])) && (defaults($profile, "gid", 0) != 0)
- && in_array($profile["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])
+ && in_array($profile["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])
) {
Worker::add(PRIORITY_LOW, "UpdateGContact", $profile["gid"]);
}
}
// Last try in gcontact for unsupported networks
- if (!in_array($data["network"], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::PUMPIO, Protocol::MAIL, Protocol::FEED])) {
+ if (!in_array($data["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::PUMPIO, Protocol::MAIL, Protocol::FEED])) {
if ($uid != 0) {
return 0;
}
return '';
}
- if (in_array($r[0]["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
+ if (in_array($r[0]["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
$sql = "(`item`.`uid` = 0 OR (`item`.`uid` = ? AND NOT `item`.`global`))";
} else {
$sql = "`item`.`uid` = ?";
const PARCEL_DIASPORA = 2;
const PARCEL_SALMON = 3;
const PARCEL_FEED = 4; // Deprecated
+ const PARCEL_ACTIVITYPUB = 5;
const PARCEL_SPLIT_CONVERSATION = 6;
const PARCEL_TWITTER = 67;
public static function insert(array $arr)
{
if (in_array(defaults($arr, 'network', Protocol::PHANTOM),
- [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::TWITTER]) && !empty($arr['uri'])) {
+ [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::TWITTER]) && !empty($arr['uri'])) {
$conversation = ['item-uri' => $arr['uri'], 'received' => DateTimeFormat::utcNow()];
if (isset($arr['parent-uri']) && ($arr['parent-uri'] != $arr['uri'])) {
unset($old_conv['source']);
}
// Update structure data all the time but the source only when its from a better protocol.
- if (isset($conversation['protocol']) && isset($conversation['source']) && ($old_conv['protocol'] < $conversation['protocol']) && ($old_conv['protocol'] != 0)) {
+ if (isset($conversation['protocol']) && isset($conversation['source']) && ($old_conv['protocol'] < $conversation['protocol'])
+ && ($old_conv['protocol'] != 0) && ($old_conv['protocol'] != self::PARCEL_ACTIVITYPUB)) {
unset($conversation['protocol']);
unset($conversation['source']);
}
// We can always comment on posts from these networks
if (array_key_exists('writable', $row) &&
- in_array($row['internal-network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
+ in_array($row['internal-network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
$row['writable'] = true;
}
* We have to check several networks since Friendica posts could be repeated
* via OStatus (maybe Diasporsa as well)
*/
- if (in_array($item['network'], [Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS, ""])) {
+ if (in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS, ""])) {
$condition = ["`uri` = ? AND `uid` = ? AND `network` IN (?, ?, ?)",
trim($item['uri']), $item['uid'],
Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS];
// Only distribute public items from native networks
$condition = ['id' => $itemid, 'uid' => 0,
- 'network' => [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""],
+ 'network' => [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""],
'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
$item = self::selectFirst(self::ITEM_FIELDLIST, ['id' => $itemid]);
if (!DBA::isResult($item)) {
}
// is it an entry from a connector? Only add an entry for natively connected networks
- if (!in_array($item["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
+ if (!in_array($item["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
return;
}
$tempfile = tempnam(get_temppath(), $filename);
file_put_contents($tempfile, json_encode(['header' => $_SERVER, 'body' => $postdata]));
- System::httpExit(200);
+ logger('Incoming message stored under ' . $tempfile);
+
+ ActivityPub::processInbox($postdata, $_SERVER);
+
+ System::httpExit(202);
}
}
if ($network != Protocol::ACTIVITYPUB) {
$data = self::detect($uri, $network, $uid);
+ } else {
+ $data = null;
}
if (in_array(defaults($data, 'network', ''), ['', Protocol::PHANTOM])) {
use Friendica\Util\Network;
use Friendica\Util\HTTPSignature;
use Friendica\Core\Protocol;
+use Friendica\Model\Conversation;
+use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Crypto;
use Friendica\Content\Text\BBCode;
+use Friendica\Content\Text\HTML;
use Friendica\Network\Probe;
/**
return $profile;
}
+ public static function processInbox($body, $header)
+ {
+ logger('Incoming message', LOGGER_DEBUG);
+
+ if (!self::verifySignature($body, $header)) {
+ logger('Invalid signature, message will be discarded.', LOGGER_DEBUG);
+ return;
+ }
+
+ $activity = json_decode($body, true);
+
+ if (!is_array($activity)) {
+ logger('Invalid body.', LOGGER_DEBUG);
+ return;
+ }
+
+ self::processActivity($activity, $body);
+ }
+
public static function fetchOutbox($url)
{
$data = self::fetchContent($url);
}
foreach ($items as $activity) {
- self::processActivity($activity, $url);
+ self::processActivity($activity);
}
}
- function processActivity($activity, $url)
+ function processActivity($activity, $body = '')
{
if (empty($activity['type'])) {
+ logger('Empty type', LOGGER_DEBUG);
return;
}
if (empty($activity['object'])) {
+ logger('Empty object', LOGGER_DEBUG);
return;
}
if (empty($activity['actor'])) {
+ logger('Empty actor', LOGGER_DEBUG);
return;
+
}
$actor = self::processElement($activity, 'actor', 'id');
if (empty($actor)) {
+ logger('Empty actor - 2', LOGGER_DEBUG);
return;
}
} elseif (!empty($activity['object']['id'])) {
$object_url = $activity['object']['id'];
} else {
+ logger('No object found', LOGGER_DEBUG);
return;
}
$receivers = self::getReceivers($activity);
if (empty($receivers)) {
+ logger('No receivers found', LOGGER_DEBUG);
return;
}
// To-Do?
unset($activity['context']);
unset($activity['location']);
+ unset($activity['signature']);
// handled
unset($activity['to']);
unset($activity['instrument']);
unset($activity['inReplyTo']);
+/*
if (!empty($activity)) {
echo "Activity\n";
print_r($activity);
die($url."\n");
}
-
+*/
$activity = $structure;
// ----------------------------------
- $item = self::fetchObject($object_url, $url);
+ $item = self::fetchObject($object_url, $activity['object']);
if (empty($item)) {
+ logger("Object data couldn't be processed", LOGGER_DEBUG);
return;
}
$item['receiver'] = array_merge($item['receiver'], $receivers);
+ logger('Processing activity: ' . $activity['type'], LOGGER_DEBUG);
+
switch ($activity['type']) {
case 'Create':
case 'Update':
- self::createItem($item);
+ self::createItem($item, $body);
break;
case 'Announce':
- self::announceItem($item);
+ self::announceItem($item, $body);
break;
case 'Like':
case 'Dislike':
- self::activityItem($item);
+ self::activityItem($item, $body);
break;
case 'Follow':
break;
default:
- echo "Unknown activity: ".$activity['type']."\n";
+ logger('Unknown activity: ' . $activity['type'], LOGGER_DEBUG);
+/* echo "Unknown activity: ".$activity['type']."\n";
print_r($item);
die();
+*/
break;
}
}
}
$condition = ['self' => true, 'nurl' => normalise_link($receiver)];
- $contact = DBA::selectFirst('contact', ['id'], $condition);
+ $contact = DBA::selectFirst('contact', ['uid'], $condition);
if (!DBA::isResult($contact)) {
continue;
}
- $receivers[$receiver] = $contact['id'];
+ $receivers[$receiver] = $contact['uid'];
}
}
return $receivers;
if (!empty($activity['instrument'])) {
$item['service'] = self::processElement($activity, 'instrument', 'name', 'Service');
}
-
+/*
// Remove all "null" fields
foreach ($item as $field => $content) {
if (is_null($content)) {
unset($item[$field]);
}
}
-
+*/
return $item;
}
- private static function fetchObject($object_url, $url)
+ private static function fetchObject($object_url, $object = [])
{
$data = self::fetchContent($object_url);
if (empty($data)) {
- return false;
+ $data = $object;
+ if (empty($data)) {
+ logger('Empty content');
+ return false;
+ } else {
+ logger('Using provided object');
+ }
}
if (empty($data['type'])) {
+ logger('Empty type');
return false;
} else {
$type = $data['type'];
+ logger('Type ' . $type);
}
if (in_array($type, ['Note', 'Article', 'Video'])) {
- $common = self::processCommonData($data, $url);
+ $common = self::processCommonData($data);
}
switch ($type) {
case 'Note':
- return array_merge($common, self::processNote($data, $url));
+ return array_merge($common, self::processNote($data));
case 'Article':
- return array_merge($common, self::processArticle($data, $url));
+ return array_merge($common, self::processArticle($data));
case 'Video':
- return array_merge($common, self::processVideo($data, $url));
+ return array_merge($common, self::processVideo($data));
case 'Announce':
if (empty($data['object'])) {
return false;
}
- return self::fetchObject($data['object'], $url);
+ return self::fetchObject($data['object']);
case 'Person':
case 'Tombstone':
break;
default:
- echo "Unknown object type: ".$data['type']."\n";
+ logger('Unknown object type: ' . $data['type'], LOGGER_DEBUG);
+/* echo "Unknown object type: ".$data['type']."\n";
print_r($data);
die($url."\n");
+*/
break;
}
}
- private static function processCommonData(&$object, $url)
+ private static function processCommonData(&$object)
{
if (empty($object['id']) || empty($object['attributedTo'])) {
return false;
}
$item = [];
+ $item['type'] = $object['type'];
$item['uri'] = $object['id'];
if (!empty($object['inReplyTo'])) {
return $item;
}
- private static function processNote($object, $url)
+ private static function processNote($object)
{
$item = [];
unset($object['quoteUrl']);
unset($object['statusnetConversationId']);
- if (empty($object))
+// if (empty($object))
return $item;
-
+/*
echo "Unknown Note\n";
print_r($object);
print_r($item);
die($url."\n");
-
+*/
return [];
}
- private static function processArticle($object, $url)
+ private static function processArticle($object)
{
$item = [];
- if (empty($object))
+// if (empty($object))
return $item;
-
+/*
echo "Unknown Article\n";
print_r($object);
print_r($item);
die($url."\n");
-
+*/
return [];
}
- private static function processVideo($object, $url)
+ private static function processVideo($object)
{
$item = [];
unset($object['shares']);
unset($object['comments']);
- if (empty($object))
+// if (empty($object))
return $item;
-
+/*
echo "Unknown Video\n";
print_r($object);
print_r($item);
die($url."\n");
-
+*/
return [];
}
return false;
}
- private static function createItem($item)
+ private static function createItem($activity, $body)
{
-// print_r($item);
+// print_r($activity);
+
+ $item = [];
+ $item['network'] = Protocol::ACTIVITYPUB;
+ $item['wall'] = 0;
+ $item['origin'] = 0;
+// $item['private'] = 0;
+ $item['gravity'] = GRAVITY_COMMENT;
+ $item['author-id'] = Contact::getIdForURL($activity['author'], 0, true);
+ $item['owner-id'] = Contact::getIdForURL($activity['owner'], 0, true);
+ $item['uri'] = $activity['uri'];
+ $item['parent-uri'] = $activity['reply-to-uri'];
+ $item['verb'] = ACTIVITY_POST; // Todo
+ $item['object-type'] = ACTIVITY_OBJ_NOTE; // Todo
+ $item['created'] = $activity['published'];
+ $item['edited'] = $activity['updated'];
+ $item['guid'] = $activity['uuid'];
+ $item['title'] = HTML::toBBCode($activity['name']);
+ $item['content-warning'] = HTML::toBBCode($activity['summary']);
+ $item['body'] = HTML::toBBCode($activity['content']);
+ $item['location'] = $activity['location'];
+// $item['attach'] = $activity['attachments'];
+// $item['tag'] = self::constructTagList($activity['tags'], $activity['sensitive']);
+ $item['app'] = $activity['service'];
+ $item['plink'] = $activity['alternate-url'];
+
+ $item['protocol'] = Conversation::PARCEL_ACTIVITYPUB;
+ $item['source'] = $body;
+// $item[''] = $activity['context'];
+ $item['conversation-uri'] = $activity['conversation'];
+
+ foreach ($activity['receiver'] as $receiver) {
+ $item['uid'] = $receiver;
+ $item['contact-id'] = Contact::getIdForURL($activity['author'], $receiver, true);
+
+ if (($receiver != 0) && empty($item['contact-id'])) {
+ $item['contact-id'] = Contact::getIdForURL($activity['author'], 0, true);
+ }
+
+ $item_id = Item::insert($item);
+ logger('Storing for user ' . $item['uid'] . ': ' . $item_id);
+ if (!empty($item_id) && ($item['uid'] == 0)) {
+ Item::distribute($item_id);
+ }
+//print_r($item);
+ }
+// $item[''] = $activity['receiver'];
}
private static function announceItem($item)
$server_url = normalise_link(self::detectServer($profile));
}
- if (!in_array($gcontacts[0]["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::FEED, Protocol::OSTATUS, ""])) {
+ if (!in_array($gcontacts[0]["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::FEED, Protocol::OSTATUS, ""])) {
logger("Profile ".$profile.": Network type ".$gcontacts[0]["network"]." can't be checked", LOGGER_DEBUG);
return false;
}
}
// It only makes sense to distribute answers to OStatus messages to Friendica and OStatus - but not Diaspora
- $networks = [Protocol::OSTATUS, Protocol::DFRN];
+ $networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DFRN];
} else {
- $networks = [Protocol::OSTATUS, Protocol::DFRN, Protocol::DIASPORA, Protocol::MAIL];
+ $networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DFRN, Protocol::DIASPORA, Protocol::MAIL];
}
} else {
$public_message = false;
return;
}
- if (!in_array($r[0]["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
+ if (!in_array($r[0]["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
return;
}
$data = Probe::uri($r[0]["url"]);
- if (!in_array($data["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
+ if (!in_array($data["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
if ($r[0]["server_url"] != "") {
PortableContact::checkServer($r[0]["server_url"], $r[0]["network"]);
}