aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/conversation.php6
-rwxr-xr-xinclude/items.php11
-rw-r--r--include/zot.php61
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) {