X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FAPContact.php;h=7b49bab8abf77248eaf9252a9f555fdd197785bd;hb=da66730e4f142c3557cdf7343bc420f7b80c883e;hp=a93484861226754eea85073035c09e9290005d6f;hpb=c2e889cfaeaa1b35333750cd6beda4090ee99f84;p=friendica.git diff --git a/src/Model/APContact.php b/src/Model/APContact.php index a934848612..7b49bab8ab 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -24,10 +24,11 @@ namespace Friendica\Model; use Friendica\Content\Text\HTML; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Logger; +use Friendica\Core\Protocol; use Friendica\Core\System; use Friendica\Database\DBA; -use Friendica\Database\DBStructure; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPException; use Friendica\Network\Probe; @@ -39,6 +40,7 @@ use Friendica\Util\DateTimeFormat; use Friendica\Util\HTTPSignature; use Friendica\Util\JsonLD; use Friendica\Util\Network; +use GuzzleHttp\Psr7\Uri; class APContact { @@ -48,7 +50,7 @@ class APContact * @param string $addr Address * @return array webfinger data */ - private static function fetchWebfingerData(string $addr) + private static function fetchWebfingerData(string $addr): array { $addr_parts = explode('@', $addr); if (count($addr_parts) != 2) { @@ -116,15 +118,16 @@ class APContact * @return array profile array * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException + * @todo Rewrite parameter $update to avoid true|false|null (boolean is binary, null adds a third case) */ - public static function getByURL(string $url, $update = null) + public static function getByURL(string $url, $update = null): array { if (empty($url) || Network::isUrlBlocked($url)) { Logger::info('Domain is blocked', ['url' => $url]); return []; } - $fetched_contact = false; + $fetched_contact = []; if (empty($update)) { if (is_null($update)) { @@ -164,6 +167,8 @@ class APContact return $fetched_contact; } $url = $apcontact['url']; + } elseif (empty(parse_url($url, PHP_URL_PATH))) { + $apcontact['baseurl'] = $url; } // Detect multiple fast repeating request to the same address @@ -220,14 +225,14 @@ class APContact $apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type')); $apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@id'); $apcontact['followers'] = JsonLD::fetchElement($compacted, 'as:followers', '@id'); - $apcontact['inbox'] = JsonLD::fetchElement($compacted, 'ldp:inbox', '@id'); + $apcontact['inbox'] = (JsonLD::fetchElement($compacted, 'ldp:inbox', '@id') ?? ''); self::unarchiveInbox($apcontact['inbox'], false); $apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id'); $apcontact['sharedinbox'] = ''; if (!empty($compacted['as:endpoints'])) { - $apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id'); + $apcontact['sharedinbox'] = (JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id') ?? ''); self::unarchiveInbox($apcontact['sharedinbox'], true); } @@ -308,6 +313,8 @@ class APContact $apcontact['manually-approve'] = (int)JsonLD::fetchElement($compacted, 'as:manuallyApprovesFollowers'); + $apcontact['suspended'] = (int)JsonLD::fetchElement($compacted, 'toot:suspended'); + if (!empty($compacted['as:generator'])) { $apcontact['baseurl'] = JsonLD::fetchElement($compacted['as:generator'], 'as:url', '@id'); $apcontact['generator'] = JsonLD::fetchElement($compacted['as:generator'], 'as:name', '@value'); @@ -347,17 +354,18 @@ class APContact if (!empty($apcontact['outbox'])) { if (!empty($local_owner)) { - $outbox = ActivityPub\Transmitter::getOutbox($local_owner); + $statuses_count = self::getStatusesCount($local_owner); } else { $outbox = ActivityPub::fetchContent($apcontact['outbox']); + $statuses_count = $outbox['totalItems'] ?? 0; } - if (!empty($outbox['totalItems'])) { + if (!empty($statuses_count)) { // Mastodon seriously allows for this condition? // Jul 20 2021 - See https://chaos.social/@m11 for a negative posts count - if ($outbox['totalItems'] < 0) { - $outbox['totalItems'] = 0; + if ($statuses_count < 0) { + $statuses_count = 0; } - $apcontact['statuses_count'] = $outbox['totalItems']; + $apcontact['statuses_count'] = $statuses_count; } } @@ -378,11 +386,11 @@ class APContact if (strlen($apcontact['photo']) > 255) { $parts = parse_url($apcontact['photo']); unset($parts['fragment']); - $apcontact['photo'] = Network::unparseURL($parts); + $apcontact['photo'] = (string)Uri::fromParts($parts); if (strlen($apcontact['photo']) > 255) { unset($parts['query']); - $apcontact['photo'] = Network::unparseURL($parts); + $apcontact['photo'] = (string)Uri::fromParts($parts); } if (strlen($apcontact['photo']) > 255) { @@ -465,7 +473,7 @@ class APContact } // Limit the length on incoming fields - $apcontact = DBStructure::getFieldsForTable('apcontact', $apcontact); + $apcontact = DI::dbaDefinition()->truncateFieldsForTable('apcontact', $apcontact); if (DBA::exists('apcontact', ['url' => $apcontact['url']])) { DBA::update('apcontact', $apcontact, ['url' => $apcontact['url']]); @@ -478,6 +486,30 @@ class APContact return DBA::selectFirst('apcontact', [], ['url' => $apcontact['url']]) ?: []; } + /** + * Fetch the number of statuses for the given owner + * + * @param array $owner + * + * @return integer + */ + private static function getStatusesCount(array $owner): int + { + $condition = [ + 'private' => [Item::PUBLIC, Item::UNLISTED], + 'author-id' => Contact::getIdForURL($owner['url'], 0, false), + 'gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], + 'network' => Protocol::DFRN, + 'parent-network' => Protocol::FEDERATED, + 'deleted' => false, + 'visible' => true, + ]; + + $count = Post::countPosts($condition); + + return $count; + } + /** * Mark the given AP Contact as "to archive" * @@ -526,8 +558,9 @@ class APContact * * @param string $url inbox url * @param boolean $shared Shared Inbox + * @return void */ - private static function unarchiveInbox($url, $shared) + private static function unarchiveInbox(string $url, bool $shared) { if (empty($url)) { return; @@ -535,4 +568,28 @@ class APContact HTTPSignature::setInboxStatus($url, true, $shared); } + + /** + * Check if the apcontact is a relay account + * + * @param array $apcontact + * + * @return bool + */ + public static function isRelay(array $apcontact): bool + { + if (empty($apcontact['nick']) || $apcontact['nick'] != 'relay') { + return false; + } + + if (!empty($apcontact['type']) && $apcontact['type'] == 'Application') { + return true; + } + + if (!empty($apcontact['type']) && in_array($apcontact['type'], ['Group', 'Service']) && is_null($apcontact['outbox'])) { + return true; + } + + return false; + } }