From 7e747b2f410e01576b809d0a52b79cbe3e660dce Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 10 Jun 2022 18:49:03 +0000 Subject: [PATCH 1/3] API: Speed improvements when fetching posts --- database.sql | 25 +++++++-- src/App.php | 2 +- src/App/Page.php | 4 +- src/Core/System.php | 2 +- src/Factory/Api/Mastodon/Account.php | 58 +++++++++++---------- src/Factory/Api/Mastodon/Status.php | 78 +++++++++++++++------------- src/Object/Api/Mastodon/Account.php | 54 ++++++++----------- static/dbstructure.config.php | 2 +- static/dbview.config.php | 19 +++++++ 9 files changed, 140 insertions(+), 104 deletions(-) diff --git a/database.sql b/database.sql index ce9d74cc6..b24f2ed5f 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2022.05-rc (Siberian Iris) --- DB_UPDATE_VERSION 1468 +-- DB_UPDATE_VERSION 1469 -- ------------------------------------------ @@ -1752,6 +1752,7 @@ CREATE VIEW `post-user-view` AS SELECT `post-content`.`target` AS `target`, `post-content`.`resource-id` AS `resource-id`, `post-user`.`contact-id` AS `contact-id`, + `contact`.`uri-id` AS `contact-uri-id`, `contact`.`url` AS `contact-link`, `contact`.`addr` AS `contact-addr`, `contact`.`name` AS `contact-name`, @@ -1776,6 +1777,7 @@ CREATE VIEW `post-user-view` AS SELECT `contact`.`avatar-date` AS `avatar-date`, `contact`.`thumb` AS `thumb`, `post-user`.`author-id` AS `author-id`, + `author`.`uri-id` AS `author-uri-id`, `author`.`url` AS `author-link`, `author`.`addr` AS `author-addr`, IF (`contact`.`url` = `author`.`url` AND `contact`.`name` != '', `contact`.`name`, `author`.`name`) AS `author-name`, @@ -1786,8 +1788,8 @@ CREATE VIEW `post-user-view` AS SELECT `author`.`hidden` AS `author-hidden`, `author`.`updated` AS `author-updated`, `author`.`gsid` AS `author-gsid`, - `author`.`uri-id` AS `author-uri-id`, `post-user`.`owner-id` AS `owner-id`, + `owner`.`uri-id` AS `owner-uri-id`, `owner`.`url` AS `owner-link`, `owner`.`addr` AS `owner-addr`, IF (`contact`.`url` = `owner`.`url` AND `contact`.`name` != '', `contact`.`name`, `owner`.`name`) AS `owner-name`, @@ -1799,6 +1801,7 @@ CREATE VIEW `post-user-view` AS SELECT `owner`.`updated` AS `owner-updated`, `owner`.`contact-type` AS `owner-contact-type`, `post-user`.`causer-id` AS `causer-id`, + `causer`.`uri-id` AS `causer-uri-id`, `causer`.`url` AS `causer-link`, `causer`.`addr` AS `causer-addr`, `causer`.`name` AS `causer-name`, @@ -1923,6 +1926,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT `post-content`.`target` AS `target`, `post-content`.`resource-id` AS `resource-id`, `post-thread-user`.`contact-id` AS `contact-id`, + `contact`.`uri-id` AS `contact-uri-id`, `contact`.`url` AS `contact-link`, `contact`.`addr` AS `contact-addr`, `contact`.`name` AS `contact-name`, @@ -1947,6 +1951,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT `contact`.`avatar-date` AS `avatar-date`, `contact`.`thumb` AS `thumb`, `post-thread-user`.`author-id` AS `author-id`, + `author`.`uri-id` AS `author-uri-id`, `author`.`url` AS `author-link`, `author`.`addr` AS `author-addr`, IF (`contact`.`url` = `author`.`url` AND `contact`.`name` != '', `contact`.`name`, `author`.`name`) AS `author-name`, @@ -1957,8 +1962,8 @@ CREATE VIEW `post-thread-user-view` AS SELECT `author`.`hidden` AS `author-hidden`, `author`.`updated` AS `author-updated`, `author`.`gsid` AS `author-gsid`, - `author`.`uri-id` AS `author-uri-id`, `post-thread-user`.`owner-id` AS `owner-id`, + `owner`.`uri-id` AS `owner-uri-id`, `owner`.`url` AS `owner-link`, `owner`.`addr` AS `owner-addr`, IF (`contact`.`url` = `owner`.`url` AND `contact`.`name` != '', `contact`.`name`, `owner`.`name`) AS `owner-name`, @@ -1970,6 +1975,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT `owner`.`updated` AS `owner-updated`, `owner`.`contact-type` AS `owner-contact-type`, `post-thread-user`.`causer-id` AS `causer-id`, + `causer`.`uri-id` AS `causer-uri-id`, `causer`.`url` AS `causer-link`, `causer`.`addr` AS `causer-addr`, `causer`.`name` AS `causer-name`, @@ -2080,6 +2086,7 @@ CREATE VIEW `post-view` AS SELECT `post-content`.`target` AS `target`, `post-content`.`resource-id` AS `resource-id`, `post`.`author-id` AS `contact-id`, + `author`.`uri-id` AS `contact-uri-id`, `author`.`url` AS `contact-link`, `author`.`addr` AS `contact-addr`, `author`.`name` AS `contact-name`, @@ -2104,6 +2111,7 @@ CREATE VIEW `post-view` AS SELECT `author`.`avatar-date` AS `avatar-date`, `author`.`thumb` AS `thumb`, `post`.`author-id` AS `author-id`, + `author`.`uri-id` AS `author-uri-id`, `author`.`url` AS `author-link`, `author`.`addr` AS `author-addr`, `author`.`name` AS `author-name`, @@ -2114,8 +2122,8 @@ CREATE VIEW `post-view` AS SELECT `author`.`hidden` AS `author-hidden`, `author`.`updated` AS `author-updated`, `author`.`gsid` AS `author-gsid`, - `author`.`uri-id` AS `author-uri-id`, `post`.`owner-id` AS `owner-id`, + `owner`.`uri-id` AS `owner-uri-id`, `owner`.`url` AS `owner-link`, `owner`.`addr` AS `owner-addr`, `owner`.`name` AS `owner-name`, @@ -2127,6 +2135,7 @@ CREATE VIEW `post-view` AS SELECT `owner`.`updated` AS `owner-updated`, `owner`.`contact-type` AS `owner-contact-type`, `post`.`causer-id` AS `causer-id`, + `causer`.`uri-id` AS `causer-uri-id`, `causer`.`url` AS `causer-link`, `causer`.`addr` AS `causer-addr`, `causer`.`name` AS `causer-name`, @@ -2213,6 +2222,7 @@ CREATE VIEW `post-thread-view` AS SELECT `post-content`.`target` AS `target`, `post-content`.`resource-id` AS `resource-id`, `post-thread`.`author-id` AS `contact-id`, + `author`.`uri-id` AS `contact-uri-id`, `author`.`url` AS `contact-link`, `author`.`addr` AS `contact-addr`, `author`.`name` AS `contact-name`, @@ -2237,6 +2247,7 @@ CREATE VIEW `post-thread-view` AS SELECT `author`.`avatar-date` AS `avatar-date`, `author`.`thumb` AS `thumb`, `post-thread`.`author-id` AS `author-id`, + `author`.`uri-id` AS `author-uri-id`, `author`.`url` AS `author-link`, `author`.`addr` AS `author-addr`, `author`.`name` AS `author-name`, @@ -2247,8 +2258,8 @@ CREATE VIEW `post-thread-view` AS SELECT `author`.`hidden` AS `author-hidden`, `author`.`updated` AS `author-updated`, `author`.`gsid` AS `author-gsid`, - `author`.`uri-id` AS `author-uri-id`, `post-thread`.`owner-id` AS `owner-id`, + `owner`.`uri-id` AS `owner-uri-id`, `owner`.`url` AS `owner-link`, `owner`.`addr` AS `owner-addr`, `owner`.`name` AS `owner-name`, @@ -2260,6 +2271,7 @@ CREATE VIEW `post-thread-view` AS SELECT `owner`.`updated` AS `owner-updated`, `owner`.`contact-type` AS `owner-contact-type`, `post-thread`.`causer-id` AS `causer-id`, + `causer`.`uri-id` AS `causer-uri-id`, `causer`.`url` AS `causer-link`, `causer`.`addr` AS `causer-addr`, `causer`.`name` AS `causer-name`, @@ -2705,6 +2717,9 @@ CREATE VIEW `account-user-view` AS SELECT `fcontact`.`notify` AS `diaspora-notify`, `fcontact`.`poll` AS `diaspora-poll`, `fcontact`.`alias` AS `diaspora-alias`, + `fcontact`.`interacting_count` AS `diaspora-interacting_count`, + `fcontact`.`interacted_count` AS `diaspora-interacted_count`, + `fcontact`.`post_count` AS `diaspora-post_count`, `apcontact`.`uuid` AS `ap-uuid`, `apcontact`.`type` AS `ap-type`, `apcontact`.`following` AS `ap-following`, diff --git a/src/App.php b/src/App.php index e55938d39..6fa79c501 100644 --- a/src/App.php +++ b/src/App.php @@ -719,7 +719,7 @@ class App } catch (HTTPException $e) { (new ModuleHTTPException())->rawContent($e); } - $page->logRuntime($this->config); + $page->logRuntime($this->config, 'runFrontend'); } /** diff --git a/src/App/Page.php b/src/App/Page.php index c78d0f9e0..d38757687 100644 --- a/src/App/Page.php +++ b/src/App/Page.php @@ -98,7 +98,7 @@ class Page implements ArrayAccess $this->method = $method; } - public function logRuntime(IManageConfigValues $config) + public function logRuntime(IManageConfigValues $config, string $origin = '') { if (in_array($this->command, $config->get('system', 'runtime_ignore'))) { return; @@ -106,7 +106,7 @@ class Page implements ArrayAccess $runtime = number_format(microtime(true) - $this->timestamp, 3); if ($runtime > $config->get('system', 'runtime_loglimit')) { - Logger::debug('Runtime', ['method' => $this->method, 'command' => $this->command, 'runtime' => $runtime]); + Logger::debug('Runtime', ['method' => $this->method, 'command' => $this->command, 'runtime' => $runtime, 'origin' => $origin]); } } diff --git a/src/Core/System.php b/src/Core/System.php index 6f1bb6188..7601a6f84 100644 --- a/src/Core/System.php +++ b/src/Core/System.php @@ -369,7 +369,7 @@ class System */ public static function exit() { - DI::page()->logRuntime(DI::config()); + DI::page()->logRuntime(DI::config(), 'exit'); exit(); } diff --git a/src/Factory/Api/Mastodon/Account.php b/src/Factory/Api/Mastodon/Account.php index cf836275c..42351969a 100644 --- a/src/Factory/Api/Mastodon/Account.php +++ b/src/Factory/Api/Mastodon/Account.php @@ -24,9 +24,8 @@ namespace Friendica\Factory\Api\Mastodon; use Friendica\App\BaseURL; use Friendica\BaseFactory; use Friendica\Collection\Api\Mastodon\Fields; -use Friendica\Model\APContact; +use Friendica\Database\DBA; use Friendica\Model\Contact; -use Friendica\Model\FContact; use Friendica\Network\HTTPException; use Friendica\Profile\ProfileField\Repository\ProfileField as ProfileFieldRepository; use ImagickException; @@ -60,31 +59,39 @@ class Account extends BaseFactory */ public function createFromContactId(int $contactId, $uid = 0): \Friendica\Object\Api\Mastodon\Account { - $cdata = Contact::getPublicAndUserContactID($contactId, $uid); - if (!empty($cdata)) { - $publicContact = Contact::getById($cdata['public']); - $userContact = Contact::getById($cdata['user']); - } else { - $publicContact = Contact::getById($contactId); - $userContact = []; - } - - if (empty($publicContact)) { + $contact = Contact::getById($contactId, ['uri-id']); + if (empty($contact)) { throw new HTTPException\NotFoundException('Contact ' . $contactId . ' not found'); } + return self::createFromUriId($contact['uri-id'], $uid); + } - $apcontact = APContact::getByURL($publicContact['url'], false); - $fcontact = FContact::getByURL($publicContact['url'], false); - - $self_contact = Contact::selectFirst(['uid'], ['nurl' => $publicContact['nurl'], 'self' => true]); - if (!empty($self_contact['uid'])) { - $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($self_contact['uid']); - $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); - } else { - $fields = new Fields(); + /** + * @param int $contactUriId + * @param int $uid Public contact (=0) or owner user id + * + * @return \Friendica\Object\Api\Mastodon\Account + * @throws HTTPException\InternalServerErrorException + * @throws ImagickException|HTTPException\NotFoundException + */ + public function createFromUriId(int $contactUriId, $uid = 0): \Friendica\Object\Api\Mastodon\Account + { + $contact = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); + if (empty($contact)) { + throw new HTTPException\NotFoundException('Contact ' . $contactUriId . ' not found'); } - return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $publicContact, $fields, $apcontact, $userContact, $fcontact); + $fields = new Fields(); + + if (Contact::isLocal($contact['url'])) { + $self_contact = Contact::selectFirst(['uid'], ['nurl' => $contact['nurl'], 'self' => true]); + if (!empty($self_contact['uid'])) { + $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($self_contact['uid']); + $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); + } + } + + return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $contact, $fields); } /** @@ -94,13 +101,10 @@ class Account extends BaseFactory */ public function createFromUserId(int $userId): \Friendica\Object\Api\Mastodon\Account { - $publicContact = Contact::selectFirst([], ['uid' => $userId, 'self' => true]); - + $contact = DBA::selectFirst('account-user-view', [], ['uid' => $userId, 'self' => true]); $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($userId); $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); - $apContact = APContact::getByURL($publicContact['url'], false); - - return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $publicContact, $fields, $apContact); + return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $contact, $fields); } } diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index cac9dfd06..63dc7c4e7 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -78,10 +78,10 @@ class Status extends BaseFactory * @throws HTTPException\InternalServerErrorException * @throws ImagickException|HTTPException\NotFoundException */ - public function createFromUriId(int $uriId, $uid = 0): \Friendica\Object\Api\Mastodon\Status + public function createFromUriId(int $uriId, $uid = 0, $item = []): \Friendica\Object\Api\Mastodon\Status { - $fields = ['uri-id', 'uid', 'author-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id', - 'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured']; + $fields = ['uri-id', 'uid', 'author-id', 'author-uri-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id', + 'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media']; $item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]); if (!$item) { $mail = DBA::selectFirst('mail', ['id'], ['uri-id' => $uriId, 'uid' => $uid]); @@ -90,42 +90,46 @@ class Status extends BaseFactory } throw new HTTPException\NotFoundException('Item with URI ID ' . $uriId . ' not found' . ($uid ? ' for user ' . $uid : '.')); } + $account = $this->mstdnAccountFactory->createFromUriId($item['author-uri-id'], $uid); - $account = $this->mstdnAccountFactory->createFromContactId($item['author-id']); + $count_announce = Post::countPosts([ + 'thr-parent-id' => $uriId, + 'gravity' => GRAVITY_ACTIVITY, + 'vid' => Verb::getID(Activity::ANNOUNCE), + 'deleted' => false + ], []); + $count_like = Post::countPosts([ + 'thr-parent-id' => $uriId, + 'gravity' => GRAVITY_ACTIVITY, + 'vid' => Verb::getID(Activity::LIKE), + 'deleted' => false + ], []); $counts = new \Friendica\Object\Api\Mastodon\Status\Counts( Post::countPosts(['thr-parent-id' => $uriId, 'gravity' => GRAVITY_COMMENT, 'deleted' => false], []), - Post::countPosts([ - 'thr-parent-id' => $uriId, - 'gravity' => GRAVITY_ACTIVITY, - 'vid' => Verb::getID(Activity::ANNOUNCE), - 'deleted' => false - ], []), - Post::countPosts([ - 'thr-parent-id' => $uriId, - 'gravity' => GRAVITY_ACTIVITY, - 'vid' => Verb::getID(Activity::LIKE), - 'deleted' => false - ], []) + $count_announce, + $count_like ); + $origin_like = ($count_like == 0) ? false : Post::exists([ + 'thr-parent-id' => $uriId, + 'uid' => $uid, + 'origin' => true, + 'gravity' => GRAVITY_ACTIVITY, + 'vid' => Verb::getID(Activity::LIKE), + 'deleted' => false + ]); + $origin_announce = ($count_announce == 0) ? false : Post::exists([ + 'thr-parent-id' => $uriId, + 'uid' => $uid, + 'origin' => true, + 'gravity' => GRAVITY_ACTIVITY, + 'vid' => Verb::getID(Activity::ANNOUNCE), + 'deleted' => false + ]); $userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes( - Post::exists([ - 'thr-parent-id' => $uriId, - 'uid' => $uid, - 'origin' => true, - 'gravity' => GRAVITY_ACTIVITY, - 'vid' => Verb::getID(Activity::LIKE) - , 'deleted' => false - ]), - Post::exists([ - 'thr-parent-id' => $uriId, - 'uid' => $uid, - 'origin' => true, - 'gravity' => GRAVITY_ACTIVITY, - 'vid' => Verb::getID(Activity::ANNOUNCE), - 'deleted' => false - ]), + $origin_like, + $origin_announce, Post\ThreadUser::getIgnored($uriId, $uid), (bool)($item['starred'] && ($item['gravity'] == GRAVITY_PARENT)), $item['featured'] @@ -136,8 +140,13 @@ class Status extends BaseFactory $mentions = $this->mstdnMentionFactory->createFromUriId($uriId)->getArrayCopy(); $tags = $this->mstdnTagFactory->createFromUriId($uriId); - $card = $this->mstdnCardFactory->createFromUriId($uriId); - $attachments = $this->mstdnAttachementFactory->createFromUriId($uriId); + if ($item['has-media']) { + $card = $this->mstdnCardFactory->createFromUriId($uriId); + $attachments = $this->mstdnAttachementFactory->createFromUriId($uriId); + } else { + $card = new \Friendica\Object\Api\Mastodon\Card([]); + $attachments = []; + } if (!empty($item['question-id'])) { $poll = $this->mstdnPollFactory->createFromId($item['question-id'], $uid)->toArray(); @@ -160,7 +169,6 @@ class Status extends BaseFactory } } - if ($item['vid'] == Verb::getID(Activity::ANNOUNCE)) { $reshare = $this->createFromUriId($item['thr-parent-id'], $uid)->toArray(); $reshared_item = Post::selectFirst(['title', 'body'], ['uri-id' => $item['thr-parent-id'],'uid' => [0, $uid]]); diff --git a/src/Object/Api/Mastodon/Account.php b/src/Object/Api/Mastodon/Account.php index 3dbe6b7fd..aac23ef5e 100644 --- a/src/Object/Api/Mastodon/Account.php +++ b/src/Object/Api/Mastodon/Account.php @@ -86,52 +86,42 @@ class Account extends BaseDataTransferObject * Creates an account record from a public contact record. Expects all contact table fields to be set. * * @param BaseURL $baseUrl - * @param array $publicContact Full contact table record with uid = 0 - * @param array $apcontact Optional full apcontact table record - * @param array $userContact Optional full contact table record with uid != 0 - * @param array $fcontact Optional full fcontact table record + * @param array $contact entry of "account-user-view" + * @param Fields $fields Profile fields * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function __construct(BaseURL $baseUrl, array $publicContact, Fields $fields, array $apcontact = [], array $userContact = [], array $fcontact = []) + public function __construct(BaseURL $baseUrl, array $contact, Fields $fields) { - $this->id = (string)$publicContact['id']; - $this->username = $publicContact['nick']; + $this->id = (string)$contact['pid']; + $this->username = $contact['nick']; $this->acct = - strpos($publicContact['url'], $baseUrl->get() . '/') === 0 ? - $publicContact['nick'] : - $publicContact['addr']; - $this->display_name = $publicContact['name']; - $this->locked = (bool)$publicContact['manually-approve'] ?? !empty($apcontact['manually-approve']); - $this->bot = ($publicContact['contact-type'] == Contact::TYPE_NEWS); - $this->discoverable = !$publicContact['unsearchable']; - $this->group = ($publicContact['contact-type'] == Contact::TYPE_COMMUNITY); + strpos($contact['url'], $baseUrl->get() . '/') === 0 ? + $contact['nick'] : + $contact['addr']; + $this->display_name = $contact['name']; + $this->locked = (bool)$contact['manually-approve']; + $this->bot = ($contact['contact-type'] == Contact::TYPE_NEWS); + $this->discoverable = !$contact['unsearchable']; + $this->group = ($contact['contact-type'] == Contact::TYPE_COMMUNITY); - $publicContactCreated = $publicContact['created'] ?: DBA::NULL_DATETIME; - $userContactCreated = $userContact['created'] ?? DBA::NULL_DATETIME; + $this->created_at = DateTimeFormat::utc($contact['created'] ?: DBA::NULL_DATETIME, DateTimeFormat::JSON); - $created = $userContactCreated < $publicContactCreated && ($userContactCreated != DBA::NULL_DATETIME) ? $userContactCreated : $publicContactCreated; - $this->created_at = DateTimeFormat::utc($created, DateTimeFormat::JSON); - - $this->note = BBCode::convertForUriId($publicContact['uri-id'] ?? 0, $publicContact['about'], BBCode::EXTERNAL); - $this->url = $publicContact['url']; - $this->avatar = Contact::getAvatarUrlForId($userContact['id'] ?? 0 ?: $publicContact['id'], Proxy::SIZE_SMALL, $userContact['updated'] ?? '' ?: $publicContact['updated']); + $this->note = BBCode::convertForUriId($contact['uri-id'], $contact['about'], BBCode::EXTERNAL); + $this->url = $contact['url']; + $this->avatar = Contact::getAvatarUrlForId($contact['id'] ?? 0 ?: $contact['pid'], Proxy::SIZE_SMALL, $contact['updated'], $contact['guid'] ?? ''); $this->avatar_static = $this->avatar; - $this->header = Contact::getHeaderUrlForId($userContact['id'] ?? 0 ?: $publicContact['id'], '', $userContact['updated'] ?? '' ?: $publicContact['updated']); + $this->header = Contact::getHeaderUrlForId($contact['id'] ?? 0 ?: $contact['pid'], '', $contact['updated'], $contact['guid'] ?? ''); $this->header_static = $this->header; - $this->followers_count = $apcontact['followers_count'] ?? $fcontact['interacted_count'] ?? 0; - $this->following_count = $apcontact['following_count'] ?? $fcontact['interacting_count'] ?? 0; - $this->statuses_count = $apcontact['statuses_count'] ?? $fcontact['post_count'] ?? 0; + $this->followers_count = $contact['ap-followers_count'] ?? $contact['diaspora-interacted_count'] ?? 0; + $this->following_count = $contact['ap-following_count'] ?? $contact['diaspora-interacting_count'] ?? 0; + $this->statuses_count = $contact['ap-statuses_count'] ?? $contact['diaspora-post_count'] ?? 0; - $publicContactLastItem = $publicContact['last-item'] ?: DBA::NULL_DATETIME; - $userContactLastItem = $userContact['last-item'] ?? DBA::NULL_DATETIME; - - $lastItem = $userContactLastItem > $publicContactLastItem ? $userContactLastItem : $publicContactLastItem; + $lastItem = $contact['last-item'] ?: DBA::NULL_DATETIME; $this->last_status_at = $lastItem != DBA::NULL_DATETIME ? DateTimeFormat::utc($lastItem, 'Y-m-d') : null; // No custom emojis per account in Friendica $this->emojis = []; $this->fields = $fields->getArrayCopy(); - } /** diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 011a298a5..d365f9805 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', 1468); + define('DB_UPDATE_VERSION', 1469); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 68217118c..040a9ebc3 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -114,6 +114,7 @@ "target" => ["post-content", "target"], "resource-id" => ["post-content", "resource-id"], "contact-id" => ["post-user", "contact-id"], + "contact-uri-id" => ["contact", "uri-id"], "contact-link" => ["contact", "url"], "contact-addr" => ["contact", "addr"], "contact-name" => ["contact", "name"], @@ -138,6 +139,7 @@ "avatar-date" => ["contact", "avatar-date"], "thumb" => ["contact", "thumb"], "author-id" => ["post-user", "author-id"], + "author-uri-id" => ["author", "uri-id"], "author-link" => ["author", "url"], "author-addr" => ["author", "addr"], "author-name" => "IF (`contact`.`url` = `author`.`url` AND `contact`.`name` != '', `contact`.`name`, `author`.`name`)", @@ -150,6 +152,7 @@ "author-gsid" => ["author", "gsid"], "author-uri-id" => ["author", "uri-id"], "owner-id" => ["post-user", "owner-id"], + "owner-uri-id" => ["owner", "uri-id"], "owner-link" => ["owner", "url"], "owner-addr" => ["owner", "addr"], "owner-name" => "IF (`contact`.`url` = `owner`.`url` AND `contact`.`name` != '', `contact`.`name`, `owner`.`name`)", @@ -161,6 +164,7 @@ "owner-updated" => ["owner", "updated"], "owner-contact-type" => ["owner", "contact-type"], "causer-id" => ["post-user", "causer-id"], + "causer-uri-id" => ["causer", "uri-id"], "causer-link" => ["causer", "url"], "causer-addr" => ["causer", "addr"], "causer-name" => ["causer", "name"], @@ -283,6 +287,7 @@ "target" => ["post-content", "target"], "resource-id" => ["post-content", "resource-id"], "contact-id" => ["post-thread-user", "contact-id"], + "contact-uri-id" => ["contact", "uri-id"], "contact-link" => ["contact", "url"], "contact-addr" => ["contact", "addr"], "contact-name" => ["contact", "name"], @@ -307,6 +312,7 @@ "avatar-date" => ["contact", "avatar-date"], "thumb" => ["contact", "thumb"], "author-id" => ["post-thread-user", "author-id"], + "author-uri-id" => ["author", "uri-id"], "author-link" => ["author", "url"], "author-addr" => ["author", "addr"], "author-name" => "IF (`contact`.`url` = `author`.`url` AND `contact`.`name` != '', `contact`.`name`, `author`.`name`)", @@ -319,6 +325,7 @@ "author-gsid" => ["author", "gsid"], "author-uri-id" => ["author", "uri-id"], "owner-id" => ["post-thread-user", "owner-id"], + "owner-uri-id" => ["owner", "uri-id"], "owner-link" => ["owner", "url"], "owner-addr" => ["owner", "addr"], "owner-name" => "IF (`contact`.`url` = `owner`.`url` AND `contact`.`name` != '', `contact`.`name`, `owner`.`name`)", @@ -330,6 +337,7 @@ "owner-updated" => ["owner", "updated"], "owner-contact-type" => ["owner", "contact-type"], "causer-id" => ["post-thread-user", "causer-id"], + "causer-uri-id" => ["causer", "uri-id"], "causer-link" => ["causer", "url"], "causer-addr" => ["causer", "addr"], "causer-name" => ["causer", "name"], @@ -438,6 +446,7 @@ "target" => ["post-content", "target"], "resource-id" => ["post-content", "resource-id"], "contact-id" => ["post", "author-id"], + "contact-uri-id" => ["author", "uri-id"], "contact-link" => ["author", "url"], "contact-addr" => ["author", "addr"], "contact-name" => ["author", "name"], @@ -462,6 +471,7 @@ "avatar-date" => ["author", "avatar-date"], "thumb" => ["author", "thumb"], "author-id" => ["post", "author-id"], + "author-uri-id" => ["author", "uri-id"], "author-link" => ["author", "url"], "author-addr" => ["author", "addr"], "author-name" => ["author", "name"], @@ -474,6 +484,7 @@ "author-gsid" => ["author", "gsid"], "author-uri-id" => ["author", "uri-id"], "owner-id" => ["post", "owner-id"], + "owner-uri-id" => ["owner", "uri-id"], "owner-link" => ["owner", "url"], "owner-addr" => ["owner", "addr"], "owner-name" => ["owner", "name"], @@ -485,6 +496,7 @@ "owner-updated" => ["owner", "updated"], "owner-contact-type" => ["owner", "contact-type"], "causer-id" => ["post", "causer-id"], + "causer-uri-id" => ["causer", "uri-id"], "causer-link" => ["causer", "url"], "causer-addr" => ["causer", "addr"], "causer-name" => ["causer", "name"], @@ -569,6 +581,7 @@ "target" => ["post-content", "target"], "resource-id" => ["post-content", "resource-id"], "contact-id" => ["post-thread", "author-id"], + "contact-uri-id" => ["author", "uri-id"], "contact-link" => ["author", "url"], "contact-addr" => ["author", "addr"], "contact-name" => ["author", "name"], @@ -593,6 +606,7 @@ "avatar-date" => ["author", "avatar-date"], "thumb" => ["author", "thumb"], "author-id" => ["post-thread", "author-id"], + "author-uri-id" => ["author", "uri-id"], "author-link" => ["author", "url"], "author-addr" => ["author", "addr"], "author-name" => ["author", "name"], @@ -605,6 +619,7 @@ "author-gsid" => ["author", "gsid"], "author-uri-id" => ["author", "uri-id"], "owner-id" => ["post-thread", "owner-id"], + "owner-uri-id" => ["owner", "uri-id"], "owner-link" => ["owner", "url"], "owner-addr" => ["owner", "addr"], "owner-name" => ["owner", "name"], @@ -616,6 +631,7 @@ "owner-updated" => ["owner", "updated"], "owner-contact-type" => ["owner", "contact-type"], "causer-id" => ["post-thread", "causer-id"], + "causer-uri-id" => ["causer", "uri-id"], "causer-link" => ["causer", "url"], "causer-addr" => ["causer", "addr"], "causer-name" => ["causer", "name"], @@ -1045,6 +1061,9 @@ "diaspora-notify" => ["fcontact", "notify"], "diaspora-poll" => ["fcontact", "poll"], "diaspora-alias" => ["fcontact", "alias"], + "diaspora-interacting_count" => ["fcontact", "interacting_count"], + "diaspora-interacted_count" => ["fcontact", "interacted_count"], + "diaspora-post_count" => ["fcontact", "post_count"], "ap-uuid" => ["apcontact", "uuid"], "ap-type" => ["apcontact", "type"], "ap-following" => ["apcontact", "following"], From 9a1abda314bf121daffc4284d7caa51705329249 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 10 Jun 2022 20:26:57 +0000 Subject: [PATCH 2/3] Use "avatar" instead of "contact" --- src/Factory/Api/Mastodon/Account.php | 14 +++++----- src/Factory/Api/Mastodon/Status.php | 2 +- src/Object/Api/Mastodon/Account.php | 42 ++++++++++++++-------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Factory/Api/Mastodon/Account.php b/src/Factory/Api/Mastodon/Account.php index 42351969a..cffd5d892 100644 --- a/src/Factory/Api/Mastodon/Account.php +++ b/src/Factory/Api/Mastodon/Account.php @@ -76,22 +76,22 @@ class Account extends BaseFactory */ public function createFromUriId(int $contactUriId, $uid = 0): \Friendica\Object\Api\Mastodon\Account { - $contact = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); - if (empty($contact)) { + $avatar = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); + if (empty($avatar)) { throw new HTTPException\NotFoundException('Contact ' . $contactUriId . ' not found'); } $fields = new Fields(); - if (Contact::isLocal($contact['url'])) { - $self_contact = Contact::selectFirst(['uid'], ['nurl' => $contact['nurl'], 'self' => true]); + if (Contact::isLocal($avatar['url'])) { + $self_contact = Contact::selectFirst(['uid'], ['nurl' => $avatar['nurl'], 'self' => true]); if (!empty($self_contact['uid'])) { $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($self_contact['uid']); $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); } } - return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $contact, $fields); + return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $avatar, $fields); } /** @@ -101,10 +101,10 @@ class Account extends BaseFactory */ public function createFromUserId(int $userId): \Friendica\Object\Api\Mastodon\Account { - $contact = DBA::selectFirst('account-user-view', [], ['uid' => $userId, 'self' => true]); + $avatar = DBA::selectFirst('account-user-view', [], ['uid' => $userId, 'self' => true]); $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($userId); $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); - return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $contact, $fields); + return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $avatar, $fields); } } diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index 63dc7c4e7..5d5894415 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -78,7 +78,7 @@ class Status extends BaseFactory * @throws HTTPException\InternalServerErrorException * @throws ImagickException|HTTPException\NotFoundException */ - public function createFromUriId(int $uriId, $uid = 0, $item = []): \Friendica\Object\Api\Mastodon\Status + public function createFromUriId(int $uriId, $uid = 0): \Friendica\Object\Api\Mastodon\Status { $fields = ['uri-id', 'uid', 'author-id', 'author-uri-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id', 'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media']; diff --git a/src/Object/Api/Mastodon/Account.php b/src/Object/Api/Mastodon/Account.php index aac23ef5e..89e3975d6 100644 --- a/src/Object/Api/Mastodon/Account.php +++ b/src/Object/Api/Mastodon/Account.php @@ -86,37 +86,37 @@ class Account extends BaseDataTransferObject * Creates an account record from a public contact record. Expects all contact table fields to be set. * * @param BaseURL $baseUrl - * @param array $contact entry of "account-user-view" + * @param array $avatar entry of "account-user-view" * @param Fields $fields Profile fields * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function __construct(BaseURL $baseUrl, array $contact, Fields $fields) + public function __construct(BaseURL $baseUrl, array $avatar, Fields $fields) { - $this->id = (string)$contact['pid']; - $this->username = $contact['nick']; + $this->id = (string)$avatar['pid']; + $this->username = $avatar['nick']; $this->acct = - strpos($contact['url'], $baseUrl->get() . '/') === 0 ? - $contact['nick'] : - $contact['addr']; - $this->display_name = $contact['name']; - $this->locked = (bool)$contact['manually-approve']; - $this->bot = ($contact['contact-type'] == Contact::TYPE_NEWS); - $this->discoverable = !$contact['unsearchable']; - $this->group = ($contact['contact-type'] == Contact::TYPE_COMMUNITY); + strpos($avatar['url'], $baseUrl->get() . '/') === 0 ? + $avatar['nick'] : + $avatar['addr']; + $this->display_name = $avatar['name']; + $this->locked = (bool)$avatar['manually-approve']; + $this->bot = ($avatar['contact-type'] == Contact::TYPE_NEWS); + $this->discoverable = !$avatar['unsearchable']; + $this->group = ($avatar['contact-type'] == Contact::TYPE_COMMUNITY); - $this->created_at = DateTimeFormat::utc($contact['created'] ?: DBA::NULL_DATETIME, DateTimeFormat::JSON); + $this->created_at = DateTimeFormat::utc($avatar['created'] ?: DBA::NULL_DATETIME, DateTimeFormat::JSON); - $this->note = BBCode::convertForUriId($contact['uri-id'], $contact['about'], BBCode::EXTERNAL); - $this->url = $contact['url']; - $this->avatar = Contact::getAvatarUrlForId($contact['id'] ?? 0 ?: $contact['pid'], Proxy::SIZE_SMALL, $contact['updated'], $contact['guid'] ?? ''); + $this->note = BBCode::convertForUriId($avatar['uri-id'], $avatar['about'], BBCode::EXTERNAL); + $this->url = $avatar['url']; + $this->avatar = Contact::getAvatarUrlForId($avatar['id'] ?? 0 ?: $avatar['pid'], Proxy::SIZE_SMALL, $avatar['updated'], $avatar['guid'] ?? ''); $this->avatar_static = $this->avatar; - $this->header = Contact::getHeaderUrlForId($contact['id'] ?? 0 ?: $contact['pid'], '', $contact['updated'], $contact['guid'] ?? ''); + $this->header = Contact::getHeaderUrlForId($avatar['id'] ?? 0 ?: $avatar['pid'], '', $avatar['updated'], $avatar['guid'] ?? ''); $this->header_static = $this->header; - $this->followers_count = $contact['ap-followers_count'] ?? $contact['diaspora-interacted_count'] ?? 0; - $this->following_count = $contact['ap-following_count'] ?? $contact['diaspora-interacting_count'] ?? 0; - $this->statuses_count = $contact['ap-statuses_count'] ?? $contact['diaspora-post_count'] ?? 0; + $this->followers_count = $avatar['ap-followers_count'] ?? $avatar['diaspora-interacted_count'] ?? 0; + $this->following_count = $avatar['ap-following_count'] ?? $avatar['diaspora-interacting_count'] ?? 0; + $this->statuses_count = $avatar['ap-statuses_count'] ?? $avatar['diaspora-post_count'] ?? 0; - $lastItem = $contact['last-item'] ?: DBA::NULL_DATETIME; + $lastItem = $avatar['last-item'] ?: DBA::NULL_DATETIME; $this->last_status_at = $lastItem != DBA::NULL_DATETIME ? DateTimeFormat::utc($lastItem, 'Y-m-d') : null; // No custom emojis per account in Friendica From 4157f816f5bbc3721a5b2054a7aef29827544685 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 10 Jun 2022 20:32:21 +0000 Subject: [PATCH 3/3] Fix for account variable name --- src/Factory/Api/Mastodon/Account.php | 14 +++++----- src/Object/Api/Mastodon/Account.php | 42 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Factory/Api/Mastodon/Account.php b/src/Factory/Api/Mastodon/Account.php index cffd5d892..d0c654fc2 100644 --- a/src/Factory/Api/Mastodon/Account.php +++ b/src/Factory/Api/Mastodon/Account.php @@ -76,22 +76,22 @@ class Account extends BaseFactory */ public function createFromUriId(int $contactUriId, $uid = 0): \Friendica\Object\Api\Mastodon\Account { - $avatar = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); - if (empty($avatar)) { + $account = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); + if (empty($account)) { throw new HTTPException\NotFoundException('Contact ' . $contactUriId . ' not found'); } $fields = new Fields(); - if (Contact::isLocal($avatar['url'])) { - $self_contact = Contact::selectFirst(['uid'], ['nurl' => $avatar['nurl'], 'self' => true]); + if (Contact::isLocal($account['url'])) { + $self_contact = Contact::selectFirst(['uid'], ['nurl' => $account['nurl'], 'self' => true]); if (!empty($self_contact['uid'])) { $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($self_contact['uid']); $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); } } - return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $avatar, $fields); + return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $account, $fields); } /** @@ -101,10 +101,10 @@ class Account extends BaseFactory */ public function createFromUserId(int $userId): \Friendica\Object\Api\Mastodon\Account { - $avatar = DBA::selectFirst('account-user-view', [], ['uid' => $userId, 'self' => true]); + $account = DBA::selectFirst('account-user-view', [], ['uid' => $userId, 'self' => true]); $profileFields = $this->profileFieldRepo->selectPublicFieldsByUserId($userId); $fields = $this->mstdnFieldFactory->createFromProfileFields($profileFields); - return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $avatar, $fields); + return new \Friendica\Object\Api\Mastodon\Account($this->baseUrl, $account, $fields); } } diff --git a/src/Object/Api/Mastodon/Account.php b/src/Object/Api/Mastodon/Account.php index 89e3975d6..3369a18c0 100644 --- a/src/Object/Api/Mastodon/Account.php +++ b/src/Object/Api/Mastodon/Account.php @@ -86,37 +86,37 @@ class Account extends BaseDataTransferObject * Creates an account record from a public contact record. Expects all contact table fields to be set. * * @param BaseURL $baseUrl - * @param array $avatar entry of "account-user-view" + * @param array $account entry of "account-user-view" * @param Fields $fields Profile fields * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function __construct(BaseURL $baseUrl, array $avatar, Fields $fields) + public function __construct(BaseURL $baseUrl, array $account, Fields $fields) { - $this->id = (string)$avatar['pid']; - $this->username = $avatar['nick']; + $this->id = (string)$account['pid']; + $this->username = $account['nick']; $this->acct = - strpos($avatar['url'], $baseUrl->get() . '/') === 0 ? - $avatar['nick'] : - $avatar['addr']; - $this->display_name = $avatar['name']; - $this->locked = (bool)$avatar['manually-approve']; - $this->bot = ($avatar['contact-type'] == Contact::TYPE_NEWS); - $this->discoverable = !$avatar['unsearchable']; - $this->group = ($avatar['contact-type'] == Contact::TYPE_COMMUNITY); + strpos($account['url'], $baseUrl->get() . '/') === 0 ? + $account['nick'] : + $account['addr']; + $this->display_name = $account['name']; + $this->locked = (bool)$account['manually-approve']; + $this->bot = ($account['contact-type'] == Contact::TYPE_NEWS); + $this->discoverable = !$account['unsearchable']; + $this->group = ($account['contact-type'] == Contact::TYPE_COMMUNITY); - $this->created_at = DateTimeFormat::utc($avatar['created'] ?: DBA::NULL_DATETIME, DateTimeFormat::JSON); + $this->created_at = DateTimeFormat::utc($account['created'] ?: DBA::NULL_DATETIME, DateTimeFormat::JSON); - $this->note = BBCode::convertForUriId($avatar['uri-id'], $avatar['about'], BBCode::EXTERNAL); - $this->url = $avatar['url']; - $this->avatar = Contact::getAvatarUrlForId($avatar['id'] ?? 0 ?: $avatar['pid'], Proxy::SIZE_SMALL, $avatar['updated'], $avatar['guid'] ?? ''); + $this->note = BBCode::convertForUriId($account['uri-id'], $account['about'], BBCode::EXTERNAL); + $this->url = $account['url']; + $this->avatar = Contact::getAvatarUrlForId($account['id'] ?? 0 ?: $account['pid'], Proxy::SIZE_SMALL, $account['updated'], $account['guid'] ?? ''); $this->avatar_static = $this->avatar; - $this->header = Contact::getHeaderUrlForId($avatar['id'] ?? 0 ?: $avatar['pid'], '', $avatar['updated'], $avatar['guid'] ?? ''); + $this->header = Contact::getHeaderUrlForId($account['id'] ?? 0 ?: $account['pid'], '', $account['updated'], $account['guid'] ?? ''); $this->header_static = $this->header; - $this->followers_count = $avatar['ap-followers_count'] ?? $avatar['diaspora-interacted_count'] ?? 0; - $this->following_count = $avatar['ap-following_count'] ?? $avatar['diaspora-interacting_count'] ?? 0; - $this->statuses_count = $avatar['ap-statuses_count'] ?? $avatar['diaspora-post_count'] ?? 0; + $this->followers_count = $account['ap-followers_count'] ?? $account['diaspora-interacted_count'] ?? 0; + $this->following_count = $account['ap-following_count'] ?? $account['diaspora-interacting_count'] ?? 0; + $this->statuses_count = $account['ap-statuses_count'] ?? $account['diaspora-post_count'] ?? 0; - $lastItem = $avatar['last-item'] ?: DBA::NULL_DATETIME; + $lastItem = $account['last-item'] ?: DBA::NULL_DATETIME; $this->last_status_at = $lastItem != DBA::NULL_DATETIME ? DateTimeFormat::utc($lastItem, 'Y-m-d') : null; // No custom emojis per account in Friendica