From 496967e7f8a05105570d5ad1894f243fb2a55262 Mon Sep 17 00:00:00 2001 From: Anubis2814 Date: Tue, 25 Apr 2023 22:10:27 -0400 Subject: [PATCH 01/30] Changed mobile icon for sidebar --- view/theme/frio/templates/nav.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/theme/frio/templates/nav.tpl b/view/theme/frio/templates/nav.tpl index ececab4d4c..88a8e4bf6f 100644 --- a/view/theme/frio/templates/nav.tpl +++ b/view/theme/frio/templates/nav.tpl @@ -41,7 +41,7 @@ {{* Left section of the NavBar with navigation shortcuts/icons *}} From e13a31c4fe0331420d4c548058c194c8b538b6dc Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 11 May 2023 08:13:19 +0000 Subject: [PATCH 02/30] Ensure that the baseurl return value is a string --- mod/message.php | 3 +-- src/Content/Smilies.php | 2 +- src/Model/Photo.php | 8 ++------ src/Model/User.php | 2 +- src/Module/HCard.php | 4 ++-- src/Module/OpenSearch.php | 2 +- src/Module/Register.php | 2 +- src/Module/WellKnown/HostMeta.php | 2 +- src/Protocol/ActivityPub/Transmitter.php | 2 +- view/theme/frio/php/default.php | 2 +- view/theme/smoothly/theme.php | 4 ++-- view/theme/vier/theme.php | 3 +-- 12 files changed, 15 insertions(+), 21 deletions(-) diff --git a/mod/message.php b/mod/message.php index 928f575ef3..d75fb240f0 100644 --- a/mod/message.php +++ b/mod/message.php @@ -54,11 +54,10 @@ function message_init(App $a) '$tabs' => $tabs, '$new' => $new, ]); - $base = DI::baseUrl(); $head_tpl = Renderer::getMarkupTemplate('message-head.tpl'); DI::page()['htmlhead'] .= Renderer::replaceMacros($head_tpl, [ - '$base' => $base + '$base' => (string)DI::baseUrl() ]); } diff --git a/src/Content/Smilies.php b/src/Content/Smilies.php index ff9d63882e..d231797b81 100644 --- a/src/Content/Smilies.php +++ b/src/Content/Smilies.php @@ -106,7 +106,7 @@ class Smilies ]; - $baseUrl = DI::baseUrl(); + $baseUrl = (string)DI::baseUrl(); $icons = [ '<3', diff --git a/src/Model/Photo.php b/src/Model/Photo.php index 74031a822e..1b87e82d51 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -918,9 +918,7 @@ class Photo */ public static function getResourceData(string $name): array { - $base = DI::baseUrl(); - - $guid = str_replace([Strings::normaliseLink($base), '/photo/'], '', Strings::normaliseLink($name)); + $guid = str_replace([Strings::normaliseLink((string)DI::baseUrl()), '/photo/'], '', Strings::normaliseLink($name)); if (parse_url($guid, PHP_URL_SCHEME)) { return []; @@ -982,9 +980,7 @@ class Photo */ public static function isLocalPage(string $name): bool { - $base = DI::baseUrl(); - - $guid = str_replace(Strings::normaliseLink($base), '', Strings::normaliseLink($name)); + $guid = str_replace(Strings::normaliseLink((string)DI::baseUrl()), '', Strings::normaliseLink($name)); $guid = preg_replace("=/photos/.*/image/(.*)=ism", '$1', $guid); if (empty($guid)) { return false; diff --git a/src/Model/User.php b/src/Model/User.php index 11d55e7f7e..3be13bebf1 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -167,7 +167,7 @@ class User $system['region'] = ''; $system['postal-code'] = ''; $system['country-name'] = ''; - $system['homepage'] = DI::baseUrl(); + $system['homepage'] = (string)DI::baseUrl(); $system['dob'] = '0000-00-00'; // Ensure that the user contains data diff --git a/src/Module/HCard.php b/src/Module/HCard.php index 92627125ab..ce63d77c35 100644 --- a/src/Module/HCard.php +++ b/src/Module/HCard.php @@ -64,9 +64,9 @@ class HCard extends BaseModule $page['htmlhead'] .= '' . "\r\n"; } - $baseUrl = DI::baseUrl(); + $baseUrl = (string)DI::baseUrl(); - $uri = urlencode('acct:' . $profile['nickname'] . '@' . $baseUrl->getHost() . ($baseUrl->getPath() ? '/' . $baseUrl->getPath() : '')); + $uri = urlencode('acct:' . $profile['nickname'] . '@' . DI::baseUrl()->getHost() . (DI::baseUrl()->getPath() ? '/' . DI::baseUrl()->getPath() : '')); $page['htmlhead'] .= '' . "\r\n"; $page['htmlhead'] .= '' . "\r\n"; diff --git a/src/Module/OpenSearch.php b/src/Module/OpenSearch.php index f01baafada..7c44bc510e 100644 --- a/src/Module/OpenSearch.php +++ b/src/Module/OpenSearch.php @@ -40,7 +40,7 @@ class OpenSearch extends BaseModule protected function rawContent(array $request = []) { $hostname = DI::baseUrl()->getHost(); - $baseUrl = DI::baseUrl(); + $baseUrl = (string)DI::baseUrl(); /** @var DOMDocument $xml */ XML::fromArray([ diff --git a/src/Module/Register.php b/src/Module/Register.php index e5c5840d22..d26fb0a3d3 100644 --- a/src/Module/Register.php +++ b/src/Module/Register.php @@ -298,7 +298,7 @@ class Register extends BaseModule $user = $result['user']; - $base_url = DI::baseUrl(); + $base_url = (string)DI::baseUrl(); if ($netpublish && intval(DI::config()->get('config', 'register_policy')) !== self::APPROVE) { $url = $base_url . '/profile/' . $user['nickname']; diff --git a/src/Module/WellKnown/HostMeta.php b/src/Module/WellKnown/HostMeta.php index 75976ac36b..eadc9f221a 100644 --- a/src/Module/WellKnown/HostMeta.php +++ b/src/Module/WellKnown/HostMeta.php @@ -46,7 +46,7 @@ class HostMeta extends BaseModule $config->set('system', 'site_pubkey', $res['pubkey']); } - $domain = DI::baseUrl(); + $domain = (string)DI::baseUrl(); XML::fromArray([ 'XRD' => [ diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index c24c29feec..3d945180a5 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -330,7 +330,7 @@ class Transmitter return [ 'type' => 'Service', 'name' => App::PLATFORM . " '" . App::CODENAME . "' " . App::VERSION . '-' . DB_UPDATE_VERSION, - 'url' => DI::baseUrl() + 'url' => (string)DI::baseUrl() ]; } diff --git a/view/theme/frio/php/default.php b/view/theme/frio/php/default.php index 0677ff900a..a75207a206 100644 --- a/view/theme/frio/php/default.php +++ b/view/theme/frio/php/default.php @@ -45,7 +45,7 @@ $is_singleuser_class = $is_singleuser ? "is-singleuser" : "is-not-singleuser"; <?php if (!empty($page['title'])) echo $page['title'] ?> - + @@ -112,7 +112,7 @@ if (! function_exists('_js_in_foot')) { /** @purpose insert stuff in bottom of page */ $ssl_state = false; - $baseurl = DI::baseUrl(); + $baseurl = (string)DI::baseUrl(); $bottom['$baseurl'] = $baseurl; $tpl = Renderer::getMarkupTemplate('bottom.tpl'); diff --git a/view/theme/vier/theme.php b/view/theme/vier/theme.php index 91e050c667..95cc9bb1fc 100644 --- a/view/theme/vier/theme.php +++ b/view/theme/vier/theme.php @@ -137,8 +137,7 @@ function vier_community_info() $show_lastusers = get_vier_config("show_lastusers", 1); // get_baseurl - $url = DI::baseUrl(); - $aside['$url'] = $url; + $aside['$url'] = $url = (string)DI::baseUrl(); // community_profiles if ($show_profiles) { From f45dbf8b01076f3d4d8cd7b9fe55594b21b31bb9 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 12 May 2023 07:00:02 +0000 Subject: [PATCH 03/30] Fix: Contacts can now be searched with a leading @ again. --- src/Core/Search.php | 60 ++++++++++++++++++--------------------- src/Module/BaseSearch.php | 18 ++++++------ 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/Core/Search.php b/src/Core/Search.php index 45b64eb517..605e3fa229 100644 --- a/src/Core/Search.php +++ b/src/Core/Search.php @@ -55,40 +55,36 @@ class Search * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getContactsFromProbe(string $user): ResultList + public static function getContactsFromProbe(string $user): ?ResultList { - $emptyResultList = new ResultList(1, 0, 1); - - if ((filter_var($user, FILTER_VALIDATE_EMAIL) && Network::isEmailDomainValid($user)) || - (substr(Strings::normaliseLink($user), 0, 7) == 'http://')) { - - $user_data = Contact::getByURL($user); - if (empty($user_data)) { - return $emptyResultList; - } - - if (!in_array($user_data['network'], Protocol::FEDERATED)) { - return $emptyResultList; - } - - $contactDetails = Contact::getByURLForUser($user_data['url'] ?? '', DI::userSession()->getLocalUserId()); - - $result = new ContactResult( - $user_data['name'] ?? '', - $user_data['addr'] ?? '', - ($contactDetails['addr'] ?? '') ?: ($user_data['url'] ?? ''), - new Uri($user_data['url'] ?? ''), - $user_data['photo'] ?? '', - $user_data['network'] ?? '', - $contactDetails['cid'] ?? 0, - $user_data['id'] ?? 0, - $user_data['tags'] ?? '' - ); - - return new ResultList(1, 1, 1, [$result]); - } else { - return $emptyResultList; + if (empty(parse_url($user, PHP_URL_SCHEME)) && !(filter_var($user, FILTER_VALIDATE_EMAIL) || Network::isEmailDomainValid($user))) { + return null; } + + $user_data = Contact::getByURL($user); + if (empty($user_data)) { + return null; + } + + if (!Protocol::supportsProbe($user_data['network'])) { + return null; + } + + $contactDetails = Contact::getByURLForUser($user_data['url'], DI::userSession()->getLocalUserId()); + + $result = new ContactResult( + $user_data['name'], + $user_data['addr'], + $user_data['addr'] ?: $user_data['url'], + new Uri($user_data['url']), + $user_data['photo'], + $user_data['network'], + $contactDetails['cid'] ?? 0, + $user_data['id'], + $user_data['tags'] + ); + + return new ResultList(1, 1, 1, [$result]); } /** diff --git a/src/Module/BaseSearch.php b/src/Module/BaseSearch.php index 675deb8fb2..3593e8a632 100644 --- a/src/Module/BaseSearch.php +++ b/src/Module/BaseSearch.php @@ -91,14 +91,16 @@ class BaseSearch extends BaseModule $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage); - if ($localSearch && empty($results)) { - $pager->setItemsPerPage(80); - $results = Search::getContactsFromLocalDirectory($search, $type, $pager->getStart(), $pager->getItemsPerPage()); - } elseif (Search::getGlobalDirectory() && empty($results)) { - $results = Search::getContactsFromGlobalDirectory($search, $type, $pager->getPage()); - $pager->setItemsPerPage($results->getItemsPage()); - } else { - $results = new ResultList(); + if (empty($results)) { + if ($localSearch) { + $pager->setItemsPerPage(80); + $results = Search::getContactsFromLocalDirectory($search, $type, $pager->getStart(), $pager->getItemsPerPage()); + } elseif (Search::getGlobalDirectory()) { + $results = Search::getContactsFromGlobalDirectory($search, $type, $pager->getPage()); + $pager->setItemsPerPage($results->getItemsPage()); + } else { + $results = new ResultList(); + } } return self::printResult($results, $pager, $header); From f709ef96f722c5e82027bf1c6bf821557b015cd3 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 12 May 2023 07:58:28 +0000 Subject: [PATCH 04/30] Updated messages.po --- view/lang/C/messages.po | 102 ++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 4dd5e43a16..dbd3ad9517 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.06-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 06:34+0000\n" +"POT-Creation-Date: 2023-05-12 07:57+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -44,7 +44,7 @@ msgstr "" msgid "Item not found." msgstr "" -#: mod/item.php:435 mod/message.php:68 mod/message.php:114 mod/notes.php:45 +#: mod/item.php:435 mod/message.php:67 mod/message.php:113 mod/notes.php:45 #: mod/photos.php:152 mod/photos.php:669 src/Model/Event.php:522 #: src/Module/Attach.php:55 src/Module/BaseApi.php:99 #: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52 @@ -219,86 +219,86 @@ msgstr "" msgid "Your password has been changed at %s" msgstr "" -#: mod/message.php:46 mod/message.php:129 src/Content/Nav.php:319 +#: mod/message.php:46 mod/message.php:128 src/Content/Nav.php:319 msgid "New Message" msgstr "" -#: mod/message.php:83 src/Module/Profile/UnkMail.php:100 +#: mod/message.php:82 src/Module/Profile/UnkMail.php:100 msgid "No recipient selected." msgstr "" -#: mod/message.php:88 +#: mod/message.php:87 msgid "Unable to locate contact information." msgstr "" -#: mod/message.php:92 src/Module/Profile/UnkMail.php:106 +#: mod/message.php:91 src/Module/Profile/UnkMail.php:106 msgid "Message could not be sent." msgstr "" -#: mod/message.php:96 src/Module/Profile/UnkMail.php:109 +#: mod/message.php:95 src/Module/Profile/UnkMail.php:109 msgid "Message collection failure." msgstr "" -#: mod/message.php:123 src/Module/Notifications/Introductions.php:135 +#: mod/message.php:122 src/Module/Notifications/Introductions.php:135 #: src/Module/Notifications/Introductions.php:170 #: src/Module/Notifications/Notification.php:85 msgid "Discard" msgstr "" -#: mod/message.php:136 src/Content/Nav.php:316 view/theme/frio/theme.php:241 +#: mod/message.php:135 src/Content/Nav.php:316 view/theme/frio/theme.php:241 msgid "Messages" msgstr "" -#: mod/message.php:149 +#: mod/message.php:148 msgid "Conversation not found." msgstr "" -#: mod/message.php:154 +#: mod/message.php:153 msgid "Message was not deleted." msgstr "" -#: mod/message.php:169 +#: mod/message.php:168 msgid "Conversation was not removed." msgstr "" -#: mod/message.php:182 mod/message.php:287 src/Module/Profile/UnkMail.php:145 +#: mod/message.php:181 mod/message.php:286 src/Module/Profile/UnkMail.php:145 msgid "Please enter a link URL:" msgstr "" -#: mod/message.php:191 src/Module/Profile/UnkMail.php:151 +#: mod/message.php:190 src/Module/Profile/UnkMail.php:151 msgid "Send Private Message" msgstr "" -#: mod/message.php:192 mod/message.php:347 +#: mod/message.php:191 mod/message.php:346 msgid "To:" msgstr "" -#: mod/message.php:193 mod/message.php:348 +#: mod/message.php:192 mod/message.php:347 msgid "Subject:" msgstr "" -#: mod/message.php:197 mod/message.php:351 src/Module/Invite.php:171 +#: mod/message.php:196 mod/message.php:350 src/Module/Invite.php:171 msgid "Your message:" msgstr "" -#: mod/message.php:200 mod/message.php:355 src/Content/Conversation.php:360 +#: mod/message.php:199 mod/message.php:354 src/Content/Conversation.php:360 #: src/Module/Post/Edit.php:131 msgid "Upload photo" msgstr "" -#: mod/message.php:201 mod/message.php:356 src/Module/Post/Edit.php:135 +#: mod/message.php:200 mod/message.php:355 src/Module/Post/Edit.php:135 #: src/Module/Profile/UnkMail.php:153 msgid "Insert web link" msgstr "" -#: mod/message.php:202 mod/message.php:358 mod/photos.php:1291 +#: mod/message.php:201 mod/message.php:357 mod/photos.php:1291 #: src/Content/Conversation.php:390 src/Content/Conversation.php:734 #: src/Module/Item/Compose.php:205 src/Module/Post/Edit.php:145 #: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:550 msgid "Please wait" msgstr "" -#: mod/message.php:203 mod/message.php:357 mod/photos.php:702 +#: mod/message.php:202 mod/message.php:356 mod/photos.php:702 #: mod/photos.php:819 mod/photos.php:1097 mod/photos.php:1138 #: mod/photos.php:1194 mod/photos.php:1268 #: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132 @@ -317,52 +317,52 @@ msgstr "" msgid "Submit" msgstr "" -#: mod/message.php:224 +#: mod/message.php:223 msgid "No messages." msgstr "" -#: mod/message.php:280 +#: mod/message.php:279 msgid "Message not available." msgstr "" -#: mod/message.php:324 +#: mod/message.php:323 msgid "Delete message" msgstr "" -#: mod/message.php:326 mod/message.php:457 +#: mod/message.php:325 mod/message.php:456 msgid "D, d M Y - g:i A" msgstr "" -#: mod/message.php:341 mod/message.php:454 +#: mod/message.php:340 mod/message.php:453 msgid "Delete conversation" msgstr "" -#: mod/message.php:343 +#: mod/message.php:342 msgid "" "No secure communications available. You may be able to " "respond from the sender's profile page." msgstr "" -#: mod/message.php:346 +#: mod/message.php:345 msgid "Send Reply" msgstr "" -#: mod/message.php:428 +#: mod/message.php:427 #, php-format msgid "Unknown sender - %s" msgstr "" -#: mod/message.php:430 +#: mod/message.php:429 #, php-format msgid "You and %s" msgstr "" -#: mod/message.php:432 +#: mod/message.php:431 #, php-format msgid "%s and You" msgstr "" -#: mod/message.php:460 +#: mod/message.php:459 #, php-format msgid "%d message" msgid_plural "%d messages" @@ -1683,7 +1683,7 @@ msgstr "" #: src/Content/Item.php:439 src/Content/Widget.php:80 #: src/Model/Contact.php:1199 src/Model/Contact.php:1210 -#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:196 +#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195 msgid "Connect/Follow" msgstr "" @@ -1804,7 +1804,7 @@ msgstr "" #: src/Module/Settings/TwoFactor/AppSpecific.php:129 #: src/Module/Settings/TwoFactor/Index.php:118 #: src/Module/Settings/TwoFactor/Recovery.php:107 -#: src/Module/Settings/TwoFactor/Verify.php:146 view/theme/vier/theme.php:241 +#: src/Module/Settings/TwoFactor/Verify.php:146 view/theme/vier/theme.php:240 msgid "Help" msgstr "" @@ -2081,46 +2081,46 @@ msgid_plural "%d invitations available" msgstr[0] "" msgstr[1] "" -#: src/Content/Widget.php:78 view/theme/vier/theme.php:194 +#: src/Content/Widget.php:78 view/theme/vier/theme.php:193 msgid "Find People" msgstr "" -#: src/Content/Widget.php:79 view/theme/vier/theme.php:195 +#: src/Content/Widget.php:79 view/theme/vier/theme.php:194 msgid "Enter name or interest" msgstr "" -#: src/Content/Widget.php:81 view/theme/vier/theme.php:197 +#: src/Content/Widget.php:81 view/theme/vier/theme.php:196 msgid "Examples: Robert Morgenstein, Fishing" msgstr "" #: src/Content/Widget.php:82 src/Module/Contact.php:432 -#: src/Module/Directory.php:96 view/theme/vier/theme.php:198 +#: src/Module/Directory.php:96 view/theme/vier/theme.php:197 msgid "Find" msgstr "" #: src/Content/Widget.php:83 src/Module/Contact/Suggestions.php:73 -#: view/theme/vier/theme.php:199 +#: view/theme/vier/theme.php:198 msgid "Friend Suggestions" msgstr "" -#: src/Content/Widget.php:84 view/theme/vier/theme.php:200 +#: src/Content/Widget.php:84 view/theme/vier/theme.php:199 msgid "Similar Interests" msgstr "" -#: src/Content/Widget.php:85 view/theme/vier/theme.php:201 +#: src/Content/Widget.php:85 view/theme/vier/theme.php:200 msgid "Random Profile" msgstr "" -#: src/Content/Widget.php:86 view/theme/vier/theme.php:202 +#: src/Content/Widget.php:86 view/theme/vier/theme.php:201 msgid "Invite Friends" msgstr "" #: src/Content/Widget.php:87 src/Module/Directory.php:88 -#: view/theme/vier/theme.php:203 +#: view/theme/vier/theme.php:202 msgid "Global Directory" msgstr "" -#: src/Content/Widget.php:89 view/theme/vier/theme.php:205 +#: src/Content/Widget.php:89 view/theme/vier/theme.php:204 msgid "Local Directory" msgstr "" @@ -3272,7 +3272,7 @@ msgstr "" msgid "[no subject]" msgstr "" -#: src/Model/Photo.php:1188 src/Module/Media/Photo/Upload.php:171 +#: src/Model/Photo.php:1184 src/Module/Media/Photo/Upload.php:171 msgid "Wall Photos" msgstr "" @@ -5546,11 +5546,11 @@ msgstr "" msgid "Forum Search - %s" msgstr "" -#: src/Module/BaseSearch.php:121 src/Module/Contact/MatchInterests.php:139 +#: src/Module/BaseSearch.php:123 src/Module/Contact/MatchInterests.php:139 msgid "No matches" msgstr "" -#: src/Module/BaseSearch.php:147 +#: src/Module/BaseSearch.php:149 #, php-format msgid "" "%d result was filtered out because your node blocks the domain it is " @@ -11876,7 +11876,7 @@ msgstr "" msgid "Community Pages" msgstr "" -#: view/theme/vier/config.php:139 view/theme/vier/theme.php:149 +#: view/theme/vier/config.php:139 view/theme/vier/theme.php:148 msgid "Community Profiles" msgstr "" @@ -11884,7 +11884,7 @@ msgstr "" msgid "Help or @NewHere ?" msgstr "" -#: view/theme/vier/config.php:141 view/theme/vier/theme.php:320 +#: view/theme/vier/config.php:141 view/theme/vier/theme.php:319 msgid "Connect Services" msgstr "" @@ -11892,10 +11892,10 @@ msgstr "" msgid "Find Friends" msgstr "" -#: view/theme/vier/config.php:143 view/theme/vier/theme.php:176 +#: view/theme/vier/config.php:143 view/theme/vier/theme.php:175 msgid "Last users" msgstr "" -#: view/theme/vier/theme.php:235 +#: view/theme/vier/theme.php:234 msgid "Quick Start" msgstr "" From add913da27831d2b9a37cc4b936265411c6a7c9d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 12 May 2023 06:06:34 -0400 Subject: [PATCH 05/30] Remove misleading concatenation in XPath expression in Protocol\Feed - Variable could be directly interpolated - Address https://github.com/friendica/friendica/issues/13025#issuecomment-1543335001 - Address https://github.com/friendica/friendica/issues/13025#issuecomment-1545074703 --- src/Protocol/Feed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php index d4eeae61e7..fced3526d4 100644 --- a/src/Protocol/Feed.php +++ b/src/Protocol/Feed.php @@ -478,7 +478,7 @@ class Feed $attachments = []; - $enclosures = $xpath->query("enclosure|' . $atomns . ':link[@rel='enclosure']", $entry); + $enclosures = $xpath->query("enclosure|$atomns:link[@rel='enclosure']", $entry); if (!empty($enclosures)) { foreach ($enclosures as $enclosure) { $href = ''; From db5078d51c7b01a6beb7145c866e38d02b2eb284 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 21:05:22 +0200 Subject: [PATCH 06/30] Move "OPTIMIZE TABLE" to own Database function --- src/Database/Database.php | 13 +++++++++++++ src/Federation/Repository/DeliveryQueueItem.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index b1ea6c1e4f..b1e31bda74 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1758,6 +1758,19 @@ class Database return (['list' => $statelist, 'amount' => $processes]); } + /** + * Optimizes tables + * + * @param string $table a given table + * + * @return bool True, if successfully optimized, otherwise false + * @throws \Exception + */ + public function optimizeTable(string $table): bool + { + return $this->e("OPTIMIZE TABLE " . DBA::buildTableString([$table])) !== false; + } + /** * Fetch a database variable * diff --git a/src/Federation/Repository/DeliveryQueueItem.php b/src/Federation/Repository/DeliveryQueueItem.php index 815cf89b50..59afd5a3ad 100644 --- a/src/Federation/Repository/DeliveryQueueItem.php +++ b/src/Federation/Repository/DeliveryQueueItem.php @@ -108,6 +108,6 @@ final class DeliveryQueueItem extends \Friendica\BaseRepository public function optimizeStorage(): bool { - return $this->db->e("OPTIMIZE TABLE " . DBA::buildTableString([self::$table_name])); + return $this->db->optimizeTable(self::$table_name); } } From 557d0e3aeb0cddddb6fc063ba7540b31c1dc2f31 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:04:51 +0200 Subject: [PATCH 07/30] Add direct field possibility --- src/Database/Database.php | 12 ++++- src/Database/DatabaseException.php | 19 ++++---- .../Repository/DeliveryQueueItem.php | 14 +++--- tests/datasets/api.fixture.php | 9 ++++ tests/src/Database/DatabaseTest.php | 45 +++++++++++++++++++ 5 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 tests/src/Database/DatabaseTest.php diff --git a/src/Database/Database.php b/src/Database/Database.php index b1e31bda74..f4959bf7e9 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1357,6 +1357,15 @@ class Database } $fields = $this->castFields($table, $fields); + $direct_fields = []; + + foreach ($fields as $key => $value) { + if (is_numeric($key)) { + $direct_fields[] = $value; + unset($fields[$key]); + } + } + $table_string = DBA::buildTableString([$table]); @@ -1369,7 +1378,8 @@ class Database } $sql = "UPDATE " . $ignore . $table_string . " SET " - . implode(" = ?, ", array_map([DBA::class, 'quoteIdentifier'], array_keys($fields))) . " = ?" + . ((count($fields) > 0) ? implode(" = ?, ", array_map([DBA::class, 'quoteIdentifier'], array_keys($fields))) . " = ?" : "") + . ((count($direct_fields) > 0) ? ((count($fields) > 0) ? " , " : "") . implode(" , ", $direct_fields) : "") . $condition_string; // Combines the updated fields parameter values with the condition parameter values diff --git a/src/Database/DatabaseException.php b/src/Database/DatabaseException.php index ba1ccfce54..9473e58081 100644 --- a/src/Database/DatabaseException.php +++ b/src/Database/DatabaseException.php @@ -38,22 +38,25 @@ class DatabaseException extends Exception * * @link https://php.net/manual/en/exception.construct.php * - * @param string $message The Database error message. - * @param int $code The Database error code. - * @param string $query The Database error query. - * @param Throwable $previous [optional] The previous throwable used for the exception chaining. + * @param string $message The Database error message. + * @param int $code The Database error code. + * @param string $query The Database error query. + * @param Throwable|null $previous [optional] The previous throwable used for the exception chaining. */ public function __construct(string $message, int $code, string $query, Throwable $previous = null) { - parent::__construct($message, $code, $previous); $this->query = $query; + + parent::__construct(sprintf('"%s" at "%s"', $message, $query) , $code, $previous); } /** - * {@inheritDoc} + * Returns the query, which caused the exception + * + * @return string */ - public function __toString() + public function getQuery(): string { - return sprintf('Database error %d "%s" at "%s"', $this->message, $this->code, $this->query); + return $this->query; } } diff --git a/src/Federation/Repository/DeliveryQueueItem.php b/src/Federation/Repository/DeliveryQueueItem.php index 59afd5a3ad..5d5198adfb 100644 --- a/src/Federation/Repository/DeliveryQueueItem.php +++ b/src/Federation/Repository/DeliveryQueueItem.php @@ -88,7 +88,8 @@ final class DeliveryQueueItem extends \Friendica\BaseRepository public function remove(Entity\DeliveryQueueItem $deliveryQueueItem): bool { - return $this->db->delete(self::$table_name, ['uri-id' => $deliveryQueueItem->postUriId, 'gsid' => $deliveryQueueItem->targetServerId]); + return $this->db->delete(self::$table_name, ['uri-id' => $deliveryQueueItem->postUriId, + 'gsid' => $deliveryQueueItem->targetServerId]); } public function removeFailedByServerId(int $gsid, int $failedThreshold): bool @@ -98,12 +99,11 @@ final class DeliveryQueueItem extends \Friendica\BaseRepository public function incrementFailed(Entity\DeliveryQueueItem $deliveryQueueItem): bool { - return $this->db->e(" - UPDATE " . DBA::buildTableString([self::$table_name]) . " - SET `failed` = `failed` + 1 - WHERE `uri-id` = ? AND `gsid` = ?", - $deliveryQueueItem->postUriId, $deliveryQueueItem->targetServerId - ); + return $this->db->update(self::$table_name, ["`failed` = `failed` + 1"], + ["`uri-id` = ? AND `gsid` = ?", + $deliveryQueueItem->postUriId, + $deliveryQueueItem->targetServerId + ]); } public function optimizeStorage(): bool diff --git a/tests/datasets/api.fixture.php b/tests/datasets/api.fixture.php index b50f706251..f5b16f9c6e 100644 --- a/tests/datasets/api.fixture.php +++ b/tests/datasets/api.fixture.php @@ -35,6 +35,15 @@ return [ 'workerqueue', 'mail', 'post-delivery-data', + 'gserver' => [ + [ + 'url' => 'https://friendica.local', + 'nurl' => 'http://friendica.local', + 'register_policy' => 0, + 'registered-users' => 0, + 'network' => 'unkn', + ], + ], // Base test config to avoid notice messages 'user' => [ [ diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php new file mode 100644 index 0000000000..e95d655f19 --- /dev/null +++ b/tests/src/Database/DatabaseTest.php @@ -0,0 +1,45 @@ +setUpVfsDir(); + + parent::setUp(); + + $this->configCache = new Cache(); + $this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); + } + + public function testUpdateIncrease() + { + $db = $this->getDbInstance(); + + self::assertTrue($db->insert('config', ['cat' => 'test', 'k' => 'inc', 'v' => 0])); + self::assertTrue($db->update('config', ["`v` = `v` + 1"], ['cat' => 'test', 'k' => 'inc'])); + self::assertEquals(1, $db->selectFirst('config', ['v'], ['cat' => 'test', 'k' => 'inc'])['v']); + } + + public function testUpdateWithField() + { + $db = $this->getDbInstance(); + + self::assertEquals('https://friendica.local', $db->selectFirst('gserver', ['url'], ['nurl' => 'http://friendica.local'])['url']); + self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); + self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); + self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); + self::assertEquals(2, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); + self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` - 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); + self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); + } +} From 5be9c9dbaf7f6e606372b4e18656631719ee8107 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:14:52 +0200 Subject: [PATCH 08/30] Use optimized update statements --- src/Core/Worker/Cron.php | 4 +-- src/Database/DBA.php | 23 ++++++++++++ src/Database/Database.php | 18 ++++++++++ src/Model/Post/Delivery.php | 2 +- src/Model/Post/DeliveryData.php | 18 +++++----- src/Protocol/ActivityPub/Queue.php | 2 +- src/Worker/Cron.php | 11 +----- src/Worker/OptimizeTables.php | 56 +++++++++++++++--------------- 8 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src/Core/Worker/Cron.php b/src/Core/Worker/Cron.php index e9b77229bc..d0b915f87a 100644 --- a/src/Core/Worker/Cron.php +++ b/src/Core/Worker/Cron.php @@ -151,8 +151,8 @@ class Cron // We are acquiring the two locks from the worker to avoid locking problems if (DI::lock()->acquire(Worker::LOCK_PROCESS, 10)) { if (DI::lock()->acquire(Worker::LOCK_WORKER, 10)) { - DBA::e("OPTIMIZE TABLE `workerqueue`"); - DBA::e("OPTIMIZE TABLE `process`"); + DBA::optimizeTable('workerqueue'); + DBA::optimizeTable('process'); DI::lock()->release(Worker::LOCK_WORKER); } DI::lock()->release(Worker::LOCK_PROCESS); diff --git a/src/Database/DBA.php b/src/Database/DBA.php index d609f108eb..e730b298d5 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -821,6 +821,29 @@ class DBA return DI::dba()->processlist(); } + /** + * Optimizes tables + * + * @param string $table a given table + * + * @return bool True, if successfully optimized, otherwise false + * @throws \Exception + */ + public static function optimizeTable(string $table): bool + { + return DI::dba()->optimizeTable($table); + } + + /** + * Kill sleeping database processes + * + * @return void + */ + public static function deleteSleepingProcesses() + { + return DI::dba()->delete(); + } + /** * Fetch a database variable * diff --git a/src/Database/Database.php b/src/Database/Database.php index f4959bf7e9..f931169ceb 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1781,6 +1781,24 @@ class Database return $this->e("OPTIMIZE TABLE " . DBA::buildTableString([$table])) !== false; } + /** + * Kill sleeping database processes + * + * @return void + */ + public function deleteSleepingProcesses() + { + $processes = $this->p("SHOW FULL PROCESSLIST"); + while ($process = $this->fetch($processes)) { + if (($process['Command'] != 'Sleep') || ($process['Time'] < 300) || ($process['db'] != $this->databaseName())) { + continue; + } + + $this->e("KILL ?", $process['Id']); + } + $this->close($processes); + } + /** * Fetch a database variable * diff --git a/src/Model/Post/Delivery.php b/src/Model/Post/Delivery.php index 0e343e8718..c53014fa51 100644 --- a/src/Model/Post/Delivery.php +++ b/src/Model/Post/Delivery.php @@ -78,7 +78,7 @@ class Delivery */ public static function incrementFailed(int $uri_id, string $inbox) { - return DBA::e('UPDATE `post-delivery` SET `failed` = `failed` + 1 WHERE `uri-id` = ? AND `inbox-id` = ?', $uri_id, ItemURI::getIdByURI($inbox)); + return DBA::update('post-delivery', ["`failed` = `failed` + 1"], ['uri-id' => $uri_id, 'inbox-id' => ItemURI::getIdByURI($inbox)]); } public static function selectForInbox(string $inbox) diff --git a/src/Model/Post/DeliveryData.php b/src/Model/Post/DeliveryData.php index e87bb0e015..327e6f9121 100644 --- a/src/Model/Post/DeliveryData.php +++ b/src/Model/Post/DeliveryData.php @@ -82,27 +82,27 @@ class DeliveryData */ public static function incrementQueueDone(int $uri_id, int $protocol = 0) { - $sql = ''; + $increments = ["`queue_done` = `queue_done` + 1"]; switch ($protocol) { case self::ACTIVITYPUB: - $sql = ", `activitypub` = `activitypub` + 1"; + $increments[] = ["`activitypub` = `activitypub` + 1"]; break; case self::DFRN: - $sql = ", `dfrn` = `dfrn` + 1"; + $increments[] = ["`dfrn` = `dfrn` + 1"]; break; case self::LEGACY_DFRN: - $sql = ", `legacy_dfrn` = `legacy_dfrn` + 1"; + $increments[] = ["`legacy_dfrn` = `legacy_dfrn` + 1"]; break; case self::DIASPORA: - $sql = ", `diaspora` = `diaspora` + 1"; + $increments[] = ["`diaspora` = `diaspora` + 1"]; break; case self::OSTATUS: - $sql = ", `ostatus` = `ostatus` + 1"; + $increments[] = ["`ostatus` = `ostatus` + 1"]; break; } - return DBA::e('UPDATE `post-delivery-data` SET `queue_done` = `queue_done` + 1' . $sql . ' WHERE `uri-id` = ?', $uri_id); + return DBA::update('post-delivery-data', $increments, ['uri-id' => $uri_id]); } /** @@ -116,7 +116,7 @@ class DeliveryData */ public static function incrementQueueFailed(int $uri_id) { - return DBA::e('UPDATE `post-delivery-data` SET `queue_failed` = `queue_failed` + 1 WHERE `uri-id` = ?', $uri_id); + return DBA::update('post-delivery-data', ["`queue_failed` = `queue_failed` + 1"], ['uri-id' => $uri_id]); } /** @@ -129,7 +129,7 @@ class DeliveryData */ public static function incrementQueueCount(int $uri_id, int $increment = 1) { - return DBA::e('UPDATE `post-delivery-data` SET `queue_count` = `queue_count` + ? WHERE `uri-id` = ?', $increment, $uri_id); + return DBA::update('post-delivery-data', ["`queue_count` = `queue_count` + $increment"], ['uri-id' => $uri_id]); } /** diff --git a/src/Protocol/ActivityPub/Queue.php b/src/Protocol/ActivityPub/Queue.php index d77785fe67..beb8817bfb 100644 --- a/src/Protocol/ActivityPub/Queue.php +++ b/src/Protocol/ActivityPub/Queue.php @@ -312,7 +312,7 @@ class Queue // Optimizing this table only last seconds if (DI::config()->get('system', 'optimize_tables')) { Logger::info('Optimize start'); - DBA::e("OPTIMIZE TABLE `inbox-entry`"); + DBA::optimizeTable('inbox-entry'); Logger::info('Optimize end'); } } diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index 8c9ea58a10..73d158070e 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -163,15 +163,6 @@ class Cron { Logger::info('Looking for sleeping processes'); - $processes = DBA::p("SHOW FULL PROCESSLIST"); - while ($process = DBA::fetch($processes)) { - if (($process['Command'] != 'Sleep') || ($process['Time'] < 300) || ($process['db'] != DBA::databaseName())) { - continue; - } - - DBA::e("KILL ?", $process['Id']); - Logger::notice('Killed sleeping process', ['id' => $process['Id']]); - } - DBA::close($processes); + DBA::deleteSleepingProcesses(); } } diff --git a/src/Worker/OptimizeTables.php b/src/Worker/OptimizeTables.php index bb4cc9e482..784c72fde5 100644 --- a/src/Worker/OptimizeTables.php +++ b/src/Worker/OptimizeTables.php @@ -40,36 +40,36 @@ class OptimizeTables Logger::info('Optimize start'); - DBA::e("OPTIMIZE TABLE `cache`"); - DBA::e("OPTIMIZE TABLE `locks`"); - DBA::e("OPTIMIZE TABLE `oembed`"); - DBA::e("OPTIMIZE TABLE `parsed_url`"); - DBA::e("OPTIMIZE TABLE `session`"); + DBA::optimizeTable('cache'); + DBA::optimizeTable('locks'); + DBA::optimizeTable('oembed'); + DBA::optimizeTable('parsed_url'); + DBA::optimizeTable('session'); if (DI::config()->get('system', 'optimize_all_tables')) { - DBA::e("OPTIMIZE TABLE `apcontact`"); - DBA::e("OPTIMIZE TABLE `contact`"); - DBA::e("OPTIMIZE TABLE `contact-relation`"); - DBA::e("OPTIMIZE TABLE `conversation`"); - DBA::e("OPTIMIZE TABLE `diaspora-contact`"); - DBA::e("OPTIMIZE TABLE `diaspora-interaction`"); - DBA::e("OPTIMIZE TABLE `fcontact`"); - DBA::e("OPTIMIZE TABLE `gserver`"); - DBA::e("OPTIMIZE TABLE `gserver-tag`"); - DBA::e("OPTIMIZE TABLE `inbox-status`"); - DBA::e("OPTIMIZE TABLE `item-uri`"); - DBA::e("OPTIMIZE TABLE `notification`"); - DBA::e("OPTIMIZE TABLE `notify`"); - DBA::e("OPTIMIZE TABLE `photo`"); - DBA::e("OPTIMIZE TABLE `post`"); - DBA::e("OPTIMIZE TABLE `post-content`"); - DBA::e("OPTIMIZE TABLE `post-delivery-data`"); - DBA::e("OPTIMIZE TABLE `post-link`"); - DBA::e("OPTIMIZE TABLE `post-thread`"); - DBA::e("OPTIMIZE TABLE `post-thread-user`"); - DBA::e("OPTIMIZE TABLE `post-user`"); - DBA::e("OPTIMIZE TABLE `storage`"); - DBA::e("OPTIMIZE TABLE `tag`"); + DBA::optimizeTable('apcontact'); + DBA::optimizeTable('contact'); + DBA::optimizeTable('contact-relation'); + DBA::optimizeTable('conversation'); + DBA::optimizeTable('diaspora-contact'); + DBA::optimizeTable('diaspora-interaction'); + DBA::optimizeTable('fcontact'); + DBA::optimizeTable('gserver'); + DBA::optimizeTable('gserver-tag'); + DBA::optimizeTable('inbox-status'); + DBA::optimizeTable('item-uri'); + DBA::optimizeTable('notification'); + DBA::optimizeTable('notify'); + DBA::optimizeTable('photo'); + DBA::optimizeTable('post'); + DBA::optimizeTable('post-content'); + DBA::optimizeTable('post-delivery-data'); + DBA::optimizeTable('post-link'); + DBA::optimizeTable('post-thread'); + DBA::optimizeTable('post-thread-user'); + DBA::optimizeTable('post-user'); + DBA::optimizeTable('storage'); + DBA::optimizeTable('tag'); } Logger::info('Optimize end'); From 7bf2606120b08426b79b3d289766e04d294a7496 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:18:00 +0200 Subject: [PATCH 09/30] Update & fix --- src/Database/DBA.php | 2 +- tests/src/Database/DatabaseTest.php | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Database/DBA.php b/src/Database/DBA.php index e730b298d5..e29a940689 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -841,7 +841,7 @@ class DBA */ public static function deleteSleepingProcesses() { - return DI::dba()->delete(); + return DI::dba()->deleteSleepingProcesses(); } /** diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php index e95d655f19..85c673f070 100644 --- a/tests/src/Database/DatabaseTest.php +++ b/tests/src/Database/DatabaseTest.php @@ -21,6 +21,9 @@ class DatabaseTest extends FixtureTest $this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); } + /** + * Test, if directly updating a field is possible + */ public function testUpdateIncrease() { $db = $this->getDbInstance(); @@ -30,13 +33,18 @@ class DatabaseTest extends FixtureTest self::assertEquals(1, $db->selectFirst('config', ['v'], ['cat' => 'test', 'k' => 'inc'])['v']); } + /** + * Test if combining directly field updates with normal updates is working + */ public function testUpdateWithField() { $db = $this->getDbInstance(); self::assertEquals('https://friendica.local', $db->selectFirst('gserver', ['url'], ['nurl' => 'http://friendica.local'])['url']); - self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); + self::assertTrue($db->update('gserver', ['active-week-users' => 0], ['nurl' => 'http://friendica.local'])); + self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test', "`active-week-users` = `active-week-users` + 2"], ['nurl' => 'http://friendica.local'])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); + self::assertEquals(2, $db->selectFirst('gserver', ['active-week-users'], ['nurl' => 'http://friendica.local'])['active-week-users']); self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); self::assertEquals(2, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` - 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); From 9386adb1849057cb204446c6d161976e5b1d2dad Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:18:11 +0200 Subject: [PATCH 10/30] Update & fix --- src/Database/DBA.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Database/DBA.php b/src/Database/DBA.php index e29a940689..930e60472f 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -836,12 +836,10 @@ class DBA /** * Kill sleeping database processes - * - * @return void */ public static function deleteSleepingProcesses() { - return DI::dba()->deleteSleepingProcesses(); + DI::dba()->deleteSleepingProcesses(); } /** From 7f184bf6fabdd8167e9fb211c5278ffab9a9d647 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:27:29 +0200 Subject: [PATCH 11/30] Adapt & remove impossible code --- src/Core/Update.php | 14 -------------- src/Core/Worker/Cron.php | 2 +- src/Database/DBStructure.php | 15 +++++++++++++-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/Core/Update.php b/src/Core/Update.php index a4c5cf313e..2718d03d0c 100644 --- a/src/Core/Update.php +++ b/src/Core/Update.php @@ -129,20 +129,6 @@ class Update DI::lock()->release('dbupdate', true); } - if (!DBStructure::existsTable('config')) { - DBA::e(<<get('system', 'build'); if (empty($build)) { diff --git a/src/Core/Worker/Cron.php b/src/Core/Worker/Cron.php index d0b915f87a..dcb9fd3ab4 100644 --- a/src/Core/Worker/Cron.php +++ b/src/Core/Worker/Cron.php @@ -197,7 +197,7 @@ class Cron // Optimizing this table only last seconds if (DI::config()->get('system', 'optimize_tables')) { Logger::info('Optimize start'); - DBA::e("OPTIMIZE TABLE `post-delivery`"); + DBA::optimizeTable('post-delivery'); Logger::info('Optimize end'); } } diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index dc1e785a50..3141ca666b 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -57,6 +57,18 @@ class DBStructure echo DI::l10n()->t('The database version had been set to %s.', $version); } + /** + * Dops a specific table + * + * @param string $table the table name + * + * @return bool true if possible, otherwise false + */ + public static function dropTable(string $table): bool + { + return DBA::isResult(DBA::e('DROP TABLE ' . DBA::quoteIdentifier($table) . ';')); + } + /** * Drop unused tables * @@ -94,8 +106,7 @@ class DBStructure $sql = 'DROP TABLE ' . DBA::quoteIdentifier($table) . ';'; echo $sql . "\n"; - $result = DBA::e($sql); - if (!DBA::isResult($result)) { + if (!static::dropTable($table)) { self::printUpdateError($sql); } } else { From db4c9773b25cd49cd7238a6b90718c9f85fb625c Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:35:32 +0200 Subject: [PATCH 12/30] add license --- tests/src/Database/DatabaseTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php index 85c673f070..06aee5a929 100644 --- a/tests/src/Database/DatabaseTest.php +++ b/tests/src/Database/DatabaseTest.php @@ -1,4 +1,23 @@ . + * + */ namespace Friendica\Test\src\Database; From 8e208a0f41e779a333d0bc7f90b88c3728f18ea5 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:36:18 +0200 Subject: [PATCH 13/30] adhere PHP CC --- tests/src/Database/DatabaseTest.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php index 06aee5a929..6943f919db 100644 --- a/tests/src/Database/DatabaseTest.php +++ b/tests/src/Database/DatabaseTest.php @@ -36,7 +36,7 @@ class DatabaseTest extends FixtureTest parent::setUp(); - $this->configCache = new Cache(); + $this->configCache = new Cache(); $this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); } @@ -61,12 +61,22 @@ class DatabaseTest extends FixtureTest self::assertEquals('https://friendica.local', $db->selectFirst('gserver', ['url'], ['nurl' => 'http://friendica.local'])['url']); self::assertTrue($db->update('gserver', ['active-week-users' => 0], ['nurl' => 'http://friendica.local'])); - self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test', "`active-week-users` = `active-week-users` + 2"], ['nurl' => 'http://friendica.local'])); + self::assertTrue($db->update('gserver', + ['site_name' => 'test', "`registered-users` = `registered-users` + 1", + 'info' => 'another test', + "`active-week-users` = `active-week-users` + 2"], ['nurl' => 'http://friendica.local' + ])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); self::assertEquals(2, $db->selectFirst('gserver', ['active-week-users'], ['nurl' => 'http://friendica.local'])['active-week-users']); - self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` + 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); + self::assertTrue($db->update('gserver', + ['site_name' => 'test', "`registered-users` = `registered-users` + 1", + 'info' => 'another test'], ['nurl' => 'http://friendica.local' + ])); self::assertEquals(2, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); - self::assertTrue($db->update('gserver', ['site_name' => 'test', "`registered-users` = `registered-users` - 1", 'info' => 'another test'], ['nurl' => 'http://friendica.local'])); + self::assertTrue($db->update('gserver', + ['site_name' => 'test', "`registered-users` = `registered-users` - 1", + 'info' => 'another test'], ['nurl' => 'http://friendica.local' + ])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); } } From 60ea36259e71c0ea561961e3d59264500ca55599 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:42:56 +0200 Subject: [PATCH 14/30] PHP-CS ... --- tests/src/Database/DatabaseTest.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php index 6943f919db..26300852c8 100644 --- a/tests/src/Database/DatabaseTest.php +++ b/tests/src/Database/DatabaseTest.php @@ -61,22 +61,24 @@ class DatabaseTest extends FixtureTest self::assertEquals('https://friendica.local', $db->selectFirst('gserver', ['url'], ['nurl' => 'http://friendica.local'])['url']); self::assertTrue($db->update('gserver', ['active-week-users' => 0], ['nurl' => 'http://friendica.local'])); - self::assertTrue($db->update('gserver', - ['site_name' => 'test', "`registered-users` = `registered-users` + 1", - 'info' => 'another test', - "`active-week-users` = `active-week-users` + 2"], ['nurl' => 'http://friendica.local' - ])); + self::assertTrue($db->update('gserver', [ + 'site_name' => 'test', "`registered-users` = `registered-users` + 1", + 'info' => 'another test', + "`active-week-users` = `active-week-users` + 2" + ], [ + 'nurl' => 'http://friendica.local' + ])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); self::assertEquals(2, $db->selectFirst('gserver', ['active-week-users'], ['nurl' => 'http://friendica.local'])['active-week-users']); - self::assertTrue($db->update('gserver', - ['site_name' => 'test', "`registered-users` = `registered-users` + 1", - 'info' => 'another test'], ['nurl' => 'http://friendica.local' - ])); + self::assertTrue($db->update('gserver', [ + 'site_name' => 'test', "`registered-users` = `registered-users` + 1", + 'info' => 'another test'], ['nurl' => 'http://friendica.local' + ])); self::assertEquals(2, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); - self::assertTrue($db->update('gserver', - ['site_name' => 'test', "`registered-users` = `registered-users` - 1", - 'info' => 'another test'], ['nurl' => 'http://friendica.local' - ])); + self::assertTrue($db->update('gserver', [ + 'site_name' => 'test', "`registered-users` = `registered-users` - 1", + 'info' => 'another test'], ['nurl' => 'http://friendica.local' + ])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); } } From a74c0e86c990801c6ce61f3620f395818f6e341f Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 13 May 2023 22:46:10 +0200 Subject: [PATCH 15/30] PHP-CS ... --- tests/src/Database/DatabaseTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php index 26300852c8..47d4032209 100644 --- a/tests/src/Database/DatabaseTest.php +++ b/tests/src/Database/DatabaseTest.php @@ -72,12 +72,16 @@ class DatabaseTest extends FixtureTest self::assertEquals(2, $db->selectFirst('gserver', ['active-week-users'], ['nurl' => 'http://friendica.local'])['active-week-users']); self::assertTrue($db->update('gserver', [ 'site_name' => 'test', "`registered-users` = `registered-users` + 1", - 'info' => 'another test'], ['nurl' => 'http://friendica.local' + 'info' => 'another test' + ], [ + 'nurl' => 'http://friendica.local' ])); self::assertEquals(2, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); self::assertTrue($db->update('gserver', [ 'site_name' => 'test', "`registered-users` = `registered-users` - 1", - 'info' => 'another test'], ['nurl' => 'http://friendica.local' + 'info' => 'another test' + ], [ + 'nurl' => 'http://friendica.local' ])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); } From 8c2678c82f09131490226de1dc308f5212a7f7c7 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 14 May 2023 11:18:59 +0200 Subject: [PATCH 16/30] fixups --- src/Database/DBStructure.php | 2 +- src/Database/DatabaseException.php | 3 +-- .../Repository/DeliveryQueueItem.php | 18 +++++++++++------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index 3141ca666b..6291d0ffc4 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -58,7 +58,7 @@ class DBStructure } /** - * Dops a specific table + * Drops a specific table * * @param string $table the table name * diff --git a/src/Database/DatabaseException.php b/src/Database/DatabaseException.php index 9473e58081..8c99b9a7ef 100644 --- a/src/Database/DatabaseException.php +++ b/src/Database/DatabaseException.php @@ -45,9 +45,8 @@ class DatabaseException extends Exception */ public function __construct(string $message, int $code, string $query, Throwable $previous = null) { - $this->query = $query; - parent::__construct(sprintf('"%s" at "%s"', $message, $query) , $code, $previous); + $this->query = $query; } /** diff --git a/src/Federation/Repository/DeliveryQueueItem.php b/src/Federation/Repository/DeliveryQueueItem.php index 5d5198adfb..37d4ad84ca 100644 --- a/src/Federation/Repository/DeliveryQueueItem.php +++ b/src/Federation/Repository/DeliveryQueueItem.php @@ -88,8 +88,10 @@ final class DeliveryQueueItem extends \Friendica\BaseRepository public function remove(Entity\DeliveryQueueItem $deliveryQueueItem): bool { - return $this->db->delete(self::$table_name, ['uri-id' => $deliveryQueueItem->postUriId, - 'gsid' => $deliveryQueueItem->targetServerId]); + return $this->db->delete(self::$table_name, [ + 'uri-id' => $deliveryQueueItem->postUriId, + 'gsid' => $deliveryQueueItem->targetServerId + ]); } public function removeFailedByServerId(int $gsid, int $failedThreshold): bool @@ -99,11 +101,13 @@ final class DeliveryQueueItem extends \Friendica\BaseRepository public function incrementFailed(Entity\DeliveryQueueItem $deliveryQueueItem): bool { - return $this->db->update(self::$table_name, ["`failed` = `failed` + 1"], - ["`uri-id` = ? AND `gsid` = ?", - $deliveryQueueItem->postUriId, - $deliveryQueueItem->targetServerId - ]); + return $this->db->update(self::$table_name, [ + "`failed` = `failed` + 1" + ], [ + "`uri-id` = ? AND `gsid` = ?", + $deliveryQueueItem->postUriId, + $deliveryQueueItem->targetServerId + ]); } public function optimizeStorage(): bool From 30c4883aa60d1af0e17a27bb4eafa52543943d33 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 14 May 2023 09:13:26 -0400 Subject: [PATCH 17/30] Escape notification text in /notifications module - This was causing literal HTML display names to be interpreted in the page --- view/templates/notifications/notification.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/templates/notifications/notification.tpl b/view/templates/notifications/notification.tpl index b5c684cd82..dcee492baa 100644 --- a/view/templates/notifications/notification.tpl +++ b/view/templates/notifications/notification.tpl @@ -1,4 +1,4 @@ From 084cd955a232c9592e80265a342cc31fc6699e28 Mon Sep 17 00:00:00 2001 From: "S. Brusch" Date: Sun, 14 May 2023 15:38:47 +0200 Subject: [PATCH 18/30] fix for probe loop in case that network of contact has changed This fixes a loop of probes / contact updates where the network has been apup and for whatever reason is now feed. In this case the contact hasn't been updated and rescheduled with next_update as null resulting in a huge number of queries. The call to hasLocalData has been moved a bit up as it checks for values that otherwise would be emptied befare the call. Fixes #13037 --- src/Model/Contact.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index b06cbff875..648193b09c 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2682,6 +2682,8 @@ class Contact return true; } + $has_local_data = self::hasLocalData($id, $contact); + $uid = $contact['uid']; unset($contact['uid']); @@ -2702,9 +2704,7 @@ class Contact $updated = DateTimeFormat::utcNow(); - $has_local_data = self::hasLocalData($id, $contact); - - if (!Probe::isProbable($ret['network'])) { + if (!Probe::isProbable($ret['network']) && !Probe::isProbable($contact['network'])) { // Periodical checks are only done on federated contacts $failed_next_update = null; $success_next_update = null; From e998c059b6162286cf70686f61884fd249dfa38a Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 14 May 2023 20:31:20 +0200 Subject: [PATCH 19/30] Escape message for notifications --- .../Notifications/Entity/Notify.php | 2 +- .../Notifications/Entity/NotifyTest.php | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/src/Navigation/Notifications/Entity/NotifyTest.php diff --git a/src/Navigation/Notifications/Entity/Notify.php b/src/Navigation/Notifications/Entity/Notify.php index b7a007a2f0..45f450b1d1 100644 --- a/src/Navigation/Notifications/Entity/Notify.php +++ b/src/Navigation/Notifications/Entity/Notify.php @@ -134,6 +134,6 @@ class Notify extends BaseEntity */ public static function formatMessage(string $name, string $message): string { - return str_replace('{0}', '' . strip_tags(BBCode::convert($name)) . '', $message); + return str_replace('{0}', '' . strip_tags(BBCode::convert($name)) . '', htmlspecialchars($message)); } } diff --git a/tests/src/Navigation/Notifications/Entity/NotifyTest.php b/tests/src/Navigation/Notifications/Entity/NotifyTest.php new file mode 100644 index 0000000000..2021759e09 --- /dev/null +++ b/tests/src/Navigation/Notifications/Entity/NotifyTest.php @@ -0,0 +1,28 @@ + [ + 'name' => 'Whiskers', + 'message' => '{0} commented in the thread "If my username causes a pop up in a piece of software, that softwar…" from ', + 'assertion' => 'Whiskers commented in the thread "If my username causes a pop up in a piece of software, that softwar…" from <script>alert("Tek");</script>', + ], + ]; + } + + /** + * @dataProvider dataFormatNotify + */ + public function testFormatNotify(string $name, string $message, string $assertion) + { + self::assertEquals($assertion, Notify::formatMessage($name, $message)); + } +} From 10aec7120a64c5f248228b37514647a0a132eb65 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 14 May 2023 20:32:34 +0200 Subject: [PATCH 20/30] add license --- .../Notifications/Entity/NotifyTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/src/Navigation/Notifications/Entity/NotifyTest.php b/tests/src/Navigation/Notifications/Entity/NotifyTest.php index 2021759e09..8db0d3ae82 100644 --- a/tests/src/Navigation/Notifications/Entity/NotifyTest.php +++ b/tests/src/Navigation/Notifications/Entity/NotifyTest.php @@ -1,4 +1,23 @@ . + * + */ namespace Friendica\Test\src\Navigation\Notifications\Entity; From 07856ee6b4ef6c95bece8afa5937a4a8119a9d37 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 14 May 2023 20:34:42 +0200 Subject: [PATCH 21/30] PHP-CS --- tests/src/Navigation/Notifications/Entity/NotifyTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/Navigation/Notifications/Entity/NotifyTest.php b/tests/src/Navigation/Notifications/Entity/NotifyTest.php index 8db0d3ae82..fac8e48293 100644 --- a/tests/src/Navigation/Notifications/Entity/NotifyTest.php +++ b/tests/src/Navigation/Notifications/Entity/NotifyTest.php @@ -30,8 +30,8 @@ class NotifyTest extends FixtureTest { return [ 'xss-notify' => [ - 'name' => 'Whiskers', - 'message' => '{0} commented in the thread "If my username causes a pop up in a piece of software, that softwar…" from ', + 'name' => 'Whiskers', + 'message' => '{0} commented in the thread "If my username causes a pop up in a piece of software, that softwar…" from ', 'assertion' => 'Whiskers commented in the thread "If my username causes a pop up in a piece of software, that softwar…" from <script>alert("Tek");</script>', ], ]; From c21e6ab952efe175d09d8d748d8a9ff99b0f3fb9 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 14 May 2023 20:52:07 +0200 Subject: [PATCH 22/30] Fixup incrementQueue --- src/Model/Post/DeliveryData.php | 10 +++++----- tests/src/Database/DatabaseTest.php | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Model/Post/DeliveryData.php b/src/Model/Post/DeliveryData.php index 327e6f9121..c1aad730c7 100644 --- a/src/Model/Post/DeliveryData.php +++ b/src/Model/Post/DeliveryData.php @@ -86,19 +86,19 @@ class DeliveryData switch ($protocol) { case self::ACTIVITYPUB: - $increments[] = ["`activitypub` = `activitypub` + 1"]; + $increments[] = "`activitypub` = `activitypub` + 1"; break; case self::DFRN: - $increments[] = ["`dfrn` = `dfrn` + 1"]; + $increments[] = "`dfrn` = `dfrn` + 1"; break; case self::LEGACY_DFRN: - $increments[] = ["`legacy_dfrn` = `legacy_dfrn` + 1"]; + $increments[] = "`legacy_dfrn` = `legacy_dfrn` + 1"; break; case self::DIASPORA: - $increments[] = ["`diaspora` = `diaspora` + 1"]; + $increments[] = "`diaspora` = `diaspora` + 1"; break; case self::OSTATUS: - $increments[] = ["`ostatus` = `ostatus` + 1"]; + $increments[] = "`ostatus` = `ostatus` + 1"; break; } diff --git a/tests/src/Database/DatabaseTest.php b/tests/src/Database/DatabaseTest.php index 47d4032209..e906834614 100644 --- a/tests/src/Database/DatabaseTest.php +++ b/tests/src/Database/DatabaseTest.php @@ -85,4 +85,19 @@ class DatabaseTest extends FixtureTest ])); self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); } + + public function testUpdateWithArray() + { + $db = $this->getDbInstance(); + + self::assertTrue($db->update('gserver', ['active-week-users' => 0, 'registered-users' => 0], ['nurl' => 'http://friendica.local'])); + + $fields = ["`registered-users` = `registered-users` + 1"]; + $fields[] = "`active-week-users` = `active-week-users` + 2"; + + self::assertTrue($db->update('gserver', $fields, ['nurl' => 'http://friendica.local'])); + + self::assertEquals(2, $db->selectFirst('gserver', ['active-week-users'], ['nurl' => 'http://friendica.local'])['active-week-users']); + self::assertEquals(1, $db->selectFirst('gserver', ['registered-users'], ['nurl' => 'http://friendica.local'])['registered-users']); + } } From 5782caba92065921c93a6a03c9ef22042efb7669 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 15 May 2023 20:46:05 +0000 Subject: [PATCH 23/30] OWA: reworked code --- src/Module/Magic.php | 160 +++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 89 deletions(-) diff --git a/src/Module/Magic.php b/src/Module/Magic.php index 0f710b6a0b..f5f9b24a05 100644 --- a/src/Module/Magic.php +++ b/src/Module/Magic.php @@ -21,6 +21,7 @@ namespace Friendica\Module; +use Exception; use Friendica\App; use Friendica\BaseModule; use Friendica\Core\L10n; @@ -30,7 +31,6 @@ use Friendica\Database\Database; use Friendica\Model\Contact; use Friendica\Model\User; use Friendica\Network\HTTPClient\Capability\ICanSendHttpRequests; -use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Util\HTTPSignature; use Friendica\Util\Profiler; @@ -65,120 +65,102 @@ class Magic extends BaseModule protected function rawContent(array $request = []) { - $this->logger->info('magic module: invoked'); + if ($_SERVER['REQUEST_METHOD'] == 'HEAD') { + $this->logger->debug('Got a HEAD request'); + System::exit(); + } - $this->logger->debug('args', ['request' => $_REQUEST]); + $this->logger->debug('Invoked', ['request' => $request]); $addr = $request['addr'] ?? ''; $dest = $request['dest'] ?? ''; $bdest = $request['bdest'] ?? ''; $owa = intval($request['owa'] ?? 0); - $cid = 0; - // bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing + // bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing if (!empty($bdest)) { $dest = hex2bin($bdest); - $this->logger->info('bdest detected. ', ['dest' => $dest]); + $this->logger->debug('bdest detected', ['dest' => $dest]); } - if (!empty($addr)) { - $cid = Contact::getIdForURL($addr); - } elseif (!empty($dest)) { - $cid = Contact::getIdForURL($dest); - } - $this->logger->info('Contact ID: ', ['cid' => $cid]); - - $contact = false; - if (!$cid) { - $this->logger->info('No contact record found', $_REQUEST); + if (!empty($addr ?: $dest)) { + $contact = Contact::getByURL($addr ?: $dest); + } + + if (empty($contact)) { if (!$owa) { - // @TODO Finding a more elegant possibility to redirect to either internal or external URL + $this->logger->info('No contact record found, no oWA, redirecting to destination.', ['request' => $request, 'server' => $_SERVER, 'dest' => $dest]); $this->app->redirect($dest); } } else { - $contact = $this->dba->selectFirst('contact', ['id', 'nurl', 'url'], ['id' => $cid]); - // Redirect if the contact is already authenticated on this site. if ($this->app->getContactId() && strpos($contact['nurl'], Strings::normaliseLink($this->baseUrl)) !== false) { - $this->logger->info('Contact is already authenticated'); + $this->logger->info('Contact is already authenticated, redirecting to destination.', ['dest' => $dest]); System::externalRedirect($dest); } - $this->logger->info('Contact URL: ', ['url' => $contact['url']]); + $this->logger->debug('Contact found', ['url' => $contact['url']]); + } + + if (!$this->userSession->getLocalUserId() || !$owa) { + $this->logger->notice('Not logged in or not OWA, redirecting to destination.', ['uid' => $this->userSession->getLocalUserId(), 'owa' => $owa, 'dest' => $dest]); + $this->app->redirect($dest); } // OpenWebAuth - if ($this->userSession->getLocalUserId() && $owa) { - $this->logger->info('Checking OWA now'); - $user = User::getById($this->userSession->getLocalUserId()); + $owner = User::getOwnerDataById($this->userSession->getLocalUserId()); - $basepath = false; - if (!empty($contact)) { - $this->logger->info('Contact found - trying friendica style basepath extraction'); - // Extract the basepath - // NOTE: we need another solution because this does only work - // for friendica contacts :-/ . We should have the basepath - // of a contact also in the contact table. - $contact_url = $contact['url']; - if (!(strpos($contact_url, '/profile/') === false)) { - $exp = explode('/profile/', $contact['url']); - $basepath = $exp[0]; - $this->logger->info('Basepath: ', ['basepath' => $basepath]); - } else { - $this->logger->info('Not possible to extract basepath in friendica style'); - } - } - if (!$basepath) { - // For the rest of the OpenWebAuth-enabled Fediverse - $parsed = parse_url($dest); - $this->logger->info('Parsed URL: ', ['parsed URL' => $parsed]); - if (!$parsed) { - System::externalRedirect($dest); - } - $basepath = $parsed['scheme'] . '://' . $parsed['host'] . (isset($parsed['port']) ? ':' . $parsed['port'] : ''); - } - - $accept_headers = ['application/x-dfrn+json', 'application/x-zot+json']; - $header = [ - 'Accept' => $accept_headers, - 'X-Open-Web-Auth' => [Strings::getRandomHex()], - ]; - - // Create a header that is signed with the local users private key. - $header = HTTPSignature::createSig( - $header, - $user['prvkey'], - 'acct:' . $user['nickname'] . '@' . $this->baseUrl->getHost() . ($this->baseUrl->getPath() ? '/' . $this->baseUrl->getPath() : '') - ); - - $this->logger->info('Headers: ', ['headers' => $header]); - - // Try to get an authentication token from the other instance. - $curlResult = $this->httpClient->get($basepath . '/owa', HttpClientAccept::DEFAULT, [HttpClientOptions::HEADERS => $header, HttpClientOptions::ACCEPT_CONTENT => $accept_headers]); - - if ($curlResult->isSuccess()) { - $j = json_decode($curlResult->getBody(), true); - $this->logger->info('Curl result body: ', ['body' => $j]); - - if ($j['success']) { - $token = ''; - if ($j['encrypted_token']) { - // The token is encrypted. If the local user is really the one the other instance - // thinks he/she is, the token can be decrypted with the local users public key. - openssl_private_decrypt(Strings::base64UrlDecode($j['encrypted_token']), $token, $user['prvkey']); - } else { - $token = $j['token']; - } - $args = (strpbrk($dest, '?&') ? '&' : '?') . 'owt=' . $token; - - $this->logger->info('Redirecting', ['path' => $dest . $args]); - System::externalRedirect($dest . $args); - } - } + $gserver = $this->dba->selectFirst('gserver', ['url'], ['id' => $contact['gsid']]); + if (empty($gserver)) { + $this->logger->notice('Server not found, redirecting to destination.', ['gsid' => $contact['gsid'], 'dest' => $dest]); System::externalRedirect($dest); } - // @TODO Finding a more elegant possibility to redirect to either internal or external URL - $this->app->redirect($dest); + $basepath = $gserver['url']; + + $header = [ + 'Accept' => ['application/x-dfrn+json', 'application/x-zot+json'], + 'X-Open-Web-Auth' => [Strings::getRandomHex()], + ]; + + // Create a header that is signed with the local users private key. + $header = HTTPSignature::createSig( + $header, + $owner['prvkey'], + 'acct:' . $owner['addr'] + ); + + $this->logger->info('Fetch from remote system', ['basepath' => $basepath, 'headers' => $header]); + + // Try to get an authentication token from the other instance. + try { + $curlResult = $this->httpClient->request('get', $basepath . '/owa', [HttpClientOptions::HEADERS => $header]); + } catch (Exception $exception) { + $this->logger->notice('URL is invalid, redirecting to destination.', ['url' => $basepath, 'error' => $exception, 'dest' => $dest]); + System::externalRedirect($dest); + } + if (!$curlResult->isSuccess()) { + $this->logger->notice('OWA request failed, redirecting to destination.', ['returncode' => $curlResult->getReturnCode(), 'dest' => $dest]); + System::externalRedirect($dest); + } + + $j = json_decode($curlResult->getBody(), true); + if (empty($j) || !$j['success']) { + $this->logger->notice('Invalid JSON, redirecting to destination.', ['json' => $j, 'dest' => $dest]); + $this->app->redirect($dest); + } + + if ($j['encrypted_token']) { + // The token is encrypted. If the local user is really the one the other instance + // thinks they is, the token can be decrypted with the local users public key. + $token = ''; + openssl_private_decrypt(Strings::base64UrlDecode($j['encrypted_token']), $token, $owner['prvkey']); + } else { + $token = $j['token']; + } + $args = (strpbrk($dest, '?&') ? '&' : '?') . 'owt=' . $token; + + $this->logger->debug('Redirecting', ['path' => $dest . $args]); + System::externalRedirect($dest . $args); } } From f604ddacb5c668fc246741c56b64e2cae2f144bf Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Tue, 16 May 2023 13:54:46 +0200 Subject: [PATCH 24/30] Update src/Module/Magic.php Co-authored-by: Hypolite Petovan --- src/Module/Magic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module/Magic.php b/src/Module/Magic.php index f5f9b24a05..5276252de2 100644 --- a/src/Module/Magic.php +++ b/src/Module/Magic.php @@ -83,7 +83,7 @@ class Magic extends BaseModule $this->logger->debug('bdest detected', ['dest' => $dest]); } - if (!empty($addr ?: $dest)) { + if ($addr ?: $dest) { $contact = Contact::getByURL($addr ?: $dest); } From 2e46d64ea08333cd3ab163a6c5815df3a02cf897 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 17 May 2023 01:28:10 +0000 Subject: [PATCH 25/30] Replace "Probe::isProbable" with "Protocol::supportsProbe" --- src/Core/Protocol.php | 7 ++++++- src/Model/Contact.php | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Core/Protocol.php b/src/Core/Protocol.php index 9890b8f285..9776848757 100644 --- a/src/Core/Protocol.php +++ b/src/Core/Protocol.php @@ -315,7 +315,12 @@ class Protocol */ public static function supportsProbe($protocol): bool { - if (in_array($protocol, self::NATIVE_SUPPORT)) { + // "Mail" can only be probed for a specific user in a specific condition, so we are ignoring it here. + if ($protocol == self::MAIL) { + return false; + } + + if (in_array($protocol, array_merge(self::NATIVE_SUPPORT, [self::ZOT, self::PHANTOM]))) { return true; } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 648193b09c..d8f2448da2 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -361,7 +361,7 @@ class Contact $background_update = DI::config()->get('system', 'update_active_contacts') ? $contact['local-data'] : true; // Update the contact in the background if needed - if ($background_update && !self::isLocal($url) && Probe::isProbable($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { + if ($background_update && !self::isLocal($url) && Protocol::supportsProbe($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { try { UpdateContact::add(['priority' => Worker::PRIORITY_LOW, 'dont_fork' => true], $contact['id']); } catch (\InvalidArgumentException $e) { @@ -1279,7 +1279,7 @@ class Contact $background_update = DI::config()->get('system', 'update_active_contacts') ? $contact['local-data'] : true; - if ($background_update && !self::isLocal($url) && Probe::isProbable($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { + if ($background_update && !self::isLocal($url) && Protocol::supportsProbe($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { try { UpdateContact::add(['priority' => Worker::PRIORITY_LOW, 'dont_fork' => true], $contact['id']); } catch (\InvalidArgumentException $e) { @@ -2704,7 +2704,7 @@ class Contact $updated = DateTimeFormat::utcNow(); - if (!Probe::isProbable($ret['network']) && !Probe::isProbable($contact['network'])) { + if (!Protocol::supportsProbe($ret['network']) && !Protocol::supportsProbe($contact['network'])) { // Periodical checks are only done on federated contacts $failed_next_update = null; $success_next_update = null; @@ -3596,7 +3596,7 @@ class Contact if (empty($contact['id']) && Network::isValidHttpUrl($url)) { Worker::add(Worker::PRIORITY_LOW, 'AddContact', 0, $url); ++$added; - } elseif (!empty($contact['network']) && Probe::isProbable($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { + } elseif (!empty($contact['network']) && Protocol::supportsProbe($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { try { UpdateContact::add(['priority' => Worker::PRIORITY_LOW, 'dont_fork' => true], $contact['id']); ++$updated; From e23a7383f81ec31deca87f2a57128c25be3a484f Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 17 May 2023 02:23:56 +0000 Subject: [PATCH 26/30] Only probr when needed, search local if nothing was found --- src/Core/Search.php | 24 +++++++++++++++--------- src/Module/BaseSearch.php | 34 ++++++++++++++++------------------ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/Core/Search.php b/src/Core/Search.php index 605e3fa229..a226784e2c 100644 --- a/src/Core/Search.php +++ b/src/Core/Search.php @@ -55,19 +55,25 @@ class Search * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getContactsFromProbe(string $user): ?ResultList + public static function getContactsFromProbe(string $user, $only_forum = false): ResultList { + $emptyResultList = new ResultList(); + if (empty(parse_url($user, PHP_URL_SCHEME)) && !(filter_var($user, FILTER_VALIDATE_EMAIL) || Network::isEmailDomainValid($user))) { - return null; + return $emptyResultList; } - + $user_data = Contact::getByURL($user); if (empty($user_data)) { - return null; + return $emptyResultList; + } + + if ($only_forum && ($user_data['contact-type'] != Contact::TYPE_COMMUNITY)) { + return $emptyResultList; } if (!Protocol::supportsProbe($user_data['network'])) { - return null; + return $emptyResultList; } $contactDetails = Contact::getByURLForUser($user_data['url'], DI::userSession()->getLocalUserId()); @@ -125,8 +131,8 @@ class Search $resultList = new ResultList( ($results['page'] ?? 0) ?: 1, - $results['count'] ?? 0, - ($results['itemsperpage'] ?? 0) ?: 30 + ($results['itemsperpage'] ?? 0) ?: 30, + $results['count'] ?? 0 ); $profiles = $results['profiles'] ?? []; @@ -170,7 +176,7 @@ class Search $contacts = Contact::searchByName($search, $type == self::TYPE_FORUM ? 'community' : '', true); - $resultList = new ResultList($start, $itemPage, count($contacts)); + $resultList = new ResultList($start, count($contacts), $itemPage); foreach ($contacts as $contact) { $result = new ContactResult( @@ -280,4 +286,4 @@ class Search return 'search?q=' . urlencode($search); } } -} +} \ No newline at end of file diff --git a/src/Module/BaseSearch.php b/src/Module/BaseSearch.php index 3593e8a632..262ec94a20 100644 --- a/src/Module/BaseSearch.php +++ b/src/Module/BaseSearch.php @@ -23,6 +23,7 @@ namespace Friendica\Module; use Friendica\BaseModule; use Friendica\Content\Pager; +use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Search; use Friendica\DI; @@ -62,18 +63,13 @@ class BaseSearch extends BaseModule } $header = ''; + $results = new ResultList(); if (strpos($search, '@') === 0) { $search = trim(substr($search, 1)); $type = Search::TYPE_PEOPLE; $header = DI::l10n()->t('People Search - %s', $search); - - if (strrpos($search, '@') > 0) { - $results = Search::getContactsFromProbe(Network::convertToIdn($search)); - } - } - - if (strpos($search, '!') === 0) { + } elseif (strpos($search, '!') === 0) { $search = trim(substr($search, 1)); $type = Search::TYPE_FORUM; $header = DI::l10n()->t('Forum Search - %s', $search); @@ -91,16 +87,18 @@ class BaseSearch extends BaseModule $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage); - if (empty($results)) { - if ($localSearch) { - $pager->setItemsPerPage(80); - $results = Search::getContactsFromLocalDirectory($search, $type, $pager->getStart(), $pager->getItemsPerPage()); - } elseif (Search::getGlobalDirectory()) { - $results = Search::getContactsFromGlobalDirectory($search, $type, $pager->getPage()); - $pager->setItemsPerPage($results->getItemsPage()); - } else { - $results = new ResultList(); - } + if (!$results->getTotal() && !$localSearch && Search::getGlobalDirectory()) { + $results = Search::getContactsFromGlobalDirectory($search, $type, $pager->getPage()); + $pager->setItemsPerPage($results->getItemsPage()); + } + + if (!$results->getTotal()) { + $pager->setItemsPerPage(80); + $results = Search::getContactsFromLocalDirectory($search, $type, $pager->getStart(), $pager->getItemsPerPage()); + } + + if (!$results->getTotal()) { + $results = Search::getContactsFromProbe(Network::convertToIdn($search), $type == Search::TYPE_FORUM); } return self::printResult($results, $pager, $header); @@ -153,4 +151,4 @@ class BaseSearch extends BaseModule '$paginate' => $pager->renderFull($results->getTotal()), ]); } -} +} \ No newline at end of file From 3f66ecf3befe3233cd731eca5701a23dd6e0003e Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 17 May 2023 02:38:47 +0000 Subject: [PATCH 27/30] Reverted accidentally reversed parameter order --- src/Core/Search.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Core/Search.php b/src/Core/Search.php index a226784e2c..8b114a468c 100644 --- a/src/Core/Search.php +++ b/src/Core/Search.php @@ -131,8 +131,8 @@ class Search $resultList = new ResultList( ($results['page'] ?? 0) ?: 1, - ($results['itemsperpage'] ?? 0) ?: 30, - $results['count'] ?? 0 + $results['count'] ?? 0, + ($results['itemsperpage'] ?? 0) ?: 30 ); $profiles = $results['profiles'] ?? []; From 8b264c38fe73bbbf724cd12e4233fe831248f526 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 17 May 2023 08:17:23 +0000 Subject: [PATCH 28/30] Unify the heading levels --- src/Content/Text/BBCode.php | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index c597554455..89bd802027 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1403,12 +1403,32 @@ class BBCode } // Check for headers - $text = preg_replace("(\[h1\](.*?)\[\/h1\])ism", '

$1

', $text); - $text = preg_replace("(\[h2\](.*?)\[\/h2\])ism", '

$1

', $text); - $text = preg_replace("(\[h3\](.*?)\[\/h3\])ism", '

$1

', $text); - $text = preg_replace("(\[h4\](.*?)\[\/h4\])ism", '

$1

', $text); - $text = preg_replace("(\[h5\](.*?)\[\/h5\])ism", '

$1

', $text); - $text = preg_replace("(\[h6\](.*?)\[\/h6\])ism", '

$1

', $text); + + if ($simple_html == self::INTERNAL) { + //Ensure to always start with

if possible + $heading_count = 0; + for ($level = 6; $level > 0; $level--) { + if (preg_match("(\[h$level\].*?\[\/h$level\])ism", $text)) { + $heading_count++; + } + } + if ($heading_count > 0) { + $heading = min($heading_count + 3, 6); + for ($level = 6; $level > 0; $level--) { + if (preg_match("(\[h$level\].*?\[\/h$level\])ism", $text)) { + $text = preg_replace("(\[h$level\](.*?)\[\/h$level\])ism", "

$1

", $text); + $heading--; + } + } + } + } else { + $text = preg_replace("(\[h1\](.*?)\[\/h1\])ism", '

$1

', $text); + $text = preg_replace("(\[h2\](.*?)\[\/h2\])ism", '

$1

', $text); + $text = preg_replace("(\[h3\](.*?)\[\/h3\])ism", '

$1

', $text); + $text = preg_replace("(\[h4\](.*?)\[\/h4\])ism", '

$1

', $text); + $text = preg_replace("(\[h5\](.*?)\[\/h5\])ism", '

$1

', $text); + $text = preg_replace("(\[h6\](.*?)\[\/h6\])ism", '

$1

', $text); + } // Check for paragraph $text = preg_replace("(\[p\](.*?)\[\/p\])ism", '

$1

', $text); From a198108222d26cfa4a899393fb48c8a91a0c1f12 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 17 May 2023 09:01:52 +0000 Subject: [PATCH 29/30] Fix tests --- tests/src/Content/Text/BBCodeTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php index 74d34f5a5e..889b12caa2 100644 --- a/tests/src/Content/Text/BBCodeTest.php +++ b/tests/src/Content/Text/BBCodeTest.php @@ -259,12 +259,12 @@ Karl Marx - Die ursprüngliche Akkumulation 'text' => '[emoji=https://fedi.underscore.world/emoji/custom/custom/heart_nb.png]:heart_nb:[/emoji]', ], 'task-12900-multiple-paragraphs' => [ - 'expectedHTML' => '

Header

  • One
  • Two

This is a paragraph
with a line feed.

Second Chapter

', - 'text' => "[h1]Header[/h1][ul][*]One[*]Two[/ul]\n\nThis is a paragraph\nwith a line feed.\n\nSecond Chapter", + 'expectedHTML' => '

Header

  • One
  • Two

This is a paragraph
with a line feed.

Second Chapter

', + 'text' => "[h4]Header[/h4][ul][*]One[*]Two[/ul]\n\nThis is a paragraph\nwith a line feed.\n\nSecond Chapter", ], 'task-12900-header-with-paragraphs' => [ - 'expectedHTML' => '

Header

Some Chapter

', - 'text' => '[h1]Header[/h1]Some Chapter', + 'expectedHTML' => '

Header

Some Chapter

', + 'text' => '[h4]Header[/h4]Some Chapter', ], 'bug-12842-ul-newlines' => [ 'expectedHTML' => '

This is:

  • some
  • amazing
  • list
', From 3dbbbb69e428d1aa874ea97bf88020e05047f20f Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 17 May 2023 14:28:40 +0000 Subject: [PATCH 30/30] Long refresh periods for connector networks --- src/Model/Contact.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index d8f2448da2..99edf3fe2b 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2711,9 +2711,13 @@ class Contact } elseif ($has_local_data) { $failed_next_update = GServer::getNextUpdateDate(false, $created, $last_update, !in_array($contact['network'], Protocol::FEDERATED)); $success_next_update = GServer::getNextUpdateDate(true, $created, $last_update, !in_array($contact['network'], Protocol::FEDERATED)); - } else { + } elseif (in_array($ret['network'], array_merge(Protocol::NATIVE_SUPPORT, [Protocol::ZOT, Protocol::PHANTOM]))) { $failed_next_update = DateTimeFormat::utc('now +6 month'); $success_next_update = DateTimeFormat::utc('now +1 month'); + } else { + // We don't check connector networks very often to not run into API rate limits + $failed_next_update = DateTimeFormat::utc('now +12 month'); + $success_next_update = DateTimeFormat::utc('now +12 month'); } if (Strings::normaliseLink($contact['url']) != Strings::normaliseLink($ret['url'])) {