From a4f1df68e4943f5b3db2b0104995452ff0d079f8 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 18 Aug 2022 07:48:39 +0000 Subject: [PATCH 1/2] Improved contact-id detection --- src/Model/Contact.php | 38 ++++++++++++++++++++++++-------------- src/Model/Item.php | 39 ++++++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 12be60812..606626192 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -327,14 +327,15 @@ class Contact /** * Tests if the given contact is a follower * - * @param int $cid Either public contact id or user's contact id - * @param int $uid User ID + * @param int $cid Either public contact id or user's contact id + * @param int $uid User ID + * @param bool $strict If "true" then contact mustn't be set to pending or readonly * * @return boolean is the contact id a follower? * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isFollower(int $cid, int $uid): bool + public static function isFollower(int $cid, int $uid, bool $strict = false): bool { if (Contact\User::isBlocked($cid, $uid)) { return false; @@ -346,20 +347,24 @@ class Contact } $condition = ['id' => $cdata['user'], 'rel' => [self::FOLLOWER, self::FRIEND]]; + if ($strict) { + $condition = array_merge($condition, ['pending' => false, 'readonly' => false, 'blocked' => false]); + } return DBA::exists('contact', $condition); } /** * Tests if the given contact url is a follower * - * @param string $url Contact URL - * @param int $uid User ID + * @param string $url Contact URL + * @param int $uid User ID + * @param bool $strict If "true" then contact mustn't be set to pending or readonly * * @return boolean is the contact id a follower? * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isFollowerByURL(string $url, int $uid): bool + public static function isFollowerByURL(string $url, int $uid, bool $strict = false): bool { $cid = self::getIdForURL($url, $uid); @@ -367,20 +372,21 @@ class Contact return false; } - return self::isFollower($cid, $uid); + return self::isFollower($cid, $uid, $strict); } /** * Tests if the given user shares with the given contact * - * @param int $cid Either public contact id or user's contact id - * @param int $uid User ID + * @param int $cid Either public contact id or user's contact id + * @param int $uid User ID + * @param bool $strict If "true" then contact mustn't be set to pending or readonly * * @return boolean is the contact sharing with given user? * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSharing(int $cid, int $uid): bool + public static function isSharing(int $cid, int $uid, bool $strict = false): bool { if (Contact\User::isBlocked($cid, $uid)) { return false; @@ -392,20 +398,24 @@ class Contact } $condition = ['id' => $cdata['user'], 'rel' => [self::SHARING, self::FRIEND]]; + if ($strict) { + $condition = array_merge($condition, ['pending' => false, 'readonly' => false, 'blocked' => false]); + } return DBA::exists('contact', $condition); } /** * Tests if the given user follow the given contact url * - * @param string $url Contact URL - * @param int $uid User ID + * @param string $url Contact URL + * @param int $uid User ID + * @param bool $strict If "true" then contact mustn't be set to pending or readonly * * @return boolean is the contact url being followed? * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSharingByURL(string $url, int $uid): bool + public static function isSharingByURL(string $url, int $uid, bool $strict = false): bool { $cid = self::getIdForURL($url, $uid); @@ -413,7 +423,7 @@ class Contact return false; } - return self::isSharing($cid, $uid); + return self::isSharing($cid, $uid, $strict); } /** diff --git a/src/Model/Item.php b/src/Model/Item.php index 702c9dee6..754516193 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -1660,26 +1660,35 @@ class Item $item['origin'] = 0; $item['wall'] = 0; - if ($item['gravity'] == GRAVITY_PARENT) { - $contact = Contact::getByURLForUser($item['owner-link'], $uid, false, ['id']); - } else { - $contact = Contact::getByURLForUser($item['author-link'], $uid, false, ['id']); + if (!empty($item['causer-id']) && Contact::isSharing($item['causer-id'], $uid, true)) { + $cdata = Contact::getPublicAndUserContactID($item['causer-id'], $uid); + $contact_id = $cdata['user'] ?? 0; } - if (!empty($contact['id'])) { - $item['contact-id'] = $contact['id']; - } else { - // Shouldn't happen at all - Logger::warning('contact-id could not be fetched', ['uid' => $uid, 'item' => $item]); - $self = DBA::selectFirst('contact', ['id'], ['self' => true, 'uid' => $uid]); - if (!DBA::isResult($self)) { - // Shouldn't happen even less - Logger::warning('self contact could not be fetched', ['uid' => $uid, 'item' => $item]); - return 0; + if (empty($contact_id)) { + if ($item['gravity'] == GRAVITY_PARENT) { + if (Contact::isSharingByURL($item['owner-link'], $uid, true)) { + $contact_id = Contact::getIdForURL($item['owner-link'], $uid); + } else { + $contact_id = Contact::getIdForURL($item['owner-link']); + } + } else { + if (Contact::isSharingByURL($item['author-link'], $uid, true)) { + $contact_id = Contact::getIdForURL($item['author-link'], $uid); + } else { + $contact_id = Contact::getIdForURL($item['author-link']); + } } - $item['contact-id'] = $self['id']; } + if (empty($contact_id)) { + Logger::warning('contact-id could not be fetched, using self contact instead.', ['uid' => $uid, 'item' => $item]); + $self = Contact::selectFirst(['id'], ['self' => true, 'uid' => $uid]); + $contact_id = $self['id']; + } + + $item['contact-id'] = $contact_id; + $notify = false; if ($item['gravity'] == GRAVITY_PARENT) { $contact = DBA::selectFirst('contact', [], ['id' => $item['contact-id'], 'self' => false]); From 51331ced9ba54b4a98ff9cfe8ee9f7c6371850f5 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 18 Aug 2022 10:13:46 +0000 Subject: [PATCH 2/2] Improved function to fetch the contact id --- src/Model/Item.php | 73 +++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/src/Model/Item.php b/src/Model/Item.php index 754516193..5ab98f206 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -448,21 +448,40 @@ class Item */ private static function contactId(array $item): int { - if (!empty($item['contact-id']) && DBA::exists('contact', ['self' => true, 'id' => $item['contact-id']])) { - return $item['contact-id']; - } elseif (($item['gravity'] == GRAVITY_PARENT) && !empty($item['uid']) && !empty($item['contact-id']) && Contact::isSharing($item['contact-id'], $item['uid'])) { - return $item['contact-id']; - } elseif (!empty($item['uid']) && !Contact::isSharing($item['author-id'], $item['uid'])) { + if ($item['uid'] == 0) { return $item['author-id']; - } elseif (!empty($item['contact-id'])) { - return $item['contact-id']; - } else { - $contact_id = Contact::getIdForURL($item['author-link'], $item['uid']); + } + if (!empty($item['causer-id']) && Contact::isSharing($item['causer-id'], $item['uid'], true)) { + $cdata = Contact::getPublicAndUserContactID($item['causer-id'], $item['uid']); + if (!empty($cdata['user'])) { + return $cdata['user']; + } + } + + if ($item['gravity'] == GRAVITY_PARENT) { + if (Contact::isSharingByURL($item['owner-link'], $item['uid'], true)) { + $contact_id = Contact::getIdForURL($item['owner-link'], $item['uid']); + } else { + $contact_id = Contact::getIdForURL($item['owner-link']); + } if (!empty($contact_id)) { return $contact_id; } } - return $item['author-id']; + + if (Contact::isSharingByURL($item['author-link'], $item['uid'], true)) { + $contact_id = Contact::getIdForURL($item['author-link'], $item['uid']); + } else { + $contact_id = Contact::getIdForURL($item['author-link']); + } + + if (!empty($contact_id)) { + return $contact_id; + } + + Logger::warning('contact-id could not be fetched, using self contact instead.', ['uid' => $item['uid'], 'item' => $item]); + $self = Contact::selectFirst(['id'], ['self' => true, 'uid' => $item['uid']]); + return $self['id']; } /** @@ -911,8 +930,9 @@ class Item Contact::checkAvatarCache($item['author-id']); Contact::checkAvatarCache($item['owner-id']); - // The contact-id should be set before "self::insert" was called - but there seems to be issues sometimes - $item['contact-id'] = self::contactId($item); + if (!Contact::isSharing($item['contact-id'], $item['uid'])) { + $item['contact-id'] = self::contactId($item); + } if (!empty($item['direction']) && in_array($item['direction'], [Conversation::PUSH, Conversation::RELAY]) && empty($item['origin']) && self::isTooOld($item)) { @@ -1660,34 +1680,7 @@ class Item $item['origin'] = 0; $item['wall'] = 0; - if (!empty($item['causer-id']) && Contact::isSharing($item['causer-id'], $uid, true)) { - $cdata = Contact::getPublicAndUserContactID($item['causer-id'], $uid); - $contact_id = $cdata['user'] ?? 0; - } - - if (empty($contact_id)) { - if ($item['gravity'] == GRAVITY_PARENT) { - if (Contact::isSharingByURL($item['owner-link'], $uid, true)) { - $contact_id = Contact::getIdForURL($item['owner-link'], $uid); - } else { - $contact_id = Contact::getIdForURL($item['owner-link']); - } - } else { - if (Contact::isSharingByURL($item['author-link'], $uid, true)) { - $contact_id = Contact::getIdForURL($item['author-link'], $uid); - } else { - $contact_id = Contact::getIdForURL($item['author-link']); - } - } - } - - if (empty($contact_id)) { - Logger::warning('contact-id could not be fetched, using self contact instead.', ['uid' => $uid, 'item' => $item]); - $self = Contact::selectFirst(['id'], ['self' => true, 'uid' => $uid]); - $contact_id = $self['id']; - } - - $item['contact-id'] = $contact_id; + $item['contact-id'] = self::contactId($item); $notify = false; if ($item['gravity'] == GRAVITY_PARENT) {