diff options
-rw-r--r-- | include/conversation.php | 6 | ||||
-rwxr-xr-x | include/items.php | 11 | ||||
-rw-r--r-- | include/zot.php | 61 |
3 files changed, 59 insertions, 19 deletions
diff --git a/include/conversation.php b/include/conversation.php index 0af603ca9..ea7719d4b 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -972,7 +972,10 @@ function item_photo_menu($item){ */ function builtin_activity_puller($item, &$conv_responses) { + // if this item is a post or comment there's nothing for us to do here, just return. + if(activity_match($item['verb'],ACTIVITY_POST)) + return; foreach($conv_responses as $mode => $v) { @@ -1036,6 +1039,9 @@ function builtin_activity_puller($item, &$conv_responses) { $conv_responses[$mode][$item['thr_parent']] ++; $conv_responses[$mode][$item['thr_parent'] . '-l'][] = $url; + + // there can only be one activity verb per item so if we found anything, we can stop looking + $return; } } diff --git a/include/items.php b/include/items.php index 2207635b6..de69a0f81 100755 --- a/include/items.php +++ b/include/items.php @@ -2280,9 +2280,16 @@ function item_store($arr,$allow_exec = false) { ); - send_status_notifications($current_post,$arr); + // 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 + // that isn't aware that we were already told to delete it. + + if(! ($arr['item_restrict'] & ITEM_DELETED)) { + send_status_notifications($current_post,$arr); + tag_deliver($arr['uid'],$current_post); + } - tag_deliver($arr['uid'],$current_post); $ret['success'] = true; $ret['item_id'] = $current_post; diff --git a/include/zot.php b/include/zot.php index 7e9a6ee54..7fd6f0d4a 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1576,6 +1576,12 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque // remove_community_tag is a no-op if this isn't a community tag activity remove_community_tag($sender,$arr,$channel['channel_id']); + // set these just in case we need to store a fresh copy of the deleted post. + // This could happen if the delete got here before the original post did. + + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $item_id = delete_imported_item($sender,$arr,$channel['channel_id']); $result[] = array($d['hash'],(($item_id) ? 'deleted' : 'delete_failed'),$channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>',$arr['mid']); @@ -1725,35 +1731,56 @@ function delete_imported_item($sender,$item,$uid) { logger('delete_imported_item invoked',LOGGER_DEBUG); - $r = q("select id, item_restrict from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' ) - and mid = '%s' and uid = %d limit 1", - dbesc($sender['hash']), - dbesc($sender['hash']), - dbesc($sender['hash']), + $ownership_valid = false; + $item_found = false; + $post_id = 0; + + $r = q("select id, item_restrict, author_xchan, owner_xchan, source_xchan from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($uid) ); + if($r) { + if($r[0]['author_xchan'] === $sender['hash'] || $r[0]['owner_xchan'] === $sender['hash'] || $r[0]['source_xchan'] === $sender['hash']) + $ownership_valid = true; + $post_id = $r[0]['id']; + $item_found = true; + } + else { - if(! $r) { + // perhaps the item is still in transit and the delete notification got here before the actual item did. Store it with the deleted flag set. + // item_store() won't try to deliver any notifications or start delivery chains if this flag is set. + // This means we won't end up with potentially even more delivery threads trying to push this delete notification. + // But this will ensure that if the (undeleted) original post comes in at a later date, we'll reject it because it will have an older timestamp. + + logger('delete received for non-existent item - storing item data.'); + if($arr['author_xchan'] === $sender['hash'] || $arr['owner_xchan'] === $sender['hash'] || $arr['source_xchan'] === $sender['hash']) { + $ownership_valid = true; + $item_result = item_store($arr); + $post_id = $item_result['item_id']; + } + } + + if($ownership_valid == false) { logger('delete_imported_item: failed: ownership issue'); return false; } - if($r[0]['item_restrict'] & ITEM_DELETED) { - logger('delete_imported_item: item was already deleted'); - return false; - } + if($item_found) { + if($r[0]['item_restrict'] & ITEM_DELETED) { + logger('delete_imported_item: item was already deleted'); + return false; + } - require_once('include/items.php'); + require_once('include/items.php'); - // Use phased deletion to set the deleted flag, call both tag_deliver and the notifier to notify downstream channels - // and then clean up after ourselves with a cron job after several days to do the delete_item_lowlevel() (DROPITEM_PHASE2). + // Use phased deletion to set the deleted flag, call both tag_deliver and the notifier to notify downstream channels + // and then clean up after ourselves with a cron job after several days to do the delete_item_lowlevel() (DROPITEM_PHASE2). - drop_item($r[0]['id'],false, DROPITEM_PHASE1); - - tag_deliver($uid,$r[0]['id']); + drop_item($post_id,false, DROPITEM_PHASE1); + tag_deliver($uid,$post_id); + } - return $r[0]['id']; + return $post_id; } function process_mail_delivery($sender,$arr,$deliveries) { |