From 9aa7da034fff6a9aef50cd021f6389198c7da8af Mon Sep 17 00:00:00 2001 From: Mike Macgirvin Date: Sun, 11 Feb 2024 06:22:39 +1100 Subject: [PATCH] more heavy lifting on conversation collections. This optionally brings collection support into item_store() and also performs clone sync, removing a lot of duplicate code. Events needed significant refactoring. We cannot combine message delivery of standard items and collection activities, so this will have an impact on outgoing message queue size and processing. --- Code/Lib/Activity.php | 10 ++- Code/Lib/Libzot.php | 4 +- Code/Lib/Share.php | 14 ++-- Code/Module/Calendar.php | 25 ++----- Code/Module/Events.php | 28 ++------ Code/Module/Impel.php | 4 +- Code/Module/Item.php | 41 ++--------- Code/Module/Like.php | 14 ++-- Code/Module/Mood.php | 4 ++ Code/Module/Plike.php | 14 ++-- Code/Module/React.php | 3 + Code/Module/Settings/Profile_edit.php | 3 + Code/Module/Share.php | 14 ++-- Code/Module/Subthread.php | 2 +- Code/Module/Tagrm.php | 4 +- Code/Module/Vote.php | 12 +--- include/datetime.php | 2 +- include/event.php | 80 ++++++---------------- include/help.php | 4 +- include/import.php | 8 +-- include/items.php | 99 +++++++++++++++++++++------ include/photos.php | 4 ++ 22 files changed, 171 insertions(+), 222 deletions(-) diff --git a/Code/Lib/Activity.php b/Code/Lib/Activity.php index 16db3382d..00e6fb7b1 100644 --- a/Code/Lib/Activity.php +++ b/Code/Lib/Activity.php @@ -4273,11 +4273,11 @@ class Activity } } else { ObjCache::Set($item['mid'], $act->raw); - $x = item_store($item, deliver: false); + $x = item_store($item, deliver: false, addAndSync: false); } if ($relay && $channel['channel_hash'] === $x['item']['owner_xchan'] && $x['item']['verb'] !== 'Add' && !$isCollectionOperation) { - $x = Activity::addToCollection($channel, json_decode($act->raw,true), $x['item']['parent_mid'], $x['item'], deliver: false); + $approval = Activity::addToCollection($channel, json_decode($act->raw,true), $x['item']['parent_mid'], $x['item'], deliver: false); } @@ -4318,10 +4318,16 @@ class Activity if ($item['owner_xchan'] === $channel['channel_hash']) { // We are the owner of this conversation, so send all received comments back downstream Run::Summon(['Notifier', 'comment-import', $x['item_id']]); + if (!empty($approval['item_id'])) { + Run::Summon(['Notifier', 'comment-import', $approval['item_id']]); + } } } elseif ($act->client && $channel['channel_hash'] === $observer_hash && !$force) { Run::Summon(['Notifier', 'wall-new', $x['item_id']]); + if (!empty($approval['item_id'])) { + Run::Summon(['Notifier', 'wall-new', $approval['item_id']]); + } } $r = q( "select * from item where id = %d limit 1", diff --git a/Code/Lib/Libzot.php b/Code/Lib/Libzot.php index 854195d52..0126a16b7 100644 --- a/Code/Lib/Libzot.php +++ b/Code/Lib/Libzot.php @@ -2097,7 +2097,7 @@ class Libzot // IConfig::Set($arr, 'activitypub', 'signed_data', $act->meta['signed_data'], false); ObjCache::Set($arr['mid'], $act->raw); - $item_result = item_store($arr); + $item_result = item_store($arr, addAndSync: false); if ($item_result['success']) { $item_id = $item_result['item_id']; @@ -2325,7 +2325,7 @@ class Libzot } - $x = item_store_update($item); + $x = item_store_update($item, addAndSync: false); // If we're updating an event that we've saved locally, we store the item info first // because event_addtocal will parse the body to get the 'new' event details diff --git a/Code/Lib/Share.php b/Code/Lib/Share.php index dfb1ec0fa..1ab568edc 100644 --- a/Code/Lib/Share.php +++ b/Code/Lib/Share.php @@ -134,22 +134,16 @@ class Share $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; $arr['id'] = $post_id; Hook::call('post_local_end', $arr); - $r = q( - "select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); - } - Run::Summon([ 'Notifier','like',$post_id ]); + if ($approval_id) { + Run::Summon(['Notifier', 'like', $approval_id]); + } } } diff --git a/Code/Module/Calendar.php b/Code/Module/Calendar.php index 7f3dea091..215ccf58e 100644 --- a/Code/Module/Calendar.php +++ b/Code/Module/Calendar.php @@ -207,28 +207,15 @@ class Calendar extends Controller $datarray['term'] = $post_tags; } - $item_id = event_store_item($datarray, $event); + $post = event_store_item($datarray, $event); - if ($item_id) { - $r = q( - "select * from item where id = %d", - intval($item_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - $z = q( - "select * from event where event_hash = '%s' and uid = %d limit 1", - dbesc($r[0]['resource_id']), - intval($channel['channel_id']) - ); - if ($z) { - Libsync::build_sync_packet($channel['channel_id'], ['event_item' => [encode_item($sync_item[0], true)], 'event' => $z]); - } - } + if (!empty($post['item_id'])) { + Run::Summon(['Notifier', 'event', $post['item_id']]); + } + if (!empty($post['approval_id'])) { + Run::Summon(['Notifier', 'event', $post['approval_id']]); } - Run::Summon(['Notifier', 'event', $item_id]); killme(); } diff --git a/Code/Module/Events.php b/Code/Module/Events.php index bf3f43fbc..911270d1b 100644 --- a/Code/Module/Events.php +++ b/Code/Module/Events.php @@ -251,31 +251,17 @@ class Events extends Controller if ($post_tags) { $datarray['term'] = $post_tags; } + $post = event_store_item($datarray, $event); - $item_id = event_store_item($datarray, $event); - - if ($item_id) { - $r = q( - "select * from item where id = %d", - intval($item_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - $z = q( - "select * from event where event_hash = '%s' and uid = %d limit 1", - dbesc($r[0]['resource_id']), - intval($channel['channel_id']) - ); - if ($z) { - Libsync::build_sync_packet($channel['channel_id'], ['event_item' => [encode_item($sync_item[0], true)], 'event' => $z]); - } + if ($share) { + if (!empty($post['item_id'])) { + Run::Summon(['Notifier', 'event', $post['item_id']]); + } + if (!empty($post['approval_id'])) { + Run::Summon(['Notifier', 'event', $post['approval_id']]); } } - if ($share) { - Run::Summon(['Notifier', 'event', $item_id]); - } } diff --git a/Code/Module/Impel.php b/Code/Module/Impel.php index 3b724cddf..93b928fbf 100644 --- a/Code/Module/Impel.php +++ b/Code/Module/Impel.php @@ -175,7 +175,7 @@ class Impel extends Controller $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original if ($arr['edited'] > $i[0]['edited']) { - $x = item_store_update($arr); + $x = item_store_update($arr, deliver: false, addAndSync: false); } } else { if (($i) && (intval($i[0]['item_deleted']))) { @@ -186,7 +186,7 @@ class Impel extends Controller intval(local_channel()) ); } else { - $x = item_store($arr); + $x = item_store($arr, deliver: false, addAndSync: false); } } diff --git a/Code/Module/Item.php b/Code/Module/Item.php index b8d8b3cb4..452bde0ea 100644 --- a/Code/Module/Item.php +++ b/Code/Module/Item.php @@ -1679,12 +1679,6 @@ class Item extends Controller Run::Summon(['Notifier', 'edit_post', $post_id]); } - if ($channel['channel_hash'] === $datarray['owner_xchan'] && $datarray['verb'] !== 'Add') { - $items = [$datarray]; - xchan_query($items); - Activity::addToCollection($channel, Activity::encode_activity(array_shift($items), true), $datarray['parent_mid'], $datarray); - } - if ($api_source) { return ($x); } @@ -1786,23 +1780,6 @@ class Item extends Controller killme(); } - if (($parent) && ($parent != $post_id)) { - // Store the comment signature information in case we need to relay to Diaspora - //$ditem = $datarray; - //$ditem['author'] = $observer; - //store_diaspora_comment_sig($ditem,$channel,$parent_item, $post_id, (($walltowall_comment) ? 1 : 0)); - } else { - $r = q( - "select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); - } - } - $datarray['id'] = $post_id; $datarray['llink'] = z_root() . '/display/?mid=' . gen_link_id($datarray['mid']); @@ -1814,25 +1791,15 @@ class Item extends Controller if (!$nopush) { Run::Summon(['Notifier', $notify_type, $post_id]); + if (intval($post['approval_id'])) { + Run::Summon(['Notifier', $notify_type, $post['approval_id']]); + } } logger('post_complete'); if ($moderated) { info(t('Your post/comment is awaiting approval.') . EOL); } - elseif ($channel['channel_hash'] === $datarray['owner_xchan'] && $datarray['verb'] !== 'Add') { - $items = [$datarray]; - xchan_query($items); - for ($x = 0; $x < count($items); $x ++) { - $items[$x] = array_merge(Activity::ap_context(), Activity::encode_activity($items[$x])); - $items[$x]['proof'] = (new JcsEddsa2022())->sign($items[$x], $channel); - } - Activity::addToCollection($channel, array_shift($items), $datarray['parent_mid'], $datarray); - - // @fixme: if this is a local top-level post, sign the original but don't deliver it.!!! - - } - // figure out how to return, depending on from whence we came @@ -2090,7 +2057,7 @@ class Item extends Controller $expire_unit = $poll['expire_unit']; $question = $poll['question']; $answers = $poll['answers']; - $term = isset($poll['tags']) ? $poll_tags : []; + $term = isset($poll['tags']) ? $poll['tags'] : []; $obj = []; $ptr = []; diff --git a/Code/Module/Like.php b/Code/Module/Like.php index ee1df8c61..4ae08e359 100644 --- a/Code/Module/Like.php +++ b/Code/Module/Like.php @@ -291,6 +291,7 @@ class Like extends Controller $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; // save the conversation from expiration @@ -300,19 +301,14 @@ class Like extends Controller $arr['id'] = $post_id; + Hook::call('post_local_end', $arr); - $r = q( - "select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); + Run::Summon([ 'Notifier', 'like', $post_id ]); + if ($approval_id) { + Run::Summon([ 'Notifier', 'like', $approval_id ]); } - Run::Summon([ 'Notifier', 'like', $post_id ]); killme(); } diff --git a/Code/Module/Mood.php b/Code/Module/Mood.php index bd9a8f559..fae1d599f 100644 --- a/Code/Module/Mood.php +++ b/Code/Module/Mood.php @@ -114,9 +114,13 @@ class Mood extends Controller $post = item_store($arr); $item_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; if ($item_id) { Run::Summon(['Notifier', 'activity', $item_id]); + if ($approval_id) { + Run::Summon(['Notifier', 'activity', $approval_id]); + } } Hook::call('post_local_end', $arr); diff --git a/Code/Module/Plike.php b/Code/Module/Plike.php index 0808edbc9..37aeed1c2 100644 --- a/Code/Module/Plike.php +++ b/Code/Module/Plike.php @@ -259,6 +259,7 @@ class Plike extends Controller $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; // save the conversation from expiration @@ -270,16 +271,6 @@ class Plike extends Controller Hook::call('post_local_end', $arr); - $r = q( - "select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0], true) ] ]); - } - $r = q( "insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", intval($channel['channel_id']), @@ -306,6 +297,9 @@ class Plike extends Controller } Run::Summon([ 'Notifier', 'like', $post_id ]); + if ($approval_id) { + Run::Summon(['Notifier', 'like', $approval_id]); + } killme(); } diff --git a/Code/Module/React.php b/Code/Module/React.php index 347b26566..aa7a1781b 100644 --- a/Code/Module/React.php +++ b/Code/Module/React.php @@ -95,6 +95,9 @@ class React extends Controller if ($x['success']) { $nid = $x['item_id']; Run::Summon(['Notifier', 'like', $nid]); + if (!empty($x['approval_id'])) { + Run::Summon(['Notifier', 'like', $x['approval_id']]); + } } } } diff --git a/Code/Module/Settings/Profile_edit.php b/Code/Module/Settings/Profile_edit.php index 84b5d2088..0217e53c7 100644 --- a/Code/Module/Settings/Profile_edit.php +++ b/Code/Module/Settings/Profile_edit.php @@ -765,6 +765,9 @@ class Profile_edit if ($i) { Run::Summon(['Notifier', 'wall-new', $i]); + if (!empty($res['approval_id'])) { + Run::Summon(['Notifier', 'wall-new', $res['approval_id']]); + } } } diff --git a/Code/Module/Share.php b/Code/Module/Share.php index 3a5d34e7b..dcd5c8989 100644 --- a/Code/Module/Share.php +++ b/Code/Module/Share.php @@ -126,6 +126,7 @@ class Share extends Controller $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; $arr['id'] = $post_id; @@ -133,17 +134,10 @@ class Share extends Controller info(t('Post repeated') . EOL); - $r = q( - "select * from item where id = %d", - intval($post_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], ['item' => [encode_item($sync_item[0], true)]]); - } - Run::Summon(['Notifier', 'wall-new', $post_id]); + if ($approval_id) { + Run::Summon(['Notifier', 'wall-new', $approval_id]); + } killme(); } diff --git a/Code/Module/Subthread.php b/Code/Module/Subthread.php index 2b703a4bb..bb5d80f42 100644 --- a/Code/Module/Subthread.php +++ b/Code/Module/Subthread.php @@ -179,7 +179,7 @@ class Subthread extends Controller $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; - $post = item_store($arr); + $post = item_store($arr, deliver: false, addAndSync: false); $post_id = $post['item_id']; $arr['id'] = $post_id; diff --git a/Code/Module/Tagrm.php b/Code/Module/Tagrm.php index fac40c766..b6800be96 100644 --- a/Code/Module/Tagrm.php +++ b/Code/Module/Tagrm.php @@ -54,7 +54,7 @@ class Tagrm extends Controller unset($item['term']); } - item_store_update($item); + item_store_update($item, deliver: false, addAndSync: false); info(t('Tag removed') . EOL); goaway(z_root() . '/' . $_SESSION['photo_return']); @@ -106,7 +106,7 @@ class Tagrm extends Controller unset($item['term']); } - item_store_update($item); + item_store_update($item, deliver: false, addAndSync: false); info(t('Tag removed') . EOL); goaway(z_root() . '/' . $_SESSION['photo_return']); diff --git a/Code/Module/Vote.php b/Code/Module/Vote.php index 16beccc2c..79cffcfdd 100644 --- a/Code/Module/Vote.php +++ b/Code/Module/Vote.php @@ -140,17 +140,11 @@ class Vote extends Controller if ($x['success']) { $itemid = $x['item_id']; Run::Summon(['Notifier', 'like', $itemid]); + if (!empty($x['approval_id'])) { + Run::Summon(['Notifier', 'like', $x['approval_id']]); + } } - $r = q( - "select * from item where id = %d", - intval($itemid) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - Libsync::build_sync_packet($channel['channel_id'], ['item' => [encode_item($sync_item[0], true)]]); - } } $ret['success'] = true; $ret['message'] = t('Response submitted. Updates may not appear instantly.'); diff --git a/include/datetime.php b/include/datetime.php index 17d80bfef..b1b461b47 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -579,7 +579,7 @@ function update_birthdays() $z = event_store_event($ev); if ($z) { - event_store_item($ev, $z); + event_store_item($ev, $z, deliver: false, addAndSync: false); q( "update abook set abook_dob = '%s' where abook_id = %d", dbesc(intval($rr['abook_dob']) + 1 . substr($rr['abook_dob'], 4)), diff --git a/include/event.php b/include/event.php index 9e84c524d..70198a47e 100644 --- a/include/event.php +++ b/include/event.php @@ -994,7 +994,7 @@ function event_import_ical($ical, $uid) logger('storing event: ' . print_r($ev, true), LOGGER_ALL); $event = event_store_event($ev); if ($event) { - $item_id = event_store_item($ev, $event); + event_store_item($ev, $event, deliver: false, addAndSync: false); return true; } } @@ -1144,10 +1144,10 @@ function event_import_ical_task($ical, $uid) $ev['private'] = 1; $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>'; - logger('storing event: ' . print_r($ev, true), LOGGER_ALL); + logger('storing task event: ' . print_r($ev, true), LOGGER_ALL); $event = event_store_event($ev); if ($event) { - $item_id = event_store_item($ev, $event); + event_store_item($ev, $event, deliver: false, addAndSync: false); return true; } } @@ -1156,7 +1156,7 @@ function event_import_ical_task($ical, $uid) } -function event_store_item($arr, $event) +function event_store_item($arr, $event, $deliver = true, $addAndSync = true) { require_once('include/datetime.php'); @@ -1179,7 +1179,6 @@ function event_store_item($arr, $event) $item_arr = []; $prefix = ''; -// $birthday = false; if (($event) && array_key_exists('event_hash', $event) && (! array_key_exists('event_hash', $arr))) { $arr['event_hash'] = $event['event_hash']; @@ -1189,7 +1188,6 @@ function event_store_item($arr, $event) if (! Channel::is_system($arr['uid'])) { $prefix = t('This event has been added to your calendar.'); } -// $birthday = true; // The event is created on your own site by the system, but appears to belong // to the birthday person. It also isn't propagated - so we need to prevent @@ -1230,62 +1228,29 @@ function event_store_item($arr, $event) $x['eventRepeat'] = $event['event_repeat']; } $object = json_encode($x); + $item_arr = []; + $item_arr['obj'] = $object; + $item_arr['edited'] = $arr['edited']; + $item_arr['allow_cid'] = $arr['allow_cid']; + $item_arr['allow_gid'] = $arr['allow_gid']; + $item_arr['deny_cid'] = $arr['deny_cid']; + $item_arr['deny_gid'] = $arr['deny_gid']; + $item_arr['item_private'] = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); + $item_arr['title'] = $arr['summary']; + $item_arr['sig'] = ''; + $item_arr['id'] = $r[0]['id']; + $item_arr['body'] = $prefix . format_event_bbcode($arr); + $item_arr['term'] = $arr['term']; - $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); + $post = item_store_update($item_arr, $deliver, $addAndSync); - /** - * @FIXME can only update sig if we have the author's channel on this site - * Until fixed, set it to nothing so it won't give us signature errors. - */ - $sig = ''; - - q( - "UPDATE item SET title = '%s', body = '%s', obj = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d", - dbesc($arr['summary']), - dbesc($prefix . format_event_bbcode($arr)), - dbesc($object), - dbesc($arr['allow_cid']), - dbesc($arr['allow_gid']), - dbesc($arr['deny_cid']), - dbesc($arr['deny_gid']), - dbesc($arr['edited']), - dbesc($sig), - intval($r[0]['item_flags']), - intval($private), - dbesc(ACTIVITY_OBJ_EVENT), - intval($r[0]['id']), - intval($arr['uid']) - ); - - q( - "delete from term where oid = %d and otype = %d", - intval($r[0]['id']), - intval(TERM_OBJ_POST) - ); - - if (($arr['term']) && (is_array($arr['term']))) { - foreach ($arr['term'] as $t) { - q( - "insert into term (uid,oid,otype,ttype,term,url) - values(%d,%d,%d,%d,'%s','%s') ", - intval($arr['uid']), - intval($r[0]['id']), - intval(TERM_OBJ_POST), - intval($t['ttype']), - dbesc($t['term']), - dbesc($t['url']) - ); - } - } - - $item_id = $r[0]['id']; /** * @hooks event_updated * Called when an event record is modified. */ Hook::call('event_updated', $event['id']); - return $item_id; + return $post; } else { $z = Channel::from_id($arr['uid']); @@ -1312,7 +1277,6 @@ function event_store_item($arr, $event) $item_arr['aid'] = $z['channel_account_id']; $item_arr['uid'] = $arr['uid']; - $item_arr['author_xchan'] = $arr['event_xchan']; $item_arr['mid'] = $arr['mid']; $item_arr['parent_mid'] = $arr['mid']; $item_arr['uuid'] = $event['event_hash']; @@ -1398,9 +1362,7 @@ function event_store_item($arr, $event) set_iconfig($item_arr, 'system', 'event_id', $event['event_hash'], true); - $res = item_store($item_arr); - - $item_id = $res['item_id']; + $post = item_store($item_arr, $deliver, $addAndSync); /** * @hooks event_created @@ -1408,7 +1370,7 @@ function event_store_item($arr, $event) */ Hook::call('event_created', $event['id']); - return $item_id; + return $post; } } diff --git a/include/help.php b/include/help.php index fdf091946..f59bbadc5 100644 --- a/include/help.php +++ b/include/help.php @@ -262,11 +262,11 @@ function store_doc_file($s) if ($r) { $item['id'] = $r[0]['id']; $item['mid'] = $item['parent_mid'] = $r[0]['mid']; - $x = item_store_update($item); + $x = item_store_update($item, deliver: false, addAndSync: false); } else { $item['uuid'] = new_uuid(); $item['mid'] = $item['parent_mid'] = z_root() . '/item/' . $item['uuid']; - $x = item_store($item); + $x = item_store($item, deliver: false, addAndSync: false); } return $x; diff --git a/include/import.php b/include/import.php index 67371a2e6..cc3ce8ed2 100644 --- a/include/import.php +++ b/include/import.php @@ -1030,12 +1030,12 @@ function import_items($channel, $items, $sync = false, $relocate = null) if ($item['edited'] >= $r[0]['edited']) { $item['id'] = $r[0]['id']; $item['uid'] = $channel['channel_id']; - $item_result = item_store_update($item, $deliver); + $item_result = item_store_update($item, $deliver, addAndSync: false); } } else { $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; - $item_result = item_store($item, $deliver); + $item_result = item_store($item, $deliver, addAndSync: false); } // preserve conversations you've been involved in from being expired @@ -1983,11 +1983,11 @@ function import_webpage_element($element, $channel, $type) $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original if ($arr['edited'] > $i[0]['edited']) { - $x = item_store_update($arr); + $x = item_store_update($arr, deliver: false, addAndSync: false); } } else { - $x = item_store($arr); + $x = item_store($arr, deliver: false, addAndSync: false); } if ($x && $x['success']) { diff --git a/include/items.php b/include/items.php index 053d027a1..6fa6e8676 100644 --- a/include/items.php +++ b/include/items.php @@ -4,6 +4,7 @@ * @brief Items related functions. */ +use Code\Lib\JcsEddsa2022; use Code\Lib\Libzot; use Code\Lib\Libsync; use Code\Lib\AccessList; @@ -467,11 +468,13 @@ function post_activity_item($arr, $deliver = true, $channel = null, $observer = * * \e array - the item returned from item_store() */ Hook::call('post_local_end', $ret['activity']); - sync_an_item($channel ? $channel['channel_id'] : $arr['uid'], $post_id); } if($post_id && $deliver) { Run::Summon([ 'Notifier','activity',$post_id ]); + if (!empty($post['approval_id'])) { + Run::Summon([ 'Notifier','activity',$post['approval_id']]); + } } return $ret; @@ -1410,7 +1413,7 @@ function item_json_encapsulate($arr,$k) { * * \e boolean \b success * * \e int \b item_id */ -function item_store($arr, $deliver = true) { +function item_store($arr, $deliver = true, $addAndSync = true) { $d = [ 'item' => $arr, @@ -1892,6 +1895,12 @@ function item_store($arr, $deliver = true) { Run::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 @@ -1902,9 +1911,7 @@ function item_store($arr, $deliver = true) { tag_deliver($arr['uid'],$current_post); } - $ret['success'] = true; - $ret['item_id'] = $current_post; - +// experimental future use // if($linkid) { // $li = [ $ret['item'] ]; // xchan_query($li); @@ -1915,7 +1922,54 @@ function item_store($arr, $deliver = true) { return $ret; } +function addToCollectionAndSync($ret) +{ + if (!$ret['success']) { + return $ret; + } + $channel = Channel::from_id($ret['item']['uid']); + if ($channel && $channel['channel_hash'] === $ret['item']['owner_xchan']) { + $items = [$ret['item']]; + 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'])) { + $items[0] = array_merge(Activity::ap_context(), Activity::encode_activity($items[0])); + $items[0]['proof'] = (new JcsEddsa2022())->sign($items[0], $channel); + $approval = Activity::addToCollection($channel, + $items[0], + $ret['item']['parent_mid'], $ret['item'], deliver: false); + 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; +} /** * @brief Update a stored item. * @@ -1923,7 +1977,7 @@ function item_store($arr, $deliver = true) { * @param boolean $deliver (optional) default true * @return array */ -function item_store_update($arr, $deliver = true) { +function item_store_update($arr, $deliver = true, $addAndSync = true) { $d = [ 'item' => $arr, @@ -2236,15 +2290,21 @@ function item_store_update($arr, $deliver = true) { Run::Summon([ 'Cache_embeds', $orig_post_id ]); } + + + $ret['success'] = true; + $ret['item_id'] = $orig_post_id; + + if ($addAndSync) { + $ret = addToCollectionAndSync($ret); + } + if($deliver) { // 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; } @@ -3082,17 +3142,6 @@ function start_delivery_chain($channel, $item, $item_id, bool|array $parent, $gr $post = item_store($arr); } - $arr['target'] = [ - 'id' => str_replace('/item/', '/conversation/', $arr['mid']), - 'type' => 'Collection', - 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'], - ]; - $arr['tgt_type'] = 'Collection'; - - $items = [$post['item']]; - xchan_query($items); - $targetCollection = Activity::addToCollection($channel, Activity::encode_activity(array_shift($items), true), $arr['target']['id'], $arr,false); - $post_id = $post['item_id']; if ($source && $post_id && !$edit) { @@ -3121,6 +3170,10 @@ function start_delivery_chain($channel, $item, $item_id, bool|array $parent, $gr $post_id = $targetCollection ? $targetCollection['item_id'] : 0; if($post_id) { Run::Summon(['Notifier', 'tgroup', $post_id ]); + if (!empty($post['approval_id'])) { + Run::Summon(['Notifier', 'tgroup', $post['approval_id']]); + } + } q("update channel set channel_lastpost = '%s' where channel_id = %d", @@ -3204,6 +3257,9 @@ function start_delivery_chain($channel, $item, $item_id, bool|array $parent, $gr if ($post_id) { Run::Summon([ 'Notifier','tgroup',$post_id ]); + if (!empty($post['approval_id'])) { + Run::Summon(['Notifier', 'tgroup', $post['approval_id']]); + } } q("update channel set channel_lastpost = '%s' where channel_id = %d", @@ -4831,12 +4887,11 @@ 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']); } - } } else { diff --git a/include/photos.php b/include/photos.php index 71471d364..4a6a187a5 100644 --- a/include/photos.php +++ b/include/photos.php @@ -569,6 +569,10 @@ function photo_upload($channel, $observer, $args) if ($visible && $deliver) { Run::Summon([ 'Notifier', 'wall-new', $item_id ]); + if (!empty($result['approval_id'])) { + Run::Summon(['Notifier', 'wall-new', $result['approval_id']]); + } + } }