aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2024-10-06 15:53:39 +0000
committerMario <mario@mariovavti.com>2024-10-06 15:53:39 +0000
commit1988d21e6c64db1a93cc81f80409ce7d918aae7d (patch)
treea180c42074fd529b0ec608c5e304e1ccadd83639
parent19eeadfe5bafb8bdec3ac102d9b9f49593cc0933 (diff)
downloadvolse-hubzilla-1988d21e6c64db1a93cc81f80409ce7d918aae7d.tar.gz
volse-hubzilla-1988d21e6c64db1a93cc81f80409ce7d918aae7d.tar.bz2
volse-hubzilla-1988d21e6c64db1a93cc81f80409ce7d918aae7d.zip
start containers
-rw-r--r--Zotlabs/Daemon/Notifier.php2
-rw-r--r--Zotlabs/Lib/Activity.php133
-rw-r--r--Zotlabs/Lib/Libzot.php1
-rw-r--r--Zotlabs/Module/Conversation.php4
-rw-r--r--Zotlabs/Module/Item.php38
-rw-r--r--include/items.php150
6 files changed, 287 insertions, 41 deletions
diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php
index 20134b8fe..76e0628bf 100644
--- a/Zotlabs/Daemon/Notifier.php
+++ b/Zotlabs/Daemon/Notifier.php
@@ -345,7 +345,7 @@ class Notifier {
}
logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG);
- logger('encoded: ' . print_r(self::$encoded_item, true), LOGGER_DEBUG);
+ hz_syslog('encoded: ' . print_r(self::$encoded_item, true), LOGGER_DEBUG);
// Send comments to the owner to re-deliver to everybody in the conversation
// We only do this if the item in question originated on this site. This prevents looping.
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index 1ea42acd3..2b9beb3f5 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -8,6 +8,7 @@ use Zotlabs\Access\PermissionRoles;
use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Master;
use Zotlabs\Web\HTTPSig;
+use Zotlabs\Entity\Item;
require_once('include/event.php');
require_once('include/html2plain.php');
@@ -570,6 +571,25 @@ class Activity {
if ($i['mid'] !== $i['parent_mid']) {
$ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent']));
+
+ $cnv = IConfig::Get($i['parent'], 'activitypub', 'context');
+ if (!$cnv) {
+ $cnv = $i['parent_mid'];
+ }
+ }
+
+ if (empty($cnv)) {
+ $cnv = IConfig::Get($i, 'activitypub', 'context');
+ if (!$cnv) {
+ $cnv = $i['parent_mid'];
+ }
+ }
+
+ if (!empty($cnv)) {
+ if (is_string($cnv) && str_starts_with($cnv, z_root())) {
+ $cnv = str_replace(['/item/', '/activity/'], ['/conversation/', '/conversation/'], $cnv);
+ }
+ $ret['context'] = $cnv;
}
if ($i['mimetype'] === 'text/bbcode') {
@@ -589,6 +609,12 @@ class Activity {
$t = self::encode_taxonomy($i);
if ($t) {
+ foreach($t as $tag) {
+ if (strcasecmp($tag['name'], '#nsfw') === 0 || strcasecmp($tag['name'], '#sensitive') === 0) {
+ $ret['sensitive'] = true;
+ }
+ }
+
$ret['tag'] = $t;
}
@@ -596,7 +622,20 @@ class Activity {
if ($a) {
$ret['attachment'] = $a;
}
-
+/*
+ if ($i['target']) {
+ if (is_string($i['target'])) {
+ $tmp = json_decode($i['target'], true);
+ if ($tmp !== null) {
+ $i['target'] = $tmp;
+ }
+ }
+ $tgt = self::encode_object($i['target']);
+ if ($tgt) {
+ $ret['target'] = $tgt;
+ }
+ }
+*/
if (intval($i['item_private']) === 0) {
$ret['to'] = [ACTIVITY_PUBLIC_INBOX];
}
@@ -938,6 +977,25 @@ class Activity {
if (!in_array($ret['type'], ['Create', 'Update', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject'])) {
$ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent']));
}
+
+ $cnv = IConfig::Get($i['parent'], 'activitypub', 'context');
+ if (!$cnv) {
+ $cnv = $item['parent_mid'];
+ }
+ }
+
+ if (empty($cnv)) {
+ $cnv = IConfig::Get($i, 'activitypub', 'context');
+ if (!$cnv) {
+ $cnv = $i['parent_mid'];
+ }
+ }
+
+ if (!empty($cnv)) {
+ if (is_string($cnv) && str_starts_with($cnv, z_root())) {
+ $cnv = str_replace(['/item/', '/activity/'], ['/conversation/', '/conversation/'], $cnv);
+ }
+ $ret['context'] = $cnv;
}
$actor = self::encode_person($i['author'], false);
@@ -1009,7 +1067,11 @@ class Activity {
call_hooks('encode_activity', $hookinfo);
+//hz_syslog(print_r($hookinfo['encoded'], true));
+
return $hookinfo['encoded'];
+
+
}
// Returns an array of URLS for any mention tags found in the item array $i.
@@ -2867,6 +2929,10 @@ class Activity {
// This isn't perfect but the best we can do for now.
$item['comment_policy'] = ((isset($act->data['commentPolicy'])) ? $act->data['commentPolicy'] : 'authenticated');
+ if (!empty($act->obj['context'])) {
+ IConfig::Set($item, 'activitypub', 'context', $act->obj['context'], 1);
+ }
+
IConfig::Set($item, 'activitypub', 'recips', $act->raw_recips);
if (intval($act->sigok)) {
@@ -3676,5 +3742,70 @@ class Activity {
}
}
+ public static function addToCollection($channel, $object, $target, $sourceItem = null, $deliver = true) {
+ if (!isset($channel['xchan_hash'])) {
+ $channel = channelx_by_hash($channel['channel_hash']);
+ }
+
+ $item = ((new Item())
+ ->setUid($channel['channel_id'])
+ ->setVerb('Add')
+ ->setAuthorXchan($channel['channel_hash'])
+ ->setOwnerXchan($channel['channel_hash'])
+ ->setObj($object)
+ ->setObjType($object['type'])
+ ->setParentMid(str_replace('/conversation/','/item/', $target))
+ ->setThrParent(str_replace('/conversation/','/item/', $target))
+ ->setApproved($object['object']['id'] ?? '')
+ ->setReplyto(z_root() . '/channel/' . $channel['channel_address'])
+ ->setTgtType('Collection')
+ ->setTarget([
+ 'id' => str_replace('/item/','/conversation/', $target),
+ 'type' => 'Collection',
+ 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'],
+ ])
+ );
+ if ($sourceItem) {
+ $item->setAllowCid($sourceItem['allow_cid'])
+ ->setAllowGid($sourceItem['allow_gid'])
+ ->setDenyCid($sourceItem['deny_cid'])
+ ->setDenyGid($sourceItem['deny_gid'])
+ ->setPrivate($sourceItem['item_private'])
+ ->setNocomment($sourceItem['item_nocomment'])
+ ->setCommentPolicy($sourceItem['comment_policy'])
+ ->setPostopts($sourceItem['postopts']);
+ }
+ $result = post_activity_item($item->toArray(), deliver: $deliver, channel: $channel, observer: $channel, addAndSync: false);
+ logger('addToCollection: ' . print_r($result, true));
+ return $result;
+ }
+
+ public static function removeFromCollection($channel, $object, $target, $deliver = true) {
+ if (!isset($channel['xchan_hash'])) {
+ $channel = channelx_by_hash($channel['channel_hash']);
+ }
+
+ $item = ((new Item())
+ ->setUid($channel['channel_id'])
+ ->setVerb('Remove')
+ ->setAuthorXchan($channel['channel_hash'])
+ ->setOwnerXchan($channel['channel_hash'])
+ ->setObj($object)
+ ->setObjType($object['type'])
+ ->setParentMid(str_replace('/conversation/','/item/', $target))
+ ->setThrParent(str_replace('/conversation/','/item/', $target))
+ ->setReplyto(z_root() . '/channel/' . $channel['channel_address'])
+ ->setTgtType('Collection')
+ ->setTarget([
+ 'id' => str_replace('/item/','/conversation/', $target),
+ 'type' => 'Collection',
+ 'attributedTo' => z_root() . '/channel/' . $channel['channel_address']
+ ])
+ );
+
+ $result = post_activity_item($item->toArray(), deliver: $deliver, channel: $channel, observer: $channel, addAndSync: false);
+ logger('removeFromCollection: ' . print_r($result, true));
+ return $result;
+ }
}
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index bc944c97c..243588d2b 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -1148,6 +1148,7 @@ class Libzot {
logger('Activity rejected: ' . print_r($data, true));
return;
}
+
if (is_array($AS->obj)) {
$item = Activity::decode_note($AS);
if (!$item) {
diff --git a/Zotlabs/Module/Conversation.php b/Zotlabs/Module/Conversation.php
index aa8349f55..c3e6ae5ec 100644
--- a/Zotlabs/Module/Conversation.php
+++ b/Zotlabs/Module/Conversation.php
@@ -16,7 +16,7 @@ class Conversation extends Controller {
public function init() {
- if (ActivityStreams::is_as_request()) {
+ if (ActivityStreams::is_as_request() || Libzot::is_zot_request()) {
$item_id = argv(1);
if (!$item_id) {
@@ -77,7 +77,7 @@ class Conversation extends Controller {
}
}
}
- elseif (Config::get('system', 'require_authenticated_fetch', false)) {
+ elseif (Config::Get('system', 'require_authenticated_fetch', false)) {
http_status_exit(403, 'Permission denied');
}
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 5618137a1..c755fadd0 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -1029,18 +1029,44 @@ class Item extends Controller {
}
- if ($moderated)
+ if ($moderated) {
$item_blocked = ITEM_MODERATED;
+ }
- if (!strlen($verb))
+ if (!strlen($verb)) {
$verb = 'Create';
+ }
$notify_type = (($parent) ? 'comment-new' : 'wall-new');
$uuid = $uuid ?? $message_id ?? item_message_id();
$mid = $mid ?? z_root() . '/item/' . $uuid;
+
+ // Set the conversation target.
+ if (empty($owner_hash)) {
+ $owner_hash = $owner_xchan['xchan_hash'];
+ }
+
+ if ($owner_hash === $channel['channel_hash']) {
+ $attributedTo = z_root() . '/channel/' . $channel['channel_address'];
+
+ $conversation = isset($parent_item) ? $parent_item['mid'] : $mid;
+ $datarray['target'] = [
+ 'id' => str_replace('/item/', '/conversation/', $conversation),
+ 'type' => 'Collection',
+ 'attributedTo' => $attributedTo,
+ ];
+ $datarray['tgt_type'] = 'Collection';
+ }
+ elseif (!empty($parent_item['target'])) {
+ $datarray['target'] = $parent_item['target'];
+ $datarray['tgt_type'] = $parent_item['tgt_type'];
+ }
+
+
+
if ($is_poll) {
$poll = [
'question' => $body,
@@ -1375,8 +1401,12 @@ class Item extends Controller {
$nopush = false;
}
- if (!$nopush)
- Master::Summon(['Notifier', $notify_type, $post_id]);
+ if (!$nopush) {
+ Master::Summon(['Notifier', $notify_type, $post_id]);
+ if (intval($post['approval_id'])) {
+ Master::Summon(['Notifier', $notify_type, $post['approval_id']]);
+ }
+ }
logger('post_complete');
diff --git a/include/items.php b/include/items.php
index 23222892f..fa699148a 100644
--- a/include/items.php
+++ b/include/items.php
@@ -431,8 +431,9 @@ function add_source_route($iid, $hash) {
* * \e boolean \b success true or false
* * \e array \b activity the resulting activity if successful
*/
-function post_activity_item($arr, $allow_code = false, $deliver = true) {
+
+function post_activity_item($arr, $allow_code = false, $deliver = true, $channel = null, $observer = null, $addAndSync = true) {
$ret = array('success' => false);
$is_comment = false;
@@ -446,8 +447,13 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
if(! array_key_exists('item_thread_top',$arr) && (! $is_comment))
$arr['item_thread_top'] = 1;
- $channel = App::get_channel();
- $observer = App::get_observer();
+ if (!$channel) {
+ $channel = App::get_channel();
+ }
+
+ if (!$observer) {
+ $observer = App::get_observer();
+ }
$arr['aid'] = ((x($arr,'aid')) ? $arr['aid'] : $channel['channel_account_id']);
$arr['uid'] = ((x($arr,'uid')) ? $arr['uid'] : $channel['channel_id']);
@@ -493,6 +499,14 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
$arr['plink'] = $arr['mid'];
}
+ if (!$arr['target']) {
+ $arr['target'] = [
+ 'id' => str_replace('/item/', '/conversation/', $arr['parent_mid']),
+ 'type' => 'Collection',
+ 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'],
+ ];
+ $arr['tgt_type'] = 'Collection';
+ }
// for the benefit of plugins, we will behave as if this is an API call rather than a normal online post
@@ -509,29 +523,32 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
return $ret;
}
- $post = item_store($arr,$allow_code,$deliver);
+ $post = item_store($arr, $allow_code, $deliver, $addAndSync);
- if($post['success']) {
- $post_id = $post['item_id'];
- $ret['success'] = true;
- $ret['item_id'] = $post_id;
- $ret['activity'] = $post['item'];
+hz_syslog('xxx: ' . print_r($post, true));
- /**
- * @hooks post_local_end
- * Called after a local post operation has completed.
- * * \e array - the item returned from item_store()
- */
- call_hooks('post_local_end', $ret['activity']);
- }
- else
+ if (!$post['success']) {
return $ret;
-
- if($post_id && $deliver) {
- Master::Summon(['Notifier','activity', $post_id]);
}
+ $post_id = $post['item_id'];
$ret['success'] = true;
+ $ret['item_id'] = $post_id;
+ $ret['activity'] = $post['item'];
+
+ /**
+ * @hooks post_local_end
+ * Called after a local post operation has completed.
+ * * \e array - the item returned from item_store()
+ */
+ call_hooks('post_local_end', $ret['activity']);
+
+ if($post_id && $deliver) {
+ Master::Summon(['Notifier', 'activity', $post_id]);
+ if (!empty($post['approval_id'])) {
+ Master::Summon(['Notifier', 'activity', $post['approval_id']]);
+ }
+ }
return $ret;
}
@@ -1594,7 +1611,7 @@ function item_json_encapsulate($arr, $k) {
* * \e boolean \b success
* * \e int \b item_id
*/
-function item_store($arr, $allow_exec = false, $deliver = true) {
+function item_store($arr, $allow_exec = false, $deliver = true, $addAndSync = true) {
$d = [
'item' => $arr,
@@ -2052,6 +2069,13 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
Master::Summon([ 'Cache_embeds', $current_post ]);
}
+ $ret['success'] = true;
+ $ret['item_id'] = $current_post;
+
+ if ($addAndSync) {
+ $ret = addToCollectionAndSync($ret);
+ }
+
// If _creating_ a deleted item, don't propagate it further or send out notifications.
// We need to store the item details just in case the delete came in before the original post,
// so that we have an item in the DB that's marked deleted and won't store a fresh post
@@ -2062,9 +2086,6 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
tag_deliver($arr['uid'],$current_post);
}
- $ret['success'] = true;
- $ret['item_id'] = $current_post;
-
return $ret;
}
@@ -2077,7 +2098,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
* @param boolean $deliver (optional) default true
* @return array
*/
-function item_store_update($arr, $allow_exec = false, $deliver = true) {
+function item_store_update($arr, $allow_exec = false, $deliver = true, $addAndSync = true) {
$d = [
'item' => $arr,
@@ -2390,17 +2411,19 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) {
Master::Summon([ 'Cache_embeds', $orig_post_id ]);
}
+ $ret['success'] = true;
+ $ret['item_id'] = $orig_post_id;
-
+ if ($addAndSync) {
+ $ret = addToCollectionAndSync($ret);
+ }
if($deliver) {
- send_status_notifications($orig_post_id,$arr);
+ // don't send notify_comment for edits
+ // send_status_notifications($orig_post_id,$arr);
tag_deliver($uid,$orig_post_id);
}
- $ret['success'] = true;
- $ret['item_id'] = $orig_post_id;
-
return $ret;
}
@@ -3101,6 +3124,11 @@ function i_am_mentioned($channel, $item, $check_groups = false) {
*/
function start_delivery_chain($channel, $item, $item_id, $parent, $group = false, $edit = false) {
+ if ($item['author_xchan'] === $channel['channel_hash'] && in_array($item['verb'], ['Add', 'Remove'])) {
+ logger('delivery chain already started');
+ return;
+ }
+
$sourced = check_item_source($channel['channel_id'],$item);
if($sourced) {
@@ -3362,7 +3390,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
$arr['deny_gid'] = $channel['channel_deny_gid'];
$arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'));
- $post = item_store($arr);
+ $post = item_store($arr, deliver: false, addAndSync: false);
$post_id = $post['item_id'];
if ($post_id) {
@@ -5092,7 +5120,7 @@ function fix_attached_permissions($uid, $body, $str_contact_allow, $str_group_al
* which will allow you to interact with it.
*/
-function copy_of_pubitem($channel,$mid) {
+function copy_of_pubitem($channel, $mid) {
$result = null;
$syschan = get_sys_channel();
@@ -5134,12 +5162,68 @@ function copy_of_pubitem($channel,$mid) {
$rv['item_wall'] = 0;
$rv['item_origin'] = 0;
- $x = item_store($rv);
+ $x = item_store($rv, deliver: false, addAndSync: false);
if($x['item_id'] && $x['item']['mid'] === $mid) {
$result = $x['item'];
+ sync_an_item($channel['channel_id'], $x['item_id']);
}
}
}
return $result;
}
+
+function addToCollectionAndSync($ret) {
+ if (!$ret['success']) {
+ return $ret;
+ }
+
+ $channel = channelx_by_n($ret['item']['uid']);
+ if ($channel && $channel['channel_hash'] === $ret['item']['owner_xchan']) {
+ $items = [$ret['item']];
+ if ((int)$items[0]['item_blocked'] === ITEM_MODERATED
+ || (int)$items[0]['item_unpublished'] || (int)$items[0]['item_delayed']) {
+ return $ret;
+ }
+ xchan_query($items);
+ $items = fetch_post_tags($items);
+ $sync_items = [];
+ $sync_items[] = encode_item($items[0], true);
+
+ if (!in_array($ret['item']['verb'], ['Add', 'Remove'])) {
+
+ $newObj = Activity::build_packet(Activity::encode_activity($items[0]), $channel, false);
+ $approval = Activity::addToCollection($channel, $newObj, $ret['item']['parent_mid'], $ret['item'], deliver: false);
+//hz_syslog(print_r($approval, true));
+ if ($approval['success']) {
+ $ret['approval_id'] = $approval['item_id'];
+ $ret['approval'] = $approval['activity'];
+ $addItems = [$approval['activity']];
+ xchan_query($addItems);
+ $addItems = fetch_post_tags($addItems);
+ $sync_items[] = encode_item($addItems[0], true);
+ }
+ }
+
+ $resource_type = $ret['item']['resource_type'];
+
+ if ($resource_type === 'event') {
+ $z = q("select * from event where event_hash = '%s' and uid = %d limit 1",
+ dbesc($ret['item']['resource_id']),
+ intval($channel['channel_id'])
+ );
+
+ if ($z) {
+ Libsync::build_sync_packet($channel['channel_id'], ['event_item' => $sync_items, 'event' => $z]);
+ }
+ }
+ elseif ($resource_type === 'photo') {
+ // reserved for future use, currently handled in the photo upload workflow
+ }
+ else {
+ Libsync::build_sync_packet($ret['item']['uid'], ['item' => $sync_items]);
+ }
+ }
+
+ return $ret;
+}