Fix codestyle

This commit is contained in:
Michael 2025-01-22 20:56:21 +00:00
parent c6a9e7aa4c
commit d74ca3ecf5
4 changed files with 476 additions and 454 deletions

View file

@ -74,12 +74,12 @@ class Contact
* This will only be assigned to contacts, not to user accounts
* @{
*/
const TYPE_UNKNOWN = -1;
const TYPE_PERSON = User::ACCOUNT_TYPE_PERSON;
const TYPE_UNKNOWN = -1;
const TYPE_PERSON = User::ACCOUNT_TYPE_PERSON;
const TYPE_ORGANISATION = User::ACCOUNT_TYPE_ORGANISATION;
const TYPE_NEWS = User::ACCOUNT_TYPE_NEWS;
const TYPE_COMMUNITY = User::ACCOUNT_TYPE_COMMUNITY;
const TYPE_RELAY = User::ACCOUNT_TYPE_RELAY;
const TYPE_NEWS = User::ACCOUNT_TYPE_NEWS;
const TYPE_COMMUNITY = User::ACCOUNT_TYPE_COMMUNITY;
const TYPE_RELAY = User::ACCOUNT_TYPE_RELAY;
/**
* @}
*/
@ -335,7 +335,7 @@ class Contact
if (!empty($fields)) {
foreach (['id', 'next-update', 'network', 'local-data'] as $internal) {
if (!in_array($internal, $fields)) {
$fields[] = $internal;
$fields[] = $internal;
$removal[] = $internal;
}
}
@ -353,9 +353,9 @@ class Contact
// Then the alias (which could be anything)
if (!DBA::isResult($contact)) {
// The link could be provided as http although we stored it as https
$ssl_url = str_replace('http://', 'https://', $url);
$ssl_url = str_replace('http://', 'https://', $url);
$condition = ['`alias` IN (?, ?, ?) AND `uid` = ? AND NOT `deleted`', $url, Strings::normaliseLink($url), $ssl_url, $uid];
$contact = DBA::selectFirst('contact', $fields, $condition, $options);
$contact = DBA::selectFirst('contact', $fields, $condition, $options);
}
if (!DBA::isResult($contact)) {
@ -846,7 +846,7 @@ class Contact
}
$fields = ['uid', 'username', 'nickname', 'page-flags', 'account-type', 'prvkey', 'pubkey'];
$user = DBA::selectFirst('user', $fields, ['uid' => $uid, 'verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]);
$user = DBA::selectFirst('user', $fields, ['uid' => $uid, 'verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]);
if (!DBA::isResult($user)) {
return false;
}
@ -877,11 +877,11 @@ class Contact
'network' => Protocol::DFRN,
'url' => $url,
// it seems as if ported accounts can have wrong values, so we make sure that now everything is fine.
'nurl' => Strings::normaliseLink($url),
'uri-id' => ItemURI::getIdByURI($url),
'addr' => $user['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3),
'notify' => DI::baseUrl() . '/dfrn_notify/' . $user['nickname'],
'poll' => DI::baseUrl() . '/feed/' . $user['nickname'],
'nurl' => Strings::normaliseLink($url),
'uri-id' => ItemURI::getIdByURI($url),
'addr' => $user['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3),
'notify' => DI::baseUrl() . '/dfrn_notify/' . $user['nickname'],
'poll' => DI::baseUrl() . '/feed/' . $user['nickname'],
];
$avatar = Photo::selectFirst(['resource-id', 'type'], ['uid' => $uid, 'profile' => true]);
@ -906,14 +906,14 @@ class Contact
$fields['micro'] = self::getDefaultAvatar($fields, Proxy::SIZE_MICRO);
}
$fields['avatar'] = User::getAvatarUrl($user);
$fields['header'] = User::getBannerUrl($user);
$fields['forum'] = in_array($user['page-flags'], [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_COMM_MAN]);
$fields['prv'] = $user['page-flags'] == User::PAGE_FLAGS_PRVGROUP;
$fields['unsearchable'] = !$profile['net-publish'];
$fields['avatar'] = User::getAvatarUrl($user);
$fields['header'] = User::getBannerUrl($user);
$fields['forum'] = in_array($user['page-flags'], [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_COMM_MAN]);
$fields['prv'] = $user['page-flags'] == User::PAGE_FLAGS_PRVGROUP;
$fields['unsearchable'] = !$profile['net-publish'];
$fields['manually-approve'] = in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP, User::PAGE_FLAGS_COMM_MAN]);
$fields['baseurl'] = DI::baseUrl();
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
$fields['baseurl'] = DI::baseUrl();
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
$update = false;
@ -1092,7 +1092,7 @@ class Contact
public static function markForArchival(array $contact)
{
if ((!isset($contact['uri-id']) || !isset($contact['url']) || !isset($contact['archive']) || !isset($contact['self']) || !isset($contact['term-date'])) && !empty($contact['id'])) {
$fields = ['id', 'uri-id', 'url', 'archive', 'self', 'term-date'];
$fields = ['id', 'uri-id', 'url', 'archive', 'self', 'term-date'];
$contact = DBA::selectFirst('contact', $fields, ['id' => $contact['id']]);
if (!DBA::isResult($contact)) {
return;
@ -1144,7 +1144,7 @@ class Contact
{
// Always unarchive the relay contact entry
if (!empty($contact['batch']) && !empty($contact['term-date']) && ($contact['term-date'] > DBA::NULL_DATETIME)) {
$fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false, 'unsearchable' => true];
$fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false, 'unsearchable' => true];
$condition = ['uid' => 0, 'network' => Protocol::FEDERATED, 'batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY];
if (!DBA::exists('contact', array_merge($condition, $fields))) {
self::update($fields, $condition);
@ -1158,7 +1158,7 @@ class Contact
}
if ((!isset($contact['url']) || !isset($contact['uri-id'])) && !empty($contact['id'])) {
$fields = ['id', 'uri-id', 'url', 'batch', 'term-date'];
$fields = ['id', 'uri-id', 'url', 'batch', 'term-date'];
$contact = DBA::selectFirst('contact', $fields, ['id' => $contact['id']]);
if (!DBA::isResult($contact)) {
return;
@ -1214,11 +1214,11 @@ class Contact
if ($contact['contact-type'] == Contact::TYPE_COMMUNITY) {
$mention_label = DI::l10n()->t('Post to group');
$mention_url = 'compose/0?body=!' . $contact['addr'];
$mention_url = 'compose/0?body=!' . $contact['addr'];
$network_label = DI::l10n()->t('View group');
} else {
$mention_label = DI::l10n()->t('Mention');
$mention_url = 'compose/0?body=@' . $contact['addr'];
$mention_url = 'compose/0?body=@' . $contact['addr'];
$network_label = DI::l10n()->t('Network Posts');
}
$network_url = 'contact/' . $contact['id'] . '/conversations';
@ -1376,10 +1376,10 @@ class Contact
if (DBA::isResult($personal_contact) && !Probe::isProbable($personal_contact['network'])) {
DI::logger()->info('Take contact data from personal contact', ['url' => $url, 'update' => $update, 'contact' => $personal_contact]);
$data = $personal_contact;
$data['photo'] = $personal_contact['avatar'];
$data = $personal_contact;
$data['photo'] = $personal_contact['avatar'];
$data['account-type'] = $personal_contact['contact-type'];
$data['hide'] = $personal_contact['unsearchable'];
$data['hide'] = $personal_contact['unsearchable'];
unset($data['avatar']);
unset($data['contact-type']);
unset($data['unsearchable']);
@ -1411,17 +1411,17 @@ class Contact
if (!$contact_id) {
// We only insert the basic data. The rest will be done in "updateFromProbeArray"
$fields = [
'uid' => $uid,
'url' => $data['url'],
'baseurl' => $data['baseurl'] ?? '',
'nurl' => Strings::normaliseLink($data['url']),
'network' => $data['network'],
'created' => DateTimeFormat::utcNow(),
'rel' => self::SHARING,
'writable' => 1,
'blocked' => 0,
'readonly' => 0,
'pending' => 0,
'uid' => $uid,
'url' => $data['url'],
'baseurl' => $data['baseurl'] ?? '',
'nurl' => Strings::normaliseLink($data['url']),
'network' => $data['network'],
'created' => DateTimeFormat::utcNow(),
'rel' => self::SHARING,
'writable' => 1,
'blocked' => 0,
'readonly' => 0,
'pending' => 0,
];
$condition = ['nurl' => Strings::normaliseLink($data['url']), 'uid' => $uid, 'deleted' => false];
@ -1634,13 +1634,13 @@ class Contact
if (DI::pConfig()->get($uid, 'system', 'infinite_scroll')) {
$tpl = Renderer::getMarkupTemplate('infinite_scroll_head.tpl');
$o = Renderer::replaceMacros($tpl, ['$reload_uri' => DI::args()->getQueryString()]);
$o = Renderer::replaceMacros($tpl, ['$reload_uri' => DI::args()->getQueryString()]);
} else {
$o = '';
}
$fields = array_merge(Item::DISPLAY_FIELDLIST, ['featured']);
$items = Post::toArray(Post::selectForUser($uid, $fields, $condition, $params));
$items = Post::toArray(Post::selectForUser($uid, $fields, $condition, $params));
$o .= DI::conversation()->render($items, ConversationContent::MODE_CONTACT_POSTS);
@ -1697,7 +1697,7 @@ class Contact
if (DI::pConfig()->get($uid, 'system', 'infinite_scroll')) {
$tpl = Renderer::getMarkupTemplate('infinite_scroll_head.tpl');
$o = Renderer::replaceMacros($tpl, ['$reload_uri' => DI::args()->getQueryString()]);
$o = Renderer::replaceMacros($tpl, ['$reload_uri' => DI::args()->getQueryString()]);
} else {
$o = '';
}
@ -1713,7 +1713,7 @@ class Contact
$sql2 = "SELECT `thr-parent-id` AS `uri-id`, `created` FROM `post-user-view` WHERE " . array_shift($condition2);
$union = array_merge($condition1, $condition2);
$sql = $sql1 . " UNION " . $sql2;
$sql = $sql1 . " UNION " . $sql2;
$sql .= " ORDER BY `created` DESC LIMIT ?, ?";
$union = array_merge($union, [$pager->getStart(), $pager->getItemsPerPage()]);
@ -1722,7 +1722,7 @@ class Contact
if (empty($last_created) && ($pager->getStart() == 0)) {
$fields = ['uri-id', 'thr-parent-id', 'gravity', 'author-id', 'created'];
$pinned = Post\Collection::selectToArrayForContact($cid, Post\Collection::FEATURED, $fields);
$items = array_merge($items, $pinned);
$items = array_merge($items, $pinned);
}
$o .= DI::conversation()->render($items, ConversationContent::MODE_CONTACTS, $update, false, 'pinned_created', $uid);
@ -1913,9 +1913,9 @@ class Contact
*/
private static function checkAvatarCacheByArray(array $contact, bool $no_update = false): array
{
$update = false;
$update = false;
$contact_fields = [];
$fields = ['photo', 'thumb', 'micro'];
$fields = ['photo', 'thumb', 'micro'];
foreach ($fields as $field) {
if (isset($contact[$field])) {
$contact_fields[] = $field;
@ -1971,7 +1971,7 @@ class Contact
if (!empty($contact['gsid'])) {
// Use default banners for certain platforms
$gserver = DBA::selectFirst('gserver', ['platform'], ['id' => $contact['gsid']]);
$gserver = DBA::selectFirst('gserver', ['platform'], ['id' => $contact['gsid']]);
$platform = strtolower($gserver['platform'] ?? '');
} else {
$platform = '';
@ -2016,18 +2016,18 @@ class Contact
switch ($size) {
case Proxy::SIZE_MICRO:
$avatar['size'] = 48;
$default = self::DEFAULT_AVATAR_MICRO;
$default = self::DEFAULT_AVATAR_MICRO;
break;
case Proxy::SIZE_THUMB:
$avatar['size'] = 80;
$default = self::DEFAULT_AVATAR_THUMB;
$default = self::DEFAULT_AVATAR_THUMB;
break;
case Proxy::SIZE_SMALL:
default:
$avatar['size'] = 300;
$default = self::DEFAULT_AVATAR_PHOTO;
$default = self::DEFAULT_AVATAR_PHOTO;
break;
}
@ -2036,14 +2036,14 @@ class Contact
$type = Contact::TYPE_PERSON;
if (!empty($contact['id'])) {
$account = DBA::selectFirst('account-user-view', ['platform', 'contact-type'], ['id' => $contact['id']]);
$platform = $account['platform'] ?? '';
$account = DBA::selectFirst('account-user-view', ['platform', 'contact-type'], ['id' => $contact['id']]);
$platform = $account['platform'] ?? '';
$type = $account['contact-type'] ?? Contact::TYPE_PERSON;
}
if (empty($platform) && !empty($contact['uri-id'])) {
$account = DBA::selectFirst('account-user-view', ['platform', 'contact-type'], ['uri-id' => $contact['uri-id']]);
$platform = $account['platform'] ?? '';
$account = DBA::selectFirst('account-user-view', ['platform', 'contact-type'], ['uri-id' => $contact['uri-id']]);
$platform = $account['platform'] ?? '';
$type = $account['contact-type'] ?? Contact::TYPE_PERSON;
}
@ -2153,7 +2153,7 @@ class Contact
return DI::baseUrl() . $default;
}
$avatar['url'] = '';
$avatar['url'] = '';
$avatar['success'] = false;
Hook::callAll('avatar_lookup', $avatar);
@ -2181,7 +2181,7 @@ class Contact
if (empty($updated)) {
$account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]);
$updated = $account['updated'] ?? '';
$guid = $account['guid'] ?? '';
$guid = $account['guid'] ?? '';
}
$guid = urlencode($guid);
@ -2249,7 +2249,7 @@ class Contact
if (empty($updated) || empty($guid)) {
$account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]);
$updated = $account['updated'] ?? '';
$guid = $account['guid'] ?? '';
$guid = $account['guid'] ?? '';
}
$guid = urlencode($guid);
@ -2380,11 +2380,11 @@ class Contact
if ($default_avatar && Proxy::isLocalImage($avatar)) {
$fields = [
'avatar' => $avatar,
'avatar' => $avatar,
'avatar-date' => DateTimeFormat::utcNow(),
'photo' => $avatar,
'thumb' => self::getDefaultAvatar($contact, Proxy::SIZE_THUMB),
'micro' => self::getDefaultAvatar($contact, Proxy::SIZE_MICRO)
'photo' => $avatar,
'thumb' => self::getDefaultAvatar($contact, Proxy::SIZE_THUMB),
'micro' => self::getDefaultAvatar($contact, Proxy::SIZE_MICRO)
];
DI::logger()->debug('Use default avatar', ['id' => $cid, 'uid' => $uid]);
}
@ -2423,11 +2423,11 @@ class Contact
$photos = Photo::importProfilePhoto($avatar, $uid, $cid, true);
if ($photos) {
$fields = [
'avatar' => $avatar,
'photo' => $photos[0],
'thumb' => $photos[1],
'micro' => $photos[2],
'blurhash' => $photos[3],
'avatar' => $avatar,
'photo' => $photos[0],
'thumb' => $photos[1],
'micro' => $photos[2],
'blurhash' => $photos[3],
'avatar-date' => DateTimeFormat::utcNow(),
];
$update = true;
@ -2480,7 +2480,7 @@ class Contact
{
// Update contact data for all users
$condition = ['self' => false, 'nurl' => Strings::normaliseLink($url)];
$contacts = DBA::select('contact', ['id', 'uid'], $condition);
$contacts = DBA::select('contact', ['id', 'uid'], $condition);
while ($contact = DBA::fetch($contacts)) {
DI::logger()->info('Deleting contact', ['id' => $contact['id'], 'uid' => $contact['uid'], 'url' => $url]);
self::remove($contact['id']);
@ -2607,7 +2607,7 @@ class Contact
public static function removeDuplicates(string $nurl, int $uid)
{
$condition = ['nurl' => $nurl, 'uid' => $uid, 'self' => false, 'deleted' => false, 'network' => Protocol::FEDERATED];
$count = DBA::count('contact', $condition);
$count = DBA::count('contact', $condition);
if ($count <= 1) {
return false;
}
@ -2622,7 +2622,7 @@ class Contact
DI::logger()->info('Found duplicates', ['count' => $count, 'first' => $first, 'uid' => $uid, 'nurl' => $nurl]);
// Find all duplicates
$condition = ["`nurl` = ? AND `uid` = ? AND `id` != ? AND NOT `self` AND NOT `deleted`", $nurl, $uid, $first];
$condition = ["`nurl` = ? AND `uid` = ? AND `id` != ? AND NOT `self` AND NOT `deleted`", $nurl, $uid, $first];
$duplicates = DBA::select('contact', ['id', 'network'], $condition);
while ($duplicate = DBA::fetch($duplicates)) {
if (!in_array($duplicate['network'], Protocol::FEDERATED)) {
@ -2693,7 +2693,7 @@ class Contact
$data = Probe::uri($contact['url'], $network, $contact['uid']);
if (in_array($data['network'], Protocol::FEDERATED) && (parse_url($data['url'], PHP_URL_SCHEME) == 'http')) {
$ssl_url = str_replace('http://', 'https://', $contact['url']);
$ssl_url = str_replace('http://', 'https://', $contact['url']);
$ssl_data = Probe::uri($ssl_url, $network, $contact['uid']);
if (($ssl_data['network'] == $data['network']) && (parse_url($ssl_data['url'], PHP_URL_SCHEME) != 'http')) {
$data = $ssl_data;
@ -2890,12 +2890,12 @@ class Contact
}
if (isset($ret['account-type']) && is_int($ret['account-type'])) {
$ret['forum'] = false;
$ret['prv'] = false;
$ret['forum'] = false;
$ret['prv'] = false;
$ret['contact-type'] = $ret['account-type'];
if (($ret['contact-type'] == User::ACCOUNT_TYPE_COMMUNITY) && isset($ret['manually-approve'])) {
$ret['forum'] = (bool)!$ret['manually-approve'];
$ret['prv'] = (bool)!$ret['forum'];
$ret['prv'] = (bool)!$ret['forum'];
}
}
@ -2914,7 +2914,7 @@ class Contact
}
$update = false;
$guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url'], $ret['baseurl'] ?? $ret['alias'] ?? '');
$guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url'], $ret['baseurl'] ?? $ret['alias'] ?? '');
// make sure to not overwrite existing values with blank entries except some technical fields
$keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl'];
@ -2981,7 +2981,7 @@ class Contact
}
if (($uid == 0) || in_array($ret['network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
$ret['last-update'] = $updated;
$ret['last-update'] = $updated;
$ret['success_update'] = $updated;
}
@ -3113,10 +3113,10 @@ class Contact
if (!empty($arr['contact']['name'])) {
$probed = false;
$ret = $arr['contact'];
$ret = $arr['contact'];
} else {
$probed = true;
$ret = Probe::uri($url, $network, $uid);
$ret = Probe::uri($url, $network, $uid);
// Ensure that the public contact exists
if ($ret['network'] != Protocol::PHANTOM) {
@ -3131,7 +3131,7 @@ class Contact
// check if we already have a contact
$condition = ['uid' => $uid, 'nurl' => Strings::normaliseLink($ret['url']), 'deleted' => false];
$contact = DBA::selectFirst('contact', ['id', 'rel', 'url', 'pending', 'hub-verify'], $condition);
$contact = DBA::selectFirst('contact', ['id', 'rel', 'url', 'pending', 'hub-verify'], $condition);
$protocol = self::getProtocol($ret['url'], $ret['network']);
@ -3210,7 +3210,7 @@ class Contact
'nick' => $ret['nick'],
'network' => $ret['network'],
'baseurl' => $ret['baseurl'],
'gsid' => $ret['gsid'] ?? null,
'gsid' => $ret['gsid'] ?? null,
'contact-type' => $ret['account-type'] ?? self::TYPE_PERSON,
'protocol' => $protocol,
'pubkey' => $ret['pubkey'],
@ -3230,7 +3230,7 @@ class Contact
return $result;
}
$contact_id = $contact['id'];
$contact_id = $contact['id'];
$result['cid'] = $contact_id;
if ($contact['contact-type'] == self::TYPE_COMMUNITY) {
@ -3275,7 +3275,7 @@ class Contact
return false;
}
$fields = ['id', 'url', 'name', 'nick', 'avatar', 'photo', 'network', 'blocked', 'baseurl'];
$fields = ['id', 'url', 'name', 'nick', 'avatar', 'photo', 'network', 'blocked', 'baseurl'];
$pub_contact = DBA::selectFirst('contact', $fields, ['id' => $datarray['author-id']]);
if (!DBA::isResult($pub_contact)) {
// Should never happen
@ -3287,10 +3287,10 @@ class Contact
return false;
}
$url = ($datarray['author-link'] ?? '') ?: $pub_contact['url'];
$name = $pub_contact['name'];
$photo = ($pub_contact['avatar'] ?? '') ?: $pub_contact["photo"];
$nick = $pub_contact['nick'];
$url = ($datarray['author-link'] ?? '') ?: $pub_contact['url'];
$name = $pub_contact['name'];
$photo = ($pub_contact['avatar'] ?? '') ?: $pub_contact["photo"];
$nick = $pub_contact['nick'];
$network = $pub_contact['network'];
// Ensure that we don't create a new contact when there already is one
@ -3368,7 +3368,7 @@ class Contact
/// @TODO Encapsulate this into a function/method
$fields = ['uid', 'username', 'email', 'page-flags', 'notify-flags', 'language'];
$user = DBA::selectFirst('user', $fields, ['uid' => $importer['uid']]);
$user = DBA::selectFirst('user', $fields, ['uid' => $importer['uid']]);
if (DBA::isResult($user) && !in_array($user['page-flags'], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_FREELOVE, User::PAGE_FLAGS_COMMUNITY])) {
// create notification
if (is_array($contact_record)) {
@ -3402,7 +3402,7 @@ class Contact
}
$condition = ['uid' => $importer['uid'], 'url' => $url, 'pending' => true];
$fields = ['pending' => false];
$fields = ['pending' => false];
if ($user['page-flags'] == User::PAGE_FLAGS_FREELOVE) {
$fields['rel'] = self::FRIEND;
}
@ -3507,7 +3507,7 @@ class Contact
DBA::update(
'contact',
['bdyear' => substr($nextbd, 0, 4), 'bd' => $nextbd],
['id' => $contact['id']]
['id' => $contact['id']]
);
}
}
@ -3662,9 +3662,9 @@ class Contact
*/
public static function isGroup(int $contactid): bool
{
$fields = ['contact-type'];
$fields = ['contact-type'];
$condition = ['id' => $contactid];
$contact = DBA::selectFirst('contact', $fields, $condition);
$contact = DBA::selectFirst('contact', $fields, $condition);
if (!DBA::isResult($contact)) {
return false;
}
@ -3682,7 +3682,7 @@ class Contact
public static function canReceivePrivateMessages(array $contact): bool
{
$protocol = $contact['network'] ?? $contact['protocol'] ?? Protocol::PHANTOM;
$self = $contact['self'] ?? false;
$self = $contact['self'] ?? false;
return in_array($protocol, [Protocol::DFRN, Protocol::DIASPORA, Protocol::ACTIVITYPUB]) && !$self;
}
@ -3713,12 +3713,12 @@ class Contact
}
$condition = [
'network' => $networks,
'server-failed' => false,
'failed' => false,
'deleted' => false,
'unsearchable' => false,
'uid' => $uid
'network' => $networks,
'server-failed' => false,
'failed' => false,
'deleted' => false,
'unsearchable' => false,
'uid' => $uid
];
if (!$show_blocked) {
@ -3762,10 +3762,10 @@ class Contact
*/
public static function addByUrls(array $urls): array
{
$added = 0;
$updated = 0;
$added = 0;
$updated = 0;
$unchanged = 0;
$count = 0;
$count = 0;
foreach ($urls as $url) {
if (empty($url) || !is_string($url)) {

View file

@ -39,44 +39,44 @@ use Psr\Http\Message\UriInterface;
class GServer
{
// Directory types
const DT_NONE = 0;
const DT_POCO = 1;
const DT_NONE = 0;
const DT_POCO = 1;
const DT_MASTODON = 2;
// Methods to detect server types
// Non endpoint specific methods
const DETECT_MANUAL = 0;
const DETECT_HEADER = 1;
const DETECT_BODY = 2;
const DETECT_HOST_META = 3;
const DETECT_CONTACTS = 4;
const DETECT_AP_ACTOR = 5;
const DETECT_MANUAL = 0;
const DETECT_HEADER = 1;
const DETECT_BODY = 2;
const DETECT_HOST_META = 3;
const DETECT_CONTACTS = 4;
const DETECT_AP_ACTOR = 5;
const DETECT_AP_COLLECTION = 6;
const DETECT_UNSPECIFIC = [self::DETECT_MANUAL, self::DETECT_HEADER, self::DETECT_BODY, self::DETECT_HOST_META, self::DETECT_CONTACTS, self::DETECT_AP_ACTOR];
// Implementation specific endpoints
// @todo Possibly add Lemmy detection via the endpoint /api/v3/site
const DETECT_FRIENDIKA = 10;
const DETECT_FRIENDICA = 11;
const DETECT_STATUSNET = 12;
const DETECT_GNUSOCIAL = 13;
const DETECT_CONFIG_JSON = 14; // Statusnet, GNU Social, Older Hubzilla/Redmatrix
const DETECT_FRIENDIKA = 10;
const DETECT_FRIENDICA = 11;
const DETECT_STATUSNET = 12;
const DETECT_GNUSOCIAL = 13;
const DETECT_CONFIG_JSON = 14; // Statusnet, GNU Social, Older Hubzilla/Redmatrix
const DETECT_SITEINFO_JSON = 15; // Newer Hubzilla
const DETECT_MASTODON_API = 16;
const DETECT_STATUS_PHP = 17; // Nextcloud
const DETECT_V1_CONFIG = 18;
const DETECT_SYSTEM_ACTOR = 20; // Mistpark, Osada, Roadhouse, Zap
const DETECT_THREADS = 21;
const DETECT_MASTODON_API = 16;
const DETECT_STATUS_PHP = 17; // Nextcloud
const DETECT_V1_CONFIG = 18;
const DETECT_SYSTEM_ACTOR = 20; // Mistpark, Osada, Roadhouse, Zap
const DETECT_THREADS = 21;
// Standardized endpoints
const DETECT_STATISTICS_JSON = 100;
const DETECT_NODEINFO_10 = 101; // Nodeinfo Version 1.0
const DETECT_NODEINFO_20 = 102; // Nodeinfo Version 2.0
const DETECT_NODEINFO2_10 = 103; // Nodeinfo2 Version 1.0
const DETECT_NODEINFO_21 = 104; // Nodeinfo Version 2.1
const DETECT_NODEINFO_22 = 105; // Nodeinfo Version 2.2
const DETECT_NODEINFO_10 = 101; // Nodeinfo Version 1.0
const DETECT_NODEINFO_20 = 102; // Nodeinfo Version 2.0
const DETECT_NODEINFO2_10 = 103; // Nodeinfo2 Version 1.0
const DETECT_NODEINFO_21 = 104; // Nodeinfo Version 2.1
const DETECT_NODEINFO_22 = 105; // Nodeinfo Version 2.2
/**
* Check for the existence of a server and adds it in the background if not existant
@ -343,7 +343,7 @@ class GServer
$gserver = DBA::selectFirst('gserver', [], ['nurl' => Strings::normaliseLink($server_url)]);
if (DBA::isResult($gserver)) {
if ($gserver['created'] <= DBA::NULL_DATETIME) {
$fields = ['created' => DateTimeFormat::utcNow()];
$fields = ['created' => DateTimeFormat::utcNow()];
$condition = ['nurl' => Strings::normaliseLink($server_url)];
self::update($fields, $condition);
}
@ -450,9 +450,11 @@ class GServer
$gserver = DBA::selectFirst('gserver', [], ['nurl' => $nurl]);
if (DBA::isResult($gserver)) {
$next_update = self::getNextUpdateDate(false, $gserver['created'], $gserver['last_contact']);
self::update(['url' => $url, 'failed' => true, 'blocked' => Network::isUrlBlocked($url), 'last_failure' => DateTimeFormat::utcNow(),
'next_contact' => $next_update, 'network' => Protocol::PHANTOM, 'detection-method' => null],
['nurl' => $nurl]);
self::update(
['url' => $url, 'failed' => true, 'blocked' => Network::isUrlBlocked($url), 'last_failure' => DateTimeFormat::utcNow(),
'next_contact' => $next_update, 'network' => Protocol::PHANTOM, 'detection-method' => null],
['nurl' => $nurl]
);
DI::logger()->info('Set failed status for existing server', ['url' => $url]);
if (self::isDefunct($gserver)) {
self::archiveContacts($gserver['id']);
@ -461,8 +463,8 @@ class GServer
}
self::insert(['url' => $url, 'nurl' => $nurl,
'network' => Protocol::PHANTOM, 'created' => DateTimeFormat::utcNow(),
'failed' => true, 'last_failure' => DateTimeFormat::utcNow()]);
'network' => Protocol::PHANTOM, 'created' => DateTimeFormat::utcNow(),
'failed' => true, 'last_failure' => DateTimeFormat::utcNow()]);
DI::logger()->info('Set failed status for new server', ['url' => $url]);
}
@ -592,7 +594,7 @@ class GServer
if ((parse_url($url, PHP_URL_HOST) == parse_url($valid_url, PHP_URL_HOST)) &&
(parse_url($url, PHP_URL_PATH) == parse_url($valid_url, PHP_URL_PATH)) &&
(parse_url($url, PHP_URL_SCHEME) != parse_url($valid_url, PHP_URL_SCHEME))) {
$url = $valid_url;
$url = $valid_url;
}
$in_webroot = empty(parse_url($url, PHP_URL_PATH));
@ -627,10 +629,10 @@ class GServer
if ($serverdata['network'] == Protocol::PHANTOM) {
if ($in_webroot) {
// Fetch the landing page, possibly it reveals some data
$accept = 'application/activity+json,application/ld+json,application/json,*/*;q=0.9';
$accept = 'application/activity+json,application/ld+json,application/json,*/*;q=0.9';
$curlResult = DI::httpClient()->get($url, $accept, [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
if (!$curlResult->isSuccess() && $curlResult->getReturnCode() == '406') {
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
$html_fetched = true;
} else {
$html_fetched = false;
@ -639,8 +641,8 @@ class GServer
if ($curlResult->isSuccess()) {
$json = json_decode($curlResult->getBodyString(), true);
if (!empty($json) && is_array($json)) {
$data = self::fetchDataFromSystemActor($json, $serverdata);
$serverdata = $data['server'];
$data = self::fetchDataFromSystemActor($json, $serverdata);
$serverdata = $data['server'];
$systemactor = $data['actor'];
if (!$html_fetched && !in_array($serverdata['detection-method'], [self::DETECT_SYSTEM_ACTOR, self::DETECT_AP_COLLECTION])) {
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
@ -739,7 +741,7 @@ class GServer
return false;
}
$serverdata['url'] = $url;
$serverdata['url'] = $url;
$serverdata['nurl'] = Strings::normaliseLink($url);
// We have to prevent an endless loop here.
@ -803,10 +805,11 @@ class GServer
$gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]);
if (!DBA::isResult($gserver)) {
$serverdata['created'] = DateTimeFormat::utcNow();
$ret = self::insert($serverdata);
$id = DBA::lastInsertId();
$id = DBA::lastInsertId();
} else {
$ret = self::update($serverdata, ['nurl' => $serverdata['nurl']]);
$ret = self::update($serverdata, ['nurl' => $serverdata['nurl']]);
$gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => $serverdata['nurl']]);
if (DBA::isResult($gserver)) {
$id = $gserver['id'];
@ -816,8 +819,8 @@ class GServer
// Count the number of known contacts from this server
if (!empty($id) && !in_array($serverdata['network'], [Protocol::PHANTOM, Protocol::FEED])) {
$apcontacts = DBA::count('apcontact', ['gsid' => $id]);
$contacts = DBA::count('contact', ['uid' => 0, 'gsid' => $id, 'failed' => false]);
$max_users = max($apcontacts, $contacts);
$contacts = DBA::count('contact', ['uid' => 0, 'gsid' => $id, 'failed' => false]);
$max_users = max($apcontacts, $contacts);
if ($max_users > $serverdata['registered-users']) {
DI::logger()->info('Update registered users', ['id' => $id, 'url' => $serverdata['nurl'], 'registered-users' => $max_users]);
self::update(['registered-users' => $max_users], ['id' => $id]);
@ -846,7 +849,7 @@ class GServer
if (!empty($systemactor)) {
$contact = Contact::getByURL($systemactor, true, ['gsid', 'baseurl', 'id', 'network', 'url', 'name']);
DI::logger()->debug('Fetched system actor', ['url' => $url, 'gsid' => $id, 'contact' => $contact]);
DI::logger()->debug('Fetched system actor', ['url' => $url, 'gsid' => $id, 'contact' => $contact]);
}
return $ret;
@ -879,9 +882,9 @@ class GServer
$data['subscribe'] = (bool)($data['subscribe'] ?? false);
if (!$data['subscribe'] || empty($data['scope']) || !in_array(strtolower($data['scope']), ['all', 'tags'])) {
$data['scope'] = '';
$data['scope'] = '';
$data['subscribe'] = false;
$data['tags'] = [];
$data['tags'] = [];
}
$gserver = DBA::selectFirst('gserver', ['id', 'url', 'network', 'relay-subscribe', 'relay-scope'], ['nurl' => Strings::normaliseLink($server_url)]);
@ -975,13 +978,14 @@ class GServer
return $serverdata;
}
$valid = false;
$valid = false;
$old_serverdata = $serverdata;
$serverdata['detection-method'] = self::DETECT_STATISTICS_JSON;
if (!empty($data['version'])) {
$valid = true;
$serverdata['version'] = $data['version'];
// Version numbers on statistics.json are presented with additional info, e.g.:
// 0.6.3.0-p1702cc1c, 0.6.99.0-p1b9ab160 or 3.4.3-2-1191.
@ -990,11 +994,13 @@ class GServer
if (!empty($data['name'])) {
$valid = true;
$serverdata['site_name'] = $data['name'];
}
if (!empty($data['network'])) {
$valid = true;
$serverdata['platform'] = strtolower($data['network']);
if ($serverdata['platform'] == 'diaspora') {
@ -1010,21 +1016,25 @@ class GServer
if (!empty($data['total_users'])) {
$valid = true;
$serverdata['registered-users'] = max($data['total_users'], 1);
}
if (!empty($data['active_users_monthly'])) {
$valid = true;
$serverdata['active-month-users'] = max($data['active_users_monthly'], 0);
}
if (!empty($data['active_users_halfyear'])) {
$valid = true;
$serverdata['active-halfyear-users'] = max($data['active_users_halfyear'], 0);
}
if (!empty($data['local_posts'])) {
$valid = true;
$serverdata['local-posts'] = max($data['local_posts'], 0);
}
@ -1065,8 +1075,8 @@ class GServer
return [];
}
$nodeinfo1_url = '';
$nodeinfo2_url = '';
$nodeinfo1_url = '';
$nodeinfo2_url = '';
$detection_method = self::DETECT_MANUAL;
foreach ($nodeinfo['links'] as $link) {
@ -1078,13 +1088,13 @@ class GServer
if ($link['rel'] == 'http://nodeinfo.diaspora.software/ns/schema/1.0') {
$nodeinfo1_url = Network::addBasePath($link['href'], $httpResult->getUrl());
} elseif (($detection_method < self::DETECT_NODEINFO_20) && ($link['rel'] == 'http://nodeinfo.diaspora.software/ns/schema/2.0')) {
$nodeinfo2_url = Network::addBasePath($link['href'], $httpResult->getUrl());
$nodeinfo2_url = Network::addBasePath($link['href'], $httpResult->getUrl());
$detection_method = self::DETECT_NODEINFO_20;
} elseif (($detection_method < self::DETECT_NODEINFO_21) && ($link['rel'] == 'http://nodeinfo.diaspora.software/ns/schema/2.1')) {
$nodeinfo2_url = Network::addBasePath($link['href'], $httpResult->getUrl());
$nodeinfo2_url = Network::addBasePath($link['href'], $httpResult->getUrl());
$detection_method = self::DETECT_NODEINFO_21;
} elseif (($detection_method < self::DETECT_NODEINFO_22) && ($link['rel'] == 'http://nodeinfo.diaspora.software/ns/schema/2.2')) {
$nodeinfo2_url = Network::addBasePath($link['href'], $httpResult->getUrl());
$nodeinfo2_url = Network::addBasePath($link['href'], $httpResult->getUrl());
$detection_method = self::DETECT_NODEINFO_22;
}
}
@ -1132,7 +1142,7 @@ class GServer
$server = [
'detection-method' => self::DETECT_NODEINFO_10,
'register_policy' => Register::CLOSED
'register_policy' => Register::CLOSED
];
if (!empty($nodeinfo['openRegistrations'])) {
@ -1232,8 +1242,8 @@ class GServer
$server = [
'detection-method' => $detection_method,
'register_policy' => Register::CLOSED,
'platform' => 'unknown',
'register_policy' => Register::CLOSED,
'platform' => 'unknown',
];
if (!empty($nodeinfo['openRegistrations'])) {
@ -1363,7 +1373,7 @@ class GServer
$server = [
'detection-method' => self::DETECT_NODEINFO2_10,
'register_policy' => Register::CLOSED
'register_policy' => Register::CLOSED
];
if (!empty($nodeinfo['openRegistrations'])) {
@ -1471,7 +1481,7 @@ class GServer
if (!empty($data['platform'])) {
$serverdata['platform'] = strtolower($data['platform']);
$serverdata['version'] = $data['version'] ?? 'N/A';
$serverdata['version'] = $data['version'] ?? 'N/A';
}
if (!empty($data['plugins'])) {
@ -1547,17 +1557,17 @@ class GServer
$actor = JsonLD::compact($data, false);
if (in_array(JsonLD::fetchElement($actor, '@type'), ActivityPub\Receiver::ACCOUNT_TYPES)) {
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['site_name'] = JsonLD::fetchElement($actor, 'as:name', '@value');
$serverdata['info'] = JsonLD::fetchElement($actor, 'as:summary', '@value');
$serverdata['info'] = JsonLD::fetchElement($actor, 'as:summary', '@value');
if (self::isNomad($actor)) {
$serverdata['platform'] = self::getNomadName($actor['@id']);
$serverdata['version'] = self::getNomadVersion($actor['@id']);
$serverdata['platform'] = self::getNomadName($actor['@id']);
$serverdata['version'] = self::getNomadVersion($actor['@id']);
$serverdata['detection-method'] = self::DETECT_SYSTEM_ACTOR;
} elseif (!empty($actor['as:generator'])) {
$generator = explode(' ', JsonLD::fetchElement($actor['as:generator'], 'as:name', '@value'));
$serverdata['platform'] = strtolower(array_shift($generator));
$serverdata['version'] = self::getNomadVersion($actor['@id']);
$generator = explode(' ', JsonLD::fetchElement($actor['as:generator'], 'as:name', '@value'));
$serverdata['platform'] = strtolower(array_shift($generator));
$serverdata['version'] = self::getNomadVersion($actor['@id']);
$serverdata['detection-method'] = self::DETECT_SYSTEM_ACTOR;
} else {
$serverdata['detection-method'] = self::DETECT_AP_ACTOR;
@ -1565,8 +1575,8 @@ class GServer
return ['server' => $serverdata, 'actor' => $actor['@id']];
} elseif ((JsonLD::fetchElement($actor, '@type') == 'as:Collection')) {
// By now only Ktistec seems to provide collections this way
$serverdata['platform'] = 'ktistec';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['platform'] = 'ktistec';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['detection-method'] = self::DETECT_AP_COLLECTION;
$actors = JsonLD::fetchElementArray($actor, 'as:items');
@ -1610,7 +1620,7 @@ class GServer
*/
private static function getNomadName(string $url): string
{
$name = 'nomad';
$name = 'nomad';
$curlResult = DI::httpClient()->get($url . '/manifest', 'application/manifest+json', [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
if ($curlResult->getReturnCode() == 418) {
@ -1729,7 +1739,7 @@ class GServer
private static function validHostMeta(string $url): bool
{
$xrd_timeout = DI::config()->get('system', 'xrd_timeout');
$curlResult = DI::httpClient()->get($url . Probe::HOST_META, HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout, HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
$curlResult = DI::httpClient()->get($url . Probe::HOST_META, HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout, HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
if (!$curlResult->isSuccess()) {
return false;
}
@ -1828,10 +1838,9 @@ class GServer
}
if (!empty($data['totalResults'])) {
$registeredUsers = $serverdata['registered-users'] ?? 0;
$serverdata['registered-users'] = max($data['totalResults'], $registeredUsers, 1);
$serverdata['directory-type'] = self::DT_POCO;
$serverdata['poco'] = $url . '/poco';
$serverdata['registered-users'] = max($data['totalResults'], $serverdata['registered-users'] ?? 0, 1);
$serverdata['directory-type'] = self::DT_POCO;
$serverdata['poco'] = $url . '/poco';
}
return $serverdata;
@ -1886,8 +1895,8 @@ class GServer
if (!empty($data['instance']) && !empty($data['serverVersion'])) {
$serverdata['platform'] = 'peertube';
$serverdata['version'] = $data['serverVersion'];
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['version'] = $data['serverVersion'];
$serverdata['network'] = Protocol::ACTIVITYPUB;
if (!empty($data['instance']['name'])) {
$serverdata['site_name'] = $data['instance']['name'];
@ -1934,7 +1943,7 @@ class GServer
if (!empty($data['version'])) {
$serverdata['platform'] = 'nextcloud';
$serverdata['version'] = $data['version'];
$serverdata['version'] = $data['version'];
if ($validHostMeta) {
$serverdata['network'] = Protocol::ACTIVITYPUB;
@ -2012,8 +2021,9 @@ class GServer
if (!empty($data['version'])) {
$serverdata['platform'] = 'mastodon';
$serverdata['version'] = $data['version'] ?? '';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['version'] = $data['version'] ?? '';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$valid = true;
}
@ -2023,7 +2033,8 @@ class GServer
if (!empty($data['title']) && empty($serverdata['platform']) && ($serverdata['network'] == Protocol::PHANTOM)) {
$serverdata['platform'] = 'mastodon';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['network'] = Protocol::ACTIVITYPUB;
$valid = true;
}
@ -2037,19 +2048,22 @@ class GServer
if (!empty($serverdata['version']) && preg_match('/.*?\(compatible;\s(.*)\s(.*)\)/ism', $serverdata['version'], $matches)) {
$serverdata['platform'] = strtolower($matches[1]);
$serverdata['version'] = $matches[2];
$serverdata['version'] = $matches[2];
$valid = true;
}
if (!empty($serverdata['version']) && strstr(strtolower($serverdata['version']), 'pleroma')) {
$serverdata['platform'] = 'pleroma';
$serverdata['version'] = trim(str_ireplace('pleroma', '', $serverdata['version']));
$serverdata['version'] = trim(str_ireplace('pleroma', '', $serverdata['version']));
$valid = true;
}
if (!empty($serverdata['platform']) && strstr($serverdata['platform'], 'pleroma')) {
$serverdata['version'] = trim(str_ireplace('pleroma', '', $serverdata['platform']));
$serverdata['version'] = trim(str_ireplace('pleroma', '', $serverdata['platform']));
$serverdata['platform'] = 'pleroma';
$valid = true;
}
@ -2086,14 +2100,14 @@ class GServer
if (!empty($data['site']['platform'])) {
$serverdata['platform'] = strtolower($data['site']['platform']['PLATFORM_NAME']);
$serverdata['version'] = $data['site']['platform']['STD_VERSION'];
$serverdata['network'] = Protocol::ZOT;
$serverdata['version'] = $data['site']['platform']['STD_VERSION'];
$serverdata['network'] = Protocol::ZOT;
}
if (!empty($data['site']['hubzilla'])) {
$serverdata['platform'] = strtolower($data['site']['hubzilla']['PLATFORM_NAME']);
$serverdata['version'] = $data['site']['hubzilla']['RED_VERSION'];
$serverdata['network'] = Protocol::ZOT;
$serverdata['version'] = $data['site']['hubzilla']['RED_VERSION'];
$serverdata['network'] = Protocol::ZOT;
}
if (!empty($data['site']['redmatrix'])) {
@ -2107,9 +2121,9 @@ class GServer
$serverdata['network'] = Protocol::ZOT;
}
$private = false;
$private = false;
$inviteonly = false;
$closed = false;
$closed = false;
if (!empty($data['site']['closed'])) {
$closed = self::toBoolean($data['site']['closed']);
@ -2196,11 +2210,11 @@ class GServer
if (!empty($serverdata['version']) && strtolower(substr($serverdata['version'], 0, 7)) == 'pleroma') {
$serverdata['platform'] = 'pleroma';
$serverdata['version'] = trim(str_ireplace('pleroma', '', $serverdata['version']));
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['version'] = trim(str_ireplace('pleroma', '', $serverdata['version']));
$serverdata['network'] = Protocol::ACTIVITYPUB;
} else {
$serverdata['platform'] = 'statusnet';
$serverdata['network'] = Protocol::OSTATUS;
$serverdata['network'] = Protocol::OSTATUS;
}
if (in_array($serverdata['detection-method'], self::DETECT_UNSPECIFIC)) {
@ -2226,11 +2240,11 @@ class GServer
$curlResult = DI::httpClient()->get($url . '/friendica/json', HttpClientAccept::DEFAULT, [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
if (!$curlResult->isSuccess()) {
$curlResult = DI::httpClient()->get($url . '/friendika/json', HttpClientAccept::DEFAULT, [HttpClientOptions::REQUEST => HttpClientRequest::SERVERINFO]);
$friendika = true;
$platform = 'Friendika';
$friendika = true;
$platform = 'Friendika';
} else {
$friendika = false;
$platform = 'Friendica';
$platform = 'Friendica';
}
if (!$curlResult->isSuccess()) {
@ -2317,12 +2331,14 @@ class GServer
$doc = new DOMDocument();
@$doc->loadHTML($curlResult->getBodyString());
$xpath = new DOMXPath($doc);
$assigned = false;
// We can only detect honk via some HTML element on their page
if ($xpath->query('//div[@id="honksonpage"]')->count() == 1) {
$serverdata['platform'] = 'honk';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['network'] = Protocol::ACTIVITYPUB;
$assigned = true;
}
@ -2358,9 +2374,11 @@ class GServer
'twitter:app:name:googleplay', 'twitter:app:name:iphone', 'twitter:app:name:ipad', 'generator'])) {
$platform = str_ireplace(array_keys($platforms), array_values($platforms), $attr['content']);
$platform = str_replace('/', ' ', $platform);
$platform_parts = explode(' ', $platform);
if ((count($platform_parts) >= 2) && in_array(strtolower($platform_parts[0]), array_values($platforms))) {
$platform = $platform_parts[0];
$serverdata['version'] = $platform_parts[1];
}
if (in_array($platform, array_values($grouped_platforms['dfrn_platforms']))) {
@ -2372,6 +2390,7 @@ class GServer
}
if (in_array($platform, array_values($platforms))) {
$serverdata['platform'] = $platform;
$assigned = true;
}
}
@ -2407,6 +2426,7 @@ class GServer
if (in_array($attr['property'], ['og:platform', 'generator'])) {
if (in_array($attr['content'], array_keys($platforms))) {
$serverdata['platform'] = $platforms[$attr['content']];
$assigned = true;
}
@ -2422,9 +2442,10 @@ class GServer
foreach ($list as $node) {
foreach ($node->attributes as $attribute) {
if (parse_url(trim($attribute->value), PHP_URL_HOST) == 'micro.blog') {
$serverdata['version'] = trim($serverdata['platform'] . ' ' . $serverdata['version']);
$serverdata['version'] = trim($serverdata['platform'] . ' ' . $serverdata['version']);
$serverdata['platform'] = 'microblog';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['network'] = Protocol::ACTIVITYPUB;
$assigned = true;
}
}
@ -2435,9 +2456,10 @@ class GServer
foreach ($list as $node) {
foreach ($node->attributes as $attribute) {
if (trim($attribute->value) == 'https://micro.blog/micropub') {
$serverdata['version'] = trim($serverdata['platform'] . ' ' . $serverdata['version']);
$serverdata['version'] = trim($serverdata['platform'] . ' ' . $serverdata['version']);
$serverdata['platform'] = 'microblog';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['network'] = Protocol::ACTIVITYPUB;
$assigned = true;
}
}
@ -2463,15 +2485,15 @@ class GServer
{
if ($curlResult->getHeader('server') == 'Mastodon') {
$serverdata['platform'] = 'mastodon';
$serverdata['network'] = Protocol::ACTIVITYPUB;
$serverdata['network'] = Protocol::ACTIVITYPUB;
} elseif ($curlResult->inHeader('x-diaspora-version')) {
$serverdata['platform'] = 'diaspora';
$serverdata['network'] = Protocol::DIASPORA;
$serverdata['version'] = $curlResult->getHeader('x-diaspora-version')[0] ?? '';
$serverdata['network'] = Protocol::DIASPORA;
$serverdata['version'] = $curlResult->getHeader('x-diaspora-version')[0] ?? '';
} elseif ($curlResult->inHeader('x-friendica-version')) {
$serverdata['platform'] = 'friendica';
$serverdata['network'] = Protocol::DFRN;
$serverdata['version'] = $curlResult->getHeader('x-friendica-version')[0] ?? '';
$serverdata['network'] = Protocol::DFRN;
$serverdata['version'] = $curlResult->getHeader('x-friendica-version')[0] ?? '';
} else {
return $serverdata;
}
@ -2497,9 +2519,12 @@ class GServer
$last_update = date('c', time() - (60 * 60 * 24 * $requery_days));
$gservers = DBA::select('gserver', ['id', 'url', 'nurl', 'network', 'poco', 'directory-type'],
$gservers = DBA::select(
'gserver',
['id', 'url', 'nurl', 'network', 'poco', 'directory-type'],
["NOT `blocked` AND NOT `failed` AND `directory-type` != ? AND `last_poco_query` < ?", GServer::DT_NONE, $last_update],
['order' => ['RAND()']]);
['order' => ['RAND()']]
);
while ($gserver = DBA::fetch($gservers)) {
DI::logger()->info('Update peer list', ['server' => $gserver['url'], 'id' => $gserver['id']]);
@ -2537,7 +2562,7 @@ class GServer
// Discover federated servers
$protocols = ['activitypub', 'diaspora', 'dfrn', 'ostatus'];
foreach ($protocols as $protocol) {
$query = '{nodes(protocol:"' . $protocol . '"){host}}';
$query = '{nodes(protocol:"' . $protocol . '"){host}}';
$curlResult = DI::httpClient()->fetch('https://the-federation.info/graphql?query=' . urlencode($query), HttpClientAccept::JSON, 0, '', HttpClientRequest::SERVERDISCOVER);
if (!empty($curlResult)) {
$data = json_decode($curlResult, true);
@ -2554,7 +2579,7 @@ class GServer
$accesstoken = DI::config()->get('system', 'instances_social_key');
if (!empty($accesstoken)) {
$api = 'https://instances.social/api/1.0/instances/list?count=0';
$api = 'https://instances.social/api/1.0/instances/list?count=0';
$curlResult = DI::httpClient()->get($api, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . $accesstoken], HttpClientOptions::REQUEST => HttpClientRequest::SERVERDISCOVER]]);
if ($curlResult->isSuccess()) {
$servers = json_decode($curlResult->getBodyString(), true);