From 7122d728716dcd10ff8385800d8de883e71e26d7 Mon Sep 17 00:00:00 2001 From: nnsrymni <82746801+nnsrymni@users.noreply.github.com> Date: Thu, 29 Dec 2022 09:15:05 +0900 Subject: [PATCH 01/27] JA translation update --- view/lang/ja/messages.po | 4 ++-- view/lang/ja/strings.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/view/lang/ja/messages.po b/view/lang/ja/messages.po index 2b3ecfe4e..d98e4d959 100644 --- a/view/lang/ja/messages.po +++ b/view/lang/ja/messages.po @@ -3030,7 +3030,7 @@ msgstr "フォロワー" #: src/BaseModule.php:219 src/Content/Widget.php:239 #: src/Module/Contact.php:861 msgid "Following" -msgstr "以下" +msgstr "フォロー中" #: src/BaseModule.php:224 src/Content/Widget.php:240 #: src/Module/Contact.php:862 @@ -3810,7 +3810,7 @@ msgstr "" #: src/Content/Widget/CalendarExport.php:54 msgid "Export" -msgstr "輸出する" +msgstr "エクスポート" #: src/Content/Widget/CalendarExport.php:55 msgid "Export calendar as ical" diff --git a/view/lang/ja/strings.php b/view/lang/ja/strings.php index 454b3bbf5..a1d2803e1 100644 --- a/view/lang/ja/strings.php +++ b/view/lang/ja/strings.php @@ -675,7 +675,7 @@ $a->strings['Page not found.'] = 'ページが見つかりません。'; $a->strings['The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it.'] = 'フォームセキュリティトークンが正しくありませんでした。これは、フォームを送信する前にフォームが長時間(3時間以上)開かれたために発生した可能性があります。'; $a->strings['All contacts'] = 'すべてのコンタクト'; $a->strings['Followers'] = 'フォロワー'; -$a->strings['Following'] = '以下'; +$a->strings['Following'] = 'フォロー中'; $a->strings['Mutual friends'] = '共通の友人'; $a->strings['Could not find any unarchived contact entry for this URL (%s)'] = 'このURL( %s )のアーカイブされていないコンタクトエントリが見つかりませんでした'; $a->strings['The contact entries have been archived'] = 'コンタクトエントリがアーカイブされました'; @@ -837,7 +837,7 @@ $a->strings['%d contact in common'] = [ ]; $a->strings['Archives'] = 'アーカイブ'; $a->strings['News'] = 'ニュース'; -$a->strings['Export'] = '輸出する'; +$a->strings['Export'] = 'エクスポート'; $a->strings['Export calendar as ical'] = 'カレンダーをicalとしてエクスポート'; $a->strings['Export calendar as csv'] = 'カレンダーをcsvとしてエクスポート'; $a->strings['No contacts'] = 'コンタクトなし'; From 501b98ec09c089aecaf75672e2e230abd98ecbb6 Mon Sep 17 00:00:00 2001 From: Hannes Heute <5753419+haheute@users.noreply.github.com> Date: Thu, 29 Dec 2022 14:45:51 +0100 Subject: [PATCH 02/27] fixed the typo --- doc/tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools.md b/doc/tools.md index 1c3b8e119..fac1f4b39 100644 --- a/doc/tools.md +++ b/doc/tools.md @@ -51,7 +51,7 @@ In */etc/fail2ban/jail.local* create a section for Friendica: bantime = 900 filter = friendica port = http,https - logpath = /var/log/friend.log + logpath = /var/log/friendica.log logencoding = utf-8 And create a filter definition in */etc/fail2ban/filter.d/friendica.conf*: From 6793e043657d090a20b892f5df5fa855a59c3bf8 Mon Sep 17 00:00:00 2001 From: Hannes Heute <5753419+haheute@users.noreply.github.com> Date: Thu, 29 Dec 2022 18:28:01 +0100 Subject: [PATCH 03/27] add link to direct message heading --- view/theme/frio/templates/mail_list.tpl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/view/theme/frio/templates/mail_list.tpl b/view/theme/frio/templates/mail_list.tpl index bfc21aaba..264c689c9 100644 --- a/view/theme/frio/templates/mail_list.tpl +++ b/view/theme/frio/templates/mail_list.tpl @@ -11,7 +11,15 @@
{{$ago}}
-

{{$from_name}}

+

+ {{if !$seen}} + + {{/if}} + {{$from_name}} + {{if !$seen}} + + {{/if}} +

