From 4157db5473ad0eea4f303a989335eae11d79cf5e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 20:32:13 +0000 Subject: [PATCH 1/9] "item" is replaced by "post-view" / postupdate check added --- boot.php | 2 +- database.sql | 5 +- include/api.php | 2 +- mod/photos.php | 2 +- mod/ping.php | 4 +- src/Content/ForumManager.php | 12 +- src/Content/Widget/TagCloud.php | 8 +- src/Core/Update.php | 22 +- src/Database/DBA.php | 2 +- src/Database/Database.php | 2 +- src/Database/PostUpdate.php | 363 +----------------- src/Factory/Notification/Notification.php | 6 +- src/Model/Event.php | 39 +- src/Model/Group.php | 2 +- src/Model/Item.php | 57 +-- src/Model/ItemContent.php | 4 +- src/Model/Nodeinfo.php | 2 +- src/Model/Notify.php | 2 +- src/Model/Tag.php | 4 +- src/Model/UserItem.php | 5 +- .../Api/Mastodon/Timelines/PublicTimeline.php | 4 +- src/Module/Profile/Status.php | 2 +- src/Module/Update/Profile.php | 23 +- src/Object/Api/Friendica/Notification.php | 2 +- src/Protocol/DFRN.php | 87 +---- static/dbstructure.config.php | 2 +- static/dbview.config.php | 3 + update.php | 218 ----------- 28 files changed, 104 insertions(+), 782 deletions(-) diff --git a/boot.php b/boot.php index 1c5b4c168..e63e3d4e8 100644 --- a/boot.php +++ b/boot.php @@ -40,7 +40,7 @@ define('FRIENDICA_PLATFORM', 'Friendica'); define('FRIENDICA_CODENAME', 'Red Hot Poker'); define('FRIENDICA_VERSION', '2021.03-dev'); define('DFRN_PROTOCOL_VERSION', '2.23'); -define('NEW_UPDATE_ROUTINE_VERSION', 1170); +define('NEW_TABLE_STRUCTURE_VERSION', 1288); /** * Constant with a HTML line break. diff --git a/database.sql b/database.sql index 8c4ab5bae..985a64211 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2021.03-dev (Red Hot Poker) --- DB_UPDATE_VERSION 1388 +-- DB_UPDATE_VERSION 1389 -- ------------------------------------------ @@ -1560,10 +1560,13 @@ CREATE VIEW `post-view` AS SELECT `contact`.`thumb` AS `contact-avatar`, `contact`.`network` AS `contact-network`, `contact`.`blocked` AS `contact-blocked`, + `contact`.`hidden` AS `contact-hidden`, `contact`.`readonly` AS `contact-readonly`, + `contact`.`archive` AS `contact-archive`, `contact`.`pending` AS `contact-pending`, `contact`.`rel` AS `contact-rel`, `contact`.`uid` AS `contact-uid`, + `contact`.`contact-type` AS `contact-contact-type`, IF (`item`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`, `contact`.`self` AS `self`, `contact`.`id` AS `cid`, diff --git a/include/api.php b/include/api.php index ccb6f718e..9a1767d6e 100644 --- a/include/api.php +++ b/include/api.php @@ -6007,7 +6007,7 @@ function bindComments(&$data) } $idStr = DBA::escape(implode(', ', $ids)); - $sql = "SELECT `parent`, COUNT(*) as comments FROM `item` WHERE `parent` IN ($idStr) AND `deleted` = ? AND `gravity`= ? GROUP BY `parent`"; + $sql = "SELECT `parent`, COUNT(*) as comments FROM `post-view` WHERE `parent` IN ($idStr) AND `deleted` = ? AND `gravity`= ? GROUP BY `parent`"; $items = DBA::p($sql, 0, GRAVITY_COMMENT); $itemsData = DBA::toArray($items); diff --git a/mod/photos.php b/mod/photos.php index b999eec38..71e32d4de 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1266,7 +1266,7 @@ function photos_content(App $a) // as a "post" but displaying instead the photo it is linked to /// @todo Rewrite this query. To do so, $sql_extra must be changed - $linked_items = q("SELECT `id` FROM `item` WHERE `resource-id` = '%s' $sql_extra LIMIT 1", + $linked_items = q("SELECT `id` FROM `post-view` WHERE `resource-id` = '%s' $sql_extra LIMIT 1", DBA::escape($datum) ); if (DBA::isResult($linked_items)) { diff --git a/mod/ping.php b/mod/ping.php index 7d8b6c353..810598a0b 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -412,8 +412,8 @@ function ping_get_notifications($uid) do { $r = q( - "SELECT `notify`.*, `item`.`visible`, `item`.`deleted` - FROM `notify` LEFT JOIN `item` ON `item`.`id` = `notify`.`iid` + "SELECT `notify`.*, `post-view`.`visible`, `post-view`.`deleted` + FROM `notify` LEFT JOIN `post-view` ON `post-view`.`id` = `notify`.`iid` WHERE `notify`.`uid` = %d AND `notify`.`msg` != '' AND NOT (`notify`.`type` IN (%d, %d)) AND $seensql `notify`.`seen` ORDER BY `notify`.`date` $order LIMIT %d, 50", diff --git a/src/Content/ForumManager.php b/src/Content/ForumManager.php index 41f3a650a..f32b1e349 100644 --- a/src/Content/ForumManager.php +++ b/src/Content/ForumManager.php @@ -209,14 +209,14 @@ class ForumManager public static function countUnseenItems() { $stmtContacts = DBA::p( - "SELECT `contact`.`id`, `contact`.`name`, COUNT(*) AS `count` FROM `item` - INNER JOIN `contact` ON `item`.`contact-id` = `contact`.`id` - WHERE `item`.`uid` = ? AND `item`.`visible` AND NOT `item`.`deleted` AND `item`.`unseen` - AND `contact`.`network`= 'dfrn' AND (`contact`.`forum` OR `contact`.`prv`) + "SELECT `contact`.`id`, `contact`.`name`, COUNT(*) AS `count` FROM `post-view` + INNER JOIN `contact` ON `post-view`.`contact-id` = `contact`.`id` + WHERE `post-view`.`uid` = ? AND `post-view`.`visible` AND NOT `post-view`.`deleted` AND `post-view`.`unseen` + AND `contact`.`network` IN (?, ?) AND `contact`.`contact-type` = ? AND NOT `contact`.`blocked` AND NOT `contact`.`hidden` AND NOT `contact`.`pending` AND NOT `contact`.`archive` - GROUP BY `contact`.`id` ", - local_user() + GROUP BY `contact`.`id`", + local_user(), Protocol::DFRN, Protocol::ACTIVITYPUB, Contact::TYPE_COMMUNITY ); return DBA::toArray($stmtContacts); diff --git a/src/Content/Widget/TagCloud.php b/src/Content/Widget/TagCloud.php index 109940a12..b2121a003 100644 --- a/src/Content/Widget/TagCloud.php +++ b/src/Content/Widget/TagCloud.php @@ -92,19 +92,19 @@ class TagCloud if ($flags) { if ($flags === 'wall') { - $sql_options .= ' AND `item`.`wall` '; + $sql_options .= ' AND `post-view`.`wall` '; } } if ($owner_id) { - $sql_options .= ' AND `item`.`owner-id` = ' . intval($owner_id) . ' '; + $sql_options .= ' AND `post-view`.`owner-id` = ' . intval($owner_id) . ' '; } // Fetch tags $tag_stmt = DBA::p("SELECT `name`, COUNT(`name`) AS `total` FROM `tag-search-view` - LEFT JOIN `item` ON `tag-search-view`.`uri-id` = `item`.`uri-id` + LEFT JOIN `post-view` ON `tag-search-view`.`uri-id` = `post-view`.`uri-id` WHERE `tag-search-view`.`uid` = ? - AND `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated` + AND `post-view`.`visible` AND NOT `post-view`.`deleted` AND NOT `post-view`.`moderated` $sql_options GROUP BY `name` ORDER BY `total` DESC $limit", $uid diff --git a/src/Core/Update.php b/src/Core/Update.php index 1d8f88d01..2758b6f49 100644 --- a/src/Core/Update.php +++ b/src/Core/Update.php @@ -22,9 +22,11 @@ namespace Friendica\Core; use Friendica\App; +use Friendica\App\Mode; use Friendica\Database\DBA; use Friendica\Database\DBStructure; use Friendica\DI; +use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Util\Strings; class Update @@ -60,8 +62,24 @@ class Update } // We don't support upgrading from very old versions anymore - if ($build < NEW_UPDATE_ROUTINE_VERSION) { - die('You try to update from a version prior to database version 1170. The direct upgrade path is not supported. Please update to version 3.5.4 before updating to this version.'); + if ($build < NEW_TABLE_STRUCTURE_VERSION) { + $error = DI::l10n('Updates from version %s are not supported. Please update at least to version 2021,01 and wait until the postupdate finished version 1383.', $build); + if (DI::mode()->getExecutor() == Mode::INDEX) { + die($error); + } else { + throw new InternalServerErrorException($error); + } + } + + // The postupdate has to completed version 1281 for the new post views to take over + $postupdate = DI::config()->get("system", "post_update_version"); + if ($postupdate < NEW_TABLE_STRUCTURE_VERSION) { + $error = DI::l10n('Updates from postupdate version %s are not supported. Please update at least to version 2021,01 and wait until the postupdate finished version 1383.', $postupdate); + if (DI::mode()->getExecutor() == Mode::INDEX) { + die($error); + } else { + throw new InternalServerErrorException($error); + } } if ($build < DB_UPDATE_VERSION) { diff --git a/src/Database/DBA.php b/src/Database/DBA.php index 1a7ff3bc5..41ab456b8 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -183,7 +183,7 @@ class DBA /** * Executes a prepared statement that returns data - * Example: $r = p("SELECT * FROM `item` WHERE `guid` = ?", $guid); + * Example: $r = p("SELECT * FROM `post` WHERE `guid` = ?", $guid); * * Please only use it with complicated queries. * For all regular queries please use DBA::select or DBA::exists diff --git a/src/Database/Database.php b/src/Database/Database.php index a95b1ad69..ae06f00e2 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -455,7 +455,7 @@ class Database /** * Executes a prepared statement that returns data * - * @usage Example: $r = p("SELECT * FROM `item` WHERE `guid` = ?", $guid); + * @usage Example: $r = p("SELECT * FROM `post` WHERE `guid` = ?", $guid); * * Please only use it with complicated queries. * For all regular queries please use DBA::select or DBA::exists diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 6e6e0dd06..2140aa837 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -27,9 +27,8 @@ use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\GServer; use Friendica\Model\Item; -use Friendica\Model\ItemURI; -use Friendica\Model\PermissionSet; use Friendica\Model\Photo; +use Friendica\Model\Post; use Friendica\Model\Post\Category; use Friendica\Model\Tag; use Friendica\Model\UserItem; @@ -53,18 +52,6 @@ class PostUpdate */ public static function update() { - if (!self::update1194()) { - return false; - } - if (!self::update1206()) { - return false; - } - if (!self::update1279()) { - return false; - } - if (!self::update1281()) { - return false; - } if (!self::update1297()) { return false; } @@ -105,352 +92,6 @@ class PostUpdate return true; } - /** - * Updates the "global" field in the item table - * - * @return bool "true" when the job is done - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function update1194() - { - // Was the script completed? - if (DI::config()->get("system", "post_update_version") >= 1194) { - return true; - } - - Logger::info("Start"); - - $end_id = DI::config()->get("system", "post_update_1194_end"); - if (!$end_id) { - $r = q("SELECT `id` FROM `item` WHERE `uid` != 0 ORDER BY `id` DESC LIMIT 1"); - if ($r) { - DI::config()->set("system", "post_update_1194_end", $r[0]["id"]); - $end_id = DI::config()->get("system", "post_update_1194_end"); - } - } - - Logger::info("End ID: ".$end_id); - - $start_id = DI::config()->get("system", "post_update_1194_start"); - - $query1 = "SELECT `item`.`id` FROM `item` "; - - $query2 = "INNER JOIN `item` AS `shadow` ON `item`.`uri` = `shadow`.`uri` AND `shadow`.`uid` = 0 "; - - $query3 = "WHERE `item`.`uid` != 0 AND `item`.`id` >= %d AND `item`.`id` <= %d - AND `item`.`visible` AND NOT `item`.`private` - AND NOT `item`.`deleted` AND NOT `item`.`moderated` - AND `item`.`network` IN ('%s', '%s', '%s', '') - AND NOT `item`.`global`"; - - $r = q($query1.$query2.$query3." ORDER BY `item`.`id` LIMIT 1", - intval($start_id), intval($end_id), - DBA::escape(Protocol::DFRN), DBA::escape(Protocol::DIASPORA), DBA::escape(Protocol::OSTATUS)); - if (!$r) { - DI::config()->set("system", "post_update_version", 1194); - Logger::info("Update is done"); - return true; - } else { - DI::config()->set("system", "post_update_1194_start", $r[0]["id"]); - $start_id = DI::config()->get("system", "post_update_1194_start"); - } - - Logger::info("Start ID: ".$start_id); - - $r = q($query1.$query2.$query3." ORDER BY `item`.`id` LIMIT 1000,1", - intval($start_id), intval($end_id), - DBA::escape(Protocol::DFRN), DBA::escape(Protocol::DIASPORA), DBA::escape(Protocol::OSTATUS)); - if ($r) { - $pos_id = $r[0]["id"]; - } else { - $pos_id = $end_id; - } - Logger::info("Progress: Start: ".$start_id." position: ".$pos_id." end: ".$end_id); - - q("UPDATE `item` ".$query2." SET `item`.`global` = 1 ".$query3, - intval($start_id), intval($pos_id), - DBA::escape(Protocol::DFRN), DBA::escape(Protocol::DIASPORA), DBA::escape(Protocol::OSTATUS)); - - Logger::info("Done"); - } - - /** - * update the "last-item" field in the "self" contact - * - * This field avoids cost intensive calls in the admin panel and in "nodeinfo" - * - * @return bool "true" when the job is done - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function update1206() - { - // Was the script completed? - if (DI::config()->get("system", "post_update_version") >= 1206) { - return true; - } - - Logger::info("Start"); - $r = q("SELECT `contact`.`id`, `contact`.`last-item`, - (SELECT MAX(`changed`) FROM `item` USE INDEX (`uid_wall_changed`) WHERE `wall` AND `uid` = `user`.`uid`) AS `lastitem_date` - FROM `user` - INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`"); - - if (!DBA::isResult($r)) { - return false; - } - foreach ($r as $user) { - if (!empty($user["lastitem_date"]) && ($user["lastitem_date"] > $user["last-item"])) { - DBA::update('contact', ['last-item' => $user['lastitem_date']], ['id' => $user['id']]); - } - } - - DI::config()->set("system", "post_update_version", 1206); - Logger::info("Done"); - return true; - } - - /** - * update the item related tables - * - * @return bool "true" when the job is done - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @throws \ImagickException - */ - private static function update1279() - { - // Was the script completed? - if (DI::config()->get("system", "post_update_version") >= 1279) { - return true; - } - - $id = DI::config()->get("system", "post_update_version_1279_id", 0); - - Logger::info("Start from item " . $id); - - $fields = array_merge(Item::MIXED_CONTENT_FIELDLIST, ['network', 'author-id', 'owner-id', 'tag', 'file', - 'author-name', 'author-avatar', 'author-link', 'owner-name', 'owner-avatar', 'owner-link', 'id', - 'uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'psid', 'post-type', 'bookmark', 'type', - 'inform', 'postopts', 'icid']); - - $start_id = $id; - $rows = 0; - $condition = ["`id` > ?", $id]; - $params = ['order' => ['id'], 'limit' => 10000]; - $items = Item::select($fields, $condition, $params); - - if (DBA::errorNo() != 0) { - Logger::info('Database error ' . DBA::errorNo() . ':' . DBA::errorMessage()); - return false; - } - - while ($item = Item::fetch($items)) { - $id = $item['id']; - - if (empty($item['author-id'])) { - $default = ['url' => $item['author-link'], 'name' => $item['author-name'], - 'photo' => $item['author-avatar'], 'network' => $item['network']]; - - $item['author-id'] = Contact::getIdForURL($item["author-link"], 0, null, $default); - } - - if (empty($item['owner-id'])) { - $default = ['url' => $item['owner-link'], 'name' => $item['owner-name'], - 'photo' => $item['owner-avatar'], 'network' => $item['network']]; - - $item['owner-id'] = Contact::getIdForURL($item["owner-link"], 0, null, $default); - } - - if (empty($item['psid'])) { - $item['psid'] = PermissionSet::getIdFromACL( - $item['uid'], - $item['allow_cid'], - $item['allow_gid'], - $item['deny_cid'], - $item['deny_gid'] - ); - } - - $item['allow_cid'] = null; - $item['allow_gid'] = null; - $item['deny_cid'] = null; - $item['deny_gid'] = null; - - if ($item['post-type'] == 0) { - if (!empty($item['type']) && ($item['type'] == 'note')) { - $item['post-type'] = Item::PT_PERSONAL_NOTE; - } elseif (!empty($item['type']) && ($item['type'] == 'photo')) { - $item['post-type'] = Item::PT_IMAGE; - } elseif (!empty($item['bookmark']) && $item['bookmark']) { - $item['post-type'] = Item::PT_PAGE; - } - } - - self::createLanguage($item); - - if (!empty($item['icid']) && !empty($item['language'])) { - DBA::update('item-content', ['language' => $item['language']], ['id' => $item['icid']]); - } - unset($item['language']); - - Item::update($item, ['id' => $id]); - - ++$rows; - } - DBA::close($items); - - DI::config()->set("system", "post_update_version_1279_id", $id); - - Logger::info("Processed rows: " . $rows . " - last processed item: " . $id); - - if ($start_id == $id) { - // Set all deprecated fields to "null" if they contain an empty string - $nullfields = ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'postopts', 'inform', 'type', - 'bookmark', 'file', 'location', 'coord', 'tag', 'plink', 'title', 'content-warning', - 'body', 'app', 'verb', 'object-type', 'object', 'target-type', 'target', - 'author-name', 'author-link', 'author-avatar', 'owner-name', 'owner-link', 'owner-avatar', - 'rendered-hash', 'rendered-html']; - foreach ($nullfields as $field) { - $fields = [$field => null]; - $condition = [$field => '']; - Logger::info("Setting '" . $field . "' to null if empty."); - // Important: This has to be a "DBA::update", not a "Item::update" - DBA::update('item', $fields, $condition); - } - - DI::config()->set("system", "post_update_version", 1279); - Logger::info("Done"); - return true; - } - - return false; - } - - private static function createLanguage(&$item) - { - if (empty($item['postopts'])) { - return; - } - - $opts = explode(',', $item['postopts']); - - $postopts = []; - - foreach ($opts as $opt) { - if (strstr($opt, 'lang=')) { - $language = substr($opt, 5); - } else { - $postopts[] = $opt; - } - } - - if (empty($language)) { - return; - } - - if (!empty($postopts)) { - $item['postopts'] = implode(',', $postopts); - } else { - $item['postopts'] = null; - } - - $lang_pairs = explode(':', $language); - - $lang_arr = []; - - foreach ($lang_pairs as $pair) { - $lang_pair_arr = explode(';', $pair); - if (count($lang_pair_arr) == 2) { - $lang_arr[$lang_pair_arr[0]] = $lang_pair_arr[1]; - } - } - - $item['language'] = json_encode($lang_arr); - } - - /** - * update item-uri data. Prerequisite for the next item structure update. - * - * @return bool "true" when the job is done - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function update1281() - { - // Was the script completed? - if (DI::config()->get("system", "post_update_version") >= 1281) { - return true; - } - - $id = DI::config()->get("system", "post_update_version_1281_id", 0); - - Logger::info("Start from item " . $id); - - $fields = ['id', 'guid', 'uri', 'uri-id', 'parent-uri', 'parent-uri-id', 'thr-parent', 'thr-parent-id']; - - $start_id = $id; - $rows = 0; - $condition = ["`id` > ?", $id]; - $params = ['order' => ['id'], 'limit' => 10000]; - $items = DBA::select('item', $fields, $condition, $params); - - if (DBA::errorNo() != 0) { - Logger::info('Database error ' . DBA::errorNo() . ':' . DBA::errorMessage()); - return false; - } - - while ($item = DBA::fetch($items)) { - $id = $item['id']; - - if (empty($item['uri'])) { - // Should not happen - continue; - } elseif (empty($item['uri-id'])) { - $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]); - } - - if (empty($item['parent-uri'])) { - $item['parent-uri-id'] = $item['uri-id']; - } elseif (empty($item['parent-uri-id'])) { - $item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']); - } - - // Very old items don't have this field - if (empty($item['thr-parent'])) { - $item['thr-parent-id'] = $item['parent-uri-id']; - } elseif (empty($item['thr-parent-id'])) { - $item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']); - } - - unset($item['id']); - unset($item['guid']); - unset($item['uri']); - unset($item['parent-uri']); - unset($item['thr-parent']); - - DBA::update('item', $item, ['id' => $id]); - - ++$rows; - } - DBA::close($items); - - DI::config()->set("system", "post_update_version_1281_id", $id); - - Logger::info("Processed rows: " . $rows . " - last processed item: " . $id); - - if ($start_id == $id) { - Logger::info("Updating item-uri in item-activity"); - DBA::e("UPDATE `item-activity` INNER JOIN `item-uri` ON `item-uri`.`uri` = `item-activity`.`uri` SET `item-activity`.`uri-id` = `item-uri`.`id` WHERE `item-activity`.`uri-id` IS NULL"); - - Logger::info("Updating item-uri in item-content"); - DBA::e("UPDATE `item-content` INNER JOIN `item-uri` ON `item-uri`.`uri` = `item-content`.`uri` SET `item-content`.`uri-id` = `item-uri`.`id` WHERE `item-content`.`uri-id` IS NULL"); - - DI::config()->set("system", "post_update_version", 1281); - Logger::info("Done"); - return true; - } - - return false; - } - /** * Set the delivery queue count to a negative value for all items preceding the feature. * @@ -822,7 +463,7 @@ class PostUpdate } while ($term = DBA::fetch($terms)) { - $item = Item::selectFirst(['uri-id', 'uid'], ['id' => $term['oid']]); + $item = Post::selectFirst(['uri-id', 'uid'], ['id' => $term['oid']]); if (!DBA::isResult($item)) { continue; } diff --git a/src/Factory/Notification/Notification.php b/src/Factory/Notification/Notification.php index 8be4eaaea..4d2d89fd2 100644 --- a/src/Factory/Notification/Notification.php +++ b/src/Factory/Notification/Notification.php @@ -302,11 +302,7 @@ class Notification extends BaseFactory */ public function getPersonalList(bool $seen = false, int $start = 0, int $limit = BaseNotifications::DEFAULT_PAGE_LIMIT) { - $myUrl = str_replace('http://', '', $this->nurl); - $diaspUrl = str_replace('/profile/', '/u/', $myUrl); - - $condition = ["NOT `wall` AND `uid` = ? AND (`item`.`author-id` = ? OR `item`.`tag` REGEXP ? OR `item`.`tag` REGEXP ?)", - local_user(), public_contact(), $myUrl . '\\]', $diaspUrl . '\\]']; + $condition = ["NOT `wall` AND `uid` = ? AND `author-id` = ?", local_user(), public_contact()]; if (!$seen) { $condition[0] .= " AND `unseen`"; diff --git a/src/Model/Event.php b/src/Model/Event.php index c247d22a8..c5a8ef788 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -513,15 +513,13 @@ class Event } // Query for the event by event id - $r = q("SELECT `event`.*, `item`.`id` AS `itemid` FROM `event` - LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid` + $events = DBA::toArray(DBA::p("SELECT `event`.*, `post-view`.`id` AS `itemid` FROM `event` + LEFT JOIN `post-view` ON `post-view`.`event-id` = `event`.`id` AND `post-view`.`uid` = `event`.`uid` WHERE `event`.`uid` = %d AND `event`.`id` = %d $sql_extra", - intval($owner_uid), - intval($event_id) - ); + $owner_uid, $event_id)); - if (DBA::isResult($r)) { - $return = self::removeDuplicates($r); + if (DBA::isResult($events)) { + $return = self::removeDuplicates($events); } return $return; @@ -554,24 +552,17 @@ class Event // Query for the event by date. // @todo Slow query (518 seconds to run), to be optimzed - $r = q("SELECT `event`.*, `item`.`id` AS `itemid` FROM `event` - LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid` - WHERE `event`.`uid` = %d AND event.ignore = %d - AND ((`adjust` = 0 AND (`finish` >= '%s' OR (nofinish AND start >= '%s')) AND `start` <= '%s') - OR (`adjust` = 1 AND (`finish` >= '%s' OR (nofinish AND start >= '%s')) AND `start` <= '%s')) - $sql_extra ", - intval($owner_uid), - intval($event_params["ignore"]), - DBA::escape($event_params["start"]), - DBA::escape($event_params["start"]), - DBA::escape($event_params["finish"]), - DBA::escape($event_params["adjust_start"]), - DBA::escape($event_params["adjust_start"]), - DBA::escape($event_params["adjust_finish"]) - ); + $events = DBA::toArray(DBA::p("SELECT `event`.*, `post-view`.`id` AS `itemid` FROM `event` + LEFT JOIN `post-view` ON `post-view`.`event-id` = `event`.`id` AND `post-view`.`uid` = `event`.`uid` + WHERE `event`.`uid` = ? AND `event`.`ignore` = ? + AND ((NOT `adjust` AND (`finish` >= ? OR (`nofinish` AND `start` >= ?)) AND `start` <= ?) + OR (`adjust` AND (`finish` >= ? OR (`nofinish` AND `start` >= ?)) AND `start` <= ?))" . $sql_extra, + $owner_uid, $event_params["ignore"], + $event_params["start"], $event_params["start"], $event_params["finish"], + $event_params["adjust_start"], $event_params["adjust_start"], $event_params["adjust_finish"])); - if (DBA::isResult($r)) { - $return = self::removeDuplicates($r); + if (DBA::isResult($events)) { + $return = self::removeDuplicates($events); } return $return; diff --git a/src/Model/Group.php b/src/Model/Group.php index 0a5151832..d332af91a 100644 --- a/src/Model/Group.php +++ b/src/Model/Group.php @@ -160,7 +160,7 @@ class Group public static function countUnseen() { $stmt = DBA::p("SELECT `group`.`id`, `group`.`name`, - (SELECT COUNT(*) FROM `item` FORCE INDEX (`uid_unseen_contactid`) + (SELECT COUNT(*) FROM `post-view` WHERE `uid` = ? AND `unseen` AND `contact-id` IN diff --git a/src/Model/Item.php b/src/Model/Item.php index f9a27b196..83f71004e 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -148,15 +148,6 @@ class Item return $postfields; } - public static function isLegacyMode() - { - if (is_null(self::$legacy_mode)) { - self::$legacy_mode = (DI::config()->get("system", "post_update_version") < 1279); - } - - return self::$legacy_mode; - } - /** * Set the pinned state of an item * @@ -226,7 +217,7 @@ class Item * @return array|false current row or false * @throws \Exception */ - public static function fetch($stmt) + private static function fetch($stmt) { $row = DBA::fetch($stmt); @@ -267,17 +258,6 @@ class Item // ---------------------- Transform item content data ---------------------- - // Fetch data from the item-content table whenever there is content there - if (self::isLegacyMode()) { - $legacy_fields = array_merge(Post\DeliveryData::LEGACY_FIELD_LIST, self::MIXED_CONTENT_FIELDLIST); - foreach ($legacy_fields as $field) { - if (empty($row[$field]) && !empty($row['internal-item-' . $field])) { - $row[$field] = $row['internal-item-' . $field]; - } - unset($row['internal-item-' . $field]); - } - } - if (array_key_exists('verb', $row)) { if (!is_null($row['internal-verb'])) { $row['verb'] = $row['internal-verb']; @@ -390,28 +370,6 @@ class Item return $retval; } - /** - * Select rows from the item table 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 = []) - { - $params['uid'] = $uid; - - if (empty($selected)) { - $selected = self::DISPLAY_FIELDLIST; - } - - return self::select($selected, $condition, $params); - } - /** * Retrieve a single record from the item table and returns it in an associative array * @@ -830,9 +788,6 @@ class Item foreach ($fields as $table => $table_fields) { foreach ($table_fields as $field => $select) { if (empty($selected) || in_array($select, $selected)) { - if (self::isLegacyMode() && in_array($select, $legacy_fields)) { - $selection[] = "`item`.`".$select."` AS `internal-item-" . $select . "`"; - } if (is_int($field)) { $selection[] = "`" . $table . "`.`" . $select . "`"; } else { @@ -904,7 +859,7 @@ class Item foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) { if (isset($fields[$field])) { $content_fields[$field] = $fields[$field]; - if (in_array($field, self::CONTENT_FIELDLIST) || !self::isLegacyMode()) { + if (in_array($field, self::CONTENT_FIELDLIST)) { unset($fields[$field]); } else { $fields[$field] = null; @@ -965,14 +920,6 @@ class Item $item_content = DBA::selectFirst('item-content', [], ['uri-id' => $item['uri-id']]); if (DBA::isResult($item_content)) { $item_fields = ['icid' => $item_content['id']]; - // Clear all fields in the item table that have a content in the item-content table - if (self::isLegacyMode()) { - foreach ($item_content as $field => $content) { - if (in_array($field, self::MIXED_CONTENT_FIELDLIST) && !empty($content)) { - $item_fields[$field] = null; - } - } - } DBA::update('item', $item_fields, ['id' => $item['id']]); } } diff --git a/src/Model/ItemContent.php b/src/Model/ItemContent.php index 88ced5d9f..304ab25d9 100644 --- a/src/Model/ItemContent.php +++ b/src/Model/ItemContent.php @@ -43,7 +43,7 @@ class ItemContent { $condition = ["`uri-id` IN (SELECT `uri-id` FROM `item-content` WHERE MATCH (`title`, `content-warning`, `body`) AGAINST (? IN BOOLEAN MODE)) AND (NOT `private` OR (`private` AND `uid` = ?)) - AND `uri-id` IN (SELECT `uri-id` FROM `item` WHERE `network` IN (?, ?, ?, ?))", + AND `uri-id` IN (SELECT `uri-id` FROM `post-view` WHERE `network` IN (?, ?, ?, ?))", $search, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]; if (!empty($last_uriid)) { @@ -71,7 +71,7 @@ class ItemContent { $condition = ["`uri-id` IN (SELECT `uri-id` FROM `item-content` WHERE MATCH (`title`, `content-warning`, `body`) AGAINST (? IN BOOLEAN MODE)) AND (NOT `private` OR (`private` AND `uid` = ?)) - AND `uri-id` IN (SELECT `uri-id` FROM `item` WHERE `network` IN (?, ?, ?, ?))", + AND `uri-id` IN (SELECT `uri-id` FROM `post-view` WHERE `network` IN (?, ?, ?, ?))", $search, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]; return Post::count($condition); } diff --git a/src/Model/Nodeinfo.php b/src/Model/Nodeinfo.php index 44181ac94..ef22c0ddd 100644 --- a/src/Model/Nodeinfo.php +++ b/src/Model/Nodeinfo.php @@ -60,7 +60,7 @@ class Nodeinfo $logger->debug('user statistics', $userStats); - $items = DBA::p("SELECT COUNT(*) AS `total`, `gravity` FROM `item` WHERE `origin` AND NOT `deleted` AND `uid` != 0 AND `gravity` IN (?, ?) GROUP BY `gravity`", + $items = DBA::p("SELECT COUNT(*) AS `total`, `gravity` FROM `post-view` WHERE `origin` AND NOT `deleted` AND `uid` != 0 AND `gravity` IN (?, ?) GROUP BY `gravity`", GRAVITY_PARENT, GRAVITY_COMMENT); while ($item = DBA::fetch($items)) { if ($item['gravity'] == GRAVITY_PARENT) { diff --git a/src/Model/Notify.php b/src/Model/Notify.php index 9ebf5c23b..bb7453d32 100644 --- a/src/Model/Notify.php +++ b/src/Model/Notify.php @@ -43,7 +43,7 @@ use Psr\Log\LoggerInterface; * @property integer parent Parent Item Id * @property boolean seen Whether the notification was read or not. * @property string verb Verb URL (@see http://activitystrea.ms) - * @property string otype Subject type (`item`, `intro` or `mail`) + * @property string otype Subject type ('item', 'intro' or 'mail') * * @property-read string name_cache Full name of the contact subject * @property-read string msg_cache Plaintext version of the notification text with a placeholder (`{0}`) for the subject contact's name. diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 4371a6e46..63a4ff492 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -452,7 +452,7 @@ class Tag public static function countByTag(string $search, int $uid = 0) { $condition = ["`name` = ? AND (NOT `private` OR (`private` AND `uid` = ?)) - AND `uri-id` IN (SELECT `uri-id` FROM `item` WHERE `network` IN (?, ?, ?, ?))", + AND `uri-id` IN (SELECT `uri-id` FROM `post-view` WHERE `network` IN (?, ?, ?, ?))", $search, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]; $params = ['group_by' => ['uri-id']]; @@ -472,7 +472,7 @@ class Tag public static function getURIIdListByTag(string $search, int $uid = 0, int $start = 0, int $limit = 100, int $last_uriid = 0) { $condition = ["`name` = ? AND (NOT `private` OR (`private` AND `uid` = ?)) - AND `uri-id` IN (SELECT `uri-id` FROM `item` WHERE `network` IN (?, ?, ?, ?))", + AND `uri-id` IN (SELECT `uri-id` FROM `post-view` WHERE `network` IN (?, ?, ?, ?))", $search, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]; if (!empty($last_uriid)) { diff --git a/src/Model/UserItem.php b/src/Model/UserItem.php index 2755bbb40..0cc3f6189 100644 --- a/src/Model/UserItem.php +++ b/src/Model/UserItem.php @@ -72,9 +72,8 @@ class UserItem // Add every user who participated so far in this thread // This can only happen with participations on global items. (means: uid = 0) - $users = DBA::p("SELECT DISTINCT(`contact`.`uid`) FROM `item` - INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` != 0 - WHERE `parent` IN (SELECT `parent` FROM `item` WHERE `id`=?)", $iid); + $users = DBA::p("SELECT DISTINCT(`contact-uid`) AS `uid` FROM `post-view` + WHERE `contact-uid` != 0 AND `parent` IN (SELECT `parent` FROM `post-view` WHERE `id` = ?)", $iid); while ($user = DBA::fetch($users)) { $uids[] = $user['uid']; } diff --git a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php index e77c330f6..a027f3739 100644 --- a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php +++ b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php @@ -62,11 +62,11 @@ class PublicTimeline extends BaseApi 'uid' => 0, 'network' => Protocol::FEDERATED]; if ($local) { - $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `item` WHERE `origin`)"]); + $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-view` WHERE `origin`)"]); } if ($remote) { - $condition = DBA::mergeConditions($condition, ["NOT `uri-id` IN (SELECT `uri-id` FROM `item` WHERE `origin`)"]); + $condition = DBA::mergeConditions($condition, ["NOT `uri-id` IN (SELECT `uri-id` FROM `post-view` WHERE `origin`)"]); } if (!empty($max_id)) { diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php index ce9c5eae2..6ee60e8f5 100644 --- a/src/Module/Profile/Status.php +++ b/src/Module/Profile/Status.php @@ -181,7 +181,7 @@ class Status extends BaseProfile $condition = DBA::mergeConditions($condition, ["((`gravity` = ? AND `wall`) OR (`gravity` = ? AND `vid` = ? AND `origin` AND `thr-parent-id` IN - (SELECT `uri-id` FROM `item` AS `i` + (SELECT `uri-id` FROM `post-view` AS `i` WHERE `gravity` = ? AND `network` IN (?, ?, ?, ?) AND `uid` IN (?, ?) AND `i`.`uri-id` = `thr-parent-id`)))", GRAVITY_PARENT, GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), GRAVITY_PARENT, diff --git a/src/Module/Update/Profile.php b/src/Module/Update/Profile.php index 56e86feb3..741bcc79c 100644 --- a/src/Module/Update/Profile.php +++ b/src/Module/Update/Profile.php @@ -71,27 +71,18 @@ class Profile extends BaseModule // If the page user is the owner of the page we should query for unseen // items. Otherwise use a timestamp of the last succesful update request. if ($is_owner || !$last_updated) { - $sql_extra4 = " AND `item`.`unseen`"; + $sql_extra4 = " AND `unseen`"; } else { $gmupdate = gmdate(DateTimeFormat::MYSQL, $last_updated); - $sql_extra4 = " AND `item`.`received` > '" . $gmupdate . "'"; + $sql_extra4 = " AND `received` > '" . $gmupdate . "'"; } $items_stmt = DBA::p( - "SELECT DISTINCT(`parent-uri`) AS `uri`, `item`.`created` - FROM `item` - INNER JOIN `contact` - ON `contact`.`id` = `item`.`contact-id` - AND NOT `contact`.`blocked` - AND NOT `contact`.`pending` - WHERE `item`.`uid` = ? - AND `item`.`visible` - AND (NOT `item`.`deleted` OR `item`.`gravity` = ?) - AND NOT `item`.`moderated` - AND `item`.`wall` - $sql_extra4 - $sql_extra - ORDER BY `item`.`received` DESC", + "SELECT DISTINCT(`parent-uri`) AS `uri`, `created` FROM `post-view` + WHERE `uid` = ? AND NOT `contact-blocked` AND NOT `contact-pending` + AND `visible` AND (NOT `deleted` OR `gravity` = ?) + AND NOT `moderated` AND `wall` $sql_extra4 $sql_extra + ORDER BY `received` DESC", $a->profile['uid'], GRAVITY_ACTIVITY ); diff --git a/src/Object/Api/Friendica/Notification.php b/src/Object/Api/Friendica/Notification.php index 9900d0a3f..aee787da1 100644 --- a/src/Object/Api/Friendica/Notification.php +++ b/src/Object/Api/Friendica/Notification.php @@ -63,7 +63,7 @@ class Notification extends BaseEntity protected $seen; /** @var string Verb URL @see http://activitystrea.ms */ protected $verb; - /** @var string Subject type (`item`, `intro` or `mail`) */ + /** @var string Subject type ('item', 'intro' or 'mail') */ protected $otype; /** @var string Full name of the contact subject (HTML) */ protected $name_cache; diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 4d5a92897..5167a5e7a 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -184,7 +184,7 @@ class DFRN // default permissions - anonymous user - $sql_extra = sprintf(" AND `item`.`private` != %s ", Item::PRIVATE); + $sql_extra = sprintf(" AND `private` != %s ", Item::PRIVATE); $owner = DBA::selectFirst('owner-view', [], ['nickname' => $owner_nick]); if (!DBA::isResult($owner)) { @@ -194,9 +194,7 @@ class DFRN $owner_id = $owner['uid']; - $sql_post_table = ""; - - if (! $public_feed) { + if (!$public_feed) { switch ($direction) { case (-1): $sql_extra = sprintf(" AND `issued-id` = '%s' ", DBA::escape($dfrn_id)); @@ -212,71 +210,41 @@ class DFRN break; // NOTREACHED } - $r = q( - "SELECT * FROM `contact` WHERE NOT `blocked` AND `contact`.`uid` = %d $sql_extra LIMIT 1", - intval($owner_id) - ); - - if (! DBA::isResult($r)) { - Logger::log(sprintf('No contact found for uid=%d', $owner_id), Logger::WARNING); + $contact = DBA::selectFirst('contact', ["NOT `blocked` AND `contact`.`uid` = ?" . $sql_extra, $owner_id]); + if (!DBA::isResult($contact)) { + Logger::notice('No contact found', ['uid' => $owner_id]); exit(); } - $contact = $r[0]; - $set = PermissionSet::get($owner_id, $contact['id']); if (!empty($set)) { - $sql_extra = " AND `item`.`psid` IN (" . implode(',', $set) .")"; + $sql_extra = " AND `psid` IN (" . implode(',', $set) .")"; } else { - $sql_extra = sprintf(" AND `item`.`private` != %s", Item::PRIVATE); + $sql_extra = sprintf(" AND `private` != %s", Item::PRIVATE); } } - if ($public_feed) { - $sort = 'DESC'; - } else { - $sort = 'ASC'; - } - - if (! strlen($last_update)) { + if (!strlen($last_update)) { $last_update = 'now -30 days'; } if (isset($category)) { - $sql_post_table = sprintf("INNER JOIN (SELECT `uri-id` FROM `category-view` WHERE `name` = '%s' AND `type` = %d AND `uid` = %d ORDER BY `uri-id` DESC) AS `category` ON `item`.`uri-id` = `category`.`uri-id` ", + $sql_extra .= sprintf(" AND `uri-id` IN (SELECT `uri-id` FROM `category-view` WHERE `name` = '%s' AND `type` = %d AND `uid` = %d)", DBA::escape(Strings::protectSprintf($category)), intval(Category::CATEGORY), intval($owner_id)); } if ($public_feed && ! $converse) { - $sql_extra .= " AND `contact`.`self` = 1 "; + $sql_extra .= " AND `self` "; } $check_date = DateTimeFormat::utc($last_update); - $r = q( - "SELECT `item`.`id` - FROM `item` USE INDEX (`uid_wall_changed`) $sql_post_table - STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - WHERE `item`.`uid` = %d AND `item`.`wall` AND `item`.`changed` > '%s' - AND `vid` != %d AND `item`.`visible` $sql_extra - ORDER BY `item`.`parent` ".$sort.", `item`.`received` ASC LIMIT 0, 300", - intval($owner_id), - DBA::escape($check_date), - Verb::getID(Activity::ANNOUNCE), - DBA::escape($sort) - ); + $condition = ["`uid` = ? AND `wall` AND `changed` > ? AND `vid` != ? AND `visible`" . $sql_extra, + $owner_id, $check_date, Verb::getID(Activity::ANNOUNCE)]; - $ids = []; - foreach ($r as $item) { - $ids[] = $item['id']; - } - - if (!empty($ids)) { - $items = Post::selectToArray(Item::DELIVER_FIELDLIST, ['id' => $ids]); - } else { - $items = []; - } + $params = ['sort' => ['parent' => $public_feed, 'received']]; + $items = Post::selectToArray(Item::DELIVER_FIELDLIST, $condition, $params, ['limit' => 300]); /* * Will check further below if this actually returned results. @@ -1924,32 +1892,15 @@ class DFRN $community = true; Logger::log("possible community action"); } else { - $sql_extra = " AND `contact`.`self` AND `item`.`wall` "; + $sql_extra = " AND `self` AND `wall`"; } // was the top-level post for this action written by somebody on this site? // Specifically, the recipient? + $parent = Post::selectFirst(['forum_mode', 'wall'], + ["`uri` = ? AND `uid` = ?" . $sql_extra, $item["thr-parent"], $importer["importer_uid"]]); - $is_a_remote_action = false; - - $parent = Post::selectFirst(['thr-parent'], ['uri' => $item["thr-parent"]]); - if (DBA::isResult($parent)) { - $r = q( - "SELECT `item`.`forum_mode`, `item`.`wall` FROM `item` - INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - WHERE `item`.`uri` = '%s' AND (`item`.`thr-parent` = '%s' OR `item`.`thr-parent` = '%s') - AND `item`.`uid` = %d - $sql_extra - LIMIT 1", - DBA::escape($parent["thr-parent"]), - DBA::escape($parent["thr-parent"]), - DBA::escape($parent["thr-parent"]), - intval($importer["importer_uid"]) - ); - if (DBA::isResult($r)) { - $is_a_remote_action = true; - } - } + $is_a_remote_action = DBA::isResult($parent); /* * Does this have the characteristics of a community or private group action? @@ -1957,7 +1908,7 @@ class DFRN * valid community action. Also forum_mode makes it valid for sure. * If neither, it's not. */ - if ($is_a_remote_action && $community && (!$r[0]["forum_mode"]) && (!$r[0]["wall"])) { + if ($is_a_remote_action && $community && (!$parent["forum_mode"]) && (!$parent["wall"])) { $is_a_remote_action = false; Logger::log("not a community action"); } diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 5199dae33..8012c3607 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', 1388); + define('DB_UPDATE_VERSION', 1389); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 1a9f194b8..5f9c1d34c 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -106,10 +106,13 @@ "contact-avatar" => ["contact", "thumb"], "contact-network" => ["contact", "network"], "contact-blocked" => ["contact", "blocked"], + "contact-hidden" => ["contact", "hidden"], "contact-readonly" => ["contact", "readonly"], + "contact-archive" => ["contact", "archive"], "contact-pending" => ["contact", "pending"], "contact-rel" => ["contact", "rel"], "contact-uid" => ["contact", "uid"], + "contact-contact-type" => ["contact", "contact-type"], "writable" => "IF (`item`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)", "self" => ["contact", "self"], "cid" => ["contact", "id"], diff --git a/update.php b/update.php index d8a281737..0a2f788f6 100644 --- a/update.php +++ b/update.php @@ -53,227 +53,9 @@ use Friendica\Model\Item; use Friendica\Model\Notify; use Friendica\Model\Photo; use Friendica\Model\Post; -use Friendica\Model\User; use Friendica\Model\Storage; -use Friendica\Util\DateTimeFormat; use Friendica\Worker\Delivery; -function update_1179() -{ - if (DI::config()->get('system', 'no_community_page')) { - DI::config()->set('system', 'community_page_style', CP_NO_COMMUNITY_PAGE); - } - - // Update the central item storage with uid=0 - Worker::add(PRIORITY_LOW, "threadupdate"); - - return Update::SUCCESS; -} - -function update_1181() -{ - - // Fill the new fields in the term table. - // deactivated, the "term" table is deprecated - // Worker::add(PRIORITY_LOW, "TagUpdate"); - - return Update::SUCCESS; -} - -function update_1189() -{ - - if (strlen(DI::config()->get('system', 'directory_submit_url')) && - !strlen(DI::config()->get('system', 'directory'))) { - DI::config()->set('system', 'directory', dirname(DI::config()->get('system', 'directory_submit_url'))); - DI::config()->delete('system', 'directory_submit_url'); - } - - return Update::SUCCESS; -} - -function update_1191() -{ - DI::config()->set('system', 'maintenance', 1); - - if (Addon::isEnabled('forumlist')) { - Addon::uninstall('forumlist'); - } - - // select old formlist addon entries - $r = q("SELECT `uid`, `cat`, `k`, `v` FROM `pconfig` WHERE `cat` = '%s' ", - DBA::escape('forumlist') - ); - - // convert old forumlist addon entries in new config entries - if (DBA::isResult($r)) { - foreach ($r as $rr) { - $uid = $rr['uid']; - $family = $rr['cat']; - $key = $rr['k']; - $value = $rr['v']; - - if ($key === 'randomise') { - DI::pConfig()->delete($uid, $family, $key); - } - - if ($key === 'show_on_profile') { - if ($value) { - DI::pConfig()->set($uid, 'feature', 'forumlist_profile', $value); - } - - DI::pConfig()->delete($uid, $family, $key); - } - - if ($key === 'show_on_network') { - if ($value) { - DI::pConfig()->set($uid, 'feature', 'forumlist_widget', $value); - } - - DI::pConfig()->delete($uid, $family, $key); - } - } - } - - DI::config()->set('system', 'maintenance', 0); - - return Update::SUCCESS; -} - -function update_1203() -{ - $r = q("UPDATE `user` SET `account-type` = %d WHERE `page-flags` IN (%d, %d)", - DBA::escape(User::ACCOUNT_TYPE_COMMUNITY), - DBA::escape(User::PAGE_FLAGS_COMMUNITY), - DBA::escape(User::PAGE_FLAGS_PRVGROUP) - ); -} - -function update_1244() -{ - // Sets legacy_password for all legacy hashes - DBA::update('user', ['legacy_password' => true], ['SUBSTR(password, 1, 4) != "$2y$"']); - - // All legacy hashes are re-hashed using the new secure hashing function - $stmt = DBA::select('user', ['uid', 'password'], ['legacy_password' => true]); - while ($user = DBA::fetch($stmt)) { - DBA::update('user', ['password' => User::hashPassword($user['password'])], ['uid' => $user['uid']]); - } - - // Logged in users are forcibly logged out - DBA::delete('session', ['1 = 1']); - - return Update::SUCCESS; -} - -function update_1245() -{ - $rino = DI::config()->get('system', 'rino_encrypt'); - - if (!$rino) { - return Update::SUCCESS; - } - - DI::config()->set('system', 'rino_encrypt', 1); - - return Update::SUCCESS; -} - -function update_1247() -{ - // Removing hooks with the old name - DBA::e("DELETE FROM `hook` -WHERE `hook` LIKE 'plugin_%'"); - - // Make sure we install the new renamed ones - Addon::reload(); -} - -function update_1260() -{ - DI::config()->set('system', 'maintenance', 1); - DI::config()->set( - 'system', - 'maintenance_reason', - DI::l10n()->t( - '%s: Updating author-id and owner-id in item and thread table. ', - DateTimeFormat::utcNow().' '.date('e') - ) - ); - - $items = DBA::p("SELECT `id`, `owner-link`, `owner-name`, `owner-avatar`, `network` FROM `item` - WHERE `owner-id` = 0 AND `owner-link` != ''"); - while ($item = DBA::fetch($items)) { - $contact = ['url' => $item['owner-link'], 'name' => $item['owner-name'], - 'photo' => $item['owner-avatar'], 'network' => $item['network']]; - $cid = Contact::getIdForURL($item['owner-link'], 0, null, $contact); - if (empty($cid)) { - continue; - } - Item::update(['owner-id' => $cid], ['id' => $item['id']]); - } - DBA::close($items); - - DBA::e("UPDATE `thread` INNER JOIN `item` ON `thread`.`iid` = `item`.`id` - SET `thread`.`owner-id` = `item`.`owner-id` WHERE `thread`.`owner-id` = 0"); - - $items = DBA::p("SELECT `id`, `author-link`, `author-name`, `author-avatar`, `network` FROM `item` - WHERE `author-id` = 0 AND `author-link` != ''"); - while ($item = DBA::fetch($items)) { - $contact = ['url' => $item['author-link'], 'name' => $item['author-name'], - 'photo' => $item['author-avatar'], 'network' => $item['network']]; - $cid = Contact::getIdForURL($item['author-link'], 0, null, $contact); - if (empty($cid)) { - continue; - } - Item::update(['author-id' => $cid], ['id' => $item['id']]); - } - DBA::close($items); - - DBA::e("UPDATE `thread` INNER JOIN `item` ON `thread`.`iid` = `item`.`id` - SET `thread`.`author-id` = `item`.`author-id` WHERE `thread`.`author-id` = 0"); - - DI::config()->set('system', 'maintenance', 0); - return Update::SUCCESS; -} - -function update_1261() -{ - // This fixes the results of an issue in the develop branch of 2018-05. - DBA::update('contact', ['blocked' => false, 'pending' => false], ['uid' => 0, 'blocked' => true, 'pending' => true]); - return Update::SUCCESS; -} - -function update_1278() -{ - DI::config()->set('system', 'maintenance', 1); - DI::config()->set( - 'system', - 'maintenance_reason', - DI::l10n()->t( - '%s: Updating post-type.', - DateTimeFormat::utcNow().' '.date('e') - ) - ); - - Item::update(['post-type' => Item::PT_PAGE], ['bookmark' => true]); - Item::update(['post-type' => Item::PT_PERSONAL_NOTE], ['type' => 'note']); - - DI::config()->set('system', 'maintenance', 0); - - return Update::SUCCESS; -} - -function update_1288() -{ - // Updates missing `uri-id` values - - DBA::e("UPDATE `item-activity` INNER JOIN `item` ON `item`.`iaid` = `item-activity`.`id` SET `item-activity`.`uri-id` = `item`.`uri-id` WHERE `item-activity`.`uri-id` IS NULL OR `item-activity`.`uri-id` = 0"); - DBA::e("UPDATE `item-content` INNER JOIN `item` ON `item`.`icid` = `item-content`.`id` SET `item-content`.`uri-id` = `item`.`uri-id` WHERE `item-content`.`uri-id` IS NULL OR `item-content`.`uri-id` = 0"); - - return Update::SUCCESS; -} - // Post-update script of PR 5751 function update_1298() { From 5a36c6b6c002d1d6eb5a79348f09f142250f3cd3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 20:56:15 +0000 Subject: [PATCH 2/9] Test for failed tests --- include/api.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/api.php b/include/api.php index 9a1767d6e..13beab027 100644 --- a/include/api.php +++ b/include/api.php @@ -2041,9 +2041,9 @@ function api_statuses_repeat($type) Logger::log('API: api_statuses_repeat: '.$id); $fields = ['uri-id', 'network', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; - $item = Item::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); - - if (DBA::isResult($item) && $item['body'] != "") { + $item = Post::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); + + if (!empty($item['body'])) { if (in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::TWITTER])) { if (!Item::performActivity($id, 'announce', local_user())) { throw new InternalServerErrorException(); @@ -2075,7 +2075,7 @@ function api_statuses_repeat($type) $item_id = item_post($a); } } else { - throw new ForbiddenException(); + throw new ForbiddenException(!DBA::isResult($item) ? 'not found' : 'empty body'); } // output the post that we just posted. From cd070954da050d356c8e32cf4d67cc3e337d19c9 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 21:03:35 +0000 Subject: [PATCH 3/9] Don't ask for empty bodies --- include/api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/api.php b/include/api.php index 13beab027..3d1afe01e 100644 --- a/include/api.php +++ b/include/api.php @@ -2043,7 +2043,7 @@ function api_statuses_repeat($type) $fields = ['uri-id', 'network', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; $item = Post::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); - if (!empty($item['body'])) { + if (DBA::isResult($item)) { if (in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::TWITTER])) { if (!Item::performActivity($id, 'announce', local_user())) { throw new InternalServerErrorException(); @@ -2075,7 +2075,7 @@ function api_statuses_repeat($type) $item_id = item_post($a); } } else { - throw new ForbiddenException(!DBA::isResult($item) ? 'not found' : 'empty body'); + throw new ForbiddenException(); } // output the post that we just posted. From f57ad057365ac32a947a4fc343ce962a1429e852 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 21:10:16 +0000 Subject: [PATCH 4/9] Added missing parameter --- src/Protocol/DFRN.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 5167a5e7a..4934e983b 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -210,7 +210,7 @@ class DFRN break; // NOTREACHED } - $contact = DBA::selectFirst('contact', ["NOT `blocked` AND `contact`.`uid` = ?" . $sql_extra, $owner_id]); + $contact = DBA::selectFirst('contact', [], ["NOT `blocked` AND `contact`.`uid` = ?" . $sql_extra, $owner_id]); if (!DBA::isResult($contact)) { Logger::notice('No contact found', ['uid' => $owner_id]); exit(); From 1a434fd8d63008189ffd78c6bd22613c0d083023 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 21:24:58 +0000 Subject: [PATCH 5/9] Add some test information --- include/api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/api.php b/include/api.php index 3d1afe01e..17fb57ad1 100644 --- a/include/api.php +++ b/include/api.php @@ -2043,7 +2043,7 @@ function api_statuses_repeat($type) $fields = ['uri-id', 'network', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; $item = Post::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); - if (DBA::isResult($item)) { + if (DBA::isResult($item) && !empty($item['body'])) { if (in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::TWITTER])) { if (!Item::performActivity($id, 'announce', local_user())) { throw new InternalServerErrorException(); @@ -2075,7 +2075,7 @@ function api_statuses_repeat($type) $item_id = item_post($a); } } else { - throw new ForbiddenException(); + throw new ForbiddenException(print_r($item, true)); } // output the post that we just posted. From 6b4245d662604466bb36932d568ace9b21c00a3e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 21:39:42 +0000 Subject: [PATCH 6/9] Test the test --- include/api.php | 1 + tests/datasets/config/A.config.php | 2 +- tests/datasets/config/B.config.php | 2 +- tests/src/Console/AutomaticInstallationConsoleTest.php | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/api.php b/include/api.php index 17fb57ad1..9edd79742 100644 --- a/include/api.php +++ b/include/api.php @@ -2041,6 +2041,7 @@ function api_statuses_repeat($type) Logger::log('API: api_statuses_repeat: '.$id); $fields = ['uri-id', 'network', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; + $fields = []; $item = Post::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); if (DBA::isResult($item) && !empty($item['body'])) { diff --git a/tests/datasets/config/A.config.php b/tests/datasets/config/A.config.php index 57d114de7..081f367c2 100644 --- a/tests/datasets/config/A.config.php +++ b/tests/datasets/config/A.config.php @@ -12,7 +12,7 @@ return [ 'password' => 'testpw', 'database' => 'testdb', 'charset' => 'utf8mb4', - 'pdo_emulate_prepares' => true, + 'pdo_emulate_prepares' => false, ], 'config' => [ diff --git a/tests/datasets/config/B.config.php b/tests/datasets/config/B.config.php index 76bcb6e76..1a0697541 100644 --- a/tests/datasets/config/B.config.php +++ b/tests/datasets/config/B.config.php @@ -12,7 +12,7 @@ return [ 'password' => 'testpw', 'database' => 'testdb', 'charset' => 'utf8mb4', - 'pdo_emulate_prepares' => true, + 'pdo_emulate_prepares' => false, ], 'config' => [ diff --git a/tests/src/Console/AutomaticInstallationConsoleTest.php b/tests/src/Console/AutomaticInstallationConsoleTest.php index f00a9e537..fdf887fe6 100644 --- a/tests/src/Console/AutomaticInstallationConsoleTest.php +++ b/tests/src/Console/AutomaticInstallationConsoleTest.php @@ -447,7 +447,7 @@ return [ 'password' => '{$conf('database', 'password')}', 'database' => '{$conf('database', 'database')}', 'charset' => 'utf8mb4', - 'pdo_emulate_prepares' => true, + 'pdo_emulate_prepares' => false, ], // **************************************************************** From 73ca1096ecc9d8b26cc0f768e81477b7b3e6fe0d Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 21:57:50 +0000 Subject: [PATCH 7/9] Fix the test data --- include/api.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/api.php b/include/api.php index 9edd79742..4aa4b21e2 100644 --- a/include/api.php +++ b/include/api.php @@ -2041,7 +2041,6 @@ function api_statuses_repeat($type) Logger::log('API: api_statuses_repeat: '.$id); $fields = ['uri-id', 'network', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; - $fields = []; $item = Post::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); if (DBA::isResult($item) && !empty($item['body'])) { @@ -2076,7 +2075,7 @@ function api_statuses_repeat($type) $item_id = item_post($a); } } else { - throw new ForbiddenException(print_r($item, true)); + throw new ForbiddenException(); } // output the post that we just posted. From 270d1aeb41eec8ec41ec3931c4513ef061ec434e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 22:08:08 +0000 Subject: [PATCH 8/9] Improve the test data --- tests/Util/Database/StaticDatabase.php | 1 - tests/datasets/api.fixture.php | 54 ++++++++++++++++++++------ tests/datasets/config/A.config.php | 1 - tests/datasets/config/B.config.php | 1 - 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/tests/Util/Database/StaticDatabase.php b/tests/Util/Database/StaticDatabase.php index c6488fc48..14cbf13c1 100644 --- a/tests/Util/Database/StaticDatabase.php +++ b/tests/Util/Database/StaticDatabase.php @@ -58,7 +58,6 @@ class StaticDatabase extends Database $this->connection = self::$staticConnection; $this->connected = true; $this->emulate_prepares = false; - $this->pdo_emulate_prepares = false; return $this->connected; } diff --git a/tests/datasets/api.fixture.php b/tests/datasets/api.fixture.php index f8c696c87..95c427d7c 100644 --- a/tests/datasets/api.fixture.php +++ b/tests/datasets/api.fixture.php @@ -179,6 +179,48 @@ return [ 'guid' => '6', ], ], + 'item-content' => [ + 'id' => 1, + 'uri-id' => 1, + 'uri-plink-hash' => '1', + 'body' => 'Parent status', + 'plink' => 'http://localhost/display/1', + ], + 'item-content' => [ + 'id' => 2, + 'uri-id' => 2, + 'uri-plink-hash' => '2', + 'body' => 'Reply', + 'plink' => 'http://localhost/display/2', + ], + 'item-content' => [ + 'id' => 3, + 'uri-id' => 3, + 'uri-plink-hash' => '3', + 'body' => 'Other user status', + 'plink' => 'http://localhost/display/3', + ], + 'item-content' => [ + 'id' => 4, + 'uri-id' => 4, + 'uri-plink-hash' => '4', + 'body' => 'Friend user reply', + 'plink' => 'http://localhost/display/4', + ], + 'item-content' => [ + 'id' => 5, + 'uri-id' => 5, + 'uri-plink-hash' => '5', + 'body' => '[share]Shared status[/share]', + 'plink' => 'http://localhost/display/5', + ], + 'item-content' => [ + 'id' => 6, + 'uri-id' => 6, + 'uri-plink-hash' => '6', + 'body' => 'Friend user status', + 'plink' => 'http://localhost/display/6', + ], 'item' => [ [ 'id' => 1, @@ -191,7 +233,6 @@ return [ 'uid' => 42, 'verb' => 'http://activitystrea.ms/schema/1.0/post', 'unseen' => 1, - 'body' => 'Parent status', 'parent' => 1, 'parent-uri-id' => 1, 'thr-parent-id' => 1, @@ -205,7 +246,6 @@ return [ 'deny_cid' => '', 'deny_gid' => '', 'guid' => '1', - 'plink' => 'http://localhost/display/1', ], [ 'id' => 2, @@ -218,7 +258,6 @@ return [ 'uid' => 42, 'verb' => 'http://activitystrea.ms/schema/1.0/post', 'unseen' => 0, - 'body' => 'Reply', 'parent' => 1, 'parent-uri-id' => 1, 'thr-parent-id' => 1, @@ -228,8 +267,6 @@ return [ 'starred' => 0, 'origin' => 1, 'guid' => '2', - 'plink' => 'http://localhost/display/2', - ], [ 'id' => 3, @@ -242,7 +279,6 @@ return [ 'uid' => 42, 'verb' => 'http://activitystrea.ms/schema/1.0/post', 'unseen' => 0, - 'body' => 'Other user status', 'parent' => 3, 'parent-uri-id' => 3, 'thr-parent-id' => 3, @@ -252,7 +288,6 @@ return [ 'starred' => 0, 'origin' => 1, 'guid' => '3', - 'plink' => 'http://localhost/display/3', ], [ 'id' => 4, @@ -275,7 +310,6 @@ return [ 'starred' => 0, 'origin' => 1, 'guid' => '4', - 'plink' => 'http://localhost/display/4', ], [ @@ -289,7 +323,6 @@ return [ 'uid' => 42, 'verb' => 'http://activitystrea.ms/schema/1.0/post', 'unseen' => 0, - 'body' => '[share]Shared status[/share]', 'parent' => 1, 'parent-uri-id' => 1, 'thr-parent-id' => 1, @@ -303,7 +336,6 @@ return [ 'deny_cid' => '', 'deny_gid' => '', 'guid' => '5', - 'plink' => 'http://localhost/display/5', ], [ 'id' => 6, @@ -316,7 +348,6 @@ return [ 'uid' => 42, 'verb' => 'http://activitystrea.ms/schema/1.0/post', 'unseen' => 0, - 'body' => 'Friend user status', 'parent' => 6, 'parent-uri-id' => 6, 'thr-parent-id' => 6, @@ -326,7 +357,6 @@ return [ 'starred' => 0, 'origin' => 1, 'guid' => '6', - 'plink' => 'http://localhost/display/6', ], ], 'notify' => [ diff --git a/tests/datasets/config/A.config.php b/tests/datasets/config/A.config.php index 081f367c2..f28e1f2e8 100644 --- a/tests/datasets/config/A.config.php +++ b/tests/datasets/config/A.config.php @@ -12,7 +12,6 @@ return [ 'password' => 'testpw', 'database' => 'testdb', 'charset' => 'utf8mb4', - 'pdo_emulate_prepares' => false, ], 'config' => [ diff --git a/tests/datasets/config/B.config.php b/tests/datasets/config/B.config.php index 1a0697541..59fadcf55 100644 --- a/tests/datasets/config/B.config.php +++ b/tests/datasets/config/B.config.php @@ -12,7 +12,6 @@ return [ 'password' => 'testpw', 'database' => 'testdb', 'charset' => 'utf8mb4', - 'pdo_emulate_prepares' => false, ], 'config' => [ From ff8b578cde6816280b72c3586242bf3bf30f0f0d Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Jan 2021 22:20:46 +0000 Subject: [PATCH 9/9] Fix the test data / unused function removed --- src/Model/Item.php | 25 ---------- tests/datasets/api.fixture.php | 86 +++++++++++++++++----------------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/src/Model/Item.php b/src/Model/Item.php index 83f71004e..c8677d842 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -370,31 +370,6 @@ class Item return $retval; } - /** - * Retrieve a single record from the item table and returns it in an associative array - * - * @param array $fields - * @param array $condition - * @param array $params - * @return bool|array - * @throws \Exception - * @see DBA::select - */ - public static function selectFirst(array $fields = [], array $condition = [], $params = []) - { - $params['limit'] = 1; - - $result = self::select($fields, $condition, $params); - - if (is_bool($result)) { - return $result; - } else { - $row = self::fetch($result); - DBA::close($result); - return $row; - } - } - /** * Select rows from the item table and returns them as an array * diff --git a/tests/datasets/api.fixture.php b/tests/datasets/api.fixture.php index 95c427d7c..7a0ad6cd4 100644 --- a/tests/datasets/api.fixture.php +++ b/tests/datasets/api.fixture.php @@ -180,47 +180,49 @@ return [ ], ], 'item-content' => [ - 'id' => 1, - 'uri-id' => 1, - 'uri-plink-hash' => '1', - 'body' => 'Parent status', - 'plink' => 'http://localhost/display/1', - ], - 'item-content' => [ - 'id' => 2, - 'uri-id' => 2, - 'uri-plink-hash' => '2', - 'body' => 'Reply', - 'plink' => 'http://localhost/display/2', - ], - 'item-content' => [ - 'id' => 3, - 'uri-id' => 3, - 'uri-plink-hash' => '3', - 'body' => 'Other user status', - 'plink' => 'http://localhost/display/3', - ], - 'item-content' => [ - 'id' => 4, - 'uri-id' => 4, - 'uri-plink-hash' => '4', - 'body' => 'Friend user reply', - 'plink' => 'http://localhost/display/4', - ], - 'item-content' => [ - 'id' => 5, - 'uri-id' => 5, - 'uri-plink-hash' => '5', - 'body' => '[share]Shared status[/share]', - 'plink' => 'http://localhost/display/5', - ], - 'item-content' => [ - 'id' => 6, - 'uri-id' => 6, - 'uri-plink-hash' => '6', - 'body' => 'Friend user status', - 'plink' => 'http://localhost/display/6', - ], + [ + 'id' => 1, + 'uri-id' => 1, + 'uri-plink-hash' => '1', + 'body' => 'Parent status', + 'plink' => 'http://localhost/display/1', + ], + [ + 'id' => 2, + 'uri-id' => 2, + 'uri-plink-hash' => '2', + 'body' => 'Reply', + 'plink' => 'http://localhost/display/2', + ], + [ + 'id' => 3, + 'uri-id' => 3, + 'uri-plink-hash' => '3', + 'body' => 'Other user status', + 'plink' => 'http://localhost/display/3', + ], + [ + 'id' => 4, + 'uri-id' => 4, + 'uri-plink-hash' => '4', + 'body' => 'Friend user reply', + 'plink' => 'http://localhost/display/4', + ], + [ + 'id' => 5, + 'uri-id' => 5, + 'uri-plink-hash' => '5', + 'body' => '[share]Shared status[/share]', + 'plink' => 'http://localhost/display/5', + ], + [ + 'id' => 6, + 'uri-id' => 6, + 'uri-plink-hash' => '6', + 'body' => 'Friend user status', + 'plink' => 'http://localhost/display/6', + ], + ], 'item' => [ [ 'id' => 1, @@ -267,8 +269,8 @@ return [ 'starred' => 0, 'origin' => 1, 'guid' => '2', + ], [ - 'id' => 3, 'uri-id' => 3, 'visible' => 1,