From 2b1d0b9db835f2fe6dd54ecf8487017656b5b9f2 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 Jan 2021 22:37:27 +0000 Subject: [PATCH] "selectForUser" and "" selectFirstForUser" is now moved to Post --- database.sql | 5 +- include/api.php | 54 ++++++------- include/conversation.php | 10 +-- include/enotify.php | 4 +- mod/display.php | 16 ++-- mod/editpost.php | 3 +- mod/item.php | 4 +- mod/notes.php | 2 +- mod/photos.php | 5 +- mod/ping.php | 6 +- src/Factory/Api/Mastodon/Status.php | 10 +-- src/Factory/Notification/Notification.php | 8 +- src/Model/Contact.php | 15 +--- src/Model/Item.php | 30 +------ src/Model/ItemContent.php | 4 +- src/Model/Post.php | 81 ++++++++++++++++++- src/Module/Api/Mastodon/Accounts/Statuses.php | 5 +- .../Api/Mastodon/Timelines/PublicTimeline.php | 3 +- src/Module/Profile/Status.php | 8 +- src/Module/Search/Acl.php | 4 +- src/Module/Search/Filed.php | 5 +- src/Module/Search/Index.php | 2 +- src/Module/Starred.php | 3 +- src/Protocol/ActivityPub/Transmitter.php | 2 +- src/Protocol/Feed.php | 2 +- src/Protocol/OStatus.php | 2 +- src/Worker/Notifier.php | 2 +- static/dbstructure.config.php | 2 +- static/dbview.config.php | 3 + 29 files changed, 179 insertions(+), 121 deletions(-) diff --git a/database.sql b/database.sql index 226c151335..28cfe41752 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2021.03-dev (Red Hot Poker) --- DB_UPDATE_VERSION 1386 +-- DB_UPDATE_VERSION 1387 -- ------------------------------------------ @@ -1582,6 +1582,7 @@ CREATE VIEW `post-view` AS SELECT IF (`contact`.`url` = `author`.`url`, `contact`.`thumb`, `author`.`thumb`) AS `author-avatar`, `author`.`network` AS `author-network`, `author`.`blocked` AS `author-blocked`, + `author`.`hidden` AS `author-hidden`, `item`.`owner-id` AS `owner-id`, `owner`.`url` AS `owner-link`, `owner`.`addr` AS `owner-addr`, @@ -1590,6 +1591,7 @@ CREATE VIEW `post-view` AS SELECT IF (`contact`.`url` = `owner`.`url`, `contact`.`thumb`, `owner`.`thumb`) AS `owner-avatar`, `owner`.`network` AS `owner-network`, `owner`.`blocked` AS `owner-blocked`, + `owner`.`hidden` AS `owner-hidden`, `item`.`causer-id` AS `causer-id`, `causer`.`url` AS `causer-link`, `causer`.`addr` AS `causer-addr`, @@ -1598,6 +1600,7 @@ CREATE VIEW `post-view` AS SELECT `causer`.`thumb` AS `causer-avatar`, `causer`.`network` AS `causer-network`, `causer`.`blocked` AS `causer-blocked`, + `causer`.`hidden` AS `causer-hidden`, `causer`.`contact-type` AS `causer-contact-type`, `post-delivery-data`.`postopts` AS `postopts`, `post-delivery-data`.`inform` AS `inform`, diff --git a/include/api.php b/include/api.php index b649d22481..00e51d249b 100644 --- a/include/api.php +++ b/include/api.php @@ -1584,13 +1584,13 @@ function api_search($type) } if (!empty($id)) { - $statuses = Item::select([], ['id' => $id]); + $statuses = Post::select([], ['id' => $id]); } } - $statuses = $statuses ?: Item::selectForUser(api_user(), [], $condition, $params); + $statuses = $statuses ?: Post::selectForUser(api_user(), [], $condition, $params); - $data['status'] = api_format_items(Item::inArray($statuses), $user_info); + $data['status'] = api_format_items(Post::toArray($statuses), $user_info); bindComments($data['status']); @@ -1661,9 +1661,9 @@ function api_statuses_home_timeline($type) } $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); - $items = Item::inArray($statuses); + $items = Post::toArray($statuses); $ret = api_format_items($items, $user_info, false, $type); @@ -1744,7 +1744,7 @@ function api_statuses_public_timeline($type) $params = ['order' => ['iid' => true], 'limit' => [$start, $count]]; $statuses = Item::selectThreadForUser(api_user(), Item::DISPLAY_FIELDLIST, $condition, $params); - $r = Item::inArray($statuses); + $r = Item::toArray($statuses); } else { $condition = ["`gravity` IN (?, ?) AND `id` > ? AND `private` = ? AND `wall` AND `item`.`origin` AND NOT `author`.`hidden`", GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC]; @@ -1759,9 +1759,9 @@ function api_statuses_public_timeline($type) } $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); - $r = Item::inArray($statuses); + $r = Post::toArray($statuses); } $ret = api_format_items($r, $user_info, false, $type); @@ -1823,7 +1823,7 @@ function api_statuses_networkpublic_timeline($type) $params = ['order' => ['iid' => true], 'limit' => [$start, $count]]; $statuses = Item::selectThreadForUser(api_user(), Item::DISPLAY_FIELDLIST, $condition, $params); - $ret = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $ret = api_format_items(Item::toArray($statuses), $user_info, false, $type); bindComments($ret); @@ -1901,14 +1901,14 @@ function api_statuses_show($type) $params = []; } - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); /// @TODO How about copying this to above methods which don't check $r ? if (!DBA::isResult($statuses)) { throw new BadRequestException("There is no status with this id."); } - $ret = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $ret = api_format_items(Post::toArray($statuses), $user_info, false, $type); if ($conversation) { $data = ['status' => $ret]; @@ -1985,13 +1985,13 @@ function api_conversation_show($type) } $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); if (!DBA::isResult($statuses)) { throw new BadRequestException("There is no status with id $id."); } - $ret = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $ret = api_format_items(Post::toArray($statuses), $user_info, false, $type); $data = ['status' => $ret]; return api_format_data("statuses", $type, $data); @@ -2199,9 +2199,9 @@ function api_statuses_mentions($type) DBA::close($useritems); $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; - $statuses = Item::selectForUser(api_user(), [], ['id' => $itemids], $params); + $statuses = Post::selectForUser(api_user(), [], ['id' => $itemids], $params); - $ret = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $ret = api_format_items(Post::toArray($statuses), $user_info, false, $type); $data = ['status' => $ret]; switch ($type) { @@ -2276,9 +2276,9 @@ function api_statuses_user_timeline($type) } $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); - $ret = api_format_items(Item::inArray($statuses), $user_info, true, $type); + $ret = api_format_items(Post::toArray($statuses), $user_info, true, $type); bindComments($ret); @@ -2336,7 +2336,7 @@ function api_favorites_create_destroy($type) $itemid = intval($_REQUEST['id'] ?? 0); } - $item = Item::selectFirstForUser(api_user(), [], ['id' => $itemid, 'uid' => api_user()]); + $item = Post::selectFirstForUser(api_user(), [], ['id' => $itemid, 'uid' => api_user()]); if (!DBA::isResult($item)) { throw new BadRequestException("Invalid item."); @@ -2430,9 +2430,9 @@ function api_favorites($type) $condition[] = $max_id; } - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); - $ret = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $ret = api_format_items(Post::toArray($statuses), $user_info, false, $type); } bindComments($ret); @@ -2873,7 +2873,7 @@ function api_format_items_activities($item, $type = "json") ]; $condition = ['uid' => $item['uid'], 'thr-parent' => $item['uri'], 'gravity' => GRAVITY_ACTIVITY]; - $ret = Item::selectForUser($item['uid'], ['author-id', 'verb'], $condition); + $ret = Post::selectForUser($item['uid'], ['author-id', 'verb'], $condition); while ($parent_item = Item::fetch($ret)) { // not used as result should be structured like other user data @@ -3321,9 +3321,9 @@ function api_lists_statuses($type) } $params = ['order' => ['id' => true], 'limit' => [$start, $count]]; - $statuses = Item::selectForUser(api_user(), [], $condition, $params); + $statuses = Post::selectForUser(api_user(), [], $condition, $params); - $items = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $items = api_format_items(Post::toArray($statuses), $user_info, false, $type); $data = ['status' => $items]; switch ($type) { @@ -4891,10 +4891,10 @@ function prepare_photo_data($type, $scale, $photo_id) $condition = ["`parent` = ? AND `uid` = ? AND (`gravity` IN (?, ?) OR `type`='photo')", $item['parent'], api_user(), GRAVITY_PARENT, GRAVITY_COMMENT]; - $statuses = Item::selectForUser(api_user(), [], $condition); + $statuses = Post::selectForUser(api_user(), [], $condition); // prepare output of comments - $commentData = api_format_items(Item::inArray($statuses), $user_info, false, $type); + $commentData = api_format_items(Post::toArray($statuses), $user_info, false, $type); $comments = []; if ($type == "xml") { $k = 0; @@ -5007,7 +5007,7 @@ function api_get_announce($item) $fields = ['author-id', 'author-name', 'author-link', 'author-avatar']; $condition = ['parent-uri' => $item['uri'], 'gravity' => GRAVITY_ACTIVITY, 'uid' => [0, $item['uid']], 'vid' => Verb::getID(Activity::ANNOUNCE)]; - $announce = Item::selectFirstForUser($item['uid'], $fields, $condition, ['order' => ['received' => true]]); + $announce = Post::selectFirstForUser($item['uid'], $fields, $condition, ['order' => ['received' => true]]); if (!DBA::isResult($announce)) { return []; } @@ -5815,7 +5815,7 @@ function api_friendica_notification_seen($type) DI::notify()->setSeen(true, $notify); if ($notify->otype === Notify\ObjectType::ITEM) { - $item = Item::selectFirstForUser(api_user(), [], ['id' => $notify->iid, 'uid' => api_user()]); + $item = Post::selectFirstForUser(api_user(), [], ['id' => $notify->iid, 'uid' => api_user()]); if (DBA::isResult($item)) { // we found the item, return it to the user $ret = api_format_items([$item], $user_info, false, $type); diff --git a/include/conversation.php b/include/conversation.php index 3261311012..0051b09866 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -718,7 +718,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o function conversation_fetch_comments($thread_items, bool $pinned, array $activity) { $comments = []; - while ($row = Item::fetch($thread_items)) { + while ($row = Post::fetch($thread_items)) { if (!empty($activity)) { if (($row['gravity'] == GRAVITY_PARENT)) { $row['post-type'] = Item::PT_ANNOUNCEMENT; @@ -827,7 +827,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid) foreach ($parents AS $parent) { if (!empty($parent['thr-parent-id']) && !empty($parent['gravity']) && ($parent['gravity'] == GRAVITY_ACTIVITY)) { - $condition = ["`item`.`parent-uri-id` = ? AND `item`.`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", + $condition = ["`parent-uri-id` = ? AND `uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", $parent['thr-parent-id'], $uid, Verb::getID(Activity::FOLLOW)]; if (!empty($parent['author-id'])) { $activity = ['causer-id' => $parent['author-id']]; @@ -838,7 +838,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid) } } } else { - $condition = ["`item`.`parent-uri` = ? AND `item`.`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", + $condition = ["`parent-uri` = ? AND `uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", $parent['uri'], $uid, Verb::getID(Activity::FOLLOW)]; $activity = []; } @@ -869,10 +869,10 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid) */ function conversation_fetch_items(array $parent, array $items, array $condition, bool $block_authors, array $params, array $activity) { if ($block_authors) { - $condition[0] .= " AND NOT `author`.`hidden`"; + $condition[0] .= " AND NOT `author-hidden`"; } - $thread_items = Item::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['pinned', 'contact-uid', 'gravity', 'post-type']), $condition, $params); + $thread_items = Post::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['pinned', 'contact-uid', 'gravity', 'post-type']), $condition, $params); $comments = conversation_fetch_comments($thread_items, $parent['pinned'] ?? false, $activity); diff --git a/include/enotify.php b/include/enotify.php index fc19d400f1..c3943e5f6d 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -167,7 +167,7 @@ function notification($params) // if it's a post figure out who's post it is. $item = null; if ($params['otype'] === Notify\ObjectType::ITEM && $parent_id) { - $item = Item::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id, 'deleted' => false]); + $item = Post::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id, 'deleted' => false]); } if (empty($item)) { @@ -619,7 +619,7 @@ function check_item_notification($itemid, $uid, $notification_type) { 'title', 'body', 'author-link', 'author-name', 'author-avatar', 'author-id', 'gravity', 'guid', 'parent-uri', 'uri', 'contact-id', 'network']; $condition = ['id' => $itemid, 'deleted' => false]; - $item = Item::selectFirstForUser($uid, $fields, $condition); + $item = Post::selectFirstForUser($uid, $fields, $condition); if (!DBA::isResult($item)) { return false; } diff --git a/mod/display.php b/mod/display.php index 07289e0132..4d03e223ef 100644 --- a/mod/display.php +++ b/mod/display.php @@ -63,7 +63,7 @@ function display_init(App $a) // Does the local user have this item? if (local_user()) { - $item = Item::selectFirstForUser(local_user(), $fields, ['guid' => $a->argv[1], 'uid' => local_user()]); + $item = Post::selectFirstForUser(local_user(), $fields, ['guid' => $a->argv[1], 'uid' => local_user()]); if (DBA::isResult($item)) { $nick = $a->user["nickname"]; } @@ -83,14 +83,14 @@ function display_init(App $a) // Is it an item with uid=0? if (!DBA::isResult($item)) { - $item = Item::selectFirstForUser(local_user(), $fields, ['guid' => $a->argv[1], 'private' => [Item::PUBLIC, Item::UNLISTED], 'uid' => 0]); + $item = Post::selectFirstForUser(local_user(), $fields, ['guid' => $a->argv[1], 'private' => [Item::PUBLIC, Item::UNLISTED], 'uid' => 0]); } } elseif ($a->argc >= 3 && $nick == 'feed-item') { $item_id = $a->argv[2]; if (substr($item_id, -5) == '.atom') { $item_id = substr($item_id, 0, -5); } - $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $item_id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'uid' => 0]); + $item = Post::selectFirstForUser(local_user(), $fields, ['id' => $item_id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'uid' => 0]); } if (!DBA::isResult($item)) { @@ -107,7 +107,7 @@ function display_init(App $a) } if ($item['gravity'] != GRAVITY_PARENT) { - $parent = Item::selectFirstForUser($item_user, $fields, ['id' => $item['parent']]); + $parent = Post::selectFirstForUser($item_user, $fields, ['id' => $item['parent']]); $item = $parent ?: $item; } @@ -206,7 +206,7 @@ function display_content(App $a, $update = false, $update_uid = 0) if (local_user()) { $condition = ['guid' => $a->argv[1], 'uid' => local_user()]; - $item = Item::selectFirstForUser(local_user(), $fields, $condition); + $item = Post::selectFirstForUser(local_user(), $fields, $condition); if (DBA::isResult($item)) { $item_id = $item['id']; $item_parent = $item['parent']; @@ -225,7 +225,7 @@ function display_content(App $a, $update = false, $update_uid = 0) if ($item_parent == 0) { $condition = ['private' => [Item::PUBLIC, Item::UNLISTED], 'guid' => $a->argv[1], 'uid' => 0]; - $item = Item::selectFirstForUser(local_user(), $fields, $condition); + $item = Post::selectFirstForUser(local_user(), $fields, $condition); if (DBA::isResult($item)) { $item_id = $item['id']; $item_parent = $item['parent']; @@ -315,9 +315,9 @@ function display_content(App $a, $update = false, $update_uid = 0) return ''; } - $condition = ["`id` = ? AND `item`.`uid` IN (0, ?) " . $sql_extra, $item_id, $item_uid]; + $condition = ["`id` = ? AND `uid` IN (0, ?) " . $sql_extra, $item_id, $item_uid]; $fields = ['parent-uri', 'body', 'title', 'author-name', 'author-avatar', 'plink', 'author-id', 'owner-id', 'contact-id']; - $item = Item::selectFirstForUser($a->profile['uid'], $fields, $condition); + $item = Post::selectFirstForUser($a->profile['uid'], $fields, $condition); if (!DBA::isResult($item)) { throw new HTTPException\NotFoundException(DI::l10n()->t('The requested item doesn\'t exist or has been deleted.')); diff --git a/mod/editpost.php b/mod/editpost.php index ff2d0f5552..4bfb63ada5 100644 --- a/mod/editpost.php +++ b/mod/editpost.php @@ -28,6 +28,7 @@ use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\FileTag; use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Util\Crypto; function editpost_content(App $a) @@ -49,7 +50,7 @@ function editpost_content(App $a) $fields = ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'type', 'body', 'title', 'file', 'wall', 'post-type', 'guid']; - $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $post_id, 'uid' => local_user()]); + $item = Post::selectFirstForUser(local_user(), $fields, ['id' => $post_id, 'uid' => local_user()]); if (!DBA::isResult($item)) { notice(DI::l10n()->t('Item not found')); diff --git a/mod/item.php b/mod/item.php index c00faf5dc5..68904d9ecb 100644 --- a/mod/item.php +++ b/mod/item.php @@ -861,7 +861,7 @@ function drop_item(int $id, string $return = '') { // locate item to be deleted $fields = ['id', 'uid', 'guid', 'contact-id', 'deleted', 'gravity', 'parent']; - $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $id]); + $item = Post::selectFirstForUser(local_user(), $fields, ['id' => $id]); if (!DBA::isResult($item)) { notice(DI::l10n()->t('Item not found.')); @@ -881,7 +881,7 @@ function drop_item(int $id, string $return = '') if ((local_user() == $item['uid']) || $contact_id) { if (!empty($item['parent'])) { - $parentitem = Item::selectFirstForUser(local_user(), ['guid'], ['id' => $item['parent']]); + $parentitem = Post::selectFirstForUser(local_user(), ['guid'], ['id' => $item['parent']]); } // delete the item diff --git a/mod/notes.php b/mod/notes.php index d3ce0fa40c..7c65a4c07a 100644 --- a/mod/notes.php +++ b/mod/notes.php @@ -86,7 +86,7 @@ function notes_content(App $a, $update = false) $count = 0; if (DBA::isResult($r)) { - $notes = Item::inArray($r); + $notes = Item::toArray($r); $count = count($notes); diff --git a/mod/photos.php b/mod/photos.php index 817e9fc53f..b999eec386 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1276,13 +1276,12 @@ function photos_content(App $a) if (!empty($link_item['parent']) && !empty($link_item['uid'])) { $condition = ["`parent` = ? AND `gravity` != ?", $link_item['parent'], GRAVITY_PARENT]; - $total = DBA::count('item', $condition); + $total = Post::count($condition); $pager = new Pager(DI::l10n(), DI::args()->getQueryString()); $params = ['order' => ['id'], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; - $result = Item::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params); - $items = Item::inArray($result); + $items = Post::toArray(Post::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params)); if (local_user() == $link_item['uid']) { Item::update(['unseen' => false], ['parent' => $link_item['parent']]); diff --git a/mod/ping.php b/mod/ping.php index 762d0a0f81..7d8b6c3537 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -28,8 +28,8 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Group; -use Friendica\Model\Item; use Friendica\Model\Notify\Type; +use Friendica\Model\Post; use Friendica\Model\Verb; use Friendica\Protocol\Activity; use Friendica\Util\DateTimeFormat; @@ -137,9 +137,9 @@ function ping_init(App $a) $condition = ["`unseen` AND `uid` = ? AND NOT `origin` AND (`vid` != ? OR `vid` IS NULL)", local_user(), Verb::getID(Activity::FOLLOW)]; - $items = Item::selectForUser(local_user(), ['wall', 'uid', 'uri-id'], $condition); + $items = Post::selectForUser(local_user(), ['wall', 'uid', 'uri-id'], $condition); if (DBA::isResult($items)) { - $items_unseen = Item::inArray($items); + $items_unseen = Post::toArray($items); $arr = ['items' => $items_unseen]; Hook::callAll('network_ping', $arr); diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index a75ab2ed3c..cd611e8eea 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -69,14 +69,14 @@ class Status extends BaseFactory $account = DI::mstdnAccount()->createFromContactId($item['author-id']); $counts = new \Friendica\Object\Api\Mastodon\Status\Counts( - DBA::count('item', ['thr-parent-id' => $uriId, 'uid' => $uid, 'gravity' => GRAVITY_COMMENT]), - DBA::count('item', ['thr-parent-id' => $uriId, 'uid' => $uid, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE)]), - DBA::count('item', ['thr-parent-id' => $uriId, 'uid' => $uid, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE)]) + Post::count(['thr-parent-id' => $uriId, 'uid' => $uid, 'gravity' => GRAVITY_COMMENT]), + Post::count(['thr-parent-id' => $uriId, 'uid' => $uid, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE)]), + Post::count(['thr-parent-id' => $uriId, 'uid' => $uid, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE)]) ); $userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes( - DBA::exists('item', ['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE)]), - DBA::exists('item', ['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE)]), + Post::exists(['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE)]), + Post::exists(['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE)]), DBA::exists('thread', ['iid' => $item['id'], 'uid' => $item['uid'], 'ignored' => true]), (bool)$item['starred'], DBA::exists('user-item', ['iid' => $item['id'], 'uid' => $item['uid'], 'pinned' => true]) diff --git a/src/Factory/Notification/Notification.php b/src/Factory/Notification/Notification.php index ba36b0cef4..8be4eaaea7 100644 --- a/src/Factory/Notification/Notification.php +++ b/src/Factory/Notification/Notification.php @@ -32,7 +32,7 @@ use Friendica\Core\PConfig\IPConfig; use Friendica\Core\Protocol; use Friendica\Core\Session\ISession; use Friendica\Database\Database; -use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Module\BaseNotifications; use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Object\Api\Friendica\Notification as ApiNotification; @@ -278,7 +278,7 @@ class Notification extends BaseFactory $formattedNotifications = []; try { - $items = Item::selectForUser(local_user(), $fields, $conditions, $params); + $items = Post::selectForUser(local_user(), $fields, $conditions, $params); while ($item = $this->dba->fetch($items)) { $formattedNotifications[] = $this->createFromItem($item); @@ -319,7 +319,7 @@ class Notification extends BaseFactory $formattedNotifications = []; try { - $items = Item::selectForUser(local_user(), $fields, $condition, $params); + $items = Post::selectForUser(local_user(), $fields, $condition, $params); while ($item = $this->dba->fetch($items)) { $formattedNotifications[] = $this->createFromItem($item); @@ -356,7 +356,7 @@ class Notification extends BaseFactory $formattedNotifications = []; try { - $items = Item::selectForUser(local_user(), $fields, $condition, $params); + $items = Post::selectForUser(local_user(), $fields, $condition, $params); while ($item = $this->dba->fetch($items)) { $item = $this->formatItem($item); diff --git a/src/Model/Contact.php b/src/Model/Contact.php index b922265e24..5b28d0fdfa 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1296,9 +1296,9 @@ class Contact } if (empty($contact["network"]) || in_array($contact["network"], Protocol::FEDERATED)) { - $sql = "(`item`.`uid` = 0 OR (`item`.`uid` = ? AND NOT `item`.`global`))"; + $sql = "(`uid` = 0 OR (`uid` = ? AND NOT `global`))"; } else { - $sql = "`item`.`uid` = ?"; + $sql = "`uid` = ?"; } $contact_field = ((($contact["contact-type"] == self::TYPE_COMMUNITY) || ($contact['network'] == Protocol::MAIL)) ? 'owner-id' : 'author-id'); @@ -1340,18 +1340,11 @@ class Contact } if ($thread_mode) { - $r = Item::selectForUser(local_user(), ['uri', 'gravity', 'parent-uri', 'thr-parent-id', 'author-id'], $condition, $params); - $items = []; - while ($item = DBA::fetch($r)) { - $items[] = $item; - } - DBA::close($r); + $items = Post::toArray(Post::selectForUser(local_user(), ['uri', 'gravity', 'parent-uri', 'thr-parent-id', 'author-id'], $condition, $params)); $o .= conversation($a, $items, 'contacts', $update, false, 'commented', local_user()); } else { - $r = Item::selectForUser(local_user(), [], $condition, $params); - - $items = Item::inArray($r); + $items = Post::toArray(Post::selectForUser(local_user(), [], $condition, $params)); $o .= conversation($a, $items, 'contact-posts', $update); } diff --git a/src/Model/Item.php b/src/Model/Item.php index fe7e85dae1..02695fae78 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -353,7 +353,7 @@ class Item * @param bool $do_close * @return array Data array */ - public static function inArray($stmt, $do_close = true) { + public static function toArray($stmt, $do_close = true) { if (is_bool($stmt)) { return $stmt; } @@ -390,28 +390,6 @@ class Item return $retval; } - /** - * Retrieve a single record from the item table for a given user and returns it in an associative array - * - * @param integer $uid User ID - * @param array $selected - * @param array $condition - * @param array $params - * @return bool|array - * @throws \Exception - * @see DBA::select - */ - public static function selectFirstForUser($uid, array $selected = [], array $condition = [], $params = []) - { - $params['uid'] = $uid; - - if (empty($selected)) { - $selected = self::DISPLAY_FIELDLIST; - } - - return self::selectFirst($selected, $condition, $params); - } - /** * Select rows from the item table for a given user * @@ -1518,7 +1496,7 @@ class Item 'wall', 'private', 'forum_mode', 'origin', 'author-id']; $condition = ['uri' => $item['thr-parent'], 'uid' => $item['uid']]; $params = ['order' => ['id' => false]]; - $parent = self::selectFirst($fields, $condition, $params); + $parent = Post::selectFirst($fields, $condition, $params); if (!DBA::isResult($parent)) { Logger::notice('item parent was not found - ignoring item', ['thr-parent' => $item['thr-parent'], 'uid' => $item['uid']]); @@ -1533,7 +1511,7 @@ class Item 'parent-uri' => $parent['parent-uri'], 'uid' => $parent['uid']]; $params = ['order' => ['id' => false]]; - $toplevel_parent = self::selectFirst($fields, $condition, $params); + $toplevel_parent = Post::selectFirst($fields, $condition, $params); if (!DBA::isResult($toplevel_parent)) { Logger::notice('item top level parent was not found - ignoring item', ['parent-uri' => $parent['parent-uri'], 'uid' => $parent['uid']]); return []; @@ -2019,7 +1997,7 @@ class Item $transmit = $notify || ($item['visible'] && ($parent_origin || $item['origin'])); if ($transmit) { - $transmit_item = self::selectFirst(['verb', 'origin'], ['id' => $item['id']]); + $transmit_item = Post::selectFirst(['verb', 'origin'], ['id' => $item['id']]); // Don't relay participation messages if (($transmit_item['verb'] == Activity::FOLLOW) && (!$transmit_item['origin'] || ($item['author-id'] != Contact::getPublicIdByUserId($uid)))) { diff --git a/src/Model/ItemContent.php b/src/Model/ItemContent.php index ad402ceceb..88ced5d9f1 100644 --- a/src/Model/ItemContent.php +++ b/src/Model/ItemContent.php @@ -56,7 +56,7 @@ class ItemContent 'limit' => [$start, $limit] ]; - $tags = DBA::select('item', ['uri-id'], $condition, $params); + $tags = Post::select(['uri-id'], $condition, $params); $uriids = []; while ($tag = DBA::fetch($tags)) { @@ -73,7 +73,7 @@ class ItemContent AND (NOT `private` OR (`private` AND `uid` = ?)) AND `uri-id` IN (SELECT `uri-id` FROM `item` WHERE `network` IN (?, ?, ?, ?))", $search, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]; - return DBA::count('item', $condition); + return Post::count($condition); } /** diff --git a/src/Model/Post.php b/src/Model/Post.php index b8f733f5d5..52b801de3c 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -89,7 +89,7 @@ class Post * @param bool $do_close * @return array Data array */ - public static function inArray($stmt, $do_close = true) { + public static function toArray($stmt, $do_close = true) { if (is_bool($stmt)) { return $stmt; } @@ -213,4 +213,83 @@ class Post return DBA::select('post-view', $selected, $condition, $params); } + + /** + * Select rows from the post view for a given user + * + * @param integer $uid User ID + * @param array $selected Array of selected fields, empty for all + * @param array $condition Array of fields for condition + * @param array $params Array of several parameters + * + * @return boolean|object + * @throws \Exception + */ + public static function selectForUser($uid, array $selected = [], array $condition = [], $params = []) + { + if (empty($selected)) { + $selected = Item::DISPLAY_FIELDLIST; + } + + $selected = array_unique(array_merge($selected, ['internal-uri-id', 'internal-uid', 'internal-file-count'])); + + $condition = DBA::mergeConditions($condition, + ["`visible` AND NOT `deleted` AND NOT `moderated` + AND NOT `author-blocked` AND NOT `owner-blocked` + AND (NOT `causer-blocked` OR `causer-id` = ?) AND NOT `contact-blocked` + AND ((NOT `contact-readonly` AND NOT `contact-pending` AND (`contact-rel` IN (?, ?))) + OR `self` OR `gravity` != ? OR `contact-uid` = ?) + AND NOT EXISTS (SELECT `iid` FROM `user-item` WHERE `hidden` AND `iid` = `id` AND `uid` = ?) + AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `author-id` AND `blocked`) + AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `owner-id` AND `blocked`) + AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `author-id` AND `ignored` AND `gravity` = ?) + AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `owner-id` AND `ignored` AND `gravity` = ?)", + 0, Contact::SHARING, Contact::FRIEND, GRAVITY_PARENT, 0, $uid, $uid, $uid, $uid, GRAVITY_PARENT, $uid, GRAVITY_PARENT]); + + $select_string = ''; + + if (in_array('pinned', $selected)) { + $selected = array_flip($selected); + unset($selected['pinned']); + $selected = array_flip($selected); + + $select_string = '(SELECT `pinned` FROM `user-item` WHERE `iid` = `post-view`.`id` AND uid=`post-view`.`uid`) AS `pinned`, '; + } + + $select_string .= implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected)); + + $condition_string = DBA::buildCondition($condition); + $param_string = DBA::buildParameter($params); + + $sql = "SELECT " . $select_string . " FROM `post-view` " . $condition_string . $param_string; + $sql = DBA::cleanQuery($sql); + + return DBA::p($sql, $condition); + } + + /** + * Retrieve a single record from the post view for a given user and returns it in an associative array + * + * @param integer $uid User ID + * @param array $selected + * @param array $condition + * @param array $params + * @return bool|array + * @throws \Exception + * @see DBA::select + */ + public static function selectFirstForUser($uid, array $selected = [], array $condition = [], $params = []) + { + $params['limit'] = 1; + + $result = self::selectForUser($uid, $selected, $condition, $params); + + if (is_bool($result)) { + return $result; + } else { + $row = self::fetch($result); + DBA::close($result); + return $row; + } + } } diff --git a/src/Module/Api/Mastodon/Accounts/Statuses.php b/src/Module/Api/Mastodon/Accounts/Statuses.php index 9e29e5f24d..0186b1ffaf 100644 --- a/src/Module/Api/Mastodon/Accounts/Statuses.php +++ b/src/Module/Api/Mastodon/Accounts/Statuses.php @@ -26,6 +26,7 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Model\Verb; use Friendica\Module\BaseApi; use Friendica\Protocol\Activity; @@ -82,10 +83,10 @@ class Statuses extends BaseApi $params['order'] = ['uri-id']; } - $items = Item::selectForUser(0, ['uri-id', 'uid'], $condition, $params); + $items = Post::selectForUser(0, ['uri-id', 'uid'], $condition, $params); $statuses = []; - while ($item = Item::fetch($items)) { + while ($item = Post::fetch($items)) { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $item['uid']); } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php index 8ed5ecd5d1..82d854014b 100644 --- a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php +++ b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php @@ -26,6 +26,7 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Module\BaseApi; use Friendica\Network\HTTPException; @@ -81,7 +82,7 @@ class PublicTimeline extends BaseApi $params['order'] = ['uri-id']; } - $items = Item::selectForUser(0, ['uri-id', 'uid'], $condition, $params); + $items = Post::selectForUser(0, ['uri-id', 'uid'], $condition, $params); $statuses = []; while ($item = Item::fetch($items)) { diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php index b937a2a4cb..ce9c5eae2d 100644 --- a/src/Module/Profile/Status.php +++ b/src/Module/Profile/Status.php @@ -183,7 +183,7 @@ class Status extends BaseProfile (`gravity` = ? AND `vid` = ? AND `origin` AND `thr-parent-id` IN (SELECT `uri-id` FROM `item` AS `i` WHERE `gravity` = ? AND `network` IN (?, ?, ?, ?) AND `uid` IN (?, ?) - AND `i`.`uri-id` = `item`.`thr-parent-id`)))", + AND `i`.`uri-id` = `thr-parent-id`)))", GRAVITY_PARENT, GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), GRAVITY_PARENT, Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::OSTATUS, 0, $a->profile['uid']]); @@ -194,7 +194,7 @@ class Status extends BaseProfile $pager = new Pager(DI::l10n(), $args->getQueryString(), $itemspage_network); $params = ['limit' => [$pager->getStart(), $pager->getItemsPerPage()], 'order' => ['received' => true]]; - $items_stmt = DBA::select('item', ['uri', 'thr-parent-id', 'gravity', 'author-id', 'received'], $condition, $params); + $items_stmt = Post::select(['uri', 'thr-parent-id', 'gravity', 'author-id', 'received'], $condition, $params); // Set a time stamp for this page. We will make use of it when we // search for new items (update routine) @@ -213,7 +213,7 @@ class Status extends BaseProfile } } - $items = DBA::toArray($items_stmt); + $items = Post::toArray($items_stmt); if ($pager->getStart() == 0 && !empty($a->profile['uid'])) { $condition = ['private' => [Item::PUBLIC, Item::UNLISTED]]; @@ -229,7 +229,7 @@ class Status extends BaseProfile } $pinned_items = Item::selectPinned($a->profile['uid'], ['uri', 'pinned'], $condition); - $pinned = Item::inArray($pinned_items); + $pinned = Item::toArray($pinned_items); $items = array_merge($items, $pinned); } diff --git a/src/Module/Search/Acl.php b/src/Module/Search/Acl.php index 6fcbfa3fd7..076b943c8c 100644 --- a/src/Module/Search/Acl.php +++ b/src/Module/Search/Acl.php @@ -332,9 +332,9 @@ class Acl extends BaseModule $condition = ["`parent` = ?", $conv_id]; $params = ['order' => ['author-name' => true]]; - $authors = Item::selectForUser(local_user(), ['author-link'], $condition, $params); + $authors = Post::selectForUser(local_user(), ['author-link'], $condition, $params); $item_authors = []; - while ($author = Item::fetch($authors)) { + while ($author = Post::fetch($authors)) { $item_authors[$author['author-link']] = $author['author-link']; } DBA::close($authors); diff --git a/src/Module/Search/Filed.php b/src/Module/Search/Filed.php index 505950f715..670554276b 100644 --- a/src/Module/Search/Filed.php +++ b/src/Module/Search/Filed.php @@ -9,7 +9,7 @@ use Friendica\Content\Widget; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; -use Friendica\Model\Item; +use Friendica\Model\Post; use Friendica\Model\Post\Category; use Friendica\Module\BaseSearch; use Friendica\Module\Security\Login; @@ -69,8 +69,7 @@ class Filed extends BaseSearch $item_condition = ['uid' => local_user(), 'uri-id' => $posts]; $item_params = ['order' => ['uri-id' => true]]; - $result = Item::selectForUser(local_user(), [], $item_condition, $item_params); - $items = Item::inArray($result); + $items = Post::toArray(Post::selectForUser(local_user(), [], $item_condition, $item_params)); $o .= conversation(DI::app(), $items, 'filed', false, false, '', local_user()); diff --git a/src/Module/Search/Index.php b/src/Module/Search/Index.php index f50b68c2aa..1c55ff4b4b 100644 --- a/src/Module/Search/Index.php +++ b/src/Module/Search/Index.php @@ -172,7 +172,7 @@ class Index extends BaseSearch if (!empty($uriids)) { $params = ['order' => ['id' => true], 'group_by' => ['uri-id']]; - $items = Item::inArray(Item::selectForUser(local_user(), [], ['uri-id' => $uriids], $params)); + $items = Post::toArray(Post::selectForUser(local_user(), [], ['uri-id' => $uriids], $params)); } if (empty($items)) { diff --git a/src/Module/Starred.php b/src/Module/Starred.php index 86f6880d50..8bc0fa3e4e 100644 --- a/src/Module/Starred.php +++ b/src/Module/Starred.php @@ -24,6 +24,7 @@ namespace Friendica\Module; use Friendica\BaseModule; use Friendica\DI; use Friendica\Model\Item; +use Friendica\Model\Post; /** * Toggle starred items @@ -42,7 +43,7 @@ class Starred extends BaseModule $itemId = intval($parameters['item']); - $item = Item::selectFirstForUser(local_user(), ['starred'], ['uid' => local_user(), 'id' => $itemId]); + $item = Post::selectFirstForUser(local_user(), ['starred'], ['uid' => local_user(), 'id' => $itemId]); if (empty($item)) { throw new \Friendica\Network\HTTPException\NotFoundException(); } diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 749931c20d..401d05c561 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -260,7 +260,7 @@ class Transmitter 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], 'deleted' => false, 'visible' => true, 'moderated' => false]); - $count = DBA::count('item', $condition); + $count = Post::count($condition); $data = ['@context' => ActivityPub::CONTEXT]; $data['id'] = DI::baseUrl() . '/outbox/' . $owner['nickname']; diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php index 6fd5ea7f87..ba01e719ad 100644 --- a/src/Protocol/Feed.php +++ b/src/Protocol/Feed.php @@ -892,7 +892,7 @@ class Feed $ret = Item::select([], $condition, $params); } - $items = Item::inArray($ret); + $items = Item::toArray($ret); $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 64ed6ae511..72008a1989 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -2129,7 +2129,7 @@ class OStatus $ret = Item::select([], $condition, $params); } - $items = Item::inArray($ret); + $items = Item::toArray($ret); $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 7a78e985c1..36081455ca 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -125,7 +125,7 @@ class Notifier return; } - $items = Post::inArray($items_stmt); + $items = Post::toArray($items_stmt); // avoid race condition with deleting entries if ($items[0]['deleted']) { diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 27752fb721..18a0d5981d 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1386); + define('DB_UPDATE_VERSION', 1387); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index b0bf7ed615..b9767c64ee 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -128,6 +128,7 @@ "author-avatar" => "IF (`contact`.`url` = `author`.`url`, `contact`.`thumb`, `author`.`thumb`)", "author-network" => ["author", "network"], "author-blocked" => ["author", "blocked"], + "author-hidden" => ["author", "hidden"], "owner-id" => ["item", "owner-id"], "owner-link" => ["owner", "url"], "owner-addr" => ["owner", "addr"], @@ -136,6 +137,7 @@ "owner-avatar" => "IF (`contact`.`url` = `owner`.`url`, `contact`.`thumb`, `owner`.`thumb`)", "owner-network" => ["owner", "network"], "owner-blocked" => ["owner", "blocked"], + "owner-hidden" => ["owner", "hidden"], "causer-id" => ["item", "causer-id"], "causer-link" => ["causer", "url"], "causer-addr" => ["causer", "addr"], @@ -144,6 +146,7 @@ "causer-avatar" => ["causer", "thumb"], "causer-network" => ["causer", "network"], "causer-blocked" => ["causer", "blocked"], + "causer-hidden" => ["causer", "hidden"], "causer-contact-type" => ["causer", "contact-type"], "postopts" => ["post-delivery-data", "postopts"], "inform" => ["post-delivery-data", "inform"],