{{if !$seen}} @@ -21,7 +29,8 @@ {{if !$seen}} {{/if}} -
+ +
From 1dbbafa1af0393b8ab05d0bfc52935a6c1fd71fd Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Thu, 29 Dec 2022 19:39:27 +0100 Subject: [PATCH 04/27] Allow adding local contacts via console --- src/Console/Contact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Console/Contact.php b/src/Console/Contact.php index 37f3f056e..d5f3c9923 100644 --- a/src/Console/Contact.php +++ b/src/Console/Contact.php @@ -157,7 +157,7 @@ HELP; $url = Probe::cleanURI($url); - $contact = ContactModel::getByURLForUser($url, $user['uid']); + $contact = ContactModel::getByURL($url, null, [], $user['uid']); if (!empty($contact)) { throw new RuntimeException('Contact already exists'); } From 119be35a79788713d85cc1d255b98b0619cf5193 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Thu, 29 Dec 2022 19:42:22 +0100 Subject: [PATCH 05/27] Return network match failure in error message instead of logging --- src/Model/Contact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index e928df7f6..bf90edcd4 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2953,7 +2953,7 @@ class Contact } if (($network != '') && ($ret['network'] != $network)) { - Logger::notice('Expected network ' . $network . ' does not match actual network ' . $ret['network']); + $result['message'] = DI::l10n()->t('Expected network %s does not match actual network %s', $network, $ret['network']); return $result; } From 9c33074bdcfb9b8ef9c43f2485ff24dd08b2a506 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Thu, 29 Dec 2022 19:44:49 +0100 Subject: [PATCH 06/27] Allow HTTP requests to hosts in local hosts file --- src/Network/HTTPClient/Client/HttpClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/HTTPClient/Client/HttpClient.php b/src/Network/HTTPClient/Client/HttpClient.php index 32a1a22fc..76af18497 100644 --- a/src/Network/HTTPClient/Client/HttpClient.php +++ b/src/Network/HTTPClient/Client/HttpClient.php @@ -69,7 +69,7 @@ class HttpClient implements ICanSendHttpRequests $this->logger->debug('Request start.', ['url' => $url, 'method' => $method]); $host = parse_url($url, PHP_URL_HOST); - if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A + DNS_AAAA)) { + if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A + DNS_AAAA) && !gethostbyname($host)) { $this->logger->debug('URL cannot be resolved.', ['url' => $url, 'callstack' => System::callstack(20)]); $this->profiler->stopRecording(); return CurlResult::createErrorCurl($url); From c0a874b8d4c49ef4c07328030a06693411f39452 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Thu, 29 Dec 2022 20:07:18 +0100 Subject: [PATCH 07/27] Update translation file with new error message --- view/lang/C/messages.po | 149 +++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 72 deletions(-) diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 9c17846db..ecc50e6db 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.03-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-28 00:37-0500\n" +"POT-Creation-Date: 2022-12-29 20:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1539,31 +1539,31 @@ msgstr "" msgid "Follow Thread" msgstr "" -#: src/Content/Item.php:387 src/Model/Contact.php:1198 +#: src/Content/Item.php:387 src/Model/Contact.php:1200 msgid "View Status" msgstr "" -#: src/Content/Item.php:388 src/Content/Item.php:406 src/Model/Contact.php:1142 -#: src/Model/Contact.php:1190 src/Model/Contact.php:1199 +#: src/Content/Item.php:388 src/Content/Item.php:406 src/Model/Contact.php:1144 +#: src/Model/Contact.php:1192 src/Model/Contact.php:1201 #: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:234 msgid "View Profile" msgstr "" -#: src/Content/Item.php:389 src/Model/Contact.php:1200 +#: src/Content/Item.php:389 src/Model/Contact.php:1202 msgid "View Photos" msgstr "" -#: src/Content/Item.php:390 src/Model/Contact.php:1191 -#: src/Model/Contact.php:1201 +#: src/Content/Item.php:390 src/Model/Contact.php:1193 +#: src/Model/Contact.php:1203 msgid "Network Posts" msgstr "" -#: src/Content/Item.php:391 src/Model/Contact.php:1192 -#: src/Model/Contact.php:1202 +#: src/Content/Item.php:391 src/Model/Contact.php:1194 +#: src/Model/Contact.php:1204 msgid "View Contact" msgstr "" -#: src/Content/Item.php:392 src/Model/Contact.php:1203 +#: src/Content/Item.php:392 src/Model/Contact.php:1205 msgid "Send PM" msgstr "" @@ -1588,7 +1588,7 @@ msgid "Languages" msgstr "" #: src/Content/Item.php:403 src/Content/Widget.php:80 -#: src/Model/Contact.php:1193 src/Model/Contact.php:1204 +#: src/Model/Contact.php:1195 src/Model/Contact.php:1206 #: src/Module/Contact/Follow.php:166 view/theme/vier/theme.php:196 msgid "Connect/Follow" msgstr "" @@ -2081,7 +2081,7 @@ msgstr "" msgid "Organisations" msgstr "" -#: src/Content/Widget.php:523 src/Model/Contact.php:1644 +#: src/Content/Widget.php:523 src/Model/Contact.php:1648 msgid "News" msgstr "" @@ -2162,8 +2162,8 @@ msgstr "" msgid "Network:" msgstr "" -#: src/Content/Widget/VCard.php:111 src/Model/Contact.php:1194 -#: src/Model/Contact.php:1205 src/Model/Profile.php:465 +#: src/Content/Widget/VCard.php:111 src/Model/Contact.php:1196 +#: src/Model/Contact.php:1207 src/Model/Profile.php:465 #: src/Module/Contact/Profile.php:419 msgid "Unfollow" msgstr "" @@ -2428,8 +2428,8 @@ msgstr "" #: src/Core/Installer.php:514 msgid "" -"The web installer needs to be able to create a file called \"local.config.php" -"\" in the \"config\" folder of your web server and it is unable to do so." +"The web installer needs to be able to create a file called \"local.config." +"php\" in the \"config\" folder of your web server and it is unable to do so." msgstr "" #: src/Core/Installer.php:515 @@ -2866,77 +2866,82 @@ msgstr "" msgid "Legacy module file not found: %s" msgstr "" -#: src/Model/Contact.php:1211 src/Module/Moderation/Users/Pending.php:102 +#: src/Model/Contact.php:1213 src/Module/Moderation/Users/Pending.php:102 #: src/Module/Notifications/Introductions.php:132 #: src/Module/Notifications/Introductions.php:204 msgid "Approve" msgstr "" -#: src/Model/Contact.php:1640 +#: src/Model/Contact.php:1644 msgid "Organisation" msgstr "" -#: src/Model/Contact.php:1648 +#: src/Model/Contact.php:1652 msgid "Forum" msgstr "" -#: src/Model/Contact.php:2877 +#: src/Model/Contact.php:2919 msgid "Disallowed profile URL." msgstr "" -#: src/Model/Contact.php:2882 src/Module/Friendica.php:82 +#: src/Model/Contact.php:2924 src/Module/Friendica.php:82 msgid "Blocked domain" msgstr "" -#: src/Model/Contact.php:2887 +#: src/Model/Contact.php:2929 msgid "Connect URL missing." msgstr "" -#: src/Model/Contact.php:2896 +#: src/Model/Contact.php:2938 msgid "" "The contact could not be added. Please check the relevant network " "credentials in your Settings -> Social Networks page." msgstr "" -#: src/Model/Contact.php:2931 +#: src/Model/Contact.php:2956 +#, php-format +msgid "Expected network %s does not match actual network %s" +msgstr "" + +#: src/Model/Contact.php:2973 msgid "The profile address specified does not provide adequate information." msgstr "" -#: src/Model/Contact.php:2933 +#: src/Model/Contact.php:2975 msgid "No compatible communication protocols or feeds were discovered." msgstr "" -#: src/Model/Contact.php:2936 +#: src/Model/Contact.php:2978 msgid "An author or name was not found." msgstr "" -#: src/Model/Contact.php:2939 +#: src/Model/Contact.php:2981 msgid "No browser URL could be matched to this address." msgstr "" -#: src/Model/Contact.php:2942 +#: src/Model/Contact.php:2984 msgid "" "Unable to match @-style Identity Address with a known protocol or email " "contact." msgstr "" -#: src/Model/Contact.php:2943 +#: src/Model/Contact.php:2985 msgid "Use mailto: in front of address to force email check." msgstr "" -#: src/Model/Contact.php:2949 +#: src/Model/Contact.php:2991 msgid "" "The profile address specified belongs to a network which has been disabled " "on this site." msgstr "" -#: src/Model/Contact.php:2954 +#: src/Model/Contact.php:2996 msgid "" "Limited profile. This person will be unable to receive direct/personal " "notifications from you." msgstr "" -#: src/Model/Contact.php:3019 +#: src/Model/Contact.php:3061 msgid "Unable to retrieve contact information." msgstr "" @@ -2963,22 +2968,22 @@ msgid "Sept" msgstr "" #: src/Model/Event.php:464 src/Module/Calendar/Show.php:128 -#: src/Util/Temporal.php:339 +#: src/Util/Temporal.php:343 msgid "today" msgstr "" #: src/Model/Event.php:465 src/Module/Calendar/Show.php:129 -#: src/Module/Settings/Display.php:235 src/Util/Temporal.php:349 +#: src/Module/Settings/Display.php:235 src/Util/Temporal.php:353 msgid "month" msgstr "" #: src/Model/Event.php:466 src/Module/Calendar/Show.php:130 -#: src/Module/Settings/Display.php:236 src/Util/Temporal.php:350 +#: src/Module/Settings/Display.php:236 src/Util/Temporal.php:354 msgid "week" msgstr "" #: src/Model/Event.php:467 src/Module/Calendar/Show.php:131 -#: src/Module/Settings/Display.php:237 src/Util/Temporal.php:351 +#: src/Module/Settings/Display.php:237 src/Util/Temporal.php:355 msgid "day" msgstr "" @@ -5022,9 +5027,9 @@ msgstr "" #: src/Module/Admin/Summary.php:98 msgid "" -"The last update failed. Please run \"php bin/console.php dbstructure update" -"\" from the command line and have a look at the errors that might appear. " -"(Some of the errors are possibly inside the logfile.)" +"The last update failed. Please run \"php bin/console.php dbstructure " +"update\" from the command line and have a look at the errors that might " +"appear. (Some of the errors are possibly inside the logfile.)" msgstr "" #: src/Module/Admin/Summary.php:103 @@ -5178,8 +5183,8 @@ msgstr "" #, php-format msgid "" "Show some informations regarding the needed information to operate the node " -"according e.g. to EU-GDPR." +"according e.g. to EU-GDPR." msgstr "" #: src/Module/Admin/Tos.php:81 @@ -8211,8 +8216,8 @@ msgstr "" #: src/Module/Profile/Profile.php:158 #, php-format msgid "" -"You're currently viewing your profile as %s Cancel" +"You're currently viewing your profile as %s Cancel" msgstr "" #: src/Module/Profile/Profile.php:167 src/Module/Settings/Account.php:576 @@ -8231,17 +8236,17 @@ msgstr "" msgid "j F" msgstr "" -#: src/Module/Profile/Profile.php:187 src/Util/Temporal.php:166 +#: src/Module/Profile/Profile.php:187 src/Util/Temporal.php:168 msgid "Birthday:" msgstr "" #: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:254 -#: src/Util/Temporal.php:168 +#: src/Util/Temporal.php:170 msgid "Age: " msgstr "" #: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:254 -#: src/Util/Temporal.php:168 +#: src/Util/Temporal.php:170 #, php-format msgid "%d year old" msgid_plural "%d years old" @@ -8779,8 +8784,8 @@ msgstr "" #: src/Module/Security/TwoFactor/Verify.php:100 #, php-format msgid "" -"If you do not have access to your authentication code you can use a two-factor recovery code." +"If you do not have access to your authentication code you can use a two-factor recovery code." msgstr "" #: src/Module/Security/TwoFactor/Verify.php:101 @@ -9763,8 +9768,8 @@ msgstr "" msgid "Location" msgstr "" -#: src/Module/Settings/Profile/Index.php:239 src/Util/Temporal.php:95 -#: src/Util/Temporal.php:97 +#: src/Module/Settings/Profile/Index.php:239 src/Util/Temporal.php:97 +#: src/Util/Temporal.php:99 msgid "Miscellaneous" msgstr "" @@ -10239,8 +10244,8 @@ msgstr "" #: src/Module/Settings/TwoFactor/Verify.php:149 #, php-format msgid "" -"

Or you can open the following URL in your mobile device:

%s

" +"

Or you can open the following URL in your mobile device:

%s

" msgstr "" #: src/Module/Settings/TwoFactor/Verify.php:156 @@ -10312,9 +10317,9 @@ msgstr "" msgid "" "At any point in time a logged in user can export their account data from the " "account settings. If the user wants " -"to delete their account they can do so at " -"%1$s/settings/removeme. The deletion of the account will be permanent. " -"Deletion of the data will also be requested from the nodes of the " +"to delete their account they can do so at %1$s/settings/removeme. The deletion of the account will be " +"permanent. Deletion of the data will also be requested from the nodes of the " "communication partners." msgstr "" @@ -11305,73 +11310,73 @@ msgstr "" msgid "thanks" msgstr "" -#: src/Util/Temporal.php:170 +#: src/Util/Temporal.php:172 msgid "YYYY-MM-DD or MM-DD" msgstr "" -#: src/Util/Temporal.php:278 +#: src/Util/Temporal.php:280 #, php-format msgid "Time zone: %s Change in Settings" msgstr "" -#: src/Util/Temporal.php:318 src/Util/Temporal.php:325 +#: src/Util/Temporal.php:320 src/Util/Temporal.php:329 msgid "never" msgstr "" -#: src/Util/Temporal.php:339 +#: src/Util/Temporal.php:343 msgid "less than a second ago" msgstr "" -#: src/Util/Temporal.php:348 +#: src/Util/Temporal.php:352 msgid "year" msgstr "" -#: src/Util/Temporal.php:348 +#: src/Util/Temporal.php:352 msgid "years" msgstr "" -#: src/Util/Temporal.php:349 +#: src/Util/Temporal.php:353 msgid "months" msgstr "" -#: src/Util/Temporal.php:350 +#: src/Util/Temporal.php:354 msgid "weeks" msgstr "" -#: src/Util/Temporal.php:351 +#: src/Util/Temporal.php:355 msgid "days" msgstr "" -#: src/Util/Temporal.php:352 +#: src/Util/Temporal.php:356 msgid "hour" msgstr "" -#: src/Util/Temporal.php:352 +#: src/Util/Temporal.php:356 msgid "hours" msgstr "" -#: src/Util/Temporal.php:353 +#: src/Util/Temporal.php:357 msgid "minute" msgstr "" -#: src/Util/Temporal.php:353 +#: src/Util/Temporal.php:357 msgid "minutes" msgstr "" -#: src/Util/Temporal.php:354 +#: src/Util/Temporal.php:358 msgid "second" msgstr "" -#: src/Util/Temporal.php:354 +#: src/Util/Temporal.php:358 msgid "seconds" msgstr "" -#: src/Util/Temporal.php:364 +#: src/Util/Temporal.php:367 #, php-format msgid "in %1$d %2$s" msgstr "" -#: src/Util/Temporal.php:367 +#: src/Util/Temporal.php:370 #, php-format msgid "%1$d %2$s ago" msgstr "" From c517ab386a3a61e006980c18295db85af56d5ba1 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 21:30:01 +0100 Subject: [PATCH 08/27] Fix messages.po and adapt README --- doc/translations.md | 10 ++++++++++ view/lang/C/messages.po | 34 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/doc/translations.md b/doc/translations.md index 23ac4a62d..8b7077b6b 100644 --- a/doc/translations.md +++ b/doc/translations.md @@ -24,6 +24,16 @@ For addons, we add support for a language when if we already support the languag ## Add new translation strings +### Supported gettext version + +We currently support the gettext version 0.19.8.1 and actively check new translation strings with this version. + +If you don't use this version, it's possible that our checks fail (f.e. because of tiny differences at linebreaks). +In case you do have a Docker environment, you can easily update the translations with the following command: +```shell +docker run --rm -v $PWD:/data -w /data friendicaci/transifex bin/run_xgettext.sh +``` + ### Core Once you have added new translation strings in your code changes, please run `bin/run_xgettext.sh` from the base Friendica directory and commit the updated `view/lang/C/messages.po` to your branch. diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index ecc50e6db..c654bca48 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.03-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-29 20:06+0100\n" +"POT-Creation-Date: 2022-12-29 20:29+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -2428,8 +2428,8 @@ msgstr "" #: src/Core/Installer.php:514 msgid "" -"The web installer needs to be able to create a file called \"local.config." -"php\" in the \"config\" folder of your web server and it is unable to do so." +"The web installer needs to be able to create a file called \"local.config.php" +"\" in the \"config\" folder of your web server and it is unable to do so." msgstr "" #: src/Core/Installer.php:515 @@ -5027,9 +5027,9 @@ msgstr "" #: src/Module/Admin/Summary.php:98 msgid "" -"The last update failed. Please run \"php bin/console.php dbstructure " -"update\" from the command line and have a look at the errors that might " -"appear. (Some of the errors are possibly inside the logfile.)" +"The last update failed. Please run \"php bin/console.php dbstructure update" +"\" from the command line and have a look at the errors that might appear. " +"(Some of the errors are possibly inside the logfile.)" msgstr "" #: src/Module/Admin/Summary.php:103 @@ -5183,8 +5183,8 @@ msgstr "" #, php-format msgid "" "Show some informations regarding the needed information to operate the node " -"according e.g. to EU-GDPR." +"according e.g. to EU-GDPR." msgstr "" #: src/Module/Admin/Tos.php:81 @@ -8216,8 +8216,8 @@ msgstr "" #: src/Module/Profile/Profile.php:158 #, php-format msgid "" -"You're currently viewing your profile as %s Cancel" +"You're currently viewing your profile as %s Cancel" msgstr "" #: src/Module/Profile/Profile.php:167 src/Module/Settings/Account.php:576 @@ -8784,8 +8784,8 @@ msgstr "" #: src/Module/Security/TwoFactor/Verify.php:100 #, php-format msgid "" -"If you do not have access to your authentication code you can use a two-factor recovery code." +"If you do not have access to your authentication code you can use a two-factor recovery code." msgstr "" #: src/Module/Security/TwoFactor/Verify.php:101 @@ -10244,8 +10244,8 @@ msgstr "" #: src/Module/Settings/TwoFactor/Verify.php:149 #, php-format msgid "" -"

Or you can open the following URL in your mobile device:

%s

" +"

Or you can open the following URL in your mobile device:

%s

" msgstr "" #: src/Module/Settings/TwoFactor/Verify.php:156 @@ -10317,9 +10317,9 @@ msgstr "" msgid "" "At any point in time a logged in user can export their account data from the " "account settings. If the user wants " -"to delete their account they can do so at %1$s/settings/removeme. The deletion of the account will be " -"permanent. Deletion of the data will also be requested from the nodes of the " +"to delete their account they can do so at " +"%1$s/settings/removeme. The deletion of the account will be permanent. " +"Deletion of the data will also be requested from the nodes of the " "communication partners." msgstr "" From 9a10bb4295ce7a17da73db4e7f7d8d71ab8df721 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 16:54:08 +0100 Subject: [PATCH 09/27] Add key-value table --- database.sql | 13 ++++++++++++- doc/database.md | 1 + doc/database/db_key-value.md | 24 ++++++++++++++++++++++++ static/dbstructure.config.php | 14 +++++++++++++- 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 doc/database/db_key-value.md diff --git a/database.sql b/database.sql index 7eb756cf2..4384d44f8 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2023.03-dev (Giant Rhubarb) --- DB_UPDATE_VERSION 1504 +-- DB_UPDATE_VERSION 1505 -- ------------------------------------------ @@ -839,6 +839,17 @@ CREATE TABLE IF NOT EXISTS `intro` ( FOREIGN KEY (`suggest-cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE ) DEFAULT COLLATE utf8mb4_general_ci COMMENT=''; +-- +-- TABLE key-value +-- +CREATE TABLE IF NOT EXISTS `key-value` ( + `id` int unsigned NOT NULL auto_increment COMMENT '', + `k` varbinary(50) NOT NULL DEFAULT '' COMMENT '', + `v` mediumtext COMMENT '', + PRIMARY KEY(`id`), + UNIQUE INDEX `k` (`k`) +) DEFAULT COLLATE utf8mb4_general_ci COMMENT='A key value storage'; + -- -- TABLE locks -- diff --git a/doc/database.md b/doc/database.md index 9fa438c8d..5759d29ec 100644 --- a/doc/database.md +++ b/doc/database.md @@ -40,6 +40,7 @@ Database Tables | [inbox-status](help/database/db_inbox-status) | Status of ActivityPub inboxes | | [intro](help/database/db_intro) | | | [item-uri](help/database/db_item-uri) | URI and GUID for items | +| [key-value](help/database/db_key-value) | A key value storage | | [locks](help/database/db_locks) | | | [mail](help/database/db_mail) | private messages | | [mailacct](help/database/db_mailacct) | Mail account data for fetching mails | diff --git a/doc/database/db_key-value.md b/doc/database/db_key-value.md new file mode 100644 index 000000000..a346e6827 --- /dev/null +++ b/doc/database/db_key-value.md @@ -0,0 +1,24 @@ +Table key-value +=========== + +A key value storage + +Fields +------ + +| Field | Description | Type | Null | Key | Default | Extra | +| ----- | ----------- | ------------- | ---- | --- | ------- | -------------- | +| id | | int unsigned | NO | PRI | NULL | auto_increment | +| k | | varbinary(50) | NO | | | | +| v | | mediumtext | YES | | NULL | | + +Indexes +------------ + +| Name | Fields | +| ------- | --------- | +| PRIMARY | id | +| k | UNIQUE, k | + + +Return to [database documentation](help/database) diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 1d573fa87..0128b0343 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1504); + define('DB_UPDATE_VERSION', 1505); } return [ @@ -889,6 +889,18 @@ return [ "uid" => ["uid"], ] ], + "key-value" => [ + "comment" => "A key value storage", + "fields" => [ + "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => ""], + "k" => ["type" => "varbinary(50)", "not null" => "1", "default" => "", "comment" => ""], + "v" => ["type" => "mediumtext", "comment" => ""], + ], + "indexes" => [ + "PRIMARY" => ["id"], + "k" => ["UNIQUE", "k"], + ], + ], "locks" => [ "comment" => "", "fields" => [ From 47764387b39138b161a269aa3970f1855c7dc02c Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 17:52:04 +0100 Subject: [PATCH 10/27] Introduce Key-Value Pair storage provider --- .../Capabilities/ICanManageKeyValuePairs.php | 64 ++++++++++ .../KeyValueStoragePersistenceException.php | 30 +++++ .../Type/AbstractKeyValueStorage.php | 48 ++++++++ .../Type/DBKeyValueStorage.php | 116 ++++++++++++++++++ src/DI.php | 6 + static/dependencies.config.php | 3 + .../KeyValueStorage/DBKeyValueStorageTest.php | 64 ++++++++++ .../KeyValueStorage/KeyValueStorageTest.php | 105 ++++++++++++++++ 8 files changed, 436 insertions(+) create mode 100644 src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php create mode 100644 src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php create mode 100644 src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php create mode 100644 src/Core/KeyValueStorage/Type/DBKeyValueStorage.php create mode 100644 tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php create mode 100644 tests/src/Core/KeyValueStorage/KeyValueStorageTest.php diff --git a/src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php b/src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php new file mode 100644 index 000000000..11c8b772b --- /dev/null +++ b/src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php @@ -0,0 +1,64 @@ +. + * + */ + +namespace Friendica\Core\KeyValueStorage\Capabilities; + +use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException; + +/** + * Interface for Friendica specific Key-Value pair storage + */ +interface ICanManageKeyValuePairs extends \ArrayAccess +{ + /** + * Get a particular value from the KeyValue Storage + * + * @param string $key The key to query + * + * @return mixed Stored value or null if it does not exist + * + * @throws KeyValueStoragePersistenceException In case the persistence layer throws errors + * + */ + public function get(string $key); + + /** + * Sets a value for a given key + * + * Note: Please do not store booleans - convert to 0/1 integer values! + * + * @param string $key The configuration key to set + * @param mixed $value The value to store + * + * @throws KeyValueStoragePersistenceException In case the persistence layer throws errors + */ + public function set(string $key, $value): void; + + /** + * Deletes the given key. + * + * @param string $key The configuration key to delete + * + * @throws KeyValueStoragePersistenceException In case the persistence layer throws errors + * + */ + public function delete(string $key): void; +} diff --git a/src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php b/src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php new file mode 100644 index 000000000..ad04c33ae --- /dev/null +++ b/src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php @@ -0,0 +1,30 @@ +. + * + */ + +namespace Friendica\Core\KeyValueStorage\Exceptions; + +class KeyValueStoragePersistenceException extends \RuntimeException +{ + public function __construct($message = "", \Throwable $previous = null) + { + parent::__construct($message, 500, $previous); + } +} diff --git a/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php new file mode 100644 index 000000000..cfcebb6ff --- /dev/null +++ b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php @@ -0,0 +1,48 @@ +. + * + */ + +namespace Friendica\Core\KeyValueStorage\Type; + +use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; + +/** + * An abstract helper class for Key-Value storage classes + */ +abstract class AbstractKeyValueStorage implements ICanManageKeyValuePairs +{ + /** {@inheritDoc} */ + public function get(string $key) + { + return $this->offsetGet($key); + } + + /** {@inheritDoc} */ + public function set(string $key, $value): void + { + $this->offsetSet($key, $value); + } + + /** {@inheritDoc} */ + public function delete(string $key): void + { + $this->offsetUnset($key); + } +} diff --git a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php new file mode 100644 index 000000000..1d7040c04 --- /dev/null +++ b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php @@ -0,0 +1,116 @@ +. + * + */ + +namespace Friendica\Core\KeyValueStorage\Type; + +use Friendica\Core\Config\Util\ValueConversion; +use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException; +use Friendica\Database\Database; + +/** + * A Key-Value storage provider with DB as persistence layer + */ +class DBKeyValueStorage extends AbstractKeyValueStorage +{ + const DB_KEY_VALUE_TABLE = 'key-value'; + + /** @var Database */ + protected $database; + + public function __construct(Database $database) + { + $this->database = $database; + } + + /** {@inheritDoc} */ + public function offsetExists($offset): bool + { + try { + return $this->database->exists(self::DB_KEY_VALUE_TABLE, ['k' => $offset]); + } catch (\Exception $exception) { + throw new KeyValueStoragePersistenceException(sprintf('Cannot check storage with key %s', $offset), $exception); + } + } + + /** {@inheritDoc} */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + try { + $result = $this->database->selectFirst(self::DB_KEY_VALUE_TABLE, ['v'], ['k' => $offset]); + + if ($this->database->isResult($result)) { + $value = ValueConversion::toConfigValue($result['v']); + + // just return it in case it is set + if (isset($value)) { + return $value; + } + } + } catch (\Exception $exception) { + throw new KeyValueStoragePersistenceException(sprintf('Cannot get value for key %s', $offset), $exception); + } + + return null; + } + + /** {@inheritDoc} */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + try { + // We store our setting values in a string variable. + // So we have to do the conversion here so that the compare below works. + // The exception are array values. + $compare_value = (!is_array($value) ? (string)$value : $value); + $stored_value = $this->get($offset); + + if (isset($stored_value) && ($stored_value === $compare_value)) { + return; + } + + $dbValue = ValueConversion::toDbValue($value); + + $return = $this->database->update(self::DB_KEY_VALUE_TABLE, ['v' => $dbValue], ['k' => $offset], true); + + if (!$return) { + throw new \Exception(sprintf('database update failed: %s', $this->database->errorMessage())); + } + } catch (\Exception $exception) { + throw new KeyValueStoragePersistenceException(sprintf('Cannot set value for %s for key %s', $value, $offset), $exception); + } + } + + /** {@inheritDoc} */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + try { + $return = $this->database->delete(self::DB_KEY_VALUE_TABLE, ['k' => $offset]); + + if (!$return) { + throw new \Exception(sprintf('database deletion failed: %s', $this->database->errorMessage())); + } + } catch (\Exception $exception) { + throw new KeyValueStoragePersistenceException(sprintf('Cannot delete value with key %s', $offset), $exception); + } + } +} diff --git a/src/DI.php b/src/DI.php index bf2b5a237..31f2511d4 100644 --- a/src/DI.php +++ b/src/DI.php @@ -22,6 +22,7 @@ namespace Friendica; use Dice\Dice; +use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Navigation\SystemMessages; @@ -181,6 +182,11 @@ abstract class DI return self::$dice->create(Core\Config\Capability\IManageConfigValues::class); } + public static function keyValue(): ICanManageKeyValuePairs + { + return self::$dice->create(Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs::class); + } + /** * @return Core\PConfig\Capability\IManagePersonalConfigValues */ diff --git a/static/dependencies.config.php b/static/dependencies.config.php index a4c52e004..645ab968e 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -245,6 +245,9 @@ return [ ['getBackend', [], Dice::CHAIN_CALL], ], ], + \Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs::class => [ + 'instanceOf' => \Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage::class, + ], Network\HTTPClient\Capability\ICanSendHttpRequests::class => [ 'instanceOf' => Network\HTTPClient\Factory\HttpClient::class, 'call' => [ diff --git a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php new file mode 100644 index 000000000..16fa9ab7e --- /dev/null +++ b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php @@ -0,0 +1,64 @@ +. + * + */ + +namespace Friendica\Test\src\Core\KeyValueStorage; + +use Friendica\Core\Config\ValueObject\Cache; +use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage; +use Friendica\Database\Definition\DbaDefinition; +use Friendica\Database\Definition\ViewDefinition; +use Friendica\Test\DatabaseTestTrait; +use Friendica\Test\Util\Database\StaticDatabase; +use Friendica\Util\BasePath; +use Friendica\Util\Profiler; + +class DBKeyValueStorageTest extends KeyValueStorageTest +{ + use DatabaseTestTrait; + + protected function setUp(): void + { + parent::setUp(); + + $this->setUpDb(); + } + + protected function tearDown(): void + { + parent::tearDown(); + + $this->tearDownDb(); + } + + public function getInstance(): ICanManageKeyValuePairs + { + $cache = new Cache(); + $cache->set('database', 'disable_pdo', true); + + $basePath = new BasePath(dirname(__FILE__, 5), $_SERVER); + + $database = new StaticDatabase($cache, new Profiler($cache), (new DbaDefinition($basePath->getPath()))->load(), (new ViewDefinition($basePath->getPath()))->load()); + $database->setTestmode(true); + + return new DBKeyValueStorage($database); + } +} diff --git a/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php new file mode 100644 index 000000000..6c393310d --- /dev/null +++ b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php @@ -0,0 +1,105 @@ +. + * + */ + +namespace Friendica\Test\src\Core\KeyValueStorage; + +use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; +use Friendica\Test\MockedTest; + +abstract class KeyValueStorageTest extends MockedTest +{ + abstract public function getInstance(): ICanManageKeyValuePairs; + + public function testInstance() + { + $instance = $this->getInstance(); + + self::assertInstanceOf(ICanManageKeyValuePairs::class, $instance); + } + + public function dataTests(): array + { + return [ + 'string' => ['k' => 'data', 'v' => 'it'], + 'boolTrue' => ['k' => 'data', 'v' => true], + 'boolFalse' => ['k' => 'data', 'v' => false], + 'integer' => ['k' => 'data', 'v' => 235], + 'decimal' => ['k' => 'data', 'v' => 2.456], + 'array' => ['k' => 'data', 'v' => ['1', 2, '3', true, false]], + 'boolIntTrue' => ['k' => 'data', 'v' => 1], + 'boolIntFalse' => ['k' => 'data', 'v' => 0], + ]; + } + + /** + * @dataProvider dataTests + */ + public function testGetSetDelete($k, $v) + { + $instance = $this->getInstance(); + + $instance->set($k, $v); + + self::assertEquals($v, $instance->get($k)); + self::assertEquals($v, $instance[$k]); + + $instance->delete($k); + + self::assertNull($instance->get($k)); + self::assertNull($instance[$k]); + } + + /** + * @dataProvider dataTests + */ + public function testSetOverride($k, $v) + { + $instance = $this->getInstance(); + + $instance->set($k, $v); + + self::assertEquals($v, $instance->get($k)); + self::assertEquals($v, $instance[$k]); + + $instance->set($k, 'another_value'); + + self::assertEquals('another_value', $instance->get($k)); + self::assertEquals('another_value', $instance[$k]); + } + + /** + * @dataProvider dataTests + */ + public function testOffsetSetDelete($k, $v) + { + $instance = $this->getInstance(); + + $instance[$k] = $v; + + self::assertEquals($v, $instance->get($k)); + self::assertEquals($v, $instance[$k]); + + unset($instance[$k]); + + self::assertNull($instance->get($k)); + self::assertNull($instance[$k]); + } +} From 10f8631cd9423629d5189ae71d82964e4db18892 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 20:18:13 +0100 Subject: [PATCH 11/27] Replace PostUpdate key-value config entries with key-value pair entries --- src/Console/AutomaticInstallation.php | 4 +- src/Console/Config.php | 4 +- src/Console/Maintenance.php | 4 +- src/Console/PostUpdate.php | 16 +-- src/Core/Update.php | 2 +- src/DI.php | 3 +- src/Database/DBStructure.php | 16 +-- src/Database/PostUpdate.php | 146 +++++++++++++------------- src/Model/Contact.php | 2 +- src/Module/Friendica.php | 3 +- update.php | 13 ++- 11 files changed, 112 insertions(+), 101 deletions(-) diff --git a/src/Console/AutomaticInstallation.php b/src/Console/AutomaticInstallation.php index 1a6d10c24..85cfa710c 100644 --- a/src/Console/AutomaticInstallation.php +++ b/src/Console/AutomaticInstallation.php @@ -100,12 +100,12 @@ Examples HELP; } - public function __construct(App\Mode $appMode, Cache $configCache, IManageConfigValues $config, Database $dba, array $argv = null) + public function __construct(App\Mode $appMode, Cache $keyValueCache, IManageConfigValues $config, Database $dba, array $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->configCache = $configCache; + $this->configCache = $keyValueCache; $this->config = $config; $this->dba = $dba; } diff --git a/src/Console/Config.php b/src/Console/Config.php index 760b1ca51..1e88d36a8 100644 --- a/src/Console/Config.php +++ b/src/Console/Config.php @@ -94,12 +94,12 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, IManageConfigValues $config, array $argv = null) + public function __construct(App\Mode $appMode, IManageConfigValues $keyValue, array $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->config = $config; + $this->config = $keyValue; } protected function doExecute(): int diff --git a/src/Console/Maintenance.php b/src/Console/Maintenance.php index 7744c9ee4..e9909ed05 100644 --- a/src/Console/Maintenance.php +++ b/src/Console/Maintenance.php @@ -69,12 +69,12 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, IManageConfigValues $config, $argv = null) + public function __construct(App\Mode $appMode, IManageConfigValues $keyValue, $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->config = $config; + $this->config = $keyValue; } protected function doExecute(): int diff --git a/src/Console/PostUpdate.php b/src/Console/PostUpdate.php index 8bec14e27..cf15fe3e3 100644 --- a/src/Console/PostUpdate.php +++ b/src/Console/PostUpdate.php @@ -22,7 +22,7 @@ namespace Friendica\Console; use Friendica\App; -use Friendica\Core\Config\Capability\IManageConfigValues; +use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; use Friendica\Core\L10n; use Friendica\Core\Update; @@ -38,9 +38,9 @@ class PostUpdate extends \Asika\SimpleConsole\Console */ private $appMode; /** - * @var IManageConfigValues + * @var ICanManageKeyValuePairs */ - private $config; + private $keyValue; /** * @var L10n */ @@ -60,13 +60,13 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, IManageConfigValues $config, L10n $l10n, array $argv = null) + public function __construct(App\Mode $appMode, ICanManageKeyValuePairs $keyValue, L10n $l10n, array $argv = null) { parent::__construct($argv); - $this->appMode = $appMode; - $this->config = $config; - $this->l10n = $l10n; + $this->appMode = $appMode; + $this->keyValue = $keyValue; + $this->l10n = $l10n; } protected function doExecute(): int @@ -83,7 +83,7 @@ HELP; $this->out($this->getHelp()); return 0; } elseif ($reset_version) { - $this->config->set('system', 'post_update_version', $reset_version); + $this->keyValue->set('post_update_version', $reset_version); echo $this->l10n->t('Post update version number has been set to %s.', $reset_version) . "\n"; return 0; } diff --git a/src/Core/Update.php b/src/Core/Update.php index 8ec96dc98..9e05c1b5b 100644 --- a/src/Core/Update.php +++ b/src/Core/Update.php @@ -76,7 +76,7 @@ class Update } // The postupdate has to completed version 1288 for the new post views to take over - $postupdate = DI::config()->get('system', 'post_update_version', self::NEW_TABLE_STRUCTURE_VERSION); + $postupdate = DI::keyValue()->get('post_update_version') ?? self::NEW_TABLE_STRUCTURE_VERSION; if ($postupdate < self::NEW_TABLE_STRUCTURE_VERSION) { $error = DI::l10n()->t('Updates from postupdate version %s are not supported. Please update at least to version 2021.01 and wait until the postupdate finished version 1383.', $postupdate); if (DI::mode()->getExecutor() == Mode::INDEX) { diff --git a/src/DI.php b/src/DI.php index 31f2511d4..a430b0daa 100644 --- a/src/DI.php +++ b/src/DI.php @@ -22,7 +22,6 @@ namespace Friendica; use Dice\Dice; -use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Navigation\SystemMessages; @@ -182,7 +181,7 @@ abstract class DI return self::$dice->create(Core\Config\Capability\IManageConfigValues::class); } - public static function keyValue(): ICanManageKeyValuePairs + public static function keyValue(): Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs { return self::$dice->create(Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs::class); } diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index cdb5d4ef9..83e238394 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -53,7 +53,7 @@ class DBStructure throw new \Asika\SimpleConsole\CommandArgsException('The version number must be numeric'); } - DI::config()->set('system', 'build', $version); + DI::keyValue()->set( 'build', $version); echo DI::l10n()->t('The database version had been set to %s.', $version); } @@ -65,7 +65,7 @@ class DBStructure */ public static function dropTables(bool $execute) { - $postupdate = DI::config()->get('system', 'post_update_version', PostUpdate::VERSION); + $postupdate = DI::keyValue()->get('post_update_version') ?? PostUpdate::VERSION; if ($postupdate < PostUpdate::VERSION) { echo DI::l10n()->t('The post update is at version %d, it has to be at %d to safely drop the tables.', $postupdate, PostUpdate::VERSION); return; @@ -176,14 +176,14 @@ class DBStructure public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false): string { if ($enable_maintenance_mode) { - DI::config()->set('system', 'maintenance', 1); + DI::keyValue()->set( 'maintenance', 1); } $status = self::update($verbose, true); if ($enable_maintenance_mode) { - DI::config()->set('system', 'maintenance', 0); - DI::config()->set('system', 'maintenance_reason', ''); + DI::keyValue()->set( 'maintenance', 0); + DI::keyValue()->set( 'maintenance_reason', ''); } return $status; @@ -213,7 +213,7 @@ class DBStructure */ private static function update(bool $verbose, bool $action, bool $install = false, array $tables = null, array $definition = null): string { - $in_maintenance_mode = DI::config()->get('system', 'maintenance'); + $in_maintenance_mode = DI::keyValue()->get('system', 'maintenance'); if ($action && !$install && self::isUpdating()) { return DI::l10n()->t('Another database update is currently running.'); @@ -494,9 +494,9 @@ class DBStructure if ($action && !$install) { if ($errors) { - DI::config()->set('system', 'dbupdate', self::UPDATE_FAILED); + DI::config()->set('system', 'dbupdate', self::UPDATE_FAILED); } else { - DI::config()->set('system', 'dbupdate', self::UPDATE_SUCCESSFUL); + DI::config()->set( 'system', 'dbupdate', self::UPDATE_SUCCESSFUL); } } diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index e57d92ceb..d54c3f221 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -129,12 +129,12 @@ class PostUpdate private static function update1297() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1297) { + if (DI::keyValue()->get('post_update_version') >= 1297) { return true; } if (!DBStructure::existsTable('item-delivery-data')) { - DI::config()->set('system', 'post_update_version', 1297); + DI::keyValue()->set('post_update_version', 1297); return true; } @@ -154,7 +154,7 @@ class PostUpdate Logger::info('Processed rows: ' . DBA::affectedRows()); - DI::config()->set('system', 'post_update_version', 1297); + DI::keyValue()->set('post_update_version', 1297); Logger::info('Done'); @@ -169,7 +169,7 @@ class PostUpdate private static function update1322() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1322) { + if (DI::keyValue()->get('post_update_version') >= 1322) { return true; } @@ -188,7 +188,7 @@ class PostUpdate } DBA::close($contact); - DI::config()->set('system', 'post_update_version', 1322); + DI::keyValue()->set('post_update_version', 1322); Logger::info('Done'); @@ -204,16 +204,16 @@ class PostUpdate private static function update1329() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1329) { + if (DI::keyValue()->get('post_update_version') >= 1329) { return true; } if (!DBStructure::existsTable('item')) { - DI::config()->set('system', 'post_update_version', 1329); + DI::keyValue()->set('post_update_version', 1329); return true; } - $id = DI::config()->get('system', 'post_update_version_1329_id', 0); + $id = DI::keyValue()->get('post_update_version_1329_id') ?? 0; Logger::info('Start', ['item' => $id]); @@ -237,12 +237,12 @@ class PostUpdate } DBA::close($items); - DI::config()->set('system', 'post_update_version_1329_id', $id); + DI::keyValue()->set('post_update_version_1329_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); if ($start_id == $id) { - DI::config()->set('system', 'post_update_version', 1329); + DI::keyValue()->set('post_update_version', 1329); Logger::info('Done'); return true; } @@ -259,16 +259,16 @@ class PostUpdate private static function update1341() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1341) { + if (DI::keyValue()->get('post_update_version') >= 1341) { return true; } if (!DBStructure::existsTable('item-content')) { - DI::config()->set('system', 'post_update_version', 1342); + DI::keyValue()->set('post_update_version', 1342); return true; } - $id = DI::config()->get('system', 'post_update_version_1341_id', 0); + $id = DI::keyValue()->get('post_update_version_1341_id') ?? 0; Logger::info('Start', ['item' => $id]); @@ -288,19 +288,19 @@ class PostUpdate $id = $item['uri-id']; ++$rows; if ($rows % 1000 == 0) { - DI::config()->set('system', 'post_update_version_1341_id', $id); + DI::keyValue()->set('post_update_version_1341_id', $id); } } DBA::close($items); - DI::config()->set('system', 'post_update_version_1341_id', $id); + DI::keyValue()->set('post_update_version_1341_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); // When there are less than 1,000 items processed this means that we reached the end // The other entries will then be processed with the regular functionality if ($rows < 1000) { - DI::config()->set('system', 'post_update_version', 1341); + DI::keyValue()->set('post_update_version', 1341); Logger::info('Done'); return true; } @@ -317,16 +317,16 @@ class PostUpdate private static function update1342() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1342) { + if (DI::keyValue()->get('post_update_version') >= 1342) { return true; } if (!DBStructure::existsTable('term') || !DBStructure::existsTable('item-content')) { - DI::config()->set('system', 'post_update_version', 1342); + DI::keyValue()->set('post_update_version', 1342); return true; } - $id = DI::config()->get('system', 'post_update_version_1342_id', 0); + $id = DI::keyValue()->get('post_update_version_1342_id') ?? 0; Logger::info('Start', ['item' => $id]); @@ -364,19 +364,19 @@ class PostUpdate $id = $term['tid']; ++$rows; if ($rows % 1000 == 0) { - DI::config()->set('system', 'post_update_version_1342_id', $id); + DI::keyValue()->set('post_update_version_1342_id', $id); } } DBA::close($terms); - DI::config()->set('system', 'post_update_version_1342_id', $id); + DI::keyValue()->set('post_update_version_1342_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); // When there are less than 1,000 items processed this means that we reached the end // The other entries will then be processed with the regular functionality if ($rows < 1000) { - DI::config()->set('system', 'post_update_version', 1342); + DI::keyValue()->set('post_update_version', 1342); Logger::info('Done'); return true; } @@ -393,16 +393,16 @@ class PostUpdate private static function update1345() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1345) { + if (DI::keyValue()->get('post_update_version') >= 1345) { return true; } if (!DBStructure::existsTable('item-delivery-data')) { - DI::config()->set('system', 'post_update_version', 1345); + DI::keyValue()->set('post_update_version', 1345); return true; } - $id = DI::config()->get('system', 'post_update_version_1345_id', 0); + $id = DI::keyValue()->get('post_update_version_1345_id') ?? 0; Logger::info('Start', ['item' => $id]); @@ -427,14 +427,14 @@ class PostUpdate } DBA::close($deliveries); - DI::config()->set('system', 'post_update_version_1345_id', $id); + DI::keyValue()->set('post_update_version_1345_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); // When there are less than 100 items processed this means that we reached the end // The other entries will then be processed with the regular functionality if ($rows < 100) { - DI::config()->set('system', 'post_update_version', 1345); + DI::keyValue()->set('post_update_version', 1345); Logger::info('Done'); return true; } @@ -476,16 +476,16 @@ class PostUpdate private static function update1346() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1346) { + if (DI::keyValue()->get('post_update_version') >= 1346) { return true; } if (!DBStructure::existsTable('term')) { - DI::config()->set('system', 'post_update_version', 1346); + DI::keyValue()->set('post_update_version', 1346); return true; } - $id = DI::config()->get('system', 'post_update_version_1346_id', 0); + $id = DI::keyValue()->get('post_update_version_1346_id') ?? 0; Logger::info('Start', ['item' => $id]); @@ -514,19 +514,19 @@ class PostUpdate $id = $term['oid']; ++$rows; if ($rows % 100 == 0) { - DI::config()->set('system', 'post_update_version_1346_id', $id); + DI::keyValue()->set('post_update_version_1346_id', $id); } } DBA::close($terms); - DI::config()->set('system', 'post_update_version_1346_id', $id); + DI::keyValue()->set('post_update_version_1346_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); // When there are less than 10 items processed this means that we reached the end // The other entries will then be processed with the regular functionality if ($rows < 10) { - DI::config()->set('system', 'post_update_version', 1346); + DI::keyValue()->set('post_update_version', 1346); Logger::info('Done'); return true; } @@ -544,16 +544,16 @@ class PostUpdate private static function update1347() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1347) { + if (DI::keyValue()->get('post_update_version') >= 1347) { return true; } if (!DBStructure::existsTable('item-activity') || !DBStructure::existsTable('item')) { - DI::config()->set('system', 'post_update_version', 1347); + DI::keyValue()->set('post_update_version', 1347); return true; } - $id = DI::config()->get('system', 'post_update_version_1347_id', 0); + $id = DI::keyValue()->get('post_update_version_1347_id') ?? 0; Logger::info('Start', ['item' => $id]); @@ -588,12 +588,12 @@ class PostUpdate } DBA::close($items); - DI::config()->set('system', 'post_update_version_1347_id', $id); + DI::keyValue()->set('post_update_version_1347_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); if ($start_id == $id) { - DI::config()->set('system', 'post_update_version', 1347); + DI::keyValue()->set('post_update_version', 1347); Logger::info('Done'); return true; } @@ -611,11 +611,11 @@ class PostUpdate private static function update1348() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1348) { + if (DI::keyValue()->get('post_update_version') >= 1348) { return true; } - $id = DI::config()->get('system', 'post_update_version_1348_id', 0); + $id = DI::keyValue()->get('post_update_version_1348_id') ?? 0; Logger::info('Start', ['contact' => $id]); @@ -641,12 +641,12 @@ class PostUpdate } DBA::close($contacts); - DI::config()->set('system', 'post_update_version_1348_id', $id); + DI::keyValue()->set('post_update_version_1348_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); if ($start_id == $id) { - DI::config()->set('system', 'post_update_version', 1348); + DI::keyValue()->set('post_update_version', 1348); Logger::info('Done'); return true; } @@ -664,11 +664,11 @@ class PostUpdate private static function update1349() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1349) { + if (DI::keyValue()->get('post_update_version') >= 1349) { return true; } - $id = DI::config()->get('system', 'post_update_version_1349_id', ''); + $id = DI::keyValue()->get('post_update_version_1349_id') ?? ''; Logger::info('Start', ['apcontact' => $id]); @@ -694,12 +694,12 @@ class PostUpdate } DBA::close($apcontacts); - DI::config()->set('system', 'post_update_version_1349_id', $id); + DI::keyValue()->set('post_update_version_1349_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); if ($start_id == $id) { - DI::config()->set('system', 'post_update_version', 1349); + DI::keyValue()->set('post_update_version', 1349); Logger::info('Done'); return true; } @@ -717,7 +717,7 @@ class PostUpdate private static function update1383() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1383) { + if (DI::keyValue()->get('post_update_version') >= 1383) { return true; } @@ -743,7 +743,7 @@ class PostUpdate } DBA::close($photos); - DI::config()->set('system', 'post_update_version', 1383); + DI::keyValue()->set('post_update_version', 1383); Logger::info('Done', ['deleted' => $deleted]); return true; } @@ -758,7 +758,7 @@ class PostUpdate private static function update1384() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1384) { + if (DI::keyValue()->get('post_update_version') >= 1384) { return true; } @@ -788,7 +788,7 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1384); + DI::keyValue()->set('post_update_version', 1384); Logger::info('Done'); return true; } @@ -806,12 +806,12 @@ class PostUpdate private static function update1400() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1400) { + if (DI::keyValue()->get('post_update_version') >= 1400) { return true; } if (!DBStructure::existsTable('item')) { - DI::config()->set('system', 'post_update_version', 1400); + DI::keyValue()->set('post_update_version', 1400); return true; } @@ -835,7 +835,7 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1400); + DI::keyValue()->set('post_update_version', 1400); Logger::info('Done'); return true; } @@ -853,7 +853,7 @@ class PostUpdate private static function update1424() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1424) { + if (DI::keyValue()->get('post_update_version') >= 1424) { return true; } @@ -877,7 +877,7 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1424); + DI::keyValue()->set('post_update_version', 1424); Logger::info('Done'); return true; } @@ -895,12 +895,12 @@ class PostUpdate private static function update1425() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1425) { + if (DI::keyValue()->get('post_update_version') >= 1425) { return true; } if (!DBStructure::existsTable('fcontact')) { - DI::config()->set('system', 'post_update_version', 1425); + DI::keyValue()->set('post_update_version', 1425); return true; } @@ -929,7 +929,7 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1425); + DI::keyValue()->set('post_update_version', 1425); Logger::info('Done'); return true; } @@ -947,7 +947,7 @@ class PostUpdate private static function update1426() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1426) { + if (DI::keyValue()->get('post_update_version') >= 1426) { return true; } @@ -976,7 +976,7 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1426); + DI::keyValue()->set('post_update_version', 1426); Logger::info('Done'); return true; } @@ -994,7 +994,7 @@ class PostUpdate private static function update1427() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1427) { + if (DI::keyValue()->get('post_update_version') >= 1427) { return true; } @@ -1023,7 +1023,7 @@ class PostUpdate Logger::info('Processed', ['rows' => $rows]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1427); + DI::keyValue()->set('post_update_version', 1427); Logger::info('Done'); return true; } @@ -1041,16 +1041,16 @@ class PostUpdate private static function update1452() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1452) { + if (DI::keyValue()->get('post_update_version') >= 1452) { return true; } if (!DBStructure::existsTable('conversation')) { - DI::config()->set('system', 'post_update_version', 1452); + DI::keyValue()->set('post_update_version', 1452); return true; } - $id = DI::config()->get('system', 'post_update_version_1452_id', 0); + $id = DI::keyValue()->get('post_update_version_1452_id') ?? 0; Logger::info('Start', ['uri-id' => $id]); @@ -1089,12 +1089,12 @@ class PostUpdate DBA::close($conversations); - DI::config()->set('system', 'post_update_version_1452_id', $id); + DI::keyValue()->set('post_update_version_1452_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id, 'last-received' => $received]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1452); + DI::keyValue()->set('post_update_version', 1452); Logger::info('Done'); return true; } @@ -1113,7 +1113,7 @@ class PostUpdate private static function update1483() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1483) { + if (DI::keyValue()->get('post_update_version') >= 1483) { return true; } @@ -1129,7 +1129,7 @@ class PostUpdate } DBA::close($posts); - DI::config()->set('system', 'post_update_version', 1483); + DI::keyValue()->set('post_update_version', 1483); Logger::info('Done'); return true; } @@ -1144,11 +1144,11 @@ class PostUpdate private static function update1484() { // Was the script completed? - if (DI::config()->get('system', 'post_update_version') >= 1484) { + if (DI::keyValue()->get('post_update_version') >= 1484) { return true; } - $id = DI::config()->get('system', 'post_update_version_1484_id', 0); + $id = DI::keyValue()->get('post_update_version_1484_id') ?? 0; Logger::info('Start', ['id' => $id]); @@ -1172,12 +1172,12 @@ class PostUpdate } DBA::close($contacts); - DI::config()->set('system', 'post_update_version_1484_id', $id); + DI::keyValue()->set('post_update_version_1484_id', $id); Logger::info('Processed', ['rows' => $rows, 'last' => $id]); if ($rows <= 100) { - DI::config()->set('system', 'post_update_version', 1484); + DI::keyValue()->set('post_update_version', 1484); Logger::info('Done'); return true; } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index bf90edcd4..1bf2f1791 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -624,7 +624,7 @@ class Contact public static function getPublicAndUserContactID(int $cid, int $uid): array { // We have to use the legacy function as long as the post update hasn't finished - if (DI::config()->get('system', 'post_update_version') < 1427) { + if (DI::keyValue()->get('post_update_version') < 1427) { return self::legacyGetPublicAndUserContactID($cid, $uid); } diff --git a/src/Module/Friendica.php b/src/Module/Friendica.php index 37bd69da4..f21b85fc4 100644 --- a/src/Module/Friendica.php +++ b/src/Module/Friendica.php @@ -42,6 +42,7 @@ class Friendica extends BaseModule protected function content(array $request = []): string { $config = DI::config(); + $keyValue = DI::keyValue(); $visibleAddonList = Addon::getVisibleList(); if (!empty($visibleAddonList)) { @@ -100,7 +101,7 @@ class Friendica extends BaseModule '' . App::VERSION . '', DI::baseUrl()->get(), '' . $config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '', - '' . $config->get('system', 'post_update_version') . '/' . PostUpdate::VERSION . ''), + '' . $keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . ''), 'friendica' => DI::l10n()->t('Please visit Friendi.ca to learn more about the Friendica project.'), 'bugs' => DI::l10n()->t('Bug reports and issues: please visit') . ' ' . '' . DI::l10n()->t('the bugtracker at github') . '', 'info' => DI::l10n()->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'), diff --git a/update.php b/update.php index 82f4fba58..fb62f28df 100644 --- a/update.php +++ b/update.php @@ -982,7 +982,7 @@ function update_1429() return Update::FAILED; } - DI::config()->set('system', 'post_update_version', 1423); + DI::keyValue()->set('post_update_version', 1423); return Update::SUCCESS; } @@ -1145,3 +1145,14 @@ function update_1502() DBA::e("UPDATE `pconfig` SET `cat` = 'calendar' WHERE `k` = 'first_day_of_week'"); return Update::SUCCESS; } + +function update_1505() +{ + $postUpdateEntries = DBA::selectToArray('config', ['k', 'v'], ["`k` LIKE ?", "post_update_%"]); + + foreach ($postUpdateEntries as $postUpdateEntry) { + DI::keyValue()->set($postUpdateEntry['k'], $postUpdateEntry['v']); + } + + return DBA::delete('config', ["`k` LIKE ?", "post_update_%"]) ? Update::SUCCESS : Update::FAILED; +} From 6b3265742aecae522c5ac9eeedacfbdb7513a371 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 20:30:19 +0100 Subject: [PATCH 12/27] Replace cron/worker "last" config entries with key-value entries --- src/Core/Worker.php | 10 +++++----- src/Core/Worker/Daemon.php | 4 ++-- src/Module/Admin/Summary.php | 2 +- src/Worker/Cron.php | 10 +++++----- src/Worker/PullDirectory.php | 4 ++-- update.php | 12 ++++++++++-- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/Core/Worker.php b/src/Core/Worker.php index d6f97eed2..cbe664529 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -89,9 +89,9 @@ class Worker self::$process = $process; // Kill stale processes every 5 minutes - $last_cleanup = DI::config()->get('system', 'worker_last_cleaned', 0); + $last_cleanup = DI::keyValue()->get('worker_last_cleaned') ?? 0; if (time() > ($last_cleanup + 300)) { - DI::config()->set('system', 'worker_last_cleaned', time()); + DI::keyValue()->set( 'worker_last_cleaned', time()); Worker\Cron::killStaleWorkers(); } @@ -388,7 +388,7 @@ class Worker $stamp = (float)microtime(true); $condition = ["`id` = ? AND `next_try` < ?", $queue['id'], DateTimeFormat::utcNow()]; if (DBA::update('workerqueue', ['done' => true], $condition)) { - DI::config()->set('system', 'last_worker_execution', DateTimeFormat::utcNow()); + DI::keyValue()->set('last_worker_execution', DateTimeFormat::utcNow()); } self::$db_duration = (microtime(true) - $stamp); self::$db_duration_write += (microtime(true) - $stamp); @@ -429,7 +429,7 @@ class Worker $stamp = (float)microtime(true); if (DBA::update('workerqueue', ['done' => true], ['id' => $queue['id']])) { - DI::config()->set('system', 'last_worker_execution', DateTimeFormat::utcNow()); + DI::keyValue()->set('last_worker_execution', DateTimeFormat::utcNow()); } self::$db_duration = (microtime(true) - $stamp); self::$db_duration_write += (microtime(true) - $stamp); @@ -1422,7 +1422,7 @@ class Worker $duration = max($start, $end) - min($start, $end); // Quit when the last cron execution had been after the previous window - $last_cron = DI::config()->get('system', 'last_cron_daily'); + $last_cron = DI::keyValue()->get('last_cron_daily'); if ($last_cron + $duration > time()) { Logger::info('The Daily cron had been executed recently', ['last' => date(DateTimeFormat::MYSQL, $last_cron), 'start' => date('H:i:s', $start), 'end' => date('H:i:s', $end)]); return false; diff --git a/src/Core/Worker/Daemon.php b/src/Core/Worker/Daemon.php index 6fd64e4f5..858acc25d 100644 --- a/src/Core/Worker/Daemon.php +++ b/src/Core/Worker/Daemon.php @@ -93,11 +93,11 @@ class Daemon } // Check every minute if the daemon is running - if (DI::config()->get('system', 'last_daemon_check', 0) + 60 > time()) { + if ((DI::keyValue()->get('last_daemon_check') ?? 0) + 60 > time()) { return; } - DI::config()->set('system', 'last_daemon_check', time()); + DI::keyValue()->set('last_daemon_check', time()); $pidfile = DI::config()->get('system', 'pidfile'); if (empty($pidfile)) { diff --git a/src/Module/Admin/Summary.php b/src/Module/Admin/Summary.php index d27a9b011..42098c95c 100644 --- a/src/Module/Admin/Summary.php +++ b/src/Module/Admin/Summary.php @@ -98,7 +98,7 @@ class Summary extends BaseAdmin $warningtext[] = DI::l10n()->t('The last update failed. Please run "php bin/console.php dbstructure update" from the command line and have a look at the errors that might appear. (Some of the errors are possibly inside the logfile.)'); } - $last_worker_call = DI::config()->get('system', 'last_worker_execution', false); + $last_worker_call = DI::keyValue()->get('last_worker_execution') ?? false; if (!$last_worker_call) { $warningtext[] = DI::l10n()->t('The worker was never executed. Please check your database structure!'); } elseif ((strtotime(DateTimeFormat::utcNow()) - strtotime($last_worker_call)) > 60 * 60) { diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index 94f002805..055a9b435 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -37,7 +37,7 @@ class Cron { $a = DI::app(); - $last = DI::config()->get('system', 'last_cron'); + $last = DI::keyValue()->get('last_cron'); $poll_interval = intval(DI::config()->get('system', 'cron_interval')); @@ -84,7 +84,7 @@ class Cron Worker::add(Worker::PRIORITY_LOW, 'PostUpdate'); // Hourly cron calls - if (DI::config()->get('system', 'last_cron_hourly', 0) + 3600 < time()) { + if ((DI::keyValue()->get('last_cron_hourly') ?? 0) + 3600 < time()) { // Update trending tags cache for the community page @@ -105,7 +105,7 @@ class Cron // Clear cache entries Worker::add(Worker::PRIORITY_LOW, 'ClearCache'); - DI::config()->set('system', 'last_cron_hourly', time()); + DI::keyValue()->set('last_cron_hourly', time()); } // Daily maintenance cron calls @@ -145,12 +145,12 @@ class Cron // Resubscribe to relay servers Relay::reSubscribe(); - DI::config()->set('system', 'last_cron_daily', time()); + DI::keyValue()->set('last_cron_daily', time()); } Logger::notice('end'); - DI::config()->set('system', 'last_cron', time()); + DI::keyValue()->set('last_cron', time()); } /** diff --git a/src/Worker/PullDirectory.php b/src/Worker/PullDirectory.php index 8a22e504c..d174d11f3 100644 --- a/src/Worker/PullDirectory.php +++ b/src/Worker/PullDirectory.php @@ -45,7 +45,7 @@ class PullDirectory return; } - $now = (int)DI::config()->get('system', 'last-directory-sync', 0); + $now = (int)(DI::keyValue()->get('last-directory-sync') ?? 0); Logger::info('Synchronization started.', ['now' => $now, 'directory' => $directory]); @@ -64,7 +64,7 @@ class PullDirectory $result = Contact::addByUrls($contacts['results']); $now = $contacts['now'] ?? 0; - DI::config()->set('system', 'last-directory-sync', $now); + DI::keyValue()->set('last-directory-sync', $now); Logger::info('Synchronization ended', ['now' => $now, 'count' => $result['count'], 'added' => $result['added'], 'updated' => $result['updated'], 'unchanged' => $result['unchanged'], 'directory' => $directory]); } diff --git a/update.php b/update.php index fb62f28df..632d173a7 100644 --- a/update.php +++ b/update.php @@ -1148,11 +1148,19 @@ function update_1502() function update_1505() { - $postUpdateEntries = DBA::selectToArray('config', ['k', 'v'], ["`k` LIKE ?", "post_update_%"]); + $conditions = [ + "(`k` LIKE ?) OR (`k` = ?) OR (`cat` = ? AND `k` LIKE ?)", + "post_update_%", + "worker_last_cleaned", + "system", + "last%" + ]; + + $postUpdateEntries = DBA::selectToArray('config', ['k', 'v'], $conditions); foreach ($postUpdateEntries as $postUpdateEntry) { DI::keyValue()->set($postUpdateEntry['k'], $postUpdateEntry['v']); } - return DBA::delete('config', ["`k` LIKE ?", "post_update_%"]) ? Update::SUCCESS : Update::FAILED; + return DBA::delete('config', $conditions) ? Update::SUCCESS : Update::FAILED; } From b227d65dfc086c4d61e471360c09a34abf21a301 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 20:34:19 +0100 Subject: [PATCH 13/27] Replace worker_daemon_mode config entry with key-value entry --- bin/daemon.php | 6 +++--- src/Core/Worker/Daemon.php | 2 +- update.php | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/bin/daemon.php b/bin/daemon.php index d5ef02a8e..b7085a490 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -115,7 +115,7 @@ if (is_readable($pidfile)) { } if (empty($pid) && in_array($mode, ['stop', 'status'])) { - DI::config()->set('system', 'worker_daemon_mode', false); + DI::keyValue()->set('worker_daemon_mode', false); die("Pidfile wasn't found. Is the daemon running?\n"); } @@ -137,7 +137,7 @@ if ($mode == 'stop') { Logger::notice('Worker daemon process was killed', ['pid' => $pid]); - DI::config()->set('system', 'worker_daemon_mode', false); + DI::keyValue()->set('worker_daemon_mode', false); die("Worker daemon process $pid was killed.\n"); } @@ -181,7 +181,7 @@ if (!$foreground) { DBA::connect(); } -DI::config()->set('system', 'worker_daemon_mode', true); +DI::keyValue()->set('worker_daemon_mode', true); // Just to be sure that this script really runs endlessly set_time_limit(0); diff --git a/src/Core/Worker/Daemon.php b/src/Core/Worker/Daemon.php index 858acc25d..7b4c358f1 100644 --- a/src/Core/Worker/Daemon.php +++ b/src/Core/Worker/Daemon.php @@ -47,7 +47,7 @@ class Daemon return true; } - $daemon_mode = DI::config()->get('system', 'worker_daemon_mode', false, true); + $daemon_mode = DI::keyValue()->get('worker_daemon_mode') ?? false; if ($daemon_mode) { return $daemon_mode; } diff --git a/update.php b/update.php index 632d173a7..ff3b6b536 100644 --- a/update.php +++ b/update.php @@ -1149,11 +1149,12 @@ function update_1502() function update_1505() { $conditions = [ - "(`k` LIKE ?) OR (`k` = ?) OR (`cat` = ? AND `k` LIKE ?)", + "(`cat` = ?) AND ((`k` LIKE ?) OR (`k` = ?) OR (`k` LIKE ?) OR (`k` = ?))", + "system", "post_update_%", "worker_last_cleaned", - "system", - "last%" + "last%", + "worker_daemon_mode", ]; $postUpdateEntries = DBA::selectToArray('config', ['k', 'v'], $conditions); From 1ed67fba3d0e33d10bf6112a15b9e086a6a5ee89 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 20:51:04 +0100 Subject: [PATCH 14/27] Replace addon "last" config entries with key-value entries --- src/Model/GServer.php | 4 ++-- update.php | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Model/GServer.php b/src/Model/GServer.php index b0a9dd5c9..6945fab3e 100644 --- a/src/Model/GServer.php +++ b/src/Model/GServer.php @@ -2145,7 +2145,7 @@ class GServer */ private static function discoverFederation() { - $last = DI::config()->get('poco', 'last_federation_discovery'); + $last = DI::keyValue()->get('poco_last_federation_discovery'); if ($last) { $next = $last + (24 * 60 * 60); @@ -2189,7 +2189,7 @@ class GServer } } - DI::config()->set('poco', 'last_federation_discovery', time()); + DI::keyValue()->set('poco_last_federation_discovery', time()); } /** diff --git a/update.php b/update.php index ff3b6b536..9aaf95193 100644 --- a/update.php +++ b/update.php @@ -1149,18 +1149,25 @@ function update_1502() function update_1505() { $conditions = [ - "(`cat` = ?) AND ((`k` LIKE ?) OR (`k` = ?) OR (`k` LIKE ?) OR (`k` = ?))", + "((`cat` = ?) AND ((`k` LIKE ?) OR (`k` = ?) OR (`k` LIKE ?) OR (`k` = ?))) OR " . + "((`cat` != ?) AND (`k` LIKE ?))", "system", "post_update_%", "worker_last_cleaned", "last%", "worker_daemon_mode", + "system", + "last_%", ]; - $postUpdateEntries = DBA::selectToArray('config', ['k', 'v'], $conditions); + $postUpdateEntries = DBA::selectToArray('config', ['cat', 'k', 'v'], $conditions); foreach ($postUpdateEntries as $postUpdateEntry) { - DI::keyValue()->set($postUpdateEntry['k'], $postUpdateEntry['v']); + if ($postUpdateEntry['cat'] === 'system') { + DI::keyValue()->set($postUpdateEntry['k'], $postUpdateEntry['v']); + } else { + DI::keyValue()->set(sprintf('%s_%s', $postUpdateEntry['cat'], $postUpdateEntry['k']), $postUpdateEntry['v']); + } } return DBA::delete('config', $conditions) ? Update::SUCCESS : Update::FAILED; From 965caf98a557c729a4591933cd72147d3672f99a Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 21:43:52 +0100 Subject: [PATCH 15/27] Replace database "update_" config entries with key-value entries --- src/Module/Admin/DBSync.php | 2 +- update.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Module/Admin/DBSync.php b/src/Module/Admin/DBSync.php index bb1fa9033..3ab9fb799 100644 --- a/src/Module/Admin/DBSync.php +++ b/src/Module/Admin/DBSync.php @@ -42,7 +42,7 @@ class DBSync extends BaseAdmin switch ($action) { case 'mark': if ($update) { - DI::config()->set('database', 'update_' . $update, 'success'); + DI::keyValue()->set('database_update_' . $update, 'success'); $curr = DI::config()->get('system', 'build'); if (intval($curr) == $update) { DI::config()->set('system', 'build', intval($curr) + 1); diff --git a/update.php b/update.php index 9aaf95193..2235b0451 100644 --- a/update.php +++ b/update.php @@ -1150,7 +1150,8 @@ function update_1505() { $conditions = [ "((`cat` = ?) AND ((`k` LIKE ?) OR (`k` = ?) OR (`k` LIKE ?) OR (`k` = ?))) OR " . - "((`cat` != ?) AND (`k` LIKE ?))", + "((`cat` != ?) AND (`k` LIKE ?)) OR " . + "((`cat` = ?) AND (`k` LIKE ?))", "system", "post_update_%", "worker_last_cleaned", @@ -1158,6 +1159,8 @@ function update_1505() "worker_daemon_mode", "system", "last_%", + "database", + "update_%", ]; $postUpdateEntries = DBA::selectToArray('config', ['cat', 'k', 'v'], $conditions); From 925c30280c853c152f465d64065a6749ec5939fa Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:12:02 +0100 Subject: [PATCH 16/27] Apply suggestions from code review Co-authored-by: Hypolite Petovan --- .../KeyValueStorage/Type/DBKeyValueStorage.php | 4 +--- src/Database/DBStructure.php | 14 +++++++------- src/Module/Admin/Summary.php | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php index 1d7040c04..60e6087e2 100644 --- a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php +++ b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php @@ -104,9 +104,7 @@ class DBKeyValueStorage extends AbstractKeyValueStorage public function offsetUnset($offset) { try { - $return = $this->database->delete(self::DB_KEY_VALUE_TABLE, ['k' => $offset]); - - if (!$return) { + if (!$this->database->delete(self::DB_KEY_VALUE_TABLE, ['k' => $offset])) { throw new \Exception(sprintf('database deletion failed: %s', $this->database->errorMessage())); } } catch (\Exception $exception) { diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index 83e238394..734046afb 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -53,7 +53,7 @@ class DBStructure throw new \Asika\SimpleConsole\CommandArgsException('The version number must be numeric'); } - DI::keyValue()->set( 'build', $version); + DI::keyValue()->set('build', $version); echo DI::l10n()->t('The database version had been set to %s.', $version); } @@ -176,14 +176,14 @@ class DBStructure public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false): string { if ($enable_maintenance_mode) { - DI::keyValue()->set( 'maintenance', 1); + DI::keyValue()->set('maintenance', 1); } $status = self::update($verbose, true); if ($enable_maintenance_mode) { - DI::keyValue()->set( 'maintenance', 0); - DI::keyValue()->set( 'maintenance_reason', ''); + DI::keyValue()->set('maintenance', 0); + DI::keyValue()->set('maintenance_reason', ''); } return $status; @@ -213,7 +213,7 @@ class DBStructure */ private static function update(bool $verbose, bool $action, bool $install = false, array $tables = null, array $definition = null): string { - $in_maintenance_mode = DI::keyValue()->get('system', 'maintenance'); + $in_maintenance_mode = DI::keyValue()->get('system', 'maintenance'); if ($action && !$install && self::isUpdating()) { return DI::l10n()->t('Another database update is currently running.'); @@ -494,9 +494,9 @@ class DBStructure if ($action && !$install) { if ($errors) { - DI::config()->set('system', 'dbupdate', self::UPDATE_FAILED); + DI::config()->set('system', 'dbupdate', self::UPDATE_FAILED); } else { - DI::config()->set( 'system', 'dbupdate', self::UPDATE_SUCCESSFUL); + DI::config()->set('system', 'dbupdate', self::UPDATE_SUCCESSFUL); } } diff --git a/src/Module/Admin/Summary.php b/src/Module/Admin/Summary.php index 42098c95c..46f9d440b 100644 --- a/src/Module/Admin/Summary.php +++ b/src/Module/Admin/Summary.php @@ -98,7 +98,7 @@ class Summary extends BaseAdmin $warningtext[] = DI::l10n()->t('The last update failed. Please run "php bin/console.php dbstructure update" from the command line and have a look at the errors that might appear. (Some of the errors are possibly inside the logfile.)'); } - $last_worker_call = DI::keyValue()->get('last_worker_execution') ?? false; + $last_worker_call = DI::keyValue()->get('last_worker_execution'); if (!$last_worker_call) { $warningtext[] = DI::l10n()->t('The worker was never executed. Please check your database structure!'); } elseif ((strtotime(DateTimeFormat::utcNow()) - strtotime($last_worker_call)) > 60 * 60) { From f944a2a620a46ff175267d97a2202dd15c860ab7 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:13:39 +0100 Subject: [PATCH 17/27] rollback unwanted change --- src/Console/AutomaticInstallation.php | 4 ++-- src/Console/Config.php | 4 ++-- src/Console/Maintenance.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Console/AutomaticInstallation.php b/src/Console/AutomaticInstallation.php index 85cfa710c..1a6d10c24 100644 --- a/src/Console/AutomaticInstallation.php +++ b/src/Console/AutomaticInstallation.php @@ -100,12 +100,12 @@ Examples HELP; } - public function __construct(App\Mode $appMode, Cache $keyValueCache, IManageConfigValues $config, Database $dba, array $argv = null) + public function __construct(App\Mode $appMode, Cache $configCache, IManageConfigValues $config, Database $dba, array $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->configCache = $keyValueCache; + $this->configCache = $configCache; $this->config = $config; $this->dba = $dba; } diff --git a/src/Console/Config.php b/src/Console/Config.php index 1e88d36a8..760b1ca51 100644 --- a/src/Console/Config.php +++ b/src/Console/Config.php @@ -94,12 +94,12 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, IManageConfigValues $keyValue, array $argv = null) + public function __construct(App\Mode $appMode, IManageConfigValues $config, array $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->config = $keyValue; + $this->config = $config; } protected function doExecute(): int diff --git a/src/Console/Maintenance.php b/src/Console/Maintenance.php index e9909ed05..7744c9ee4 100644 --- a/src/Console/Maintenance.php +++ b/src/Console/Maintenance.php @@ -69,12 +69,12 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, IManageConfigValues $keyValue, $argv = null) + public function __construct(App\Mode $appMode, IManageConfigValues $config, $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->config = $keyValue; + $this->config = $config; } protected function doExecute(): int From 7c4c40906099244c966ea9eb3e412fea8d17d28c Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:36:08 +0100 Subject: [PATCH 18/27] Change key-value table - Make "k" as primary key - Added "updated_at" --- database.sql | 22 +++++++++-- doc/database/db_key-value.md | 17 ++++----- .../Type/DBKeyValueStorage.php | 5 ++- static/dbstructure.config.php | 7 ++-- .../KeyValueStorage/DBKeyValueStorageTest.php | 38 +++++++++++++++++-- 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/database.sql b/database.sql index 4384d44f8..892de72f1 100644 --- a/database.sql +++ b/database.sql @@ -843,11 +843,10 @@ CREATE TABLE IF NOT EXISTS `intro` ( -- TABLE key-value -- CREATE TABLE IF NOT EXISTS `key-value` ( - `id` int unsigned NOT NULL auto_increment COMMENT '', - `k` varbinary(50) NOT NULL DEFAULT '' COMMENT '', + `k` varbinary(50) NOT NULL COMMENT '', `v` mediumtext COMMENT '', - PRIMARY KEY(`id`), - UNIQUE INDEX `k` (`k`) + `updated_at` int unsigned NOT NULL COMMENT 'timestamp of the last update', + PRIMARY KEY(`k`) ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='A key value storage'; -- @@ -1843,6 +1842,21 @@ CREATE TABLE IF NOT EXISTS `worker-ipc` ( PRIMARY KEY(`key`) ) ENGINE=MEMORY DEFAULT COLLATE utf8mb4_general_ci COMMENT='Inter process communication between the frontend and the worker'; +-- +-- TABLE advancedcontentfilter_rules +-- +CREATE TABLE IF NOT EXISTS `advancedcontentfilter_rules` ( + `id` int unsigned NOT NULL auto_increment COMMENT 'Auto incremented rule id', + `uid` int unsigned NOT NULL COMMENT 'Owner user id', + `name` varchar(255) NOT NULL COMMENT 'Rule name', + `expression` mediumtext NOT NULL COMMENT 'Expression text', + `serialized` mediumtext NOT NULL COMMENT 'Serialized parsed expression', + `active` boolean NOT NULL DEFAULT '1' COMMENT 'Whether the rule is active or not', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Creation date', + PRIMARY KEY(`id`), + INDEX `uid_active` (`uid`,`active`) +) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Advancedcontentfilter addon rules'; + -- -- VIEW application-view -- diff --git a/doc/database/db_key-value.md b/doc/database/db_key-value.md index a346e6827..514fdaa69 100644 --- a/doc/database/db_key-value.md +++ b/doc/database/db_key-value.md @@ -6,19 +6,18 @@ A key value storage Fields ------ -| Field | Description | Type | Null | Key | Default | Extra | -| ----- | ----------- | ------------- | ---- | --- | ------- | -------------- | -| id | | int unsigned | NO | PRI | NULL | auto_increment | -| k | | varbinary(50) | NO | | | | -| v | | mediumtext | YES | | NULL | | +| Field | Description | Type | Null | Key | Default | Extra | +| ---------- | ---------------------------- | ------------- | ---- | --- | ------- | ----- | +| k | | varbinary(50) | NO | PRI | NULL | | +| v | | mediumtext | YES | | NULL | | +| updated_at | timestamp of the last update | int unsigned | YES | | NULL | | Indexes ------------ -| Name | Fields | -| ------- | --------- | -| PRIMARY | id | -| k | UNIQUE, k | +| Name | Fields | +| ------- | ------ | +| PRIMARY | k | Return to [database documentation](help/database) diff --git a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php index 60e6087e2..1c9e44ce8 100644 --- a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php +++ b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php @@ -89,7 +89,10 @@ class DBKeyValueStorage extends AbstractKeyValueStorage $dbValue = ValueConversion::toDbValue($value); - $return = $this->database->update(self::DB_KEY_VALUE_TABLE, ['v' => $dbValue], ['k' => $offset], true); + $return = $this->database->update(self::DB_KEY_VALUE_TABLE, [ + 'v' => $dbValue, + 'updated_at' => time() + ], ['k' => $offset], true); if (!$return) { throw new \Exception(sprintf('database update failed: %s', $this->database->errorMessage())); diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 0128b0343..3b3d6067c 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -892,13 +892,12 @@ return [ "key-value" => [ "comment" => "A key value storage", "fields" => [ - "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => ""], - "k" => ["type" => "varbinary(50)", "not null" => "1", "default" => "", "comment" => ""], + "k" => ["type" => "varbinary(50)", "not null" => "1", "primary" => "1", "comment" => ""], "v" => ["type" => "mediumtext", "comment" => ""], + "updated_at" => ["type" => "int unsigned", "not null" => "0", "comment" => "timestamp of the last update"], ], "indexes" => [ - "PRIMARY" => ["id"], - "k" => ["UNIQUE", "k"], + "PRIMARY" => ["k"], ], ], "locks" => [ diff --git a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php index 16fa9ab7e..967da78a4 100644 --- a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php +++ b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php @@ -24,6 +24,7 @@ namespace Friendica\Test\src\Core\KeyValueStorage; use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; use Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage; +use Friendica\Database\Database; use Friendica\Database\Definition\DbaDefinition; use Friendica\Database\Definition\ViewDefinition; use Friendica\Test\DatabaseTestTrait; @@ -35,6 +36,9 @@ class DBKeyValueStorageTest extends KeyValueStorageTest { use DatabaseTestTrait; + /** @var Database */ + protected $database; + protected function setUp(): void { parent::setUp(); @@ -56,9 +60,37 @@ class DBKeyValueStorageTest extends KeyValueStorageTest $basePath = new BasePath(dirname(__FILE__, 5), $_SERVER); - $database = new StaticDatabase($cache, new Profiler($cache), (new DbaDefinition($basePath->getPath()))->load(), (new ViewDefinition($basePath->getPath()))->load()); - $database->setTestmode(true); + $this->database = new StaticDatabase($cache, new Profiler($cache), (new DbaDefinition($basePath->getPath()))->load(), (new ViewDefinition($basePath->getPath()))->load()); + $this->database->setTestmode(true); - return new DBKeyValueStorage($database); + return new DBKeyValueStorage($this->database); + } + + /** @dataProvider dataTests */ + public function testUpdatedAt($k, $v) + { + $instance = $this->getInstance(); + + $instance->set($k, $v); + + self::assertEquals($v, $instance->get($k)); + self::assertEquals($v, $instance[$k]); + + $entry = $this->database->selectFirst(DBKeyValueStorage::DB_KEY_VALUE_TABLE, ['updated_at'], ['k' => $k]); + self::assertNotEmpty($entry); + + $updateAt = $entry['updated_at']; + + $instance->set($k, 'another_value'); + + self::assertEquals('another_value', $instance->get($k)); + self::assertEquals('another_value', $instance[$k]); + + $entry = $this->database->selectFirst(DBKeyValueStorage::DB_KEY_VALUE_TABLE, ['updated_at'], ['k' => $k]); + self::assertNotEmpty($entry); + + $updateAtAfter = $entry['updated_at']; + + self::assertLessThanOrEqual($updateAt, $updateAtAfter); } } From 8894b482dc9487c3e5dd6372f3d27b0775596e73 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:36:45 +0100 Subject: [PATCH 19/27] Find last "update_" config entry occurrence --- src/Module/Admin/DBSync.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Module/Admin/DBSync.php b/src/Module/Admin/DBSync.php index 3ab9fb799..70d835fcd 100644 --- a/src/Module/Admin/DBSync.php +++ b/src/Module/Admin/DBSync.php @@ -76,13 +76,13 @@ class DBSync extends BaseAdmin $o = DI::l10n()->t("Executing %s failed with error: %s", $func, $retval); } elseif ($retval === Update::SUCCESS) { $o = DI::l10n()->t('Update %s was successfully applied.', $func); - DI::config()->set('database', $func, 'success'); + DI::keyValue()->set(sprintf('database_%s', $func), 'success'); } else { $o = DI::l10n()->t('Update %s did not return a status. Unknown if it succeeded.', $func); } } else { $o = DI::l10n()->t('There was no additional update function %s that needed to be called.', $func) . "
"; - DI::config()->set('database', $func, 'success'); + DI::keyValue()->set(sprintf('database_%s', $func), 'success'); } return $o; From 86f80af432e0399494384152a3708c411d00a125 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:37:12 +0100 Subject: [PATCH 20/27] Rename Interface --- src/Console/PostUpdate.php | 6 +++--- ...ICanManageKeyValuePairs.php => IManageKeyValuePairs.php} | 2 +- src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php | 4 ++-- src/DI.php | 4 ++-- static/dependencies.config.php | 2 +- tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php | 4 ++-- tests/src/Core/KeyValueStorage/KeyValueStorageTest.php | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) rename src/Core/KeyValueStorage/Capabilities/{ICanManageKeyValuePairs.php => IManageKeyValuePairs.php} (97%) diff --git a/src/Console/PostUpdate.php b/src/Console/PostUpdate.php index cf15fe3e3..702b12710 100644 --- a/src/Console/PostUpdate.php +++ b/src/Console/PostUpdate.php @@ -22,7 +22,7 @@ namespace Friendica\Console; use Friendica\App; -use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; use Friendica\Core\L10n; use Friendica\Core\Update; @@ -38,7 +38,7 @@ class PostUpdate extends \Asika\SimpleConsole\Console */ private $appMode; /** - * @var ICanManageKeyValuePairs + * @var IManageKeyValuePairs */ private $keyValue; /** @@ -60,7 +60,7 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, ICanManageKeyValuePairs $keyValue, L10n $l10n, array $argv = null) + public function __construct(App\Mode $appMode, IManageKeyValuePairs $keyValue, L10n $l10n, array $argv = null) { parent::__construct($argv); diff --git a/src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php b/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php similarity index 97% rename from src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php rename to src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php index 11c8b772b..64b317bf1 100644 --- a/src/Core/KeyValueStorage/Capabilities/ICanManageKeyValuePairs.php +++ b/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php @@ -26,7 +26,7 @@ use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceExceptio /** * Interface for Friendica specific Key-Value pair storage */ -interface ICanManageKeyValuePairs extends \ArrayAccess +interface IManageKeyValuePairs extends \ArrayAccess { /** * Get a particular value from the KeyValue Storage diff --git a/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php index cfcebb6ff..169d27f69 100644 --- a/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php +++ b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php @@ -21,12 +21,12 @@ namespace Friendica\Core\KeyValueStorage\Type; -use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; /** * An abstract helper class for Key-Value storage classes */ -abstract class AbstractKeyValueStorage implements ICanManageKeyValuePairs +abstract class AbstractKeyValueStorage implements IManageKeyValuePairs { /** {@inheritDoc} */ public function get(string $key) diff --git a/src/DI.php b/src/DI.php index a430b0daa..ecdf92530 100644 --- a/src/DI.php +++ b/src/DI.php @@ -181,9 +181,9 @@ abstract class DI return self::$dice->create(Core\Config\Capability\IManageConfigValues::class); } - public static function keyValue(): Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs + public static function keyValue(): Core\KeyValueStorage\Capabilities\IManageKeyValuePairs { - return self::$dice->create(Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs::class); + return self::$dice->create(Core\KeyValueStorage\Capabilities\IManageKeyValuePairs::class); } /** diff --git a/static/dependencies.config.php b/static/dependencies.config.php index 645ab968e..116874445 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -245,7 +245,7 @@ return [ ['getBackend', [], Dice::CHAIN_CALL], ], ], - \Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs::class => [ + \Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs::class => [ 'instanceOf' => \Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage::class, ], Network\HTTPClient\Capability\ICanSendHttpRequests::class => [ diff --git a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php index 967da78a4..1492c3de5 100644 --- a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php +++ b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php @@ -22,7 +22,7 @@ namespace Friendica\Test\src\Core\KeyValueStorage; use Friendica\Core\Config\ValueObject\Cache; -use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; use Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage; use Friendica\Database\Database; use Friendica\Database\Definition\DbaDefinition; @@ -53,7 +53,7 @@ class DBKeyValueStorageTest extends KeyValueStorageTest $this->tearDownDb(); } - public function getInstance(): ICanManageKeyValuePairs + public function getInstance(): IManageKeyValuePairs { $cache = new Cache(); $cache->set('database', 'disable_pdo', true); diff --git a/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php index 6c393310d..b3aee20f5 100644 --- a/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php +++ b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php @@ -21,18 +21,18 @@ namespace Friendica\Test\src\Core\KeyValueStorage; -use Friendica\Core\KeyValueStorage\Capabilities\ICanManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; use Friendica\Test\MockedTest; abstract class KeyValueStorageTest extends MockedTest { - abstract public function getInstance(): ICanManageKeyValuePairs; + abstract public function getInstance(): IManageKeyValuePairs; public function testInstance() { $instance = $this->getInstance(); - self::assertInstanceOf(ICanManageKeyValuePairs::class, $instance); + self::assertInstanceOf(IManageKeyValuePairs::class, $instance); } public function dataTests(): array From a330a3c22d215637c01c5112a37b5af53a5d9e66 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:38:01 +0100 Subject: [PATCH 21/27] Make PHP-CS happy again --- src/Core/KeyValueStorage/Type/DBKeyValueStorage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php index 1c9e44ce8..de8320c5e 100644 --- a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php +++ b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php @@ -90,7 +90,7 @@ class DBKeyValueStorage extends AbstractKeyValueStorage $dbValue = ValueConversion::toDbValue($value); $return = $this->database->update(self::DB_KEY_VALUE_TABLE, [ - 'v' => $dbValue, + 'v' => $dbValue, 'updated_at' => time() ], ['k' => $offset], true); From f95d5c7f89c4b27414f96a9cd58cd5ef44c075de Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:47:20 +0100 Subject: [PATCH 22/27] Remove accidentally created table --- database.sql | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/database.sql b/database.sql index 892de72f1..2ae33689c 100644 --- a/database.sql +++ b/database.sql @@ -1842,21 +1842,6 @@ CREATE TABLE IF NOT EXISTS `worker-ipc` ( PRIMARY KEY(`key`) ) ENGINE=MEMORY DEFAULT COLLATE utf8mb4_general_ci COMMENT='Inter process communication between the frontend and the worker'; --- --- TABLE advancedcontentfilter_rules --- -CREATE TABLE IF NOT EXISTS `advancedcontentfilter_rules` ( - `id` int unsigned NOT NULL auto_increment COMMENT 'Auto incremented rule id', - `uid` int unsigned NOT NULL COMMENT 'Owner user id', - `name` varchar(255) NOT NULL COMMENT 'Rule name', - `expression` mediumtext NOT NULL COMMENT 'Expression text', - `serialized` mediumtext NOT NULL COMMENT 'Serialized parsed expression', - `active` boolean NOT NULL DEFAULT '1' COMMENT 'Whether the rule is active or not', - `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Creation date', - PRIMARY KEY(`id`), - INDEX `uid_active` (`uid`,`active`) -) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Advancedcontentfilter addon rules'; - -- -- VIEW application-view -- From 9936081c7e38e82e930aa759363052aa6c682deb Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 22:56:27 +0100 Subject: [PATCH 23/27] Fix DBA lock test --- .../src/Core/Lock/DatabaseLockDriverTest.php | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/src/Core/Lock/DatabaseLockDriverTest.php b/tests/src/Core/Lock/DatabaseLockDriverTest.php index bd4cb9cc9..70c5f3764 100644 --- a/tests/src/Core/Lock/DatabaseLockDriverTest.php +++ b/tests/src/Core/Lock/DatabaseLockDriverTest.php @@ -21,15 +21,16 @@ namespace Friendica\Test\src\Core\Lock; +use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Lock\Type\DatabaseLock; -use Friendica\Core\Config\Factory\Config; -use Friendica\DI; +use Friendica\Database\Database; +use Friendica\Database\Definition\DbaDefinition; +use Friendica\Database\Definition\ViewDefinition; use Friendica\Test\DatabaseTestTrait; use Friendica\Test\Util\Database\StaticDatabase; use Friendica\Test\Util\VFSTrait; +use Friendica\Util\BasePath; use Friendica\Util\Profiler; -use Mockery; -use Psr\Log\NullLogger; class DatabaseLockDriverTest extends LockTest { @@ -38,6 +39,9 @@ class DatabaseLockDriverTest extends LockTest protected $pid = 123; + /** @var Database */ + protected $database; + protected function setUp(): void { $this->setUpVfsDir(); @@ -49,7 +53,15 @@ class DatabaseLockDriverTest extends LockTest protected function getInstance() { - return new DatabaseLock(DI::dba(), $this->pid); + $cache = new Cache(); + $cache->set('database', 'disable_pdo', true); + + $basePath = new BasePath(dirname(__FILE__, 5), $_SERVER); + + $this->database = new StaticDatabase($cache, new Profiler($cache), (new DbaDefinition($basePath->getPath()))->load(), (new ViewDefinition($basePath->getPath()))->load()); + $this->database->setTestmode(true); + + return new DatabaseLock($this->database, $this->pid); } protected function tearDown(): void From 0d6a4c8951f2cb5af72804c9584ca5b685beb1d8 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 23:27:36 +0100 Subject: [PATCH 24/27] fix SQL --- database.sql | 2 +- static/dbstructure.config.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database.sql b/database.sql index 2ae33689c..b7d4ac35d 100644 --- a/database.sql +++ b/database.sql @@ -845,7 +845,7 @@ CREATE TABLE IF NOT EXISTS `intro` ( CREATE TABLE IF NOT EXISTS `key-value` ( `k` varbinary(50) NOT NULL COMMENT '', `v` mediumtext COMMENT '', - `updated_at` int unsigned NOT NULL COMMENT 'timestamp of the last update', + `updated_at` int unsigned COMMENT 'timestamp of the last update', PRIMARY KEY(`k`) ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='A key value storage'; diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 3b3d6067c..7ced8172f 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -894,7 +894,7 @@ return [ "fields" => [ "k" => ["type" => "varbinary(50)", "not null" => "1", "primary" => "1", "comment" => ""], "v" => ["type" => "mediumtext", "comment" => ""], - "updated_at" => ["type" => "int unsigned", "not null" => "0", "comment" => "timestamp of the last update"], + "updated_at" => ["type" => "int unsigned", "comment" => "timestamp of the last update"], ], "indexes" => [ "PRIMARY" => ["k"], From f96aec18cc4110394bcc1959fabd1a90f5fc93cc Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 29 Dec 2022 23:38:14 +0100 Subject: [PATCH 25/27] Fixup maintenance mode --- src/Database/DBStructure.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index 734046afb..7de6799cf 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -176,14 +176,14 @@ class DBStructure public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false): string { if ($enable_maintenance_mode) { - DI::keyValue()->set('maintenance', 1); + DI::config()->set('system', 'maintenance', 1); } $status = self::update($verbose, true); if ($enable_maintenance_mode) { - DI::keyValue()->set('maintenance', 0); - DI::keyValue()->set('maintenance_reason', ''); + DI::config()->set('system', 'maintenance', 0); + DI::config()->set('system', 'maintenance_reason', ''); } return $status; @@ -213,7 +213,7 @@ class DBStructure */ private static function update(bool $verbose, bool $action, bool $install = false, array $tables = null, array $definition = null): string { - $in_maintenance_mode = DI::keyValue()->get('system', 'maintenance'); + $in_maintenance_mode = DI::config()->get('system', 'maintenance'); if ($action && !$install && self::isUpdating()) { return DI::l10n()->t('Another database update is currently running.'); From 12df6297d7d164201b7717dd6ef0263f05493a5b Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 29 Dec 2022 11:37:36 -0500 Subject: [PATCH 26/27] Remove attachment tags before checking for end of body images --- src/Model/Item.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Model/Item.php b/src/Model/Item.php index 112c36a9c..8a533ee70 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -3016,6 +3016,8 @@ class Item $item['hashtags'] = $tags['hashtags']; $item['mentions'] = $tags['mentions']; + $item['body'] = preg_replace("#\s*\[attachment .*?].*?\[/attachment]\s*#ism", "\n", $item['body']); + if (!$is_preview) { $item['body'] = Post\Media::removeFromEndOfBody($item['body'] ?? ''); } @@ -3065,8 +3067,6 @@ class Item $attachments = Post\Media::splitAttachments($item['uri-id'], $shared_links, $item['has-media'] ?? false); $item['body'] = self::replaceVisualAttachments($attachments, $item['body'] ?? ''); - $item['body'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']); - self::putInCache($item); $item['body'] = $body; $s = $item["rendered-html"]; @@ -3166,7 +3166,7 @@ class Item ], ]); } - + /** * Check if the body contains a link From 00eaa99eb3abc552791bf95fb20879e4bc999073 Mon Sep 17 00:00:00 2001 From: Philipp Date: Fri, 30 Dec 2022 17:15:15 +0100 Subject: [PATCH 27/27] Make updated_at not nullable, it should get set at the creation as well --- database.sql | 2 +- doc/database/db_key-value.md | 2 +- static/dbstructure.config.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/database.sql b/database.sql index b7d4ac35d..2ae33689c 100644 --- a/database.sql +++ b/database.sql @@ -845,7 +845,7 @@ CREATE TABLE IF NOT EXISTS `intro` ( CREATE TABLE IF NOT EXISTS `key-value` ( `k` varbinary(50) NOT NULL COMMENT '', `v` mediumtext COMMENT '', - `updated_at` int unsigned COMMENT 'timestamp of the last update', + `updated_at` int unsigned NOT NULL COMMENT 'timestamp of the last update', PRIMARY KEY(`k`) ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='A key value storage'; diff --git a/doc/database/db_key-value.md b/doc/database/db_key-value.md index 514fdaa69..2ed3baa48 100644 --- a/doc/database/db_key-value.md +++ b/doc/database/db_key-value.md @@ -10,7 +10,7 @@ Fields | ---------- | ---------------------------- | ------------- | ---- | --- | ------- | ----- | | k | | varbinary(50) | NO | PRI | NULL | | | v | | mediumtext | YES | | NULL | | -| updated_at | timestamp of the last update | int unsigned | YES | | NULL | | +| updated_at | timestamp of the last update | int unsigned | NO | | NULL | | Indexes ------------ diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 7ced8172f..25e416d50 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -894,7 +894,7 @@ return [ "fields" => [ "k" => ["type" => "varbinary(50)", "not null" => "1", "primary" => "1", "comment" => ""], "v" => ["type" => "mediumtext", "comment" => ""], - "updated_at" => ["type" => "int unsigned", "comment" => "timestamp of the last update"], + "updated_at" => ["type" => "int unsigned", "not null" => "1", "comment" => "timestamp of the last update"], ], "indexes" => [ "PRIMARY" => ["k"],