From cb5a20ba2cbad131267542ff55b394a9763b4c2c Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 24 Jan 2013 16:44:10 -0800 Subject: uncomplicate item deletion and fixup all the other linked tables --- include/items.php | 173 ++++++++++++++++++++++----------------------------- include/notifier.php | 7 ++- include/zot.php | 15 +---- version.inc | 2 +- 4 files changed, 82 insertions(+), 115 deletions(-) diff --git a/include/items.php b/include/items.php index 04d088d44..bce1f2dfa 100755 --- a/include/items.php +++ b/include/items.php @@ -4017,17 +4017,21 @@ function drop_items($items) { } +// Delete item with given item $id. $interactive means we're running interactively, and must check +// permissions to carry out this act. If it is non-interactive, we are deleting something at the +// system's request and do not check permission. This is very important to know. + function drop_item($id,$interactive = true) { $a = get_app(); // locate item to be deleted - $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", + $r = q("SELECT * FROM item WHERE id = %d LIMIT 1", intval($id) ); - if(! count($r)) { + if(! $r) { if(! $interactive) return 0; notice( t('Item not found.') . EOL); @@ -4036,128 +4040,101 @@ function drop_item($id,$interactive = true) { $item = $r[0]; - $owner = $item['uid']; - - $cid = 0; - - // check if logged in user is either the author or owner of this item - - if(is_array($_SESSION['remote'])) { - foreach($_SESSION['remote'] as $visitor) { - if($visitor['uid'] == $item['uid'] && $visitor['cid'] == $item['contact-id']) { - $cid = $visitor['cid']; - break; - } - } - } - + $ok_to_delete = false; - if((local_user() == $item['uid']) || ($cid) || (! $interactive)) { - - // delete the item - - $r = q(" UPDATE `item` SET - `item_restrict` = (item_restrict|%d) , - `title` = '', - `body` = '', - `changed` = '%s', - `edited` = '%s' WHERE `id` = %d LIMIT 1", - intval(ITEM_DELETED), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($item['id']) - ); + // system deletion + if(! $interactive) + $ok_to_delete = true; + // owner deletion + if(local_user() && local_user() == $item['uid']) + $ok_to_delete = true; + // author deletion + $observer = $a->get_observer(); + if($observer && $observer['xchan_hash'] && ($observer['xchan_hash'] === $item['author_xchan'])) + $ok_to_delete = true; - // clean up categories and tags so they don't end up as orphans + if($ok_to_delete) { - $matches = false; - $cnt = preg_match_all('/<(.*?)>/',$item['file'],$matches,PREG_SET_ORDER); - if($cnt) { - foreach($matches as $mtch) { - file_tag_unsave_file($item['uid'],$item['id'],$mtch[1],true); - } - } - - $matches = false; - - $cnt = preg_match_all('/\[(.*?)\]/',$item['file'],$matches,PREG_SET_ORDER); - if($cnt) { - foreach($matches as $mtch) { - file_tag_unsave_file($item['uid'],$item['id'],$mtch[1],false); - } - } - - // If item is a link to a photo resource, nuke all the associated photos - // (visitors will not have photo resources) - // This only applies to photos uploaded from the photos page. Photos inserted into a post do not - // generate a resource_id and therefore aren't intimately linked to the item. - - if(strlen($item['resource_id'])) { - q("DELETE FROM `photo` WHERE `resource_id` = '%s' AND `uid` = %d ", - dbesc($item['resource_id']), - intval($item['uid']) - ); - // ignore the result - } - - // If item is a link to an event, nuke the event record. - - if(intval($item['event-id'])) { - q("DELETE FROM `event` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($item['event-id']), - intval($item['uid']) - ); - // ignore the result - } - - // clean up item_id and sign meta-data tables - - $r = q("DELETE FROM item_id where iid in (select id from item where parent = %d and uid = %d)", - intval($item['id']), - intval($item['uid']) - ); + $notify_id = intval($item['id']); - $r = q("DELETE FROM sign where iid in (select id from item where parent = %d and uid = %d)", + $items = q("select * from item where parent = %d and uid = %d", intval($item['id']), intval($item['uid']) ); - - // If it's the parent of a comment thread, kill all the kids - - if($item['uri'] == $item['parent_uri']) { - $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s', `body` = '' , `title` = '' - WHERE `parent_uri` = '%s' AND `uid` = %d ", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($item['parent_uri']), - intval($item['uid']) - ); - // ignore the result + if($items) { + foreach($items as $i) + delete_item_lowlevel($i); } - $drop_id = intval($item['id']); + if(! $interactive) + return 1; // send the notification upstream/downstream as the case may be + // only send notifications to others if this is the owner's wall item. - if(! $interactive) - return $owner; + if($item['item_flags'] & ITEM_WALL) + proc_run('php','include/notifier.php','drop',$notify_id); - proc_run('php',"include/notifier.php","drop","$drop_id"); goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); - //NOTREACHED + } else { if(! $interactive) return 0; notice( t('Permission denied.') . EOL); goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); - //NOTREACHED } } +// This function does not check for permission and does not send notifications and does not check recursion. +// It merely destroys all resources associated with an item. +// Please do not use without a suitable wrapper. + +function delete_item_lowlevel($item) { + + $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), title = '', body = '', + changed = '%s', edited = '%s' WHERE id = %d LIMIT 1", + intval(ITEM_DELETED), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($item['id']) + ); + + $r = q("delete from term where otype = %d and oid = %d limit 1", + intval(TERM_OBJ_POST), + intval($item['id']) + ); + + // If item is a link to a photo resource, nuke all the associated photos + // This only applies to photos uploaded from the photos page. Photos inserted into a post do not + // generate a resource_id and therefore aren't intimately linked to the item. + + if(strlen($item['resource_id'])) { + if($item['resource_type'] === 'event') { + q("delete from event where event_hash = '%s' and uid = %d limit 1", + dbesc($item['resource_id']), + intval($item['uid']) + ); + } + elseif($item['resource_type'] === 'photo') { + q("DELETE FROM `photo` WHERE `resource_id` = '%s' AND `uid` = %d ", + dbesc($item['resource_id']), + intval($item['uid']) + ); + } + } + + q("delete from item_id where iid = %d and uid = %d limit 1", + intval($item['id']), + intval($item['uid']) + ); + + return true; +} + function first_post_date($uid,$wall = false) { diff --git a/include/notifier.php b/include/notifier.php index 74da8f2f8..dddf0aade 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -240,9 +240,10 @@ function notifier_run($argv, $argc){ // $cmd === 'relay' indicates the owner is sending it to the original recipients // don't allow the item in the relay command to relay to owner under any circumstances, it will loop - logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false')); - logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false')); - logger('notifier: target_item_flags: ' . $target_item['item_flags'] . ' ' . (($target_item['item_flags'] & ITEM_ORIGIN ) ? 'true' : 'false')); + + logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA); + logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA); + logger('notifier: target_item_flags: ' . $target_item['item_flags'] . ' ' . (($target_item['item_flags'] & ITEM_ORIGIN ) ? 'true' : 'false'), LOGGER_DATA); // tag_deliver'd post which needs to be sent back to the original author diff --git a/include/zot.php b/include/zot.php index f35c6f93e..5c930aba4 100644 --- a/include/zot.php +++ b/include/zot.php @@ -998,19 +998,8 @@ function delete_imported_item($sender,$item,$uid) { return; } - $r = q("update item set body = '', title = '', item_restrict = %d, edited = '%s', changed = '%s' - where ( thr_parent = '%s' or parent_uri = '%s' ) and uid = %d", - intval(ITEM_DELETED), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($item['uri']), - dbesc($item['uri']), - intval($uid) - ); - - if(! $r) - logger("delete_imported_item: db update failed. Item = {$item['uri']} uid = $uid"); - + require_once('include/items.php'); + drop_item($r[0]['id'],false); } function process_mail_delivery($sender,$arr,$deliveries) { diff --git a/version.inc b/version.inc index e0fd2ec91..c03d65d8f 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -2013-01-23.209 +2013-01-24.210 -- cgit v1.2.3