Fix for not being able to delete items

This commit is contained in:
Michael 2018-05-26 18:07:27 +00:00
parent e9dbf55400
commit bdbc51229a
12 changed files with 65 additions and 25 deletions

View file

@ -41,7 +41,7 @@ define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily'); define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily');
define('FRIENDICA_VERSION', '2018.05-rc'); define('FRIENDICA_VERSION', '2018.05-rc');
define('DFRN_PROTOCOL_VERSION', '2.23'); define('DFRN_PROTOCOL_VERSION', '2.23');
define('DB_UPDATE_VERSION', 1265); define('DB_UPDATE_VERSION', 1266);
define('NEW_UPDATE_ROUTINE_VERSION', 1170); define('NEW_UPDATE_ROUTINE_VERSION', 1170);
/** /**

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2018.05-rc (The Tazmans Flax-lily) -- Friendica 2018.05-rc (The Tazmans Flax-lily)
-- DB_UPDATE_VERSION 1265 -- DB_UPDATE_VERSION 1266
-- ------------------------------------------ -- ------------------------------------------
@ -1076,6 +1076,16 @@ CREATE TABLE IF NOT EXISTS `userd` (
INDEX `username` (`username`(32)) INDEX `username` (`username`(32))
) DEFAULT COLLATE utf8mb4_general_ci; ) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE user-item
--
CREATE TABLE IF NOT EXISTS `user-item` (
`iid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item id',
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
`hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Hidden marker',
PRIMARY KEY(`uid`,`iid`)
) DEFAULT COLLATE utf8mb4_general_ci;
-- --
-- TABLE workerqueue -- TABLE workerqueue
-- --

View file

@ -1663,7 +1663,7 @@ function api_search($type)
$r = dba::p( $r = dba::p(
"SELECT ".item_fieldlists()." "SELECT ".item_fieldlists()."
FROM `item` ".item_joins()." FROM `item` ".item_joins(api_user())."
WHERE ".item_condition()." AND (`item`.`uid` = 0 OR (`item`.`uid` = ? AND NOT `item`.`global`)) WHERE ".item_condition()." AND (`item`.`uid` = 0 OR (`item`.`uid` = ? AND NOT `item`.`global`))
AND `item`.`body` LIKE CONCAT('%',?,'%') AND `item`.`body` LIKE CONCAT('%',?,'%')
$sql_extra $sql_extra
@ -1827,7 +1827,7 @@ function api_statuses_public_timeline($type)
"SELECT " . item_fieldlists() . " "SELECT " . item_fieldlists() . "
FROM `thread` FROM `thread`
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
" . item_joins() . " " . item_joins(api_user()) . "
STRAIGHT_JOIN `user` ON `user`.`uid` = `thread`.`uid` STRAIGHT_JOIN `user` ON `user`.`uid` = `thread`.`uid`
AND NOT `user`.`hidewall` AND NOT `user`.`hidewall`
AND `verb` = ? AND `verb` = ?
@ -1856,7 +1856,7 @@ function api_statuses_public_timeline($type)
$r = dba::p( $r = dba::p(
"SELECT " . item_fieldlists() . " "SELECT " . item_fieldlists() . "
FROM `item` FROM `item`
" . item_joins() . " " . item_joins(api_user()) . "
STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid` STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
AND NOT `user`.`hidewall` AND NOT `user`.`hidewall`
AND `verb` = ? AND `verb` = ?
@ -1930,7 +1930,7 @@ function api_statuses_networkpublic_timeline($type)
"SELECT " . item_fieldlists() . " "SELECT " . item_fieldlists() . "
FROM `thread` FROM `thread`
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
" . item_joins() . " " . item_joins(api_user()) . "
WHERE `thread`.`uid` = 0 WHERE `thread`.`uid` = 0
AND `verb` = ? AND `verb` = ?
AND NOT `thread`.`private` AND NOT `thread`.`private`

View file

@ -405,10 +405,12 @@ function visible_activity($item) {
/** /**
* @brief SQL query for items * @brief SQL query for items
*
* @param int $uid user id
*/ */
function item_query() { function item_query($uid = 0) {
return "SELECT " . item_fieldlists() . " FROM `item` " . return "SELECT " . item_fieldlists() . " FROM `item` " .
item_joins() . " WHERE " . item_condition(); item_joins($uid) . " WHERE " . item_condition();
} }
/** /**
@ -467,16 +469,19 @@ These Fields are not added below (yet). They are here to for bug search.
/** /**
* @brief SQL join for contacts that are needed for displaying items * @brief SQL join for contacts that are needed for displaying items
*
* @param int $uid user id
*/ */
function item_joins() { function item_joins($uid = 0) {
return sprintf("STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` return sprintf("STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND NOT `contact`.`blocked` AND NOT `contact`.`blocked`
AND ((NOT `contact`.`readonly` AND NOT `contact`.`pending` AND (`contact`.`rel` IN (%s, %s))) AND ((NOT `contact`.`readonly` AND NOT `contact`.`pending` AND (`contact`.`rel` IN (%s, %s)))
OR `contact`.`self` OR (`item`.`id` != `item`.`parent`) OR `contact`.`uid` = 0) OR `contact`.`self` OR (`item`.`id` != `item`.`parent`) OR `contact`.`uid` = 0)
INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id` AND NOT `author`.`blocked` INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id` AND NOT `author`.`blocked`
INNER JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id` AND NOT `owner`.`blocked` INNER JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id` AND NOT `owner`.`blocked`
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = %d
LEFT JOIN `event` ON `event-id` = `event`.`id`", LEFT JOIN `event` ON `event-id` = `event`.`id`",
CONTACT_IS_SHARING, CONTACT_IS_FRIEND CONTACT_IS_SHARING, CONTACT_IS_FRIEND, intval($uid)
); );
} }
@ -484,7 +489,7 @@ function item_joins() {
* @brief SQL condition for items that are needed for displaying items * @brief SQL condition for items that are needed for displaying items
*/ */
function item_condition() { function item_condition() {
return "`item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`"; return "`item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated` AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`) ";
} }
/** /**
@ -497,7 +502,7 @@ function item_condition() {
* that are based on unique features of the calling module. * that are based on unique features of the calling module.
* *
*/ */
function conversation(App $a, $items, $mode, $update, $preview = false, $order = 'commented') { function conversation(App $a, $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0) {
require_once 'mod/proxy.php'; require_once 'mod/proxy.php';
$ssl_state = ((local_user()) ? true : false); $ssl_state = ((local_user()) ? true : false);
@ -521,7 +526,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false, $order =
$previewing = (($preview) ? ' preview ' : ''); $previewing = (($preview) ? ' preview ' : '');
if ($mode === 'network') { if ($mode === 'network') {
$items = conversation_add_children($items, false, $order); $items = conversation_add_children($items, false, $order, $uid);
$profile_owner = local_user(); $profile_owner = local_user();
if (!$update) { if (!$update) {
/* /*
@ -885,7 +890,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false, $order =
* *
* @return array items with parents and comments * @return array items with parents and comments
*/ */
function conversation_add_children($parents, $block_authors, $order) { function conversation_add_children($parents, $block_authors, $order, $uid = 0) {
$max_comments = Config::get('system', 'max_comments', 100); $max_comments = Config::get('system', 'max_comments', 100);
if ($max_comments > 0) { if ($max_comments > 0) {
@ -899,7 +904,7 @@ function conversation_add_children($parents, $block_authors, $order) {
$block_sql = $block_authors ? "AND NOT `author`.`hidden` AND NOT `author`.`blocked`" : ""; $block_sql = $block_authors ? "AND NOT `author`.`hidden` AND NOT `author`.`blocked`" : "";
foreach ($parents AS $parent) { foreach ($parents AS $parent) {
$thread_items = dba::p(item_query()."AND `item`.`parent-uri` = ? $thread_items = dba::p(item_query(local_user())."AND `item`.`parent-uri` = ?
AND `item`.`uid` IN (0, ?) $block_sql AND `item`.`uid` IN (0, ?) $block_sql
ORDER BY `item`.`uid` ASC, `item`.`commented` DESC" . $limit, ORDER BY `item`.`uid` ASC, `item`.`commented` DESC" . $limit,
$parent['uri'], local_user()); $parent['uri'], local_user());

View file

@ -346,7 +346,7 @@ function display_content(App $a, $update = false, $update_uid = 0) {
return ''; return '';
} }
$r = dba::p(item_query()."AND `item`.`parent-uri` = (SELECT `parent-uri` FROM `item` WHERE `id` = ?) $r = dba::p(item_query(local_user())."AND `item`.`parent-uri` = (SELECT `parent-uri` FROM `item` WHERE `id` = ?)
AND `item`.`uid` IN (0, ?) $sql_extra AND `item`.`uid` IN (0, ?) $sql_extra
ORDER BY `item`.`uid` ASC, `parent` DESC, `gravity` ASC, `id` ASC", ORDER BY `item`.`uid` ASC, `parent` DESC, `gravity` ASC, `id` ASC",
$item_id, local_user() $item_id, local_user()

View file

@ -345,7 +345,7 @@ function networkConversation($a, $items, $mode, $update, $ordering = '')
// Set this so that the conversation function can find out contact info for our wall-wall items // Set this so that the conversation function can find out contact info for our wall-wall items
$a->page_contact = $a->contact; $a->page_contact = $a->contact;
$o = conversation($a, $items, $mode, $update, false, $ordering); $o = conversation($a, $items, $mode, $update, false, $ordering, local_user());
if (!$update) { if (!$update) {
if (PConfig::get(local_user(), 'system', 'infinite_scroll')) { if (PConfig::get(local_user(), 'system', 'infinite_scroll')) {
@ -456,7 +456,7 @@ function networkFlatView(App $a, $update = 0)
$items = q("SELECT %s FROM `item` $sql_post_table %s $items = q("SELECT %s FROM `item` $sql_post_table %s
WHERE %s AND `item`.`uid` = %d WHERE %s AND `item`.`uid` = %d
ORDER BY `item`.`id` DESC $pager_sql ", ORDER BY `item`.`id` DESC $pager_sql ",
item_fieldlists(), item_joins(), item_condition(), item_fieldlists(), item_joins($_SESSION['uid']), item_condition(),
intval($_SESSION['uid']) intval($_SESSION['uid'])
); );
@ -774,12 +774,15 @@ function networkThreadedView(App $a, $update, $parent)
AND (`item`.`parent-uri` != `item`.`uri` AND (`item`.`parent-uri` != `item`.`uri`
OR `contact`.`uid` = `item`.`uid` AND `contact`.`self` OR `contact`.`uid` = `item`.`uid` AND `contact`.`self`
OR `contact`.`rel` IN (%d, %d) AND NOT `contact`.`readonly`) OR `contact`.`rel` IN (%d, %d) AND NOT `contact`.`readonly`)
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = %d
WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`deleted` WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`deleted`
AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`)
AND NOT `item`.`moderated` AND $sql_extra4 AND NOT `item`.`moderated` AND $sql_extra4
$sql_extra3 $sql_extra $sql_range $sql_nets $sql_extra3 $sql_extra $sql_range $sql_nets
ORDER BY `order_date` DESC LIMIT 100", ORDER BY `order_date` DESC LIMIT 100",
intval(CONTACT_IS_SHARING), intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND), intval(CONTACT_IS_FRIEND),
intval(local_user()),
intval(local_user()) intval(local_user())
); );
} else { } else {
@ -791,12 +794,15 @@ function networkThreadedView(App $a, $update, $parent)
AND (`item`.`parent-uri` != `item`.`uri` AND (`item`.`parent-uri` != `item`.`uri`
OR `contact`.`uid` = `item`.`uid` AND `contact`.`self` OR `contact`.`uid` = `item`.`uid` AND `contact`.`self`
OR `contact`.`rel` IN (%d, %d) AND NOT `contact`.`readonly`) OR `contact`.`rel` IN (%d, %d) AND NOT `contact`.`readonly`)
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = %d
WHERE `thread`.`uid` = %d AND `thread`.`visible` AND NOT `thread`.`deleted` WHERE `thread`.`uid` = %d AND `thread`.`visible` AND NOT `thread`.`deleted`
AND NOT `thread`.`moderated` AND NOT `thread`.`moderated`
AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`)
$sql_extra2 $sql_extra3 $sql_range $sql_extra $sql_nets $sql_extra2 $sql_extra3 $sql_range $sql_extra $sql_nets
ORDER BY `order_date` DESC $pager_sql", ORDER BY `order_date` DESC $pager_sql",
intval(CONTACT_IS_SHARING), intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND), intval(CONTACT_IS_FRIEND),
intval(local_user()),
intval(local_user()) intval(local_user())
); );
} }

View file

@ -82,7 +82,7 @@ function notes_content(App $a, $update = false)
WHERE %s AND `item`.`uid` = %d AND `item`.`type` = 'note' WHERE %s AND `item`.`uid` = %d AND `item`.`type` = 'note'
AND `contact`.`self` AND `item`.`id` = `item`.`parent` AND NOT `item`.`wall` AND `contact`.`self` AND `item`.`id` = `item`.`parent` AND NOT `item`.`wall`
$sql_extra ", $sql_extra ",
item_joins(), item_joins(local_user()),
item_condition(), item_condition(),
intval(local_user()) intval(local_user())
); );
@ -97,7 +97,7 @@ function notes_content(App $a, $update = false)
AND `item`.`id` = `item`.`parent` AND NOT `item`.`wall` AND `item`.`id` = `item`.`parent` AND NOT `item`.`wall`
$sql_extra $sql_extra
ORDER BY `item`.`created` DESC LIMIT %d ,%d ", ORDER BY `item`.`created` DESC LIMIT %d ,%d ",
item_joins(), item_joins(local_user()),
item_condition(), item_condition(),
intval(local_user()), intval(local_user()),
intval($a->pager['start']), intval($a->pager['start']),
@ -119,7 +119,7 @@ function notes_content(App $a, $update = false)
$sql_extra $sql_extra
ORDER BY `parent` DESC, `gravity` ASC, `item`.`id` ASC ", ORDER BY `parent` DESC, `gravity` ASC, `item`.`id` ASC ",
item_fieldlists(), item_fieldlists(),
item_joins(), item_joins(local_user()),
item_condition(), item_condition(),
intval(local_user()), intval(local_user()),
dbesc($parents_str) dbesc($parents_str)

View file

@ -339,7 +339,7 @@ function profile_content(App $a, $update = 0)
$parents_str = implode(', ', $parents_arr); $parents_str = implode(', ', $parents_arr);
$items = q(item_query() . " AND `item`.`uid` = %d $items = q(item_query($a->profile['profile_uid']) . " AND `item`.`uid` = %d
AND `item`.`parent` IN (%s) AND `item`.`parent` IN (%s)
$sql_extra ", $sql_extra ",
intval($a->profile['profile_uid']), intval($a->profile['profile_uid']),

View file

@ -204,7 +204,7 @@ function search_content(App $a) {
AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`term` = '%s' AND `item`.`verb` = '%s' AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`term` = '%s' AND `item`.`verb` = '%s'
AND NOT `author`.`blocked` AND NOT `author`.`hidden` AND NOT `author`.`blocked` AND NOT `author`.`hidden`
ORDER BY term.created DESC LIMIT %d , %d ", ORDER BY term.created DESC LIMIT %d , %d ",
item_fieldlists(), item_joins(), item_condition(), item_fieldlists(), item_joins(local_user()), item_condition(),
intval(local_user()), intval(local_user()),
intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search)), dbesc(ACTIVITY_POST), intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search)), dbesc(ACTIVITY_POST),
intval($a->pager['start']), intval($a->pager['itemspage'])); intval($a->pager['start']), intval($a->pager['itemspage']));
@ -219,7 +219,7 @@ function search_content(App $a) {
AND NOT `author`.`blocked` AND NOT `author`.`hidden` AND NOT `author`.`blocked` AND NOT `author`.`hidden`
$sql_extra $sql_extra
GROUP BY `item`.`uri`, `item`.`id` ORDER BY `item`.`id` DESC LIMIT %d , %d", GROUP BY `item`.`uri`, `item`.`id` ORDER BY `item`.`id` DESC LIMIT %d , %d",
item_fieldlists(), item_joins(), item_condition(), item_fieldlists(), item_joins(local_user()), item_condition(),
intval(local_user()), intval(local_user()),
intval($a->pager['start']), intval($a->pager['itemspage'])); intval($a->pager['start']), intval($a->pager['itemspage']));
} }

View file

@ -1786,6 +1786,17 @@ class DBStructure
"username" => ["username(32)"], "username" => ["username(32)"],
] ]
]; ];
$database["user-item"] = [
"comment" => "User specific item data",
"fields" => [
"iid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => ["item" => "id"], "comment" => "Item id"],
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => ["user" => "uid"], "comment" => "User id"],
"hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Hidden marker"],
],
"indexes" => [
"PRIMARY" => ["uid", "iid"],
]
];
$database["workerqueue"] = [ $database["workerqueue"] = [
"comment" => "Background tasks queue entries", "comment" => "Background tasks queue entries",
"fields" => [ "fields" => [

View file

@ -1049,7 +1049,7 @@ class Contact extends BaseObject
$contact = ($r[0]["contact-type"] == ACCOUNT_TYPE_COMMUNITY ? 'owner-id' : 'author-id'); $contact = ($r[0]["contact-type"] == ACCOUNT_TYPE_COMMUNITY ? 'owner-id' : 'author-id');
$r = q(item_query() . " AND `item`.`" . $contact . "` = %d AND " . $sql . $r = q(item_query(local_user()) . " AND `item`.`" . $contact . "` = %d AND " . $sql .
" AND `item`.`verb` = '%s' ORDER BY `item`.`created` DESC LIMIT %d, %d", " AND `item`.`verb` = '%s' ORDER BY `item`.`created` DESC LIMIT %d, %d",
intval($author_id), intval(local_user()), dbesc(ACTIVITY_POST), intval($author_id), intval(local_user()), dbesc(ACTIVITY_POST),
intval($a->pager['start']), intval($a->pager['itemspage']) intval($a->pager['start']), intval($a->pager['itemspage'])

View file

@ -201,8 +201,16 @@ class Item extends BaseObject
// send the notification upstream/downstream // send the notification upstream/downstream
Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", "drop", intval($item['id'])); Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", "drop", intval($item['id']));
} elseif ($item['uid'] != 0) {
// When we delete just our local user copy of an item, we have to set an marker to hide it
$global_item = dba::selectFirst('item', ['id'], ['uri' => $item['uri'], 'uid' => 0, 'deleted' => false]);
if (DBM::is_result($global_item)) {
dba::update('user-item', ['hidden' => true], ['iid' => $global_item['id'], 'uid' => $item['uid']], true);
}
} }
logger('Item with ID ' . $item_id . " has been deleted.", LOGGER_DEBUG); logger('Item with ID ' . $item_id . " has been deleted.", LOGGER_DEBUG);
return true; return true;