Porównaj commity

...

181 Commity

Autor SHA1 Wiadomość Data
Hypolite Petovan 0ccb3e7efe
Merge pull request #14017 from annando/active-admin-check
Automatically close the registration when the admin is inactive
2024-03-22 11:52:24 +00:00
Michael 4b695e361c Automatically close the registration when the admin is inactive 2024-03-22 04:19:40 +00:00
Hypolite Petovan 4834255acf
Merge pull request #14015 from annando/did
Internal support for Bluesky tokens
2024-03-21 22:10:09 +00:00
Michael 325932dc5a Internal support for Bluesky tokens 2024-03-21 21:33:12 +00:00
Hypolite Petovan faac52e078
Merge pull request #14020 from annando/issue-13714
Issue 13714: Support for "commentsEnabled" and "capabilities"
2024-03-21 17:21:51 +00:00
Michael 7a0c5d141e Issue 13714: Support for "commentsEnabled" and "capabilities" 2024-03-21 17:11:20 +00:00
Hypolite Petovan 732d738b82
Merge pull request #14022 from annando/channel-only
Possibility to mark contacts as "channel only"
2024-03-21 16:11:49 +00:00
Michael 3d267c7b8f Possibility to mark contacts as "channel only" 2024-03-21 13:20:52 +00:00
Hypolite Petovan 987e6c5ea6
Merge pull request #14016 from annando/issue-13787
Issue 13787: Filter in circles editor by contact relation
2024-03-21 13:07:57 +00:00
Hypolite Petovan 9e240c24ce
Merge pull request #14023 from annando/files
Updated database.sql / messages.po
2024-03-21 13:03:31 +00:00
Michael 3b419cae1e Issue 13787: Filter in circles editor by contact relation 2024-03-21 12:58:54 +00:00
Hypolite Petovan 56f3743e75
Merge pull request #14021 from annando/worker-idletime
Execute a worker task when there hadn't one for some seconds
2024-03-21 12:41:20 +00:00
Hypolite Petovan f26f35f009
Merge pull request #14018 from annando/content-type-check
Improved Content-Type check on incoming requests
2024-03-21 11:58:08 +00:00
Michael fdd777d75d Updated database.sql / messages.po 2024-03-21 10:49:42 +00:00
Michael aff45278e1 Execute a worker task when there hadn't one for some seconds 2024-03-21 09:10:07 +00:00
Michael 11a16589da Improved Content-Type check on incoming requests 2024-03-21 09:02:25 +00:00
Tobias Diekershoff f60638787e added empty 2024.06 block to the CHANGELOG 2024-03-21 08:10:42 +01:00
Tobias Diekershoff c5936bb51e bump version to 2024.06-dev 2024-03-21 08:09:16 +01:00
Tobias Diekershoff f13c5dcbaf bump version to 2024.03 2024-03-21 08:01:47 +01:00
Tobias Diekershoff 2fcd090b11 new expiration date for security.txt 2024-03-21 08:01:12 +01:00
Tobias Diekershoff 4aa53beaea Merge branch '2024.03-rc' into stable 2024-03-21 07:58:02 +01:00
Tobias Diekershoff 25a22ad3ae set release date in CHANGELOG 2024-03-21 07:56:18 +01:00
Tobias Diekershoff ae217ce27c
Merge pull request #13963 from tobiasd/2024.03-CHANGELOG
CHANGELOG for 2024.03
2024-03-21 07:54:54 +01:00
Hypolite Petovan 17dea0aa5a
Merge pull request #14013 from foss-/patch-13
Update FAQ.md
2024-03-21 00:20:14 +00:00
foss- bd142218c1
Update FAQ.md
fix Windows link for Whalebird
2024-03-21 00:12:42 +01:00
Michael Vogel ce8d0b3b57
Merge pull request #14011 from MrPetovan/task/composer
Update Composer dependencies ahead of release
2024-03-20 10:00:31 +01:00
Hypolite Petovan 8f7edcef22 Update Composer dependencies ahead of release
Main changes:
- Updating matriphe/iso-639 (1.2 => 1.3)
- Updating phpseclib/phpseclib (3.0.35 => 3.0.37)
- Updating smarty/smarty (v4.3.4 => v4.5.1)
- Updating composer/ca-bundle (1.4.0 => 1.5.0)

Dev changes:
- Updating mockery/mockery (1.6.7 => 1.6.10)
- Updating sebastian/resource-operations (3.0.3 => 3.0.4)
- Updating sebastian/global-state (5.0.6 => 5.0.7)
- Updating sebastian/exporter (4.0.5 => 4.0.6)
- Updating sebastian/diff (4.0.5 => 4.0.6)
- Updating sebastian/cli-parser (1.0.1 => 1.0.2)
- Updating theseer/tokenizer (1.2.2 => 1.2.3)
- Updating nikic/php-parser (v5.0.0 => v5.0.2)
- Updating phpunit/php-code-coverage (9.2.30 => 9.2.31)
- Updating phar-io/manifest (2.0.3 => 2.0.4)
- Updating phpunit/phpunit (9.6.15 => 9.6.17)
- Updating symfony/stopwatch (v5.4.21 => v5.4.35)
- Updating symfony/polyfill-php80 (v1.28.0 => v1.29.0)
- Updating symfony/process (v5.4.34 => v5.4.36)
- Updating symfony/polyfill-php81 (v1.28.0 => v1.29.0)
- Updating symfony/polyfill-mbstring (v1.28.0 => v1.29.0)
- Updating symfony/polyfill-php73 (v1.28.0 => v1.29.0)
- Updating symfony/finder (v5.4.27 => v5.4.35)
- Updating symfony/polyfill-ctype (v1.28.0 => v1.29.0)
- Updating symfony/filesystem (v5.4.25 => v5.4.35)
- Updating symfony/event-dispatcher (v5.4.34 => v5.4.35)
- Updating symfony/polyfill-intl-normalizer (v1.28.0 => v1.29.0)
- Updating symfony/polyfill-intl-grapheme (v1.28.0 => v1.29.0)
- Updating symfony/string (v5.4.34 => v5.4.36)
- Updating symfony/console (v5.4.34 => v5.4.36)
- Updating composer/pcre (3.1.1 => 3.1.3)
- Updating friendsofphp/php-cs-fixer (v3.46.0 => v3.52.1)
2024-03-19 23:19:43 -04:00
Hypolite Petovan 2f526f7a80
Merge pull request #14010 from friendica/2024.03-CREDITS
updated the credits
2024-03-18 16:40:11 +00:00
Tobias Diekershoff 2780b3e3a4 updated CHANGELOG 2024-03-18 17:21:18 +01:00
Tobias Diekershoff 2785b074f8 updated the credits 2024-03-18 17:08:46 +01:00
Hypolite Petovan 8a693fed37
Merge pull request #13991 from foss-/patch-13
Re-wrote themes.md
2024-03-18 12:35:11 +00:00
Hypolite Petovan 6f5585ffd7
Merge pull request #14009 from foss-/patch-15
Update FAQ.md
2024-03-18 04:26:59 +00:00
foss- c9f6590353
Update FAQ.md
- Pachli website instead of GitHub link
2024-03-18 04:32:09 +01:00
foss- 3f1cac2251
Update doc/FAQ.md
- link to tusky website

Co-authored-by: Hypolite Petovan <hypolite@mrpetovan.com>
2024-03-18 04:30:29 +01:00
Hypolite Petovan 3a8f1f6304
Merge pull request #14008 from foss-/patch-14
Update API-Mastodon.md
2024-03-18 02:25:58 +00:00
foss- a5c265b6aa
Update FAQ.md
- fix typo
- added Pachli
- fixed Subway Tooter F-Droid link and specified Izzy repo)
- removed Fedi (last update in 2021, https://fediapp.com/ dead)
- updated Husky repo link
- changed tusky link to repo instead of website
2024-03-18 00:53:24 +01:00
foss- ea79782a93
Update API-Mastodon.md Fixes #13914
- removed unsupported clients (information is no longer accurate) and simplified Clients section
- new API Endpoints were added in https://github.com/friendica/friendica/pull/14007
2024-03-18 00:24:06 +01:00
Hypolite Petovan 882673c260
Merge pull request #14007 from annando/api-documentation
Slightly updated API documentation
2024-03-17 15:02:22 +00:00
Michael 668bb3e6f4 Slightly updated API documentation 2024-03-17 14:40:35 +00:00
Hypolite Petovan 7331e44a1c
Merge pull request #14006 from annando/accounttype
Fix accounttype/nosharer url
2024-03-16 17:19:55 +00:00
Michael 1ffdb19c8e Fix accounttype/nosharer url 2024-03-16 16:44:25 +00:00
Hypolite Petovan 5c62d91960
Merge pull request #14005 from annando/issue-13984
Issue 13984: Fix preview picture
2024-03-16 15:07:54 +00:00
Hypolite Petovan 7615a3103f
Merge pull request #14002 from annando/relais-update
Fix handling of relay contact updates
2024-03-16 15:07:16 +00:00
Michael 2ecdd683ac Issue 13984: Fix preview picture 2024-03-16 10:30:43 +00:00
Michael a9b78d1974 Merge remote-tracking branch 'upstream/2024.03-rc' into relais-update 2024-03-16 08:35:56 +00:00
Michael Vogel e6c23e69cc
Apply suggestions from code review
Co-authored-by: Hypolite Petovan <hypolite@mrpetovan.com>
2024-03-16 09:19:57 +01:00
Hypolite Petovan c81a47c764
Merge pull request #14004 from annando/warning
Fix "Undefined variable $success"
2024-03-16 08:15:42 +00:00
Hypolite Petovan 4bbc1d84ce
Merge pull request #14003 from annando/issue-14001
Issue 14001: Fix "Incorrect integer value"
2024-03-16 08:14:45 +00:00
Hypolite Petovan f7cb9ec504
Merge pull request #14000 from nupplaphil/feat/CI_php83
[CI] Add PHP 8.3 and upgrade CI images
2024-03-16 08:08:01 +00:00
Michael 28363a5416 Fix "Undefined variable $success" 2024-03-16 07:58:51 +00:00
Michael f1be6d5181 Issue 14001: Fix "Incorrect integer value" 2024-03-16 07:53:12 +00:00
Michael b75fdbbd32 Fix handling of relais contact updates 2024-03-16 05:30:21 +00:00
Philipp 9ce2142d99
Adhere deprecation notes
- Use `when:`
- Remove `group: lint`
2024-03-15 23:59:08 +01:00
Philipp 4f24247aa7
Use PHP 8.2 for other pipelines 2024-03-15 23:58:31 +01:00
Philipp 0eec20d203
Use PHP 8.2 for codecoverage 2024-03-15 23:58:31 +01:00
Philipp adeb9af502
Update PHP 8.1 and PHP 8.2 CI image 2024-03-15 23:03:44 +01:00
Philipp c577773e07
[CI] Add PHP 8.3 2024-03-15 22:55:48 +01:00
Tobias Diekershoff b8396daca2
Merge pull request #13998 from annando/probe-hide
Fix: "unsearchable" is now stored
2024-03-15 07:24:13 +01:00
Michael eaddf5318a Fix: "unsearchable" is now stored 2024-03-15 06:07:47 +00:00
Tobias Diekershoff aee9a61fb1 added missing closed issue 2024-03-14 08:42:42 +01:00
Tobias Diekershoff 81b5ed160b Updated CHANGELOG 2024-03-14 08:40:55 +01:00
Tobias Diekershoff 49b79d0457
Merge pull request #13993 from annando/statistics
Systems added to the federation statistics
2024-03-14 07:35:23 +01:00
Michael 8ce1797480 Systems added to the federation statistics 2024-03-14 04:33:19 +00:00
foss- 650aa089d9
Re-wrote themes.md
- rewrite to reflect new default theme frio and describe settings options
- old information was obsolete and replaced (please double check)
2024-03-13 12:17:27 +01:00
Michael Vogel 2c689f2b73
Merge pull request #13990 from friendica/bug/profile-rss-xss
Escape HTML characters in profile RSS titles
2024-03-12 21:52:14 +01:00
Hypolite Petovan aac5d41fd6
Escape HTML characters in profile RSS titles
Thanks to @r1pu5u for the tip left through the `security.txt` contact address!
2024-03-12 20:42:00 +00:00
Hypolite Petovan 57187f26ae
Merge pull request #13978 from annando/issue-13972
Default behaviour for adding media types
2024-03-12 20:06:24 +00:00
Hypolite Petovan 7446048d5d
Merge pull request #13987 from annando/api-issues
Fixes API-Issues #13985 and #13986
2024-03-12 19:33:42 +00:00
Hypolite Petovan d3ee4d589b
Merge pull request #13988 from annando/network-groups
"network/group" fragments are removed
2024-03-12 19:31:58 +00:00
Michael fda832cd83 "network/group" fragments are removed 2024-03-12 08:02:00 +00:00
Michael 30f31828ae Fixes API-Issues #13985 and #13986 2024-03-12 03:12:36 +00:00
Tobias Diekershoff cd7a663733
Merge pull request #13983 from annando/fix-notice
Fix notice when sending private messages
2024-03-10 20:09:25 +01:00
Michael 3b024450ff Fix notice when sending private messages 2024-03-10 18:55:58 +00:00
Tobias Diekershoff e22ef85386
Merge pull request #13982 from annando/no-unknown-media
Fix: Don't attach unknown media
2024-03-10 14:28:14 +01:00
Tobias Diekershoff e206175a50
Merge pull request #13980 from annando/mail-summary
Fix: Subject for private messages from Friendica systems
2024-03-10 13:55:09 +01:00
Michael 76d469675e Fix: Don't attach unknown media to posts 2024-03-10 10:14:54 +00:00
Michael 3496d3948a Fix: Subject for private messages from Friendica systems 2024-03-09 22:32:38 +00:00
Michael 00b325d521 Default behaviour for adding media types 2024-03-09 15:45:38 +00:00
Tobias Diekershoff 2077e00eae
Merge pull request #13977 from annando/dont-retry
Don't retry when fetching invalid content
2024-03-09 13:59:36 +01:00
Michael a1427a52b3 Don't offer the invalid content type 2024-03-09 10:46:53 +00:00
Michael 40a47b076d Don't retry when fetching invalid content 2024-03-09 10:37:43 +00:00
Hypolite Petovan f041701765
Merge pull request #13976 from annando/content-type-logging
Centralized logging for a wrong JSON content-type
2024-03-08 11:03:03 -05:00
Michael d9bedbb473 Centralized logging for a wrong JSON content-type 2024-03-08 13:48:21 +00:00
Hypolite Petovan 013bba50bc
Merge pull request #13975 from annando/check-content-type
Check for the content type before fetching the content
2024-03-07 21:58:43 -05:00
Michael 5f0657a30c Don't show the body in the log 2024-03-07 22:29:04 +00:00
Michael 435b30be11 Check for the content type before fetching the content 2024-03-07 22:16:52 +00:00
Hypolite Petovan 73863561d2
Merge pull request #13974 from annando/videoheight
Set default value for max video height
2024-03-07 09:33:11 -05:00
Michael 67696d08da Set default value for max video height 2024-03-07 14:22:40 +00:00
Hypolite Petovan 1b00b91767
Merge pull request #13973 from annando/parent-activity
Change the last activity for delegation parents and siblings as well
2024-03-07 09:02:46 -05:00
Michael 68c2bdb98e Change the last activity for delegation parents and siblings as well 2024-03-07 06:12:36 +00:00
Michael Vogel 54852ecb56
Merge pull request #13970 from MrPetovan/bug/warnings
Address a couple of warnings
2024-03-06 20:13:40 +01:00
Hypolite Petovan 8c4b2107b5 Include author-alias to the field list in mod/photos
- It's used to generate magic links of authors of comments on photos
- Address https://github.com/friendica/friendica/issues/13761#issuecomment-1980738080
2024-03-06 12:07:43 -05:00
Hypolite Petovan 111df607bc Don't call mb_strlen() on $body if it isn't set in Model\Post\Counts
- Address https://github.com/friendica/friendica/issues/13761#issuecomment-1978354153
2024-03-06 12:01:25 -05:00
Tobias Diekershoff b8b76e870d
Merge pull request #13967 from annando/diaspora-avatar
Issue 13939: Fix avatars for Diaspora
2024-03-06 06:55:39 +01:00
Michael 41c89abe68 Update routine added 2024-03-06 03:41:13 +00:00
Michael 24e7556f85 Transmit the user avatar path 2024-03-06 03:25:04 +00:00
Michael 8cc7bad1ea Issue 13939: Fix avatars for Diaspora 2024-03-06 03:00:09 +00:00
Hypolite Petovan 2357385162
Merge pull request #13966 from annando/max-video-height
Reduce the height of portrait videos
2024-03-05 19:01:48 -05:00
Michael 31b92b16ed Reduce the height of portrait videos 2024-03-05 21:25:00 +00:00
Hypolite Petovan 3ad4ab2940
Merge pull request #13965 from annando/last-activity
Improved assigning of "last-activity" and "login_date"
2024-03-05 10:38:41 -05:00
Michael Vogel 5ab81abaa6
Merge pull request #10 from MrPetovan/bug/last-activity-api-fixture-fix
Normalize API fixture data
2024-03-05 16:29:00 +01:00
Hypolite Petovan 1b651519a3 Normalize API fixture data
- Change public contact name to the related local user name
- Add location data to profile record that is used to update self and public contact during Auth
2024-03-05 10:10:15 -05:00
Michael ba07172a65 Compare with the utc value 2024-03-05 14:24:40 +00:00
Michael 72e045e744 Improved assigning of "last-activity" and "login_date" 2024-03-05 14:06:26 +00:00
Tobias Diekershoff 2cedbae206 ypots 2024-03-05 07:14:39 +01:00
Tobias Diekershoff a6b033c4f6 CHANGELOG for 2024.03 2024-03-04 17:38:32 +01:00
Michael Vogel dc96a72173
Merge pull request #13962 from tobiasd/20240304-lng
translation updates
2024-03-04 16:49:13 +01:00
Tobias Diekershoff 38141edbea translation updates 2024-03-04 16:40:13 +01:00
Tobias Diekershoff 9b0e243350
Merge pull request #13961 from annando/issue-13765
Issue 13765: Fixed creation of self user contact for approval
2024-03-04 11:44:55 +01:00
Michael 52cc8ab73b Issue 13765: Fixed creation of self user contact for approval 2024-03-04 07:30:04 +00:00
Hypolite Petovan ea4e66c74c
Merge pull request #13957 from annando/issue-13940
Issue 13940: handle posts that can't be found in contexts
2024-03-03 13:42:00 -05:00
Hypolite Petovan f4826bae52
Merge pull request #13960 from annando/oembed-full-cleanup
Oembed: Some more cleanup
2024-03-03 13:41:35 -05:00
Michael 7471513269 Issue 13940: handle posts that can't be found in contexts 2024-03-03 18:32:26 +00:00
Michael ae37c44cc0 Oembed: Some more cleanup 2024-03-03 18:06:25 +00:00
Hypolite Petovan 424e219c53
Merge pull request #13956 from annando/issue-13955
Issue 13955: Check for publish date upon receival
2024-03-03 12:23:13 -05:00
Michael bae7644d6f Issue 13955: Check for publish date upon receival 2024-03-02 19:21:14 +00:00
Michael Vogel f2ccce05b8
Merge pull request #13948 from MrPetovan/task/12420-frio-remove-legacy-scheme
[frio] Remove legacy schemes
2024-03-02 06:06:15 +01:00
Michael Vogel 89ffe6875f
Merge pull request #13942 from MrPetovan/bug/fix-api-fixture
Fix API fixture data
2024-03-02 05:48:19 +01:00
Hypolite Petovan 7284210bf7 Updated main translation file after changing some strings 2024-03-01 08:52:58 -05:00
Hypolite Petovan 4fcc92e532 [frio] Delete legacy scheme files 2024-03-01 08:48:41 -05:00
Hypolite Petovan 2c259c5c6f [frio] Remove legacy schemes
- [frio] Replace default scheme file by default scheme value
- [frio] Simplify frio theme settings
- [frio] Remove query string scheme setting
2024-03-01 08:48:38 -05:00
Hypolite Petovan 39d25b9699
Merge pull request #13954 from annando/issue-13953
Issue 13953: Fix warning during postupdate
2024-03-01 08:38:42 -05:00
Michael 5df1ead001 Issue 13953: Fix warning during postupdate 2024-03-01 08:41:12 +00:00
Hypolite Petovan 2d4f28dcde
Merge pull request #13951 from annando/issue-13949
Issue 13949: Block access via OAuth
2024-02-29 21:00:12 -05:00
Michael dd55ba2d77 Issue 13949: Block access via OAuth 2024-02-29 22:03:57 +00:00
Hypolite Petovan c9f7d9baff
Merge pull request #13946 from annando/issue-13819
Issue 13819: Ensure to not use OEmbed if not wanted
2024-02-29 07:54:43 -05:00
Hypolite Petovan 504a2e91e2
Merge pull request #13945 from annando/errors
Exceptions and warnings fixed
2024-02-29 07:53:13 -05:00
Michael 40e882004e Use the exact embed URLs 2024-02-29 07:40:36 +00:00
Michael e394a6b0fa Issue 13819: Ensure to not use OEmbed if not wanted 2024-02-29 07:37:58 +00:00
Michael 8cf82a8449 Exceptions and warnings fixed 2024-02-29 04:40:04 +00:00
Hypolite Petovan 0d922b75af Use public contact ids where they should be used in API fixture data 2024-02-27 08:41:51 -05:00
Hypolite Petovan ba0a8069c4 Normalize local node hostname across API fixtures
- This was causing the fixture data to be wrongly "repaired" in Model\User::getOwnerDataById because of a mismatch between the local base URL and the fixture-provided self contact URL
2024-02-27 08:41:51 -05:00
Hypolite Petovan d37699bc08 Throw Not Found exception when $uid doesn't exist in Factory\Api\Twitter\User->createFromUserId
- Contact::getPublicIdByUserId() wrongly returns 0 when $uid doesn't exist, which is an existing albeit invalid record.
2024-02-27 08:41:51 -05:00
Hypolite Petovan ac087749e3
Merge pull request #13938 from annando/output-type
Image handling: separate between output and input type, use Imagick on PNG
2024-02-25 10:01:34 -05:00
Michael ddc9f5f595 Image handling: separate between outout and input type, use Imagick on PNG 2024-02-25 08:52:52 +00:00
Tobias Diekershoff 35bba685fa
Merge pull request #13936 from annando/rounding
Round the load to two digits
2024-02-24 18:56:11 +01:00
Michael e52fa44d3f Round the load to two digits 2024-02-24 17:37:30 +00:00
Hypolite Petovan f74d6f9ebb
Merge pull request #13932 from annando/oembed-cleanup
Unused OEmbed functionality is removed
2024-02-24 11:03:48 -05:00
Michael ae358cae4c Updated messages.po 2024-02-24 15:29:33 +00:00
Michael b572b8989f Use media link instead of proxy for pictures 2024-02-24 15:11:27 +00:00
Michael 5800a973cb Fixed positive list 2024-02-24 13:56:12 +00:00
Michael Vogel 44ce5471b3
Onepoll: Prevent errors with invalid mails (#13934) 2024-02-24 13:18:44 +01:00
Michael e05b57cd5d messages.po updated 2024-02-24 11:56:55 +00:00
Michael ecdf8f2b47 Merge remote-tracking branch 'upstream/2024.03-rc' into oembed-cleanup 2024-02-24 11:54:35 +00:00
Michael Vogel 1c5681c199
Merge pull request #13933 from annando/fix2
Accidentally merged changes are reverted
2024-02-24 12:40:19 +01:00
Michael 20fd25258a Accidentally changes are reverted 2024-02-24 11:35:32 +00:00
Michael 00bb538fd0 Merge branch '2024.03-rc' of https://github.com/friendica/friendica into 2024.03-rc 2024-02-24 11:01:44 +00:00
Michael 12bdbaaba8 OEmbed: Complete cleanup 2024-02-24 11:01:34 +00:00
Michael 821a135033 Unused OEmbed functionality is removed 2024-02-24 10:58:18 +00:00
Michael Vogel 0ff37c0075
Merge pull request #13931 from MrPetovan/bug/13930-photo-preview-sizes
Increase API photo preview size for Mastodon API to 640
2024-02-24 09:39:31 +01:00
Hypolite Petovan 0a73050de1 Increase API photo preview size for Mastodon API to 640 2024-02-23 22:41:21 -05:00
Hypolite Petovan a25dbf839a Remove photo user id fallback from 2021
- Remove deprecated /photos/{nickname} fallback routes
- The contact id fallback is a lie, there's no replacement feature
2024-02-23 22:41:18 -05:00
Hypolite Petovan e16b6ee6e1
Check form security token in /settings/userexport module (#13929)
* Escape HTML in the location field of a calendar event post

- This allowed script tags to be interpreted in the post display of an event.

* Add form security token check to /admin/phpinfo module

- This prevents basic XSS attacks against /admin/phpinfo

* Add form security token check to /babel module

- This prevents basic XSS attacks against /babel

* Prevent pass-through for attachments

- This addresses a straightforward Reflected XSS vulnerability if a malicious HTML/Javascript file is attached to a post through upload

* Prevent overwriting cid on event edit

- This allowed to share an event as any other user after zeroing the cid field of an existing event

* Check form security token in /settings/userexport module

- Prevents basic XSS attacks against /settings/userexport/*
2024-02-22 21:08:32 +01:00
Hypolite Petovan 5c5d7eb04f
Fix several vulnerabilities (#13927)
* Escape HTML in the location field of a calendar event post

- This allowed script tags to be interpreted in the post display of an event.

* Add form security token check to /admin/phpinfo module

- This prevents basic XSS attacks against /admin/phpinfo

* Add form security token check to /babel module

- This prevents basic XSS attacks against /babel

* Prevent pass-through for attachments

- This addresses a straightforward Reflected XSS vulnerability if a malicious HTML/Javascript file is attached to a post through upload

* Prevent overwriting cid on event edit

- This allowed to share an event as any other user after zeroing the cid field of an existing event
2024-02-22 06:53:52 +01:00
Michael Vogel fc3898fe64
Updated Bluesky logo (#13926) 2024-02-21 18:23:36 +01:00
Michael Vogel 71384e6f39
Issue 13909: Filter channels by network (#13924) 2024-02-20 07:11:26 +01:00
Michael Vogel d95c9d28a8
Issue 13922: "voted" must not be null (#13923) 2024-02-20 07:09:55 +01:00
Hypolite Petovan bb7d25dfc9
Merge pull request #13921 from annando/content-type
Check for activity pub mime types
2024-02-19 05:57:47 -05:00
Michael Vogel d5c0f086bd
Disallow mail addresses for registration (#13920)
* Disallow mail addresses for registration

* Order for allow/disallow has been changed
2024-02-19 09:33:20 +01:00
Michael 892e0a5623 Check for activity pub mime types 2024-02-19 07:11:56 +00:00
Michael Vogel cb294cf411
Avoid problems with an empty domain in the blocklist (#13919)
* Avoid problems with an empty domain in the blocklist

* Test code removed
2024-02-19 07:22:19 +01:00
Michael Vogel 9ad452a19b
Merge pull request #13918 from MrPetovan/bug/fixup-13911
Move Api\Mastodon\Instance\Extended to ExtendedDescription
2024-02-19 04:05:42 +01:00
Hypolite Petovan 623a5be8a6 Clarify condition on offset in Mastodon\Search->searchStatuses 2024-02-18 18:48:37 -05:00
Hypolite Petovan d1cd9a016e Move Api\Mastodon\Instance\Extended to ExtendedDescription
- Add reference to Mastodon documentation
2024-02-18 18:47:59 -05:00
Michael Vogel 7d5d3b3c29
Issue 13293: Endpoint /api/v1/accounts/lookup implemented (#13917) 2024-02-18 20:17:06 +01:00
Michael Vogel bcec6c5ab2
Issue #13899: Fix error on postupdate (#13915) 2024-02-18 20:09:56 +01:00
Michael Vogel 6384265cbd
Issue #13823: Fix "Mutes" endpoint (#13916) 2024-02-18 20:07:51 +01:00
Michael Vogel f12276eff8
New channel "quiet sharers" for posts from lesser frequent posters (#13913) 2024-02-18 15:54:21 +01:00
Michael Vogel c6160a1c38
Fix API issues #13887, #13886, #13863, #13809, #13897 (#13911) 2024-02-18 15:52:30 +01:00
Michael Vogel 07c20da08f
Issue 13905: ostatus context added (#13912) 2024-02-18 15:46:41 +01:00
Michael Vogel 4eefd0a205
Merge pull request #13908 from MrPetovan/bug/warnings
Avoid passing null bytes in regular expression in Object\Image
2024-02-18 05:33:41 +01:00
Hypolite Petovan 78bc1359e0
Merge pull request #13907 from annando/fix-relations
Fix contact-relation follower calculation
2024-02-17 22:30:56 -05:00
Hypolite Petovan 1956c2ecfd Avoid passing null bytes in regular expression in Object\Image
- Remove capturing expression for A|B in favor of bracket syntax in regular expression since matches aren't used.
- Regular expressions have their own character escape notation including backslashes that need to be escaped in a PHP string.
- Actually address https://github.com/friendica/friendica/issues/13761#issuecomment-1949930922
2024-02-17 22:27:37 -05:00
Michael ade2369b5d Merge remote-tracking branch 'upstream/2024.03-rc' into fix-relations 2024-02-17 21:56:56 +00:00
Michael 0d2ea97eb1 Fix comtact-relation follower calculation 2024-02-17 21:32:17 +00:00
Michael Vogel 08fa51d0bb
Fix the handling of unhandled image types and of animations (#13904)
* Fix the handling of unhandled image types and of animations

* Avoid warnings
2024-02-17 15:46:48 +01:00
Michael 7d10518e94 Revert "Fix unhandled image detection"
This reverts commit 1069cfb570.
2024-02-17 10:50:09 +00:00
Michael 1069cfb570 Fix unhandled image detection 2024-02-17 10:46:48 +00:00
Michael Vogel 14e5b06029
Image handling reworked, new image formats added (#13900)
* Image handling reworked, new image formats added

* Updated messages.po

* The dot is now part of the file extension

* Added WebP in install documentation

* Handle unhandled mime types

* Fixed animated picture detected
2024-02-17 07:45:41 +01:00
Tobias Diekershoff 1ea8a4042d bump version to 2024.03-rc 2024-02-14 08:24:41 +01:00
Tobias Diekershoff f9c484c642 updated changelog 2023-12-24 18:05:59 +01:00
214 zmienionych plików z 14936 dodań i 14465 usunięć

Wyświetl plik

@ -39,7 +39,7 @@ steps:
branch: [ develop, '*-rc' ]
event: push
composer_install:
image: friendicaci/php7.4:php7.4.33
image: friendicaci/php8.2:php8.2.16
commands:
- export COMPOSER_HOME=.composer
- composer validate

Wyświetl plik

@ -1,10 +1,11 @@
matrix:
include:
- PHP_MAJOR_VERSION: 7.4
PHP_VERSION: 7.4.33
- PHP_MAJOR_VERSION: 8.2
PHP_VERSION: 8.2.16
branches:
exclude: [ stable ]
when:
- branch:
exclude: [ stable ]
# This forces CI executions at the "opensocial" labeled location (because of much more power...)
labels:

Wyświetl plik

@ -8,5 +8,6 @@ steps:
commands:
- /check-messages.sh
branches:
exclude: [ stable ]
when:
- branch:
exclude: [ stable ]

Wyświetl plik

@ -5,9 +5,11 @@ matrix:
- PHP_MAJOR_VERSION: 8.0
PHP_VERSION: 8.0.30
- PHP_MAJOR_VERSION: 8.1
PHP_VERSION: 8.1.23
PHP_VERSION: 8.1.27
- PHP_MAJOR_VERSION: 8.2
PHP_VERSION: 8.2.11
PHP_VERSION: 8.2.16
- PHP_MAJOR_VERSION: 8.3
PHP_VERSION: 8.3.3
# This forces PHP Unit executions at the "opensocial" labeled location (because of much more power...)
labels:
@ -16,7 +18,6 @@ labels:
steps:
php-lint:
image: php:${PHP_MAJOR_VERSION}
group: lint
commands:
- find . -name \*.php -not -path './vendor/*' -not -path './view/asset/*' -print0 | xargs -0 -n1 php -l
restore_cache:
@ -64,7 +65,7 @@ steps:
- cp config/local-sample.config.php config/local.config.php
- if ! bin/wait-for-connection $MYSQL_HOST $MYSQL_PORT 300; then echo "[ERROR] Waited 300 seconds, no response" >&2; exit 1; fi
- mysql -h$MYSQL_HOST -P$MYSQL_PORT -p$MYSQL_PASSWORD -u$MYSQL_USER $MYSQL_DATABASE < database.sql
- if [ "${PHP_MAJOR_VERSION}" = "7.4" -a "${CI_REPO}" = "friendica/friendica" ]; then
- if [ "${PHP_MAJOR_VERSION}" = "8.2" -a "${CI_REPO}" = "friendica/friendica" ]; then
phpenmod xdebug;
export XDEBUG_MODE=coverage;
phpunit --configuration tests/phpunit.xml -d memory_limit=-1 --coverage-clover clover.xml;
@ -75,8 +76,8 @@ steps:
image: friendicaci/codecov
when:
matrix:
PHP_MAJOR_VERSION: 7.4
PHP_VERSION: 7.4.33
PHP_MAJOR_VERSION: 8.2
PHP_VERSION: 8.2.16
repo:
- friendica/friendica
commands:

Wyświetl plik

@ -37,7 +37,7 @@ steps:
branch: stable
event: tag
composer_install:
image: friendicaci/php7.4:php7.4.33
image: friendicaci/php8.2:php8.2.16
commands:
- export COMPOSER_HOME=.composer
- composer validate

Wyświetl plik

@ -1,9 +1,71 @@
Version 2024.03 (unreleased)
Version 2024.06 (unreleased)
Friendica Core
Friendica Addons
Closed Issues
Version 2024.03 (2024-03-21)
Friendica Core
Updates to the translations AR, BG, CS, DE, EO, ES, FR, GD, HU, IS, IT, JA, PL, RO, RU, SV
Updates to the themes (frio, vier) [annando, foss-, haheute, MrPetovan, Raroun, toddy15]
Improved the channel feature [annando]
Improved the search performance [annando]
Improved spam detection [annando]
Improved the account overview on the moderation page [annando]
Improved account creation via CLI console [mexon]
Improved the Mastodon compatible API [annando, MrPetovan]
Improved logging of the system load value [annando]
Improved image handling [annando]
Improved detection of user activity [annando]
Improved display of embedded videos [annando]
Fixed an issue that could lead to empty URLs in the server block list [annando]
Fixed XSS attacks [leoOliver, MrPetovan, snajafov]
Fixed an issue when importing emails [annando]
Fixed an issue that blocked users could still use the API [annando]
Fixed an issue when fetching remote content [annando, arcanicanis]
Fixed an issue with unescaped HTML characters for RSS feeds [MrPetovan, r1pu5u]
Fixed an issue when showing the post preview [annando]
General code cleanup [annando, MrPetovan]
Updated the PasswordExposed usage [mexon]
Removed fpostit (Friendica post bookmarklet) [MrPetovan]
Removed the possibility for users to follow relays directly [annando]
Removed unused OEmbed functionality [annando]
Removed legacy schemes from frio theme [MrPetovan]
Added blur effect to sensitive images and user setting against it [annando]
Added account type Channel Relay [annando]
Added OCR generated image descriptions via tesseract addon [annando]
Added WebP and BMP support [annando]
Added blocked email addresses for registration [annando]
Friendica Addons
advancedcontentfilter
Updated dependency for PHP8.2 compatibility [MrPetovan]
blockbot
Fixed an issue preventing the creation of previews on remote systems [annando]
Updated block lists [annando]
bluesky
Overhaul of the Bluesky connector [annando]
Fixed problem with empty quoted shares [annando]
openstreetmap
Fix a config problem [haheute]
pnut:
Connector addon was added [spacenerdmo]
tesseract
Added the addon to generate image descriptions from images via OCR [annando]
tumblr
Improved handling of quoted shares [annando]
url_replace
Added addon to replace URLs from Twitter, Youtube and some others using 12ft.io [toddy15]
Fixed an issue with empty config vars [MrPetovan]
Closed Issues
903, 7732, 8768, 11142, 13220, 13293, 13765, 13768, 13809,
13814, 13814, 13818, 13819, 13822, 13823, 13828, 13837, 13839,
13844, 13845, 13859, 13863, 13873, 13877, 13886, 13887, 13897,
13899, 13905, 13909, 13922, 13925, 13930, 13939, 13940, 13946,
13947, 13949, 13950, 13953, 13955, 13959, 13968, 13969, 13972,
13984, 13985, 13986
Version 2023.12 (2023-12-24)
Friendica Core
@ -505,7 +567,7 @@ Version 2022.02 (2022-02-06)
Added a media tab on profile pages [annando]
Removed video tab on profile pages [annando]
Bumped the minimal version of PHP to 7.3
Friendica Addons
Updates to the translations AR, DE, FR, HU, IT, PL, SV [translation teams]
Deprecated addons: blogger, buffer, jappixmini, notimeline, xmpp
@ -530,7 +592,7 @@ Version 2022.02 (2022-02-06)
Fixed API calls [MrPetovan]
Fixed a problem leading to duplicated links [annando]
Updated twitteroauth dependency [nupplaphil]
Closed Issues
9720, 10301, 10365, 10454, 10634, 10691, 10725, 10726, 10729, 10734,
10737, 10739, 10745, 10754, 10767, 10791, 10829, 10832, 10839, 10841,
@ -634,7 +696,7 @@ Version 2021.07 (2021-07-04)
The "authenticate" hook was moved deeper into the process [very-ape]
Added support for RTL languages [MrPetovan]
Added download link for the calendar entries [annando]
Friendica Addons
Updates to the translations DE, HU, IT, JA [translation teams]
nitter
@ -659,7 +721,7 @@ Version 2021.07 (2021-07-04)
adaptation of new addon functionalities and code improvements [mexon]
phpmailer
updated dependencies [nupplaphil]
Closed Issues
7967, 8262, 9715, 9064, 9993, 10055, 10147, 10184, 10198, 10205, 10210,
10219, 10232, 10254, 10287, 10293, 10306, 10312, 10314, 10342, 10364,
@ -1053,7 +1115,7 @@ Version 2020.03 "Red Hot Poker" (2020-03-30)
Added fetching of contact relations [annando]
unicode emoticons:
Extended the list of supported emoticons [loma-one]
Closed Issues:
4599, 5562, 6205, 6418, 6757, 7558, 7560, 7771, 7808, 7817, 7892,
7964, 7968, 7978, 7984, 7991, 7992, 7994, 8002, 8008, 8014, 8058,
@ -1290,7 +1352,7 @@ Version 2019.06 (2019-06-23)
Version 2019.04 (2019-04-28)
Friendica Core:
Fixed a privacy problem with postings accessed by feed [MrPetovan]
Version 2019.03 (2019-03-22)
Friendica Core:
Update to the translation (CS, DE, EN-GB, EN-US, ES, FR, IT, PL, SV, ZH-CN) [translation teams]
@ -1465,7 +1527,7 @@ Version 2019.01 (2019-01-21)
6268, 6282, 6283, 6208, 6289, 6294, 6308, 6309, 6313, 6316, 6323,
6329, 6334, 6344, 6347, 6343, 6349, 6350, 6355, 6358, 6360, 6361,
6363, 6368, 6370, 6391, 6394, 6424, 6425, 6439, 6459
Version 2018.09 (2018-09-23)
Friendica Core:
Update to the translation (CS, DE, EN-US, FI, IT, NL, PL, ZH-CN) [translation teams]
@ -1500,13 +1562,13 @@ Version 2018.09 (2018-09-23)
Fixed a bug in the daemon mode of the background worker [annando]
Fixed a bug in the frio theme that contact filtering [rabuzarus]
Fixed a bug that mangled the display of some additional smileys [abanink]
Fixed a bug in generating registration mails [MrPetovan]
Fixed a bug in generating registration mails [MrPetovan]
Fixed a bug that caused blank re-share bodies [MrPetovon]
Fixed a bug in the API handling of private mails [fabrixxm]
Fixed a bug when calling the mail() function [miqrogroove]
Fixed a bug that caused deleted accounts being displayed in the local directory [miqrogroove]
Fixed a bug when checking the domain of an email address [VVelox]
Fixed a bug that prevented re-shares from Twitter to be shown as this [annando]
Fixed a bug that prevented re-shares from Twitter to be shown as this [annando]
Fixed a bug that caused broken profile links [miqrogroove]
Fixed a bug that caused content from unknown accounts appearing in the timeline [annando]
Fixed a bug with the ignoring and blocking of contacts [annando]

Wyświetl plik

@ -32,6 +32,7 @@ Anthronaut
Anton
Antron Samurai
Anubis2814
arcanicanis
Arian - Cazare Muncitori
Asher Pen
atjn
@ -136,6 +137,7 @@ gudzpoz
GunChleoc
guzzisti
Haakon Meland Eriksen
haheute
Hank Grabowski
Hannes Heute
Hans Meine
@ -147,6 +149,7 @@ hlad
hoergen
Hubert Kościański
Hypolite Petovan
ike
Ilmari
ImgBotApp
irhen
@ -222,6 +225,7 @@ Michal Šupler
Michalina
Mike Macgirvin
miqrogroove
Morgan McMillian
mpanhans
mytbk
nathilia-peirce
@ -255,8 +259,10 @@ Pierre Bernardeau
Pierre Rudloff
Piotr Blonkowski
Piotr Strębski
pixelroot
pokerazor
R C
r1pu5u
Rabuzarus
Radek
Rafael Garau
@ -294,9 +300,11 @@ Senex Petrovic
Seth
SickShark X
Silke Meyer
Simon
Simon L'nu
Simon Rupf
Simó Albert i Beltran
snajafov
softmetz
soko1
Spencer Dub

Wyświetl plik

@ -1 +1 @@
2024.03-dev
2024.06-dev

360
composer.lock wygenerowano
Wyświetl plik

@ -299,28 +299,28 @@
},
{
"name": "composer/ca-bundle",
"version": "1.4.0",
"version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "b66d11b7479109ab547f9405b97205640b17d385"
"reference": "0c5ccfcfea312b5c5a190a21ac5cef93f74baf99"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/b66d11b7479109ab547f9405b97205640b17d385",
"reference": "b66d11b7479109ab547f9405b97205640b17d385",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/0c5ccfcfea312b5c5a190a21ac5cef93f74baf99",
"reference": "0c5ccfcfea312b5c5a190a21ac5cef93f74baf99",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"ext-pcre": "*",
"php": "^5.3.2 || ^7.0 || ^8.0"
"php": "^7.2 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.55",
"phpstan/phpstan": "^1.10",
"psr/log": "^1.0",
"symfony/phpunit-bridge": "^4.2 || ^5",
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
"symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"type": "library",
"extra": {
@ -366,7 +366,7 @@
"type": "tidelift"
}
],
"time": "2023-12-18T12:05:55+00:00"
"time": "2024-03-15T14:00:32+00:00"
},
{
"name": "dasprid/enum",
@ -1498,16 +1498,16 @@
},
{
"name": "matriphe/iso-639",
"version": "1.2",
"version": "1.3",
"source": {
"type": "git",
"url": "https://github.com/matriphe/php-iso-639.git",
"reference": "0245d844daeefdd22a54b47103ffdb0e03c323e1"
"reference": "9a4a5823147890e70e0e0f60f3baea95e8d3b5f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matriphe/php-iso-639/zipball/0245d844daeefdd22a54b47103ffdb0e03c323e1",
"reference": "0245d844daeefdd22a54b47103ffdb0e03c323e1",
"url": "https://api.github.com/repos/matriphe/php-iso-639/zipball/9a4a5823147890e70e0e0f60f3baea95e8d3b5f1",
"reference": "9a4a5823147890e70e0e0f60f3baea95e8d3b5f1",
"shasum": ""
},
"require-dev": {
@ -1538,7 +1538,7 @@
"language",
"laravel"
],
"time": "2017-07-19T15:11:19+00:00"
"time": "2024-03-17T21:30:14+00:00"
},
{
"name": "mattwright/urlresolver",
@ -3327,16 +3327,16 @@
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.35",
"version": "3.0.37",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "4b1827beabce71953ca479485c0ae9c51287f2fe"
"reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe",
"reference": "4b1827beabce71953ca479485c0ae9c51287f2fe",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cfa2013d0f68c062055180dd4328cc8b9d1f30b8",
"reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8",
"shasum": ""
},
"require": {
@ -3429,7 +3429,7 @@
"type": "tidelift"
}
],
"time": "2023-12-29T01:59:53+00:00"
"time": "2024-03-03T02:14:58+00:00"
},
{
"name": "pragmarx/google2fa",
@ -4044,16 +4044,16 @@
},
{
"name": "smarty/smarty",
"version": "v4.3.4",
"version": "v4.5.1",
"source": {
"type": "git",
"url": "https://github.com/smarty-php/smarty.git",
"reference": "3931d8f54b8f7a4ffab538582d34d4397ba8daa5"
"reference": "42b869e3a098b1c8ee07922ccded0e5a5dceadcd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/3931d8f54b8f7a4ffab538582d34d4397ba8daa5",
"reference": "3931d8f54b8f7a4ffab538582d34d4397ba8daa5",
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/42b869e3a098b1c8ee07922ccded0e5a5dceadcd",
"reference": "42b869e3a098b1c8ee07922ccded0e5a5dceadcd",
"shasum": ""
},
"require": {
@ -4101,7 +4101,7 @@
"keywords": [
"templating"
],
"time": "2023-09-14T10:59:08+00:00"
"time": "2024-03-18T14:19:07+00:00"
},
{
"name": "spomky-labs/base64url",
@ -4423,6 +4423,7 @@
"type": "patreon"
}
],
"abandoned": "web-token/jwt-library",
"time": "2021-03-17T14:55:52+00:00"
},
{
@ -4497,6 +4498,7 @@
"type": "patreon"
}
],
"abandoned": "web-token/jwt-library",
"time": "2021-03-17T14:55:52+00:00"
},
{
@ -4570,6 +4572,7 @@
"type": "patreon"
}
],
"abandoned": "web-token/jwt-library",
"time": "2021-03-01T19:55:28+00:00"
},
{
@ -4636,6 +4639,7 @@
"type": "patreon"
}
],
"abandoned": "web-token/jwt-library",
"time": "2021-01-21T19:18:03+00:00"
},
{
@ -4705,6 +4709,7 @@
"type": "patreon"
}
],
"abandoned": "web-token/jwt-library",
"time": "2021-03-24T13:35:17+00:00"
},
{
@ -4762,16 +4767,16 @@
"packages-dev": [
{
"name": "composer/pcre",
"version": "3.1.1",
"version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
"url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
"shasum": ""
},
"require": {
@ -4825,7 +4830,7 @@
"type": "tidelift"
}
],
"time": "2023-10-11T07:11:09+00:00"
"time": "2024-03-19T10:26:25+00:00"
},
{
"name": "composer/semver",
@ -5073,16 +5078,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.46.0",
"version": "v3.52.1",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "be6831c9af1740470d2a773119b9273f8ac1c3d2"
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/be6831c9af1740470d2a773119b9273f8ac1c3d2",
"reference": "be6831c9af1740470d2a773119b9273f8ac1c3d2",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/6e77207f0d851862ceeb6da63e6e22c01b1587bc",
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc",
"shasum": ""
},
"require": {
@ -5092,7 +5097,7 @@
"ext-json": "*",
"ext-tokenizer": "*",
"php": "^7.4 || ^8.0",
"sebastian/diff": "^4.0 || ^5.0",
"sebastian/diff": "^4.0 || ^5.0 || ^6.0",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0",
"symfony/filesystem": "^5.4 || ^6.0 || ^7.0",
@ -5113,7 +5118,8 @@
"php-cs-fixer/accessible-object": "^1.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4",
"phpunit/phpunit": "^9.6 || ^10.5.5",
"phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2",
"symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
},
"suggest": {
@ -5156,7 +5162,7 @@
"type": "github"
}
],
"time": "2024-01-03T21:38:46+00:00"
"time": "2024-03-19T21:02:43+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@ -5253,16 +5259,16 @@
},
{
"name": "mockery/mockery",
"version": "1.6.7",
"version": "1.6.10",
"source": {
"type": "git",
"url": "https://github.com/mockery/mockery.git",
"reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06"
"reference": "47065d1be1fa05def58dc14c03cf831d3884ef0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
"reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
"url": "https://api.github.com/repos/mockery/mockery/zipball/47065d1be1fa05def58dc14c03cf831d3884ef0b",
"reference": "47065d1be1fa05def58dc14c03cf831d3884ef0b",
"shasum": ""
},
"require": {
@ -5274,8 +5280,8 @@
"phpunit/phpunit": "<8.0"
},
"require-dev": {
"phpunit/phpunit": "^8.5 || ^9.6.10",
"symplify/easy-coding-standard": "^12.0.8"
"phpunit/phpunit": "^8.5 || ^9.6.17",
"symplify/easy-coding-standard": "^12.1.14"
},
"type": "library",
"autoload": {
@ -5325,7 +5331,7 @@
"test double",
"testing"
],
"time": "2023-12-10T02:24:34+00:00"
"time": "2024-03-19T16:15:45+00:00"
},
{
"name": "myclabs/deep-copy",
@ -5384,16 +5390,16 @@
},
{
"name": "nikic/php-parser",
"version": "v5.0.0",
"version": "v5.0.2",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc"
"reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
"reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13",
"reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13",
"shasum": ""
},
"require": {
@ -5434,24 +5440,25 @@
"parser",
"php"
],
"time": "2024-01-07T17:17:35+00:00"
"time": "2024-03-05T20:51:40+00:00"
},
{
"name": "phar-io/manifest",
"version": "2.0.3",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
"reference": "97803eca37d319dfa7826cc2437fc020857acb53"
"reference": "54750ef60c58e43759730615a392c31c80e23176"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
"reference": "97803eca37d319dfa7826cc2437fc020857acb53",
"url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
"reference": "54750ef60c58e43759730615a392c31c80e23176",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"ext-phar": "*",
"ext-xmlwriter": "*",
"phar-io/version": "^3.0.1",
@ -5490,7 +5497,13 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"time": "2021-07-20T11:28:43+00:00"
"funding": [
{
"url": "https://github.com/theseer",
"type": "github"
}
],
"time": "2024-03-03T12:33:53+00:00"
},
{
"name": "phar-io/version",
@ -5541,16 +5554,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.30",
"version": "9.2.31",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089"
"reference": "48c34b5d8d983006bd2adc2d0de92963b9155965"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089",
"reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965",
"reference": "48c34b5d8d983006bd2adc2d0de92963b9155965",
"shasum": ""
},
"require": {
@ -5610,7 +5623,7 @@
"type": "github"
}
],
"time": "2023-12-22T06:47:57+00:00"
"time": "2024-03-02T06:37:42+00:00"
},
{
"name": "phpunit/php-file-iterator",
@ -5839,16 +5852,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.6.15",
"version": "9.6.17",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1"
"reference": "1a156980d78a6666721b7e8e8502fe210b587fcd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1",
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a156980d78a6666721b7e8e8502fe210b587fcd",
"reference": "1a156980d78a6666721b7e8e8502fe210b587fcd",
"shasum": ""
},
"require": {
@ -5933,7 +5946,7 @@
"type": "tidelift"
}
],
"time": "2023-12-01T16:55:19+00:00"
"time": "2024-02-23T13:14:51+00:00"
},
{
"name": "psr/event-dispatcher",
@ -5983,16 +5996,16 @@
},
{
"name": "sebastian/cli-parser",
"version": "1.0.1",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/cli-parser.git",
"reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
"reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
"reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
"url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
"reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
"shasum": ""
},
"require": {
@ -6031,7 +6044,7 @@
"type": "github"
}
],
"time": "2020-09-28T06:08:49+00:00"
"time": "2024-03-02T06:27:43+00:00"
},
{
"name": "sebastian/code-unit",
@ -6261,16 +6274,16 @@
},
{
"name": "sebastian/diff",
"version": "4.0.5",
"version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
"reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
"reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
"reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
"shasum": ""
},
"require": {
@ -6319,7 +6332,7 @@
"type": "github"
}
],
"time": "2023-05-07T05:35:17+00:00"
"time": "2024-03-02T06:30:58+00:00"
},
{
"name": "sebastian/environment",
@ -6382,16 +6395,16 @@
},
{
"name": "sebastian/exporter",
"version": "4.0.5",
"version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
"reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
"reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
"reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
"shasum": ""
},
"require": {
@ -6451,20 +6464,20 @@
"type": "github"
}
],
"time": "2022-09-14T06:03:37+00:00"
"time": "2024-03-02T06:33:00+00:00"
},
{
"name": "sebastian/global-state",
"version": "5.0.6",
"version": "5.0.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "bde739e7565280bda77be70044ac1047bc007e34"
"reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34",
"reference": "bde739e7565280bda77be70044ac1047bc007e34",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
"reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
"shasum": ""
},
"require": {
@ -6511,7 +6524,7 @@
"type": "github"
}
],
"time": "2023-08-02T09:26:13+00:00"
"time": "2024-03-02T06:35:11+00:00"
},
{
"name": "sebastian/lines-of-code",
@ -6731,16 +6744,16 @@
},
{
"name": "sebastian/resource-operations",
"version": "3.0.3",
"version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
"reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
"reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
"reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
"reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
"shasum": ""
},
"require": {
@ -6752,7 +6765,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
"dev-main": "3.0-dev"
}
},
"autoload": {
@ -6778,7 +6791,7 @@
"type": "github"
}
],
"time": "2020-09-28T06:45:17+00:00"
"time": "2024-03-14T16:00:52+00:00"
},
{
"name": "sebastian/type",
@ -6883,16 +6896,16 @@
},
{
"name": "symfony/console",
"version": "v5.4.34",
"version": "v5.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "4b4d8cd118484aa604ec519062113dd87abde18c"
"reference": "39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/4b4d8cd118484aa604ec519062113dd87abde18c",
"reference": "4b4d8cd118484aa604ec519062113dd87abde18c",
"url": "https://api.github.com/repos/symfony/console/zipball/39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e",
"reference": "39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e",
"shasum": ""
},
"require": {
@ -6975,20 +6988,20 @@
"type": "tidelift"
}
],
"time": "2023-12-08T13:33:03+00:00"
"time": "2024-02-20T16:33:57+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v5.4.34",
"version": "v5.4.35",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "e3bca343efeb613f843c254e7718ef17c9bdf7a3"
"reference": "7a69a85c7ea5bdd1e875806a99c51a87d3a74b38"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e3bca343efeb613f843c254e7718ef17c9bdf7a3",
"reference": "e3bca343efeb613f843c254e7718ef17c9bdf7a3",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7a69a85c7ea5bdd1e875806a99c51a87d3a74b38",
"reference": "7a69a85c7ea5bdd1e875806a99c51a87d3a74b38",
"shasum": ""
},
"require": {
@ -7057,7 +7070,7 @@
"type": "tidelift"
}
],
"time": "2023-12-27T21:12:56+00:00"
"time": "2024-01-23T13:51:25+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@ -7137,16 +7150,16 @@
},
{
"name": "symfony/filesystem",
"version": "v5.4.25",
"version": "v5.4.35",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364"
"reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/0ce3a62c9579a53358d3a7eb6b3dfb79789a6364",
"reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/5a553607d4ffbfa9c0ab62facadea296c9db7086",
"reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086",
"shasum": ""
},
"require": {
@ -7194,20 +7207,20 @@
"type": "tidelift"
}
],
"time": "2023-05-31T13:04:02+00:00"
"time": "2024-01-23T13:51:25+00:00"
},
{
"name": "symfony/finder",
"version": "v5.4.27",
"version": "v5.4.35",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d"
"reference": "abe6d6f77d9465fed3cd2d029b29d03b56b56435"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/ff4bce3c33451e7ec778070e45bd23f74214cd5d",
"reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d",
"url": "https://api.github.com/repos/symfony/finder/zipball/abe6d6f77d9465fed3cd2d029b29d03b56b56435",
"reference": "abe6d6f77d9465fed3cd2d029b29d03b56b56435",
"shasum": ""
},
"require": {
@ -7254,7 +7267,7 @@
"type": "tidelift"
}
],
"time": "2023-07-31T08:02:31+00:00"
"time": "2024-01-23T13:51:25+00:00"
},
{
"name": "symfony/options-resolver",
@ -7324,16 +7337,16 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@ -7347,9 +7360,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7399,20 +7409,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "875e90aeea2777b6f135677f618529449334a612"
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
"reference": "875e90aeea2777b6f135677f618529449334a612",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"shasum": ""
},
"require": {
@ -7423,9 +7433,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7477,20 +7484,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": ""
},
"require": {
@ -7501,9 +7508,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7558,20 +7562,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "42292d99c55abe617799667f454222c54c60e229"
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "42292d99c55abe617799667f454222c54c60e229",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@ -7585,9 +7589,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7638,20 +7639,20 @@
"type": "tidelift"
}
],
"time": "2023-07-28T09:04:16+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php73",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
"reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5"
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5",
"reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2",
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2",
"shasum": ""
},
"require": {
@ -7659,9 +7660,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7714,20 +7712,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"shasum": ""
},
"require": {
@ -7735,9 +7733,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7794,20 +7789,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "7581cd600fa9fd681b797d00b02f068e2f13263b"
"reference": "c565ad1e63f30e7477fc40738343c62b40bc672d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b",
"reference": "7581cd600fa9fd681b797d00b02f068e2f13263b",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d",
"reference": "c565ad1e63f30e7477fc40738343c62b40bc672d",
"shasum": ""
},
"require": {
@ -7815,9 +7810,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -7870,20 +7862,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/process",
"version": "v5.4.34",
"version": "v5.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a"
"reference": "4fdf34004f149cc20b2f51d7d119aa500caad975"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/8fa22178dfc368911dbd513b431cd9b06f9afe7a",
"reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a",
"url": "https://api.github.com/repos/symfony/process/zipball/4fdf34004f149cc20b2f51d7d119aa500caad975",
"reference": "4fdf34004f149cc20b2f51d7d119aa500caad975",
"shasum": ""
},
"require": {
@ -7929,7 +7921,7 @@
"type": "tidelift"
}
],
"time": "2023-12-02T08:41:43+00:00"
"time": "2024-02-12T15:49:53+00:00"
},
{
"name": "symfony/service-contracts",
@ -7991,16 +7983,16 @@
},
{
"name": "symfony/stopwatch",
"version": "v5.4.21",
"version": "v5.4.35",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
"reference": "f83692cd869a6f2391691d40a01e8acb89e76fee"
"reference": "887762aa99ff16f65dc8b48aafead415f942d407"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/f83692cd869a6f2391691d40a01e8acb89e76fee",
"reference": "f83692cd869a6f2391691d40a01e8acb89e76fee",
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/887762aa99ff16f65dc8b48aafead415f942d407",
"reference": "887762aa99ff16f65dc8b48aafead415f942d407",
"shasum": ""
},
"require": {
@ -8046,20 +8038,20 @@
"type": "tidelift"
}
],
"time": "2023-02-14T08:03:56+00:00"
"time": "2024-01-23T13:51:25+00:00"
},
{
"name": "symfony/string",
"version": "v5.4.34",
"version": "v5.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "e3f98bfc7885c957488f443df82d97814a3ce061"
"reference": "4e232c83622bd8cd32b794216aa29d0d266d353b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/e3f98bfc7885c957488f443df82d97814a3ce061",
"reference": "e3f98bfc7885c957488f443df82d97814a3ce061",
"url": "https://api.github.com/repos/symfony/string/zipball/4e232c83622bd8cd32b794216aa29d0d266d353b",
"reference": "4e232c83622bd8cd32b794216aa29d0d266d353b",
"shasum": ""
},
"require": {
@ -8129,20 +8121,20 @@
"type": "tidelift"
}
],
"time": "2023-12-09T13:20:28+00:00"
"time": "2024-02-01T08:49:30+00:00"
},
{
"name": "theseer/tokenizer",
"version": "1.2.2",
"version": "1.2.3",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"shasum": ""
},
"require": {
@ -8175,7 +8167,7 @@
"type": "github"
}
],
"time": "2023-11-20T00:12:19+00:00"
"time": "2024-03-03T12:36:25+00:00"
}
],
"aliases": [],

Wyświetl plik

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2024.03-dev (Yellow Archangel)
-- DB_UPDATE_VERSION 1552
-- Friendica 2024.06-dev (Yellow Archangel)
-- DB_UPDATE_VERSION 1559
-- ------------------------------------------
@ -539,6 +539,7 @@ CREATE TABLE IF NOT EXISTS `contact-relation` (
`relation-score` smallint unsigned COMMENT 'score for interactions of relation-cid on cid',
`thread-score` smallint unsigned COMMENT 'score for interactions of cid on threads of relation-cid',
`relation-thread-score` smallint unsigned COMMENT 'score for interactions of relation-cid on threads of cid',
`post-score` smallint unsigned COMMENT 'score for the amount of posts from cid that can be seen by relation-cid',
PRIMARY KEY(`cid`,`relation-cid`),
INDEX `relation-cid` (`relation-cid`),
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
@ -1346,11 +1347,12 @@ CREATE TABLE IF NOT EXISTS `post-engagement` (
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
`owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner',
`contact-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Person, organisation, news, community, relay',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio)',
`language` char(2) COMMENT 'Language information about this post in the ISO 639-1 format',
`searchtext` mediumtext COMMENT 'Simplified text for the full text search',
`size` int unsigned COMMENT 'Body size',
`created` datetime COMMENT '',
`network` char(4) COMMENT '',
`restricted` boolean NOT NULL DEFAULT '0' COMMENT 'If true, this post is either unlisted or not from a federated network',
`comments` mediumint unsigned COMMENT 'Number of comments',
`activities` mediumint unsigned COMMENT 'Number of activities (like, dislike, ...)',
@ -1469,7 +1471,7 @@ CREATE TABLE IF NOT EXISTS `post-question-option` (
CREATE TABLE IF NOT EXISTS `post-searchindex` (
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
`owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio)',
`language` char(2) COMMENT 'Language information about this post in the ISO 639-1 format',
`searchtext` mediumtext COMMENT 'Simplified text for the full text search',
`size` int unsigned COMMENT 'Body size',
@ -1548,6 +1550,7 @@ CREATE TABLE IF NOT EXISTS `post-user` (
`post-reason` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Reason why the post arrived at the user',
`vid` smallint unsigned COMMENT 'Id of the verb table entry that contains the activity verbs',
`private` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '0=public, 1=private, 2=unlisted',
`restrictions` tinyint unsigned COMMENT 'Bit array of post restrictions (1 = Reply, 2 = Like, 4 = Announce)',
`global` boolean NOT NULL DEFAULT '0' COMMENT '',
`visible` boolean NOT NULL DEFAULT '0' COMMENT '',
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'item has been marked for deletion',
@ -1945,6 +1948,7 @@ CREATE TABLE IF NOT EXISTS `user-contact` (
`ignored` boolean COMMENT 'Posts from this contact are ignored',
`collapsed` boolean COMMENT 'Posts from this contact are collapsed',
`hidden` boolean COMMENT 'This contact is hidden from the others',
`channel-only` boolean COMMENT 'This contact is displayed only in channels, but not in the network stream.',
`is-blocked` boolean COMMENT 'User is blocked by this contact',
`channel-frequency` tinyint unsigned COMMENT 'Controls the frequency of the appearance of this contact in channels',
`pending` boolean COMMENT '',
@ -2015,7 +2019,8 @@ CREATE VIEW `application-view` AS SELECT
`application-token`.`follow` AS `follow`,
`application-token`.`push` AS `push`
FROM `application-token`
INNER JOIN `application` ON `application-token`.`application-id` = `application`.`id`;
INNER JOIN `application` ON `application-token`.`application-id` = `application`.`id`
INNER JOIN `user` ON `user`.`uid` = `application-token`.`uid` AND `user`.`verified` AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND NOT `user`.`account_expired`;
--
-- VIEW circle-member-view
@ -2122,6 +2127,7 @@ CREATE VIEW `post-searchindex-user-view` AS SELECT
`post-thread-user`.`commented` AS `commented`,
`post-thread-user`.`received` AS `received`,
`post-thread-user`.`created` AS `created`,
`post-thread-user`.`network` AS `network`,
`post-searchindex`.`language` AS `restricted`,
0 AS `comments`,
0 AS `activities`
@ -2196,6 +2202,7 @@ CREATE VIEW `post-user-view` AS SELECT
`post-content`.`location` AS `location`,
`post-content`.`coord` AS `coord`,
`post-content`.`sensitive` AS `sensitive`,
`post-user`.`restrictions` AS `restrictions`,
`post-content`.`app` AS `app`,
`post-content`.`object-type` AS `object-type`,
`post-content`.`object` AS `object`,
@ -2381,6 +2388,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`post-content`.`location` AS `location`,
`post-content`.`coord` AS `coord`,
`post-content`.`sensitive` AS `sensitive`,
`post-user`.`restrictions` AS `restrictions`,
`post-content`.`app` AS `app`,
`post-content`.`object-type` AS `object-type`,
`post-content`.`object` AS `object`,
@ -2872,36 +2880,6 @@ CREATE VIEW `tag-view` AS SELECT
LEFT JOIN `tag` ON `post-tag`.`tid` = `tag`.`id`
LEFT JOIN `contact` ON `post-tag`.`cid` = `contact`.`id`;
--
-- VIEW network-item-view
--
DROP VIEW IF EXISTS `network-item-view`;
CREATE VIEW `network-item-view` AS SELECT
`post-user`.`uri-id` AS `uri-id`,
`post-thread-user`.`post-user-id` AS `parent`,
`post-user`.`received` AS `received`,
`post-thread-user`.`commented` AS `commented`,
`post-user`.`created` AS `created`,
`post-user`.`uid` AS `uid`,
`post-thread-user`.`starred` AS `starred`,
`post-thread-user`.`mention` AS `mention`,
`post-user`.`network` AS `network`,
`post-user`.`unseen` AS `unseen`,
`post-user`.`gravity` AS `gravity`,
`post-user`.`contact-id` AS `contact-id`,
`ownercontact`.`contact-type` AS `contact-type`
FROM `post-user`
INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
WHERE `post-user`.`visible` AND NOT `post-user`.`deleted`
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = `post-thread-user`.`uid` AND `cid` IN (`authorcontact`.`id`, `ownercontact`.`id`) AND (`blocked` OR `ignored`))
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
--
-- VIEW network-thread-view
--
@ -2927,8 +2905,8 @@ CREATE VIEW `network-thread-view` AS SELECT
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = `post-thread-user`.`uid` AND `cid` IN (`authorcontact`.`id`, `ownercontact`.`id`) AND (`blocked` OR `ignored`))
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = `post-thread-user`.`uid` AND `cid` IN (`post-thread-user`.`author-id`, `post-thread-user`.`owner-id`, `post-thread-user`.`causer-id`) AND (`blocked` OR `ignored` OR `channel-only`))
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
--
-- VIEW owner-view

Wyświetl plik

@ -11,21 +11,7 @@ Authentication is the same as described in [Using the APIs](help/api#Authenticat
## Clients
### Supported apps
For supported apps please have a look at the [FAQ](help/FAQ#clients)
### Unsupported apps
#### Android
- [Fedilab](https://framagit.org/tom79/fedilab) Automatically uses the legacy API, see issue: https://framagit.org/tom79/fedilab/-/issues/520
- [Mammut](https://github.com/jamiesanson/Mammut) There are problems with the token request, see issue https://github.com/jamiesanson/Mammut/issues/19
#### iOS
- [Mast](https://github.com/Beesitech/Mast) Doesn't accept the entered instance name. Claims that it is invalid (Message is: "Not a valid instance (may be closed or dead)")
- [Toot!](https://apps.apple.com/app/toot/id1229021451)
Please find a list of supported apps at [FAQ](help/FAQ#clients).
## Entities
@ -170,7 +156,8 @@ Example:
- [`GET /api/v1/followed_tags`](https://docs.joinmastodon.org/methods/followed_tags/)
- [`GET /api/v1/instance`](https://docs.joinmastodon.org/methods/instance/#v1)
- `GET /api/v1/instance/rules` Undocumented, returns Terms of Service
- [`GET /api/v1/instance/extended_description`](https://docs.joinmastodon.org/methods/instance/#extended_description)
- [`GET /api/v1/instance/rules`](https://docs.joinmastodon.org/methods/instance/#rules)
- [`GET /api/v1/instance/peers`](https://docs.joinmastodon.org/methods/instance#list-of-connected-domains)
- [`GET /api/v1/lists`](https://docs.joinmastodon.org/methods/timelines/lists/)
- [`POST /api/v1/lists`](https://docs.joinmastodon.org/methods/timelines/lists/)
@ -314,7 +301,6 @@ They refer to features or data that don't exist in Friendica yet.
- [`PUT /api/v1/filters/:id`](https://docs.joinmastodon.org/methods/accounts/filters/)
- [`DELETE /api/v1/filters/:id`](https://docs.joinmastodon.org/methods/accounts/filters/)
- [`GET /api/v1/instance/activity`](https://docs.joinmastodon.org/methods/instance#weekly-activity)
- [`POST /api/v1/markers`](https://docs.joinmastodon.org/methods/timelines/markers/)
- [`PUT /api/v1/scheduled_statuses/:id`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
- [`GET /api/v1/statuses/{id:\d+}/history`](https://github.com/mastodon/mastodon/pull/16697)
- [`GET /api/v1/streaming`](https://docs.joinmastodon.org/methods/timelines/streaming/)

Wyświetl plik

@ -34,6 +34,7 @@ General
* y - for you
* f - followers
* r - sharers of sharers
* q - quiet sharers
* h - what's hot
* i - Images
* v - Videos

Wyświetl plik

@ -33,6 +33,7 @@ Predefined Channels
* Language: Posts in your language.
* Followers: Posts from your followers that you don't follow.
* Sharers of sharers: Posts from accounts that are followed by accounts that you follow.
* Quiet sharers: Posts from accounts that you follow but who don't post very often.
* Images: Posts with images.
* Audio: Posts with audio.
* Videos: Posts with videos.

Wyświetl plik

@ -178,12 +178,12 @@ The available features are client specific and may differ.
#### Android
* [AndStatus](http://andstatus.org) ([F-Droid](https://f-droid.org/repository/browse/?fdid=org.andstatus.app), [Google Play](https://play.google.com/store/apps/details?id=org.andstatus.app))
* [Fedi](https://github.com/Big-Fig/Fediverse.app) ([Google Play](https://play.google.com/store/apps/details?id=com.fediverse.app))
* [Fedilab](https://fedilab.app) ([F-Droid](https://f-droid.org/app/fr.gouv.etalab.mastodon), [Google Play](https://play.google.com/store/apps/details?id=app.fedilab.android))
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) ([F-Droid](https://git.friendi.ca/lubuwest/Friendiqa#install), [Google Play](https://play.google.com/store/apps/details?id=org.qtproject.friendiqa))
* [Husky](https://git.sr.ht/~captainepoch/husky) ([F-Droid](https://f-droid.org/repository/browse/?fdid=su.xash.husky), [Google Play](https://play.google.com/store/apps/details?id=su.xash.husky))
* [Husky](https://codeberg.org/husky/husky) ([F-Droid](https://f-droid.org/repository/browse/?fdid=su.xash.husky), [Google Play](https://play.google.com/store/apps/details?id=su.xash.husky))
* [Mastodon](https://github.com/mastodon/mastodon-android) ([F-Droid](https://f-droid.org/en/packages/org.joinmastodon.android/), [Google Play](https://play.google.com/store/apps/details?id=org.joinmastodon.android))
* [Subway Tooter](https://github.com/tateisu/SubwayTooter) ([F-Droid](https://android.izzysoft.de/repo/apk/jp.juggler.subwaytooter))
* [Pachli](https://pachli.app/) ([F-Droid](https://f-droid.org/en/packages/app.pachli/), [Google Play](https://play.google.com/store/apps/details?id=app.pachli))
* [Subway Tooter](https://github.com/tateisu/SubwayTooter) ([F-Droid via Izzy](https://android.izzysoft.de/repo/apk/jp.juggler.subwaytooter.noFcm))
* [Tooot](https://tooot.app/) ([Google Play](https://play.google.com/store/apps/details?id=com.xmflsct.app.tooot))
* [Tusky](https://tusky.app) ([F-Droid](https://f-droid.org/repository/browse/?fdid=com.keylesspalace.tusky), [Google Play](https://play.google.com/store/apps/details?id=com.keylesspalace.tusky))
* [TwidereX](https://github.com/TwidereProject/TwidereX-Android) ([F-Droid](https://f-droid.org/en/packages/com.twidere.twiderex/), [Google Play](https://play.google.com/store/apps/details?id=com.twidere.twiderex))
@ -193,7 +193,7 @@ The available features are client specific and may differ.
* [Mastodon](https://joinmastodon.org/apps) ([App Store](https://apps.apple.com/us/app/mastodon-for-iphone/id1571998974))
* [Stella*](https://www.stella-app.net/) ([App Store](https://apps.apple.com/us/app/stella-for-mastodon-twitter/id921372048))
* [Tooot](https://github.com/tooot-app) ([App Store](https://apps.apple.com/app/id1549772269)
* [Tooot](https://github.com/tooot-app) ([App Store](https://apps.apple.com/app/id1549772269))
* [TwidereX](https://github.com/TwidereProject/TwidereX-iOS) ([App Store](https://apps.apple.com/app/twidere-x/id1530314034))
#### Linux
@ -211,7 +211,7 @@ The available features are client specific and may differ.
#### Windows
* [TheDesk](https://thedesk.top/en/) ([GitHub](https://github.com/cutls/TheDesk))
* [Whalebird](https://whalebird.social/en/desktop/contents) ([Website Download](https://whalebird.social/en/desktop/contents/downloads#windows), [GitHub](https://github.com/h3poteto/whalebird-desktop))
* [Whalebird](https://whalebird.social/en/desktop/contents) ([Microsoft Store](https://apps.microsoft.com/detail/9nbw4csdv5hc), [GitHub](https://github.com/h3poteto/whalebird-desktop))
#### Web Frontend

Wyświetl plik

@ -44,7 +44,7 @@ For alternative server configurations (such as Nginx server and MariaDB database
### Optional
* PHP ImageMagick extension (php-imagick) for animated GIF support.
* PHP ImageMagick extension (php-imagick) for animated GIF and animated WebP support.
## Installation procedure

Wyświetl plik

@ -6,17 +6,18 @@ Contact relations
Fields
------
| Field | Description | Type | Null | Key | Default | Extra |
| --------------------- | -------------------------------------------------------- | ----------------- | ---- | --- | ------------------- | ----- |
| cid | contact the related contact had interacted with | int unsigned | NO | PRI | 0 | |
| relation-cid | related contact who had interacted with the contact | int unsigned | NO | PRI | 0 | |
| last-interaction | Date of the last interaction by relation-cid on cid | datetime | NO | | 0001-01-01 00:00:00 | |
| follow-updated | Date of the last update of the contact relationship | datetime | NO | | 0001-01-01 00:00:00 | |
| follows | if true, relation-cid follows cid | boolean | NO | | 0 | |
| score | score for interactions of cid on relation-cid | smallint unsigned | YES | | NULL | |
| relation-score | score for interactions of relation-cid on cid | smallint unsigned | YES | | NULL | |
| thread-score | score for interactions of cid on threads of relation-cid | smallint unsigned | YES | | NULL | |
| relation-thread-score | score for interactions of relation-cid on threads of cid | smallint unsigned | YES | | NULL | |
| Field | Description | Type | Null | Key | Default | Extra |
| --------------------- | ----------------------------------------------------------------------- | ----------------- | ---- | --- | ------------------- | ----- |
| cid | contact the related contact had interacted with | int unsigned | NO | PRI | 0 | |
| relation-cid | related contact who had interacted with the contact | int unsigned | NO | PRI | 0 | |
| last-interaction | Date of the last interaction by relation-cid on cid | datetime | NO | | 0001-01-01 00:00:00 | |
| follow-updated | Date of the last update of the contact relationship | datetime | NO | | 0001-01-01 00:00:00 | |
| follows | if true, relation-cid follows cid | boolean | NO | | 0 | |
| score | score for interactions of cid on relation-cid | smallint unsigned | YES | | NULL | |
| relation-score | score for interactions of relation-cid on cid | smallint unsigned | YES | | NULL | |
| thread-score | score for interactions of cid on threads of relation-cid | smallint unsigned | YES | | NULL | |
| relation-thread-score | score for interactions of relation-cid on threads of cid | smallint unsigned | YES | | NULL | |
| post-score | score for the amount of posts from cid that can be seen by relation-cid | smallint unsigned | YES | | NULL | |
Indexes
------------

Wyświetl plik

@ -11,11 +11,12 @@ Fields
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
| owner-id | Item owner | int unsigned | NO | | 0 | |
| contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio) | tinyint | NO | | 0 | |
| language | Language information about this post in the ISO 639-1 format | char(2) | YES | | NULL | |
| searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | |
| size | Body size | int unsigned | YES | | NULL | |
| created | | datetime | YES | | NULL | |
| network | | char(4) | YES | | NULL | |
| restricted | If true, this post is either unlisted or not from a federated network | boolean | NO | | 0 | |
| comments | Number of comments | mediumint unsigned | YES | | NULL | |
| activities | Number of activities (like, dislike, ...) | mediumint unsigned | YES | | NULL | |

Wyświetl plik

@ -10,7 +10,7 @@ Fields
| ---------- | --------------------------------------------------------------------- | ------------ | ---- | --- | ------- | ----- |
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
| owner-id | Item owner | int unsigned | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio) | tinyint | NO | | 0 | |
| language | Language information about this post in the ISO 639-1 format | char(2) | YES | | NULL | |
| searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | |
| size | Body size | int unsigned | YES | | NULL | |

Wyświetl plik

@ -25,6 +25,7 @@ Fields
| post-reason | Reason why the post arrived at the user | tinyint unsigned | NO | | 0 | |
| vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | YES | | NULL | |
| private | 0=public, 1=private, 2=unlisted | tinyint unsigned | NO | | 0 | |
| restrictions | Bit array of post restrictions (1 = Reply, 2 = Like, 4 = Announce) | tinyint unsigned | YES | | NULL | |
| global | | boolean | NO | | 0 | |
| visible | | boolean | NO | | 0 | |
| deleted | item has been marked for deletion | boolean | NO | | 0 | |

Wyświetl plik

@ -6,29 +6,30 @@ User specific public contact data
Fields
------
| Field | Description | Type | Null | Key | Default | Extra |
| ------------------------- | ----------------------------------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
| cid | Contact id of the linked public contact | int unsigned | NO | PRI | 0 | |
| uid | User id | mediumint unsigned | NO | PRI | 0 | |
| uri-id | Id of the item-uri table entry that contains the contact url | int unsigned | YES | | NULL | |
| blocked | Contact is completely blocked for this user | boolean | YES | | NULL | |
| ignored | Posts from this contact are ignored | boolean | YES | | NULL | |
| collapsed | Posts from this contact are collapsed | boolean | YES | | NULL | |
| hidden | This contact is hidden from the others | boolean | YES | | NULL | |
| is-blocked | User is blocked by this contact | boolean | YES | | NULL | |
| channel-frequency | Controls the frequency of the appearance of this contact in channels | tinyint unsigned | YES | | NULL | |
| pending | | boolean | YES | | NULL | |
| rel | The kind of the relation between the user and the contact | tinyint unsigned | YES | | NULL | |
| info | | mediumtext | YES | | NULL | |
| notify_new_posts | | boolean | YES | | NULL | |
| remote_self | 0 => No mirroring, 1-2 => Mirror as own post, 3 => Mirror as reshare | tinyint unsigned | YES | | NULL | |
| fetch_further_information | 0 => None, 1 => Fetch information, 3 => Fetch keywords, 2 => Fetch both | tinyint unsigned | YES | | NULL | |
| ffi_keyword_denylist | | text | YES | | NULL | |
| subhub | | boolean | YES | | NULL | |
| hub-verify | | varbinary(383) | YES | | NULL | |
| protocol | Protocol of the contact | char(4) | YES | | NULL | |
| rating | Automatically detected feed poll frequency | tinyint | YES | | NULL | |
| priority | Feed poll priority | tinyint unsigned | YES | | NULL | |
| Field | Description | Type | Null | Key | Default | Extra |
| ------------------------- | -------------------------------------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
| cid | Contact id of the linked public contact | int unsigned | NO | PRI | 0 | |
| uid | User id | mediumint unsigned | NO | PRI | 0 | |
| uri-id | Id of the item-uri table entry that contains the contact url | int unsigned | YES | | NULL | |
| blocked | Contact is completely blocked for this user | boolean | YES | | NULL | |
| ignored | Posts from this contact are ignored | boolean | YES | | NULL | |
| collapsed | Posts from this contact are collapsed | boolean | YES | | NULL | |
| hidden | This contact is hidden from the others | boolean | YES | | NULL | |
| channel-only | This contact is displayed only in channels, but not in the network stream. | boolean | YES | | NULL | |
| is-blocked | User is blocked by this contact | boolean | YES | | NULL | |
| channel-frequency | Controls the frequency of the appearance of this contact in channels | tinyint unsigned | YES | | NULL | |
| pending | | boolean | YES | | NULL | |
| rel | The kind of the relation between the user and the contact | tinyint unsigned | YES | | NULL | |
| info | | mediumtext | YES | | NULL | |
| notify_new_posts | | boolean | YES | | NULL | |
| remote_self | 0 => No mirroring, 1-2 => Mirror as own post, 3 => Mirror as reshare | tinyint unsigned | YES | | NULL | |
| fetch_further_information | 0 => None, 1 => Fetch information, 3 => Fetch keywords, 2 => Fetch both | tinyint unsigned | YES | | NULL | |
| ffi_keyword_denylist | | text | YES | | NULL | |
| subhub | | boolean | YES | | NULL | |
| hub-verify | | varbinary(383) | YES | | NULL | |
| protocol | Protocol of the contact | char(4) | YES | | NULL | |
| rating | Automatically detected feed poll frequency | tinyint | YES | | NULL | |
| priority | Feed poll priority | tinyint unsigned | YES | | NULL | |
Indexes
------------

Wyświetl plik

@ -2,153 +2,10 @@
* [Home](help)
To change the look of friendica you have to touch the themes.
The current default theme is [Vier](https://github.com/friendica/friendica/tree/stable/view/theme/vier) but there are numerous others.
Have a look at [github.com/bkil/friendica-themes](https://github.com/bkil/friendica-themes) for an overview of the existing themes.
In case none of them suits your needs, there are several ways to change a theme.
The default Theme in Friendica is called [frio](https://github.com/friendica/friendica/tree/stable/view/theme/frio).
So, how to work on the UI of friendica.
Open `Settings > Display > Custom Theme Settings` adjust the Theme to your liking. Select your preferred Appearance - light, dark or black - and your favorite Accent color. Click `Submit` to save your changes.
You can either directly edit an existing theme.
But you might loose your changes when the theme is updated by the friendica team.
The `Custom` Appearance allows to tweak the themes CSS and set colors for UI elements. So called `schemestrings` can be shared between users.
If you are almost happy with an existing theme, the easiest way to cover your needs is to create a new theme, inheriting most of the properties of the parent theme and change just minor stuff.
The below for a more detailed description of theme heritage.
Some themes also allow users to select *variants* of the theme.
Those theme variants most often contain an additional [CSS](https://en.wikipedia.org/wiki/CSS) file to override some styling of the default theme values.
From the themes in the main repository *vier* and *vier* are using this methods for variations.
Quattro is using a slightly different approach.
Third you can start your theme from scratch.
Which is the most complex way to change friendicas look.
But it leaves you the most freedom.
So below for a *detailed* description and the meaning of some special files.
### Styling
If you want to change the styling of a theme, have a look at the themes CSS file.
In most cases, you can found these in
/view/theme/**your-theme-name**/style.css
sometimes, there is also a file called style.php in the theme directory.
This is only needed if the theme allows the user to change certain things of the theme dynamically.
Say the font size or set a background image.
### Templates
If you want to change the structure of the theme, you need to change the templates used by the theme.
Friendica themes are using [SMARTY3](http://www.smarty.net/) for templating.
The default template can be found in
/view/templates
if you want to override any template within your theme create your version of the template in
/view/theme/**your-theme-name**/templates
any template that exists there will be used instead of the default one.
### JavaScript
The same rule applies to the JavaScript files found in
/js
they will be overwritten by files in
/view/theme/**your-theme-name**/js.
## Creating a Theme from Scratch
Keep patient.
Basically what you have to do is identify which template you have to change so it looks more like what you want.
Adopt the CSS of the theme accordingly.
And iterate the process until you have the theme the way you want it.
*Use the source Luke.* and don't hesitate to ask in @[developers](https://forum.friendi.ca/profile/developers) or @[helpers](https://forum.friendi.ca/profile/helpers).
## Special Files
### unsupported
If a file with this name (which might be empty) exists in the theme directory, the theme is marked as *unsupported*.
An unsupported theme may not be selected by a user in the settings.
Users who are already using it wont notice anything.
### README(.md)
The contents of this file, with or without the .md which indicates [Markdown](https://daringfireball.net/projects/markdown/) syntax, will be displayed at most repository hosting services and in the theme page within the admin panel of friendica.
This file should contain information you want to let others know about your theme.
### screenshot.[png|jpg]
If you want to have a preview image of your theme displayed in the settings you should take a screenshot and save it with this name.
Supported formats are PNG and JPEG.
### theme.php
This is the main definition file of the theme.
In the header of that file, some meta information is stored.
For example, have a look at the theme.php of the *vier* theme:
<?php
/**
* [Licence]
*
* Name: Vier
* Version: 1.2
* Author: Fabio <http://kirgroup.com/profile/fabrixxm>
* Author: Ike <http://pirati.ca/profile/heluecht>
* Author: Beanow <https://fc.oscp.info/profile/beanow>
* Maintainer: Ike <http://pirati.ca/profile/heluecht>
* Description: "Vier" is a very compact and modern theme. It uses the font awesome font library: http://fortawesome.github.com/Font-Awesome/
*/
You see the definition of the theme's name, it's version and the initial author of the theme.
These three pieces of information should be listed.
If the original author is no longer working on the theme, but a maintainer has taken over, the maintainer should be listed as well.
The information from the theme header will be displayed in the admin panel.
The first thing in file is to import the `App` class from `\Friendica\` namespace.
use Friendica\App;
This will make our job a little easier, as we don't have to specify the full name every time we need to use the `App` class.
The next crucial part of the theme.php file is a definition of an init function.
The name of the function is <theme-name>_init.
So in the case of vier it is
function vier_init(App $a) {
$a->theme_info = array();
$a->set_template_engine('smarty3');
}
Here we have set the basic theme information, in this case they are empty.
But the array needs to be set.
And we have set the template engine that should be used by friendica for this theme.
At the moment you should use the *smarty3* engine.
There once was a friendica specific templating engine as well but that is not used anymore.
If you like to use another templating engine, please implement it.
If you want to add something to the HTML header of the theme, one way to do so is by adding it to the theme.php file.
To do so, add something alike
DI::page()['htmlhead'] .= <<< EOT
/* stuff you want to add to the header */
EOT;
So you can access the properties of this friendica session from the theme.php file as well.
### default.php
This file covers the structure of the underlying HTML layout.
The default file is in
/view/default.php
if you want to change it, say adding a 4th column for banners of your favourite FLOSS projects, place a new default.php file in your theme directory.
As with the theme.php file, you can use the properties of the $a variable with holds the friendica application to decide what content is displayed.
In the `General Theme Settings` you can also find the [vier](https://github.com/friendica/friendica/tree/stable/view/theme/vier) Theme, which precedes frio and is no longer officially maintained.

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 5.0 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 7.8 KiB

Wyświetl plik

@ -278,7 +278,7 @@ function item_process(array $post, array $request, bool $preview, string $return
$post['quote-uri-id'] = Item::getQuoteUriId($post['body'], $post['uid']);
$post['body'] = BBCode::removeSharedData(Item::setHashtags($post['body']));
$post['writable'] = true;
$post['sensitive'] = true;
$post['sensitive'] = false;
$o = DI::conversation()->render([$post], Conversation::MODE_SEARCH, false, true);

Wyświetl plik

@ -132,8 +132,6 @@ function photos_post(App $a)
throw new HTTPException\NotFoundException(DI::l10n()->t('User not found.'));
}
$phototypes = Images::supportedTypes();
$can_post = false;
$visitor = 0;
@ -337,7 +335,7 @@ function photos_post(App $a)
if (DBA::isResult($photos)) {
$photo = $photos[0];
$ext = $phototypes[$photo['type']];
$ext = Images::getExtensionByMimeType($photo['type']);
Photo::update(
['desc' => $desc, 'album' => $albname, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_circle_allow, 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_circle_deny],
['resource-id' => $resource_id, 'uid' => $page_owner_uid]
@ -590,8 +588,6 @@ function photos_content(App $a)
$profile = Profile::getByUID($user['uid']);
$phototypes = Images::supportedTypes();
$_SESSION['photo_return'] = DI::args()->getCommand();
// Parse arguments
@ -844,7 +840,7 @@ function photos_content(App $a)
foreach ($r as $rr) {
$twist = !$twist;
$ext = $phototypes[$rr['type']];
$ext = Images::getExtensionByMimeType($rr['type']);
$imgalt_e = $rr['filename'];
$desc_e = $rr['desc'];
@ -855,7 +851,7 @@ function photos_content(App $a)
'link' => 'photos/' . $user['nickname'] . '/image/' . $rr['resource-id']
. ($order_field === 'created' ? '?order=created' : ''),
'title' => DI::l10n()->t('View Photo'),
'src' => 'photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' . $ext,
'src' => 'photo/' . $rr['resource-id'] . '-' . $rr['scale'] . $ext,
'alt' => $imgalt_e,
'desc' => $desc_e,
'ext' => $ext,
@ -1013,9 +1009,9 @@ function photos_content(App $a)
}
$photo = [
'href' => 'photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']],
'href' => 'photo/' . $hires['resource-id'] . '-' . $hires['scale'] . Images::getExtensionByMimeType($hires['type']),
'title' => DI::l10n()->t('View Full Size'),
'src' => 'photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?_u=' . DateTimeFormat::utcNow('ymdhis'),
'src' => 'photo/' . $lores['resource-id'] . '-' . $lores['scale'] . Images::getExtensionByMimeType($lores['type']) . '?_u=' . DateTimeFormat::utcNow('ymdhis'),
'height' => $hires['height'],
'width' => $hires['width'],
'album' => $hires['album'],
@ -1043,7 +1039,7 @@ function photos_content(App $a)
$pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$params = ['order' => ['id'], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
$items = Post::toArray(Post::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params));
$items = Post::toArray(Post::selectForUser($link_item['uid'], array_merge(Item::ITEM_FIELDLIST, ['author-alias']), $condition, $params));
if (DI::userSession()->getLocalUserId() == $link_item['uid']) {
Item::update(['unseen' => false], ['parent' => $link_item['parent']]);

Wyświetl plik

@ -1,6 +1,6 @@
Contact: mailto:info@friendi.ca
Expires: 2024-10-30T23:59:59Z
Expires: 2025-01-30T23:59:59Z
Preferred-Languages: en

Wyświetl plik

@ -43,6 +43,7 @@ use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
use Friendica\Network\HTTPException;
use Friendica\Protocol\ATProtocol\DID;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPInputData;
use Friendica\Util\HTTPSignature;
@ -64,7 +65,7 @@ class App
{
const PLATFORM = 'Friendica';
const CODENAME = 'Yellow Archangel';
const VERSION = '2024.03-dev';
const VERSION = '2024.06-dev';
// Allow themes to control internal parameters
// by changing App values in theme.php
@ -565,8 +566,8 @@ class App
*/
public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, Nav $nav, ModuleHTTPException $httpException, HTTPInputData $httpInput, float $start_time, array $server)
{
$requeststring = ($_SERVER['REQUEST_METHOD'] ?? '') . ' ' . ($_SERVER['REQUEST_URI'] ?? '') . ' ' . ($_SERVER['SERVER_PROTOCOL'] ?? '');
$this->logger->debug('Request received', ['address' => $_SERVER['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $_SERVER['HTTP_REFERER'] ?? '', 'user-agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']);
$requeststring = ($server['REQUEST_METHOD'] ?? '') . ' ' . ($server['REQUEST_URI'] ?? '') . ' ' . ($server['SERVER_PROTOCOL'] ?? '');
$this->logger->debug('Request received', ['address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '']);
$request_start = microtime(true);
$this->profiler->set($start_time, 'start');
@ -593,8 +594,10 @@ class App
Core\Hook::callAll('init_1');
}
DID::routeRequest($this->args->getCommand(), $server);
if ($this->mode->isNormal() && !$this->mode->isBackend()) {
$requester = HTTPSignature::getSigner('', $_SERVER);
$requester = HTTPSignature::getSigner('', $server);
if (!empty($requester)) {
Profile::addVisitorCookieForHandle($requester);
}
@ -716,10 +719,10 @@ class App
$response = $page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId());
}
$this->logger->debug('Request processed sucessfully', ['response' => $response->getStatusCode(), 'address' => $_SERVER['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $_SERVER['HTTP_REFERER'] ?? '', 'user-agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
$this->logger->debug('Request processed sucessfully', ['response' => $response->getStatusCode(), 'address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
System::echoResponse($response);
} catch (HTTPException $e) {
$this->logger->debug('Request processed with exception', ['response' => $e->getCode(), 'address' => $_SERVER['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $_SERVER['HTTP_REFERER'] ?? '', 'user-agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
$this->logger->debug('Request processed with exception', ['response' => $e->getCode(), 'address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
$httpException->rawContent($e);
}
$page->logRuntime($this->config, 'runFrontend');

Wyświetl plik

@ -150,7 +150,7 @@ HELP;
if ($valid) {
$this->out('3', false);
$image = new Image($imgdata, Images::getMimeTypeByData($imgdata));
$image = new Image($imgdata);
if (!$image->isValid()) {
$this->out(' ' . $this->l10n->t('invalid image for id %s', $resourceid) . ' ', false);
$valid = false;

Wyświetl plik

@ -80,13 +80,18 @@ class Avatar
return $fields;
}
if (!$fetchResult->isSuccess()) {
Logger::debug('Fetching was unsuccessful', ['avatar' => $avatar]);
return $fields;
}
$img_str = $fetchResult->getBodyString();
if (empty($img_str)) {
Logger::debug('Avatar is invalid', ['avatar' => $avatar]);
return $fields;
}
$image = new Image($img_str, Images::getMimeTypeByData($img_str));
$image = new Image($img_str, $fetchResult->getContentType(), $avatar);
if (!$image->isValid()) {
Logger::debug('Avatar picture is invalid', ['avatar' => $avatar]);
return $fields;
@ -145,7 +150,7 @@ class Avatar
return '';
}
$path = $filename . $size . '.' . $image->getExt();
$path = $filename . $size . $image->getExt();
$basepath = self::basePath();
if (empty($basepath)) {

Wyświetl plik

@ -28,6 +28,7 @@ class Channel extends Timeline
const DISCOVER = 'discover';
const FOLLOWERS = 'followers';
const SHARERSOFSHARERS = 'sharersofsharers';
const QUIETSHARERS = 'quietsharers';
const IMAGE = 'image';
const VIDEO = 'video';
const AUDIO = 'audio';

Wyświetl plik

@ -45,6 +45,7 @@ final class Channel extends Timeline
new ChannelEntity(ChannelEntity::LANGUAGE, $native, $this->l10n->t('Posts in %s', $native), 'g'),
new ChannelEntity(ChannelEntity::FOLLOWERS, $this->l10n->t('Followers'), $this->l10n->t('Posts from your followers that you don\'t follow'), 'f'),
new ChannelEntity(ChannelEntity::SHARERSOFSHARERS, $this->l10n->t('Sharers of sharers'), $this->l10n->t('Posts from accounts that are followed by accounts that you follow'), 'r'),
new ChannelEntity(ChannelEntity::QUIETSHARERS, $this->l10n->t('Quiet sharers'), $this->l10n->t('Posts from accounts that you follow but who don\'t post very often'), 'q'),
new ChannelEntity(ChannelEntity::IMAGE, $this->l10n->t('Images'), $this->l10n->t('Posts with images'), 'i'),
new ChannelEntity(ChannelEntity::AUDIO, $this->l10n->t('Audio'), $this->l10n->t('Posts with audio'), 'd'),
new ChannelEntity(ChannelEntity::VIDEO, $this->l10n->t('Videos'), $this->l10n->t('Posts with videos'), 'v'),
@ -55,6 +56,6 @@ final class Channel extends Timeline
public function isTimeline(string $selectedTab): bool
{
return in_array($selectedTab, [ChannelEntity::WHATSHOT, ChannelEntity::FORYOU, ChannelEntity::DISCOVER, ChannelEntity::FOLLOWERS, ChannelEntity::SHARERSOFSHARERS, ChannelEntity::IMAGE, ChannelEntity::VIDEO, ChannelEntity::AUDIO, ChannelEntity::LANGUAGE]);
return in_array($selectedTab, [ChannelEntity::WHATSHOT, ChannelEntity::FORYOU, ChannelEntity::DISCOVER, ChannelEntity::FOLLOWERS, ChannelEntity::SHARERSOFSHARERS, ChannelEntity::QUIETSHARERS, ChannelEntity::IMAGE, ChannelEntity::VIDEO, ChannelEntity::AUDIO, ChannelEntity::LANGUAGE]);
}
}

Wyświetl plik

@ -695,7 +695,7 @@ class Item
$item['body'] = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
}
$shared_content = BBCode::getShareOpeningTag($item['author-name'], $item['author-link'], $item['author-avatar'], $item['plink'], $item['created'], $item['guid'], $item['uri']);
$shared_content = BBCode::getShareOpeningTag($item['author-name'], $item['author-link'], $item['author-avatar'], $item['plink'] ?? $item['uri'], $item['created'], $item['guid'], $item['uri']);
if (!empty($item['title'])) {
$shared_content .= '[h3]' . $item['title'] . "[/h3]\n";
@ -1105,4 +1105,35 @@ class Item
Tag::store($toUriId, $receiver['type'], $receiver['name'], $receiver['url']);
}
}
/**
* Check if the item is too old
*
* @param string $created
* @param integer $uid
* @return boolean item is too old
*/
public function isTooOld(string $created, int $uid = 0): bool
{
// check for create date and expire time
$expire_interval = DI::config()->get('system', 'dbclean-expire-days', 0);
if ($uid) {
$user = DBA::selectFirst('user', ['expire'], ['uid' => $uid]);
if (DBA::isResult($user) && ($user['expire'] > 0) && (($user['expire'] < $expire_interval) || ($expire_interval == 0))) {
$expire_interval = $user['expire'];
}
}
if (($expire_interval > 0) && !empty($created)) {
$expire_date = time() - ($expire_interval * 86400);
$created_date = strtotime($created);
if ($created_date < $expire_date) {
Logger::notice('Item created before expiration interval.', ['created' => date('c', $created_date), 'expired' => date('c', $expire_date)]);
return true;
}
}
return false;
}
}

Wyświetl plik

@ -251,7 +251,7 @@ class Nav
$nav['home'] = [$homelink, $this->l10n->t('Home'), '', $this->l10n->t('Home Page')];
}
if (intval($this->config->get('config', 'register_policy')) === \Friendica\Module\Register::OPEN && !$this->session->isAuthenticated()) {
if (\Friendica\Module\Register::getPolicy() === \Friendica\Module\Register::OPEN && !$this->session->isAuthenticated()) {
$nav['register'] = ['register', $this->l10n->t('Register'), '', $this->l10n->t('Create an account')];
}

Wyświetl plik

@ -22,10 +22,9 @@
namespace Friendica\Content;
use DOMDocument;
use DOMNode;
use DOMText;
use DOMXPath;
use Exception;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Hook;
use Friendica\Core\Renderer;
@ -49,32 +48,15 @@ use Friendica\Util\Strings;
*/
class OEmbed
{
/**
* Callback for fetching URL, checking allowance and returning formatted HTML
*
* @param array $matches
* @return string Formatted HTML
*/
public static function replaceCallback(array $matches): string
{
$embedurl = $matches[1];
$j = self::fetchURL($embedurl, !self::isAllowedURL($embedurl));
$s = self::formatObject($j);
return $s;
}
/**
* Get data from an URL to embed its content.
*
* @param string $embedurl The URL from which the data should be fetched.
* @param bool $no_rich_type If set to true rich type content won't be fetched.
* @param bool $use_parseurl Use the "ParseUrl" functionality to add additional data
* @param string $embedurl The URL from which the data should be fetched.
*
* @return \Friendica\Object\OEmbed
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function fetchURL(string $embedurl, bool $no_rich_type = false, bool $use_parseurl = true): \Friendica\Object\OEmbed
private static function fetchURL(string $embedurl): \Friendica\Object\OEmbed
{
$embedurl = trim($embedurl, '\'"');
@ -119,7 +101,7 @@ class OEmbed
$href = str_replace(['http://www.youtube.com/', 'http://player.vimeo.com/'],
['https://www.youtube.com/', 'https://player.vimeo.com/'], $href);
$result = DI::httpClient()->fetchFull($href . '&maxwidth=' . $a->getThemeInfoValue('videowidth'));
if ($result->getReturnCode() === 200) {
if ($result->isSuccess()) {
$json_string = $result->getBodyString();
break;
}
@ -157,57 +139,55 @@ class OEmbed
}
// Improve the OEmbed data with data from OpenGraph, Twitter cards and other sources
if ($use_parseurl) {
$data = ParseUrl::getSiteinfoCached($embedurl, false);
$data = ParseUrl::getSiteinfoCached($embedurl);
if (($oembed->type == 'error') && empty($data['title']) && empty($data['text'])) {
return $oembed;
}
if (($oembed->type == 'error') && empty($data['title']) && empty($data['text'])) {
return $oembed;
}
if ($no_rich_type || ($oembed->type == 'error')) {
$oembed->html = '';
$oembed->type = $data['type'];
if (!self::isAllowedURL($embedurl) || ($oembed->type == 'error')) {
$oembed->html = '';
$oembed->type = $data['type'];
if ($oembed->type == 'photo') {
if (!empty($data['images'])) {
$oembed->url = $data['images'][0]['src'];
$oembed->width = $data['images'][0]['width'];
$oembed->height = $data['images'][0]['height'];
} else {
$oembed->type = 'link';
}
if ($oembed->type == 'photo') {
if (!empty($data['images'])) {
$oembed->url = $data['images'][0]['src'];
$oembed->width = $data['images'][0]['width'];
$oembed->height = $data['images'][0]['height'];
} else {
$oembed->type = 'link';
}
}
}
if (!empty($data['title'])) {
$oembed->title = $data['title'];
}
if (!empty($data['title'])) {
$oembed->title = $data['title'];
}
if (!empty($data['text'])) {
$oembed->description = $data['text'];
}
if (!empty($data['text'])) {
$oembed->description = $data['text'];
}
if (!empty($data['publisher_name'])) {
$oembed->provider_name = $data['publisher_name'];
}
if (!empty($data['publisher_name'])) {
$oembed->provider_name = $data['publisher_name'];
}
if (!empty($data['publisher_url'])) {
$oembed->provider_url = $data['publisher_url'];
}
if (!empty($data['publisher_url'])) {
$oembed->provider_url = $data['publisher_url'];
}
if (!empty($data['author_name'])) {
$oembed->author_name = $data['author_name'];
}
if (!empty($data['author_name'])) {
$oembed->author_name = $data['author_name'];
}
if (!empty($data['author_url'])) {
$oembed->author_url = $data['author_url'];
}
if (!empty($data['author_url'])) {
$oembed->author_url = $data['author_url'];
}
if (!empty($data['images']) && ($oembed->type != 'photo')) {
$oembed->thumbnail_url = $data['images'][0]['src'];
$oembed->thumbnail_width = $data['images'][0]['width'];
$oembed->thumbnail_height = $data['images'][0]['height'];
}
if (!empty($data['images']) && ($oembed->type != 'photo')) {
$oembed->thumbnail_url = $data['images'][0]['src'];
$oembed->thumbnail_width = $data['images'][0]['width'];
$oembed->thumbnail_height = $data['images'][0]['height'];
}
Hook::callAll('oembed_fetch_url', $embedurl, $oembed);
@ -219,9 +199,10 @@ class OEmbed
* Returns a formatted string from OEmbed object
*
* @param \Friendica\Object\OEmbed $oembed
* @param int $uriid
* @return string
*/
private static function formatObject(\Friendica\Object\OEmbed $oembed): string
private static function formatObject(\Friendica\Object\OEmbed $oembed, int $uriid): string
{
$ret = '<div class="oembed ' . $oembed->type . '">';
@ -241,22 +222,22 @@ class OEmbed
'$escapedhtml' => base64_encode($oembed->html),
'$tw' => $tw,
'$th' => $th,
'$turl' => $oembed->thumbnail_url,
'$turl' => BBCode::proxyUrl($oembed->thumbnail_url, BBCode::INTERNAL, $uriid, Proxy::SIZE_SMALL),
]);
} else {
$ret = $oembed->html;
$ret .= Proxy::proxifyHtml($oembed->html, $uriid);
}
break;
case 'photo':
$ret .= '<img width="' . $oembed->width . '" src="' . Proxy::proxifyUrl($oembed->url) . '">';
$ret .= '<img width="' . $oembed->width . '" src="' . BBCode::proxyUrl($oembed->url, BBCode::INTERNAL, $uriid, Proxy::SIZE_MEDIUM) . '">';
break;
case 'link':
break;
case 'rich':
$ret .= Proxy::proxifyHtml($oembed->html);
$ret .= Proxy::proxifyHtml($oembed->html, $uriid);
break;
}
@ -294,12 +275,21 @@ class OEmbed
$ret .= '<a href="' . $oembed->embed_url . '" rel="oembed">' . $oembed->embed_url . '</a>';
}
$ret .= "</h4>";
if ($oembed->type == 'link') {
if (!empty($oembed->thumbnail_url)) {
$ret .= '<img width="' . $oembed->width . '" src="' . BBCode::proxyUrl($oembed->thumbnail_url, BBCode::INTERNAL, $uriid, Proxy::SIZE_MEDIUM) . '">';
}
if (!empty($oembed->description)) {
$ret .= '<p>' . $oembed->description . '</p>';
}
}
} elseif (!strpos($oembed->html, $oembed->embed_url)) {
// add <a> for html2bbcode conversion
$ret .= '<a href="' . $oembed->embed_url . '" rel="oembed">' . $oembed->title . '</a>';
}
$ret .= '</div>';
$test = Proxy::proxifyHtml($ret, $uriid);
return str_replace("\n", "", $ret);
}
@ -308,51 +298,19 @@ class OEmbed
* Converts BBCode to HTML code
*
* @param string $text
* @param int $uriid
* @return string
*/
public static function BBCode2HTML(string $text): string
public static function BBCode2HTML(string $text, int $uriid): string
{
if (DI::config()->get('system', 'no_oembed')) {
return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "<!-- oembed $1 --><i>" . DI::l10n()->t('Embedding disabled') . " : $1</i><!-- /oembed $1 -->", $text);
}
return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", [self::class, 'replaceCallback'], $text);
}
/**
* Find <span class='oembed'>..<a href='url' rel='oembed'>..</a></span>
* and replace it with [embed]url[/embed]
*
* @param string $text
* @return string
*/
public static function HTML2BBCode(string $text): string
{
// start parser only if 'oembed' is in text
if (strpos($text, 'oembed')) {
// convert non ascii chars to html entities
$html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text));
// If it doesn't parse at all, just return the text.
$dom = new DOMDocument();
if (!@$dom->loadHTML($html_text)) {
return $text;
}
$xpath = new DOMXPath($dom);
$xattr = self::buildXPath('class', 'oembed');
$entries = $xpath->query("//div[$xattr]");
$xattr = "@rel='oembed'"; //oe_build_xpath("rel","oembed");
foreach ($entries as $e) {
$href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue;
if (!is_null($href)) {
$e->parentNode->replaceChild(new DOMText('[embed]' . $href . '[/embed]'), $e);
}
}
return self::getInnerHTML($dom->getElementsByTagName('body')->item(0));
} else {
if (!preg_match_all("/\[embed\](.+?)\[\/embed\]/is", $text, $matches, PREG_SET_ORDER)) {
return $text;
}
foreach ($matches as $match) {
$data = self::fetchURL($match[1]);
$text = str_replace($match[0], self::formatObject($data, $uriid), $text);
}
return $text;
}
/**
@ -373,26 +331,25 @@ class OEmbed
return false;
}
$str_allowed = DI::config()->get('system', 'allowed_oembed', '');
if (empty($str_allowed)) {
$allowed = DI::config()->get('system', 'allowed_oembed', '');
if (empty($allowed)) {
return false;
}
$allowed = explode(',', $str_allowed);
return Network::isDomainAllowed($domain, $allowed);
return Network::isDomainMatch($domain, explode(',', $allowed));
}
/**
* Returns a formatted HTML code from given URL and sets optional title
*
* @param string $url URL to fetch
* @param string $title Optional title (default: what comes from OEmbed object)
* @param string $title title (default: what comes from OEmbed object)
* @param int $uriid
* @return string Formatted HTML
*/
public static function getHTML(string $url, string $title = ''): string
public static function getHTML(string $url, string $title, int $uriid): string
{
$o = self::fetchURL($url, !self::isAllowedURL($url));
$o = self::fetchURL($url);
if (!is_object($o) || property_exists($o, 'type') && $o->type == 'error') {
throw new Exception('OEmbed failed for URL: ' . $url);
@ -402,74 +359,8 @@ class OEmbed
$o->title = $title;
}
$html = self::formatObject($o);
$html = self::formatObject($o, $uriid);
return $html;
}
/**
* Generates the iframe HTML for an oembed attachment.
*
* Width and height are given by the remote, and are regularly too small for
* the generated iframe.
*
* The width is entirely discarded for the actual width of the post, while fixed
* height is used as a starting point before the inevitable resizing.
*
* Since the iframe is automatically resized on load, there are no need for ugly
* and impractical scrollbars.
*
* @todo This function is currently unused until someone™ adds support for a separate OEmbed domain
*
* @param string $src Original remote URL to embed
* @param string $width
* @param string $height
* @return string Formatted HTML
*
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @see oembed_format_object()
*/
private static function iframe(string $src, string $width, string $height): string
{
if (!$height || strstr($height, '%')) {
$height = '200';
}
$width = '100%';
$src = DI::baseUrl() . '/oembed/' . Strings::base64UrlEncode($src);
return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $src . '" allowfullscreen scrolling="no" frameborder="no">' . DI::l10n()->t('Embedded content') . '</iframe>';
}
/**
* Generates attribute search XPath string
*
* Generates an XPath query to select elements whose provided attribute contains
* the provided value in a space-separated list.
*
* @param string $attr Name of the attribute to search
* @param string $value Value to search in a space-separated list
* @return string
*/
private static function buildXPath(string $attr, $value): string
{
// https://www.westhoffswelt.de/blog/2009/6/9/select-html-elements-with-more-than-one-css-class-using-xpath
return "contains(normalize-space(@$attr), ' $value ') or substring(normalize-space(@$attr), 1, string-length('$value') + 1) = '$value ' or substring(normalize-space(@$attr), string-length(@$attr) - string-length('$value')) = ' $value' or @$attr = '$value'";
}
/**
* Returns the inner XML string of a provided DOMNode
*
* @param DOMNode $node
* @return string
*/
private static function getInnerHTML(DOMNode $node): string
{
$innerHTML = '';
$children = $node->childNodes;
foreach ($children as $child) {
$innerHTML .= $child->ownerDocument->saveXML($child);
}
return $innerHTML;
}
}

Wyświetl plik

@ -27,6 +27,7 @@ use Friendica\Content\Post\Collection;
use Friendica\Content\Post\Entity;
use Friendica\Content\Post\Factory;
use Friendica\Database\Database;
use Friendica\Model\Post;
use Friendica\Util\Strings;
use Psr\Log\LoggerInterface;
@ -62,7 +63,7 @@ class PostMedia extends BaseRepository
public function selectByUriId(int $uriId): Collection\PostMedias
{
return $this->_select(['uri-id' => $uriId]);
return $this->_select(["`uri-id` = ? AND `type` != ?", $uriId, Post\Media::UNKNOWN]);
}
public function save(Entity\PostMedia $PostMedia): Entity\PostMedia

Wyświetl plik

@ -40,6 +40,7 @@ use Friendica\Model\Post;
use Friendica\Model\Tag;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
use Friendica\Util\Images;
use Friendica\Util\Map;
use Friendica\Util\Network;
use Friendica\Util\ParseUrl;
@ -309,7 +310,7 @@ class BBCode
return trim($text);
}
private static function proxyUrl(string $image, int $simplehtml = self::INTERNAL, int $uriid = 0, string $size = ''): string
public static function proxyUrl(string $image, int $simplehtml = self::INTERNAL, int $uriid = 0, string $size = ''): string
{
// Only send proxied pictures to API and for internal display
if (!in_array($simplehtml, [self::INTERNAL, self::MASTODON_API, self::TWITTER_API])) {
@ -452,7 +453,7 @@ class BBCode
$return = '';
try {
if ($tryoembed && OEmbed::isAllowedURL($data['url'])) {
$return = OEmbed::getHTML($data['url'], $data['title']);
$return = OEmbed::getHTML($data['url'], $data['title'], $uriid);
} else {
throw new Exception('OEmbed is disabled for this attachment.');
}
@ -1027,12 +1028,12 @@ class BBCode
if (is_null($text)) {
$curlResult = DI::httpClient()->head($match[1], [HttpClientOptions::TIMEOUT => DI::config()->get('system', 'xrd_timeout')]);
if ($curlResult->isSuccess()) {
$mimetype = $curlResult->getHeader('Content-Type')[0] ?? '';
$mimetype = $curlResult->getContentType() ?? '';
} else {
$mimetype = '';
}
if (substr($mimetype, 0, 6) == 'image/') {
if (Images::isSupportedMimeType($mimetype)) {
$text = '[url=' . $match[1] . ']' . $match[1] . '[/url]';
} else {
$text = '[url=' . $match[2] . ']' . $match[2] . '[/url]';
@ -1125,13 +1126,13 @@ class BBCode
$curlResult = DI::httpClient()->head($match[1], [HttpClientOptions::TIMEOUT => DI::config()->get('system', 'xrd_timeout')]);
if ($curlResult->isSuccess()) {
$mimetype = $curlResult->getHeader('Content-Type')[0] ?? '';
$mimetype = $curlResult->getContentType() ?? '';
} else {
$mimetype = '';
}
// if its a link to a picture then embed this picture
if (substr($mimetype, 0, 6) == 'image/') {
if (Images::isSupportedMimeType($mimetype)) {
$text = '[img]' . $match[1] . '[/img]';
} else {
if (!empty($match[3])) {
@ -1244,6 +1245,42 @@ class BBCode
return $match[1] . '[url=' . $data['url'] . ']' . $data['nick'] . '[/url]';
}
/**
* Replace mention links
*
* @param string $body HTML/BBCode
* @return string Body with replaced mentions
*/
public static function setMentionsToAddr(string $body): string
{
DI::profiler()->startRecording('rendering');
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
$body = preg_replace_callback($regexp, [self::class, 'mentionToAddrCallback'], $body);
DI::profiler()->stopRecording();
return $body;
}
/**
* Callback function to replace a Friendica style mention in a mention with the addr
*
* @param array $match Matching values for the callback
* @return string Replaced mention or empty string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function mentionToAddrCallback(array $match): string
{
if (empty($match[2])) {
return '';
}
$data = Contact::getByURL($match[2], false, ['url', 'nick', 'addr']);
if (empty($data['nick'])) {
return $match[0];
}
return $match[1] . ($data['addr'] ?: $data['nick']);
}
/**
* Normalize links to Youtube and Vimeo to a unified format.
*
@ -1357,12 +1394,12 @@ class BBCode
* $match[1] = $url
* $match[2] = $title or absent
*/
$try_oembed_callback = function (array $match) {
$try_oembed_callback = function (array $match) use ($uriid) {
$url = $match[1];
$title = $match[2] ?? '';
try {
$return = OEmbed::getHTML($url, $title);
$return = OEmbed::getHTML($url, $title, $uriid);
} catch (Exception $ex) {
$return = $match[0];
}
@ -1787,7 +1824,7 @@ class BBCode
$text = self::normalizeVideoLinks($text);
// Youtube extensions
if ($try_oembed) {
if ($try_oembed && OEmbed::isAllowedURL('https://www.youtube.com/embed/')) {
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->getThemeInfoValue('videowidth') . '" height="' . $a->getThemeInfoValue('videoheight') . '" src="https://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $text);
} else {
$text = preg_replace(
@ -1798,7 +1835,7 @@ class BBCode
}
// Vimeo extensions
if ($try_oembed) {
if ($try_oembed && OEmbed::isAllowedURL('https://player.vimeo.com/video')) {
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->getThemeInfoValue('videowidth') . '" height="' . $a->getThemeInfoValue('videoheight') . '" src="https://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $text);
} else {
$text = preg_replace(
@ -1809,7 +1846,7 @@ class BBCode
}
// oembed tag
$text = OEmbed::BBCode2HTML($text);
$text = OEmbed::BBCode2HTML($text, $uriid);
// Avoid triple linefeeds through oembed
$text = str_replace("<br style='clear:left'></span><br><br>", "<br style='clear:left'></span><br>", $text);
@ -2056,13 +2093,7 @@ class BBCode
);
// Default iframe allowed domains/path
$allowedIframeDomains = [
DI::baseUrl()->getHost()
. (DI::baseUrl()->getPath() ? '/' . DI::baseUrl()->getPath() : '')
. '/oembed/', # The path part has to change with the source in Content\Oembed::iframe
'www.youtube.com/embed/',
'player.vimeo.com/video/',
];
$allowedIframeDomains = DI::config()->get('system', 'no_oembed_rich_content') ? [] : ['www.youtube.com/embed/', 'player.vimeo.com/video/'];
$allowedIframeDomains = array_merge(
$allowedIframeDomains,

Wyświetl plik

@ -103,6 +103,7 @@ class Widget
{
// Always hide content from these networks
$networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT];
Addon::loadAddons();
if (!Addon::isEnabled("discourse")) {
$networks[] = Protocol::DISCOURSE;

Wyświetl plik

@ -104,7 +104,7 @@ class VCard
$mention_label = DI::l10n()->t('Post to group');
$mention_link = 'compose/0?body=!' . $contact['addr'];
}
$showgroup_link = 'network/group/' . $id;
$showgroup_link = 'contact/' . $id . '/conversations';
} elseif (!$hide_mention) {
$mention_label = DI::l10n()->t('Mention');
$mention_link = 'compose/0?body=@' . $contact['addr'];

Wyświetl plik

@ -632,23 +632,10 @@ class Installer
*/
public function checkImagick()
{
$imagick = false;
$gif = false;
if (class_exists('Imagick')) {
$imagick = true;
$supported = Images::supportedTypes();
if (array_key_exists('image/gif', $supported)) {
$gif = true;
}
}
if (!$imagick) {
$this->addCheck(DI::l10n()->t('ImageMagick PHP extension is not installed'), $imagick, false, "");
if (!class_exists('Imagick')) {
$this->addCheck(DI::l10n()->t('ImageMagick PHP extension is not installed'), false, false, "");
} else {
$this->addCheck(DI::l10n()->t('ImageMagick PHP extension is installed'), $imagick, false, "");
if ($imagick) {
$this->addCheck(DI::l10n()->t('ImageMagick supports GIF'), $gif, false, "");
}
$this->addCheck(DI::l10n()->t('ImageMagick PHP extension is installed'), true, false, "");
}
// Imagick is not required

Wyświetl plik

@ -473,7 +473,7 @@ class System
return false;
}
return max($load_arr[0], $load_arr[1]);
return round(max($load_arr[0], $load_arr[1]), 2);
}
/**

Wyświetl plik

@ -21,6 +21,7 @@
namespace Friendica\Core;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Worker\Entity\Process;
use Friendica\Database\DBA;
use Friendica\DI;
@ -54,7 +55,8 @@ class Worker
const FAST_COMMANDS = ['APDelivery', 'Delivery'];
const LOCK_PROCESS = 'worker_process';
const LOCK_WORKER = 'worker';
const LOCK_WORKER = 'worker';
const LAST_CHECK = 'worker::check';
private static $up_start;
private static $db_duration = 0;
@ -832,6 +834,17 @@ class Worker
} else {
self::spawnWorker();
}
} elseif (($active > $queues) && ($active < $maxqueues) && ($load < $maxsysload)) {
$max_idletime = DI::config()->get('system', 'worker_max_idletime');
$last_check = DI::cache()->get(self::LAST_CHECK);
$last_date = $last_check ? date('c', $last_check) : '';
if (($max_idletime > 0) && (time() > $last_check + $max_idletime) && !DBA::exists('workerqueue', ["`done` AND `executed` > ?", DateTimeFormat::utc('now - ' . $max_idletime . ' second')])) {
DI::cache()->set(self::LAST_CHECK, time(), Duration::HOUR);
Logger::info('The last worker execution had been too long ago.', ['last' => $last_check, 'last-check' => $last_date, 'seconds' => $max_idletime, 'load' => $load, 'max_load' => $maxsysload, 'active_worker' => $active, 'max_worker' => $maxqueues]);
return false;
} elseif ($max_idletime > 0) {
Logger::debug('Maximum idletime not reached.', ['last' => $last_check, 'last-check' => $last_date, 'seconds' => $max_idletime, 'load' => $load, 'max_load' => $maxsysload, 'active_worker' => $active, 'max_worker' => $maxqueues]);
}
}
}

Wyświetl plik

@ -23,6 +23,7 @@ namespace Friendica\Factory\Api\Mastodon;
use Friendica\BaseFactory;
use Friendica\Database\Database;
use Friendica\Model\Subscription;
use Friendica\Network\HTTPException\UnprocessableEntityException;
use Psr\Log\LoggerInterface;
@ -56,6 +57,8 @@ class Application extends BaseFactory
$application['client_secret'],
$application['id'],
$application['redirect_uri'],
$application['website']);
$application['website'],
Subscription::getPublicVapidKey(),
);
}
}

Wyświetl plik

@ -84,7 +84,7 @@ class Attachment extends BaseFactory
$type = 'audio';
} elseif (($filetype == 'video') || ($attachment['type'] == Post\Media::VIDEO)) {
$type = 'video';
} elseif ($attachment['mimetype'] == 'image/gif') {
} elseif ($attachment['mimetype'] == image_type_to_mime_type(IMAGETYPE_GIF)) {
$type = 'gifv';
} elseif (($filetype == 'image') || ($attachment['type'] == Post\Media::IMAGE)) {
$type = 'image';
@ -95,12 +95,12 @@ class Attachment extends BaseFactory
$remote = $attachment['url'];
if ($type == 'image') {
$url = Post\Media::getPreviewUrlForId($attachment['id']);
$preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_SMALL);
$preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_MEDIUM);
} else {
$url = $attachment['url'];
if (!empty($attachment['preview'])) {
$preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_SMALL);
$preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_MEDIUM);
} else {
$preview = '';
}
@ -130,14 +130,13 @@ class Attachment extends BaseFactory
'blurhash' => $photo['blurhash'],
];
$photoTypes = Images::supportedTypes();
$ext = $photoTypes[$photo['type']];
$ext = Images::getExtensionByMimeType($photo['type']);
$url = $this->baseUrl . '/photo/' . $photo['resource-id'] . '-0.' . $ext;
$url = $this->baseUrl . '/photo/' . $photo['resource-id'] . '-0' . $ext;
$preview = Photo::selectFirst(['scale'], ["`resource-id` = ? AND `uid` = ? AND `scale` > ?", $photo['resource-id'], $photo['uid'], 0], ['order' => ['scale']]);
if (!empty($preview)) {
$preview_url = $this->baseUrl . '/photo/' . $photo['resource-id'] . '-' . $preview['scale'] . '.' . $ext;
$preview_url = $this->baseUrl . '/photo/' . $photo['resource-id'] . '-' . $preview['scale'] . $ext;
} else {
$preview_url = '';
}

Wyświetl plik

@ -67,10 +67,12 @@ class Poll extends BaseFactory
if (empty($uid)) {
$ownvotes = null;
$voted = null;
} else {
$ownvotes = [];
$voted = false;
}
return new \Friendica\Object\Api\Mastodon\Poll($question, $options, $expired, $votes, $ownvotes);
return new \Friendica\Object\Api\Mastodon\Poll($question, $options, $expired, $votes, $ownvotes, $voted);
}
}

Wyświetl plik

@ -32,7 +32,6 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\Tag as TagModel;
use Friendica\Model\Verb;
use Friendica\Network\HTTPException;
use Friendica\Object\Api\Mastodon\Status\FriendicaDeliveryData;
@ -60,8 +59,6 @@ class Status extends BaseFactory
private $mstdnAttachmentFactory;
/** @var Emoji */
private $mstdnEmojiFactory;
/** @var Error */
private $mstdnErrorFactory;
/** @var Poll */
private $mstdnPollFactory;
/** @var ContentItem */
@ -78,7 +75,6 @@ class Status extends BaseFactory
Card $mstdnCardFactory,
Attachment $mstdnAttachmentFactory,
Emoji $mstdnEmojiFactory,
Error $mstdnErrorFactory,
Poll $mstdnPollFactory,
ContentItem $contentItem,
ACLFormatter $aclFormatter
@ -91,7 +87,6 @@ class Status extends BaseFactory
$this->mstdnCardFactory = $mstdnCardFactory;
$this->mstdnAttachmentFactory = $mstdnAttachmentFactory;
$this->mstdnEmojiFactory = $mstdnEmojiFactory;
$this->mstdnErrorFactory = $mstdnErrorFactory;
$this->mstdnPollFactory = $mstdnPollFactory;
$this->contentItem = $contentItem;
$this->aclFormatter = $aclFormatter;

Wyświetl plik

@ -38,10 +38,14 @@ class StatusSource extends BaseFactory
*/
public function createFromUriId(int $uriId, int $uid): \Friendica\Object\Api\Mastodon\StatusSource
{
$post = Post::selectOriginal(['uri-id', 'raw-body', 'body', 'title'], ['uri-id' => $uriId, 'uid' => [0, $uid]]);
$post = Post::selectOriginal(['uri-id', 'raw-body', 'body', 'title', 'content-warning'], ['uri-id' => $uriId, 'uid' => [0, $uid]]);
$spoiler_text = $post['title'] ?: BBCode::toPlaintext(BBCode::getAbstract($post['body'], Protocol::ACTIVITYPUB));
$body = BBCode::toMarkdown(Post\Media::removeFromEndOfBody($post['body']));
$spoiler_text = $post['title'] ?: $post['content-warning'] ?: BBCode::toPlaintext(BBCode::getAbstract($post['body'], Protocol::ACTIVITYPUB));
$body = Post\Media::removeFromEndOfBody($post['body']);
$body = Post\Media::addHTMLLinkToBody($uriId, $body);
$body = BBCode::setMentionsToAddr($body);
$body = BBCode::toPlaintext($body);
return new \Friendica\Object\Api\Mastodon\StatusSource($post['uri-id'], $body, $spoiler_text);
}

Wyświetl plik

@ -24,10 +24,9 @@ namespace Friendica\Factory\Api\Twitter;
use Friendica\BaseFactory;
use Friendica\Model\APContact;
use Friendica\Model\Contact;
use Friendica\Network\HTTPException;
use Friendica\Factory\Api\Twitter\Status;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Network\HTTPException;
use Psr\Log\LoggerInterface;
class User extends BaseFactory
@ -85,9 +84,17 @@ class User extends BaseFactory
* @param bool $include_user_entities
*
* @return \Friendica\Object\Api\Twitter\User
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException If the $uid doesn't exist
* @throws \ImagickException
*/
public function createFromUserId(int $uid, bool $skip_status = true, bool $include_user_entities = true): \Friendica\Object\Api\Twitter\User
{
return $this->createFromContactId(Contact::getPublicIdByUserId($uid), $uid, $skip_status, $include_user_entities);
$cid = Contact::getPublicIdByUserId($uid);
if (!$cid) {
throw new HTTPException\NotFoundException();
}
return $this->createFromContactId($cid, $uid, $skip_status, $include_user_entities);
}
}

Wyświetl plik

@ -208,6 +208,8 @@ class APContact
if (!$failed && ($curlResult->getReturnCode() == 410)) {
$data = ['@context' => ActivityPub::CONTEXT, 'id' => $url, 'type' => 'Tombstone'];
} elseif (!$failed && !HTTPSignature::isValidContentType($curlResult->getContentType(), $url)) {
$failed = true;
}
} catch (\Exception $exception) {
Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]);
@ -374,6 +376,9 @@ class APContact
}
$apcontact['discoverable'] = JsonLD::fetchElement($compacted, 'toot:discoverable', '@value');
if (is_null($apcontact['discoverable']) && ($apcontact['type'] == 'Application')) {
$apcontact['discoverable'] = false;
}
if (!empty($apcontact['photo'])) {
$apcontact['photo'] = Network::addBasePath($apcontact['photo'], $apcontact['url']);

Wyświetl plik

@ -755,7 +755,7 @@ class Contact
$user = DBA::selectFirst(
'user',
['uid', 'username', 'nickname', 'pubkey', 'prvkey'],
['uid' => $uid, 'verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]
['uid' => $uid, 'account_removed' => false, 'account_expired' => false]
);
if (!DBA::isResult($user)) {
return false;
@ -842,7 +842,6 @@ class Contact
return false;
}
$file_suffix = 'jpg';
$url = DI::baseUrl() . '/profile/' . $user['nickname'];
$fields = [
@ -875,17 +874,11 @@ class Contact
$fields['avatar-date'] = DateTimeFormat::utcNow();
}
// Creating the path to the avatar, beginning with the file suffix
$types = Images::supportedTypes();
if (isset($types[$avatar['type']])) {
$file_suffix = $types[$avatar['type']];
}
// We are adding a timestamp value so that other systems won't use cached content
$timestamp = strtotime($fields['avatar-date']);
$prefix = DI::baseUrl() . '/photo/' . $avatar['resource-id'] . '-';
$suffix = '.' . $file_suffix . '?ts=' . $timestamp;
$suffix = Images::getExtensionByMimeType($avatar['type']) . '?ts=' . $timestamp;
$fields['photo'] = $prefix . '4' . $suffix;
$fields['thumb'] = $prefix . '5' . $suffix;
@ -1137,7 +1130,7 @@ class Contact
{
// Always unarchive the relay contact entry
if (!empty($contact['batch']) && !empty($contact['term-date']) && ($contact['term-date'] > DBA::NULL_DATETIME)) {
$fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false];
$fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false, 'unsearchable' => true];
$condition = ['uid' => 0, 'network' => Protocol::FEDERATED, 'batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY];
if (!DBA::exists('contact', array_merge($condition, $fields))) {
self::update($fields, $condition);
@ -1212,13 +1205,12 @@ class Contact
$mention_label = DI::l10n()->t('Post to group');
$mention_url = 'compose/0?body=!' . $contact['addr'];
$network_label = DI::l10n()->t('View group');
$network_url = 'network/group/' . $contact['id'];
} else {
$mention_label = DI::l10n()->t('Mention');
$mention_url = 'compose/0?body=@' . $contact['addr'];
$network_label = DI::l10n()->t('Network Posts');
$network_url = 'contact/' . $contact['id'] . '/conversations';
}
$network_url = 'contact/' . $contact['id'] . '/conversations';
$follow_link = '';
$unfollow_link = '';
@ -2313,8 +2305,8 @@ class Contact
$fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]);
$img_str = $fetchResult->getBodyString();
if (!empty($img_str)) {
$image = new Image($img_str, Images::getMimeTypeByData($img_str));
if ($fetchResult->isSuccess() && !empty($img_str)) {
$image = new Image($img_str, $fetchResult->getContentType(), $avatar);
if ($image->isValid()) {
$update_fields['blurhash'] = $image->getBlurHash();
} else {
@ -2827,13 +2819,19 @@ class Contact
}
// We must not try to update relay contacts via probe. They are no real contacts.
// See Relay::updateContact() for more details.
// We check after the probing to be able to correct falsely detected contact types.
if (($contact['contact-type'] == self::TYPE_RELAY) &&
if (($contact['contact-type'] == self::TYPE_RELAY) && Strings::compareLink($contact['url'], $contact['baseurl']) &&
(!Strings::compareLink($ret['url'], $contact['url']) || in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM]))
) {
self::updateContact($id, $uid, $uriid, $contact['url'], ['failed' => false, 'local-data' => $has_local_data, 'last-update' => $updated, 'next-update' => $success_next_update, 'success_update' => $updated]);
Logger::info('Not updating relais', ['id' => $id, 'url' => $contact['url']]);
return true;
if (GServer::reachable($contact)) {
self::updateContact($id, $uid, $uriid, $contact['url'], ['failed' => false, 'local-data' => $has_local_data, 'last-update' => $updated, 'next-update' => $success_next_update, 'success_update' => $updated, 'unsearchable' => true]);
Logger::info('Not updating relay', ['id' => $id, 'url' => $contact['url']]);
return true;
}
Logger::info('Relay server is not reachable', ['id' => $id, 'url' => $contact['url']]);
self::updateContact($id, $uid, $uriid, $contact['url'], ['failed' => true, 'local-data' => $has_local_data, 'last-update' => $updated, 'next-update' => $failed_next_update, 'failure_update' => $updated, 'unsearchable' => true]);
return false;
}
// If Probe::uri fails the network code will be different ("feed" or "unkn")

Wyświetl plik

@ -22,6 +22,7 @@
namespace Friendica\Model\Contact;
use Exception;
use Friendica\Content\Widget;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Database\Database;
@ -78,14 +79,14 @@ class Relation
*/
public static function discoverByUser(int $uid)
{
$contact = Contact::selectFirst(['id', 'url', 'network'], ['uid' => $uid, 'self' => true]);
$contact = Contact::selectFirst(['id', 'url', 'network'], ['id' => Contact::getPublicIdByUserId($uid)]);
if (empty($contact)) {
Logger::warning('Self contact for user not found', ['uid' => $uid]);
return;
}
$followers = self::getContacts($uid, [Contact::FOLLOWER, Contact::FRIEND]);
$followings = self::getContacts($uid, [Contact::SHARING, Contact::FRIEND]);
$followers = self::getContacts($uid, [Contact::FOLLOWER, Contact::FRIEND], false);
$followings = self::getContacts($uid, [Contact::SHARING, Contact::FRIEND], false);
self::updateFollowersFollowings($contact, $followers, $followings);
}
@ -207,10 +208,11 @@ class Relation
* Fetch contact url list from the given local user
*
* @param integer $uid
* @param array $rel
* @param array $rel
* @param bool $only_ap
* @return array contact list
*/
private static function getContacts(int $uid, array $rel): array
private static function getContacts(int $uid, array $rel, bool $only_ap = true): array
{
$list = [];
$profile = Profile::getByUID($uid);
@ -219,15 +221,22 @@ class Relation
}
$condition = [
'rel' => $rel,
'uid' => $uid,
'self' => false,
'rel' => $rel,
'uid' => $uid,
'self' => false,
'deleted' => false,
'hidden' => false,
'hidden' => false,
'archive' => false,
'pending' => false,
'blocked' => false,
'failed' => false,
];
$condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]);
if ($only_ap) {
$condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]);
} else {
$networks = Widget::unavailableNetworks();
$condition = DBA::mergeConditions($condition, array_merge(["NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")"], $networks));
}
$contacts = DBA::select('contact', ['url'], $condition);
while ($contact = DBA::fetch($contacts)) {
$list[] = $contact['url'];
@ -870,6 +879,20 @@ class Relation
DBA::update('contact-relation', ['thread-score' => $score], ['relation-cid' => $contact_id, 'cid' => $interaction['author-id']]);
}
DBA::close($interactions);
$total = DBA::fetchFirst("SELECT count(*) AS `posts` FROM `post-thread-user` WHERE EXISTS(SELECT `cid` FROM `contact-relation` WHERE `cid` = `post-thread-user`.`author-id` AND `relation-cid` = ? AND `follows`) AND `uid` = ? AND `created` > ?",
$contact_id, $uid, DateTimeFormat::utc('now - ' . $days . ' day'));
Logger::debug('Calculate post-score', ['uid' => $uid, 'total' => $total['posts']]);
$posts = DBA::p("SELECT `author-id`, count(*) AS `posts` FROM `post-thread-user` WHERE EXISTS(SELECT `cid` FROM `contact-relation` WHERE `cid` = `post-thread-user`.`author-id` AND `relation-cid` = ? AND `follows`) AND `uid` = ? AND `created` > ? GROUP BY `author-id`",
$contact_id, $uid, DateTimeFormat::utc('now - ' . $days . ' day'));
while ($post = DBA::fetch($posts)) {
$score = min((int)(($post['posts'] / $total['posts']) * 65535), 65535);
DBA::update('contact-relation', ['post-score' => $score], ['relation-cid' => $contact_id, 'cid' => $post['author-id']]);
}
DBA::close($posts);
Logger::debug('Calculation - end', ['uid' => $uid]);
}
}

Wyświetl plik

@ -364,6 +364,53 @@ class User
return $frequency;
}
/**
* Set the channel only value for contact id and user id
*
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
* @param int $isChannelOnly Is channel only
* @return void
* @throws \Exception
*/
public static function setChannelOnly(int $cid, int $uid, bool $isChannelOnly)
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
return;
}
DBA::update('user-contact', ['channel-only' => $isChannelOnly], ['cid' => $cdata['public'], 'uid' => $uid], true);
}
/**
* Returns if the contact is channel only for contact id and user id
*
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
* @return bool Contact is channel only
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function getChannelOnly(int $cid, int $uid): bool
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
return false;
}
$isChannelOnly = false;
if (!empty($cdata['public'])) {
$public_contact = DBA::selectFirst('user-contact', ['channel-only'], ['cid' => $cdata['public'], 'uid' => $uid]);
if (DBA::isResult($public_contact)) {
$isChannelOnly = $public_contact['channel-only'] ?? false;
}
}
return $isChannelOnly;
}
/**
* Set/Release that the user is blocked by the contact
*

Wyświetl plik

@ -925,9 +925,6 @@ class Event
$end_short = '';
}
// Format the event location.
$location = self::locationToArray($item['event-location']);
// Construct the profile link (magic-auth).
$author = [
'uid' => 0,
@ -964,7 +961,7 @@ class Event
'$show_map_label' => DI::l10n()->t('Show map'),
'$hide_map_label' => DI::l10n()->t('Hide map'),
'$map_btn_label' => DI::l10n()->t('Show map'),
'$location' => $location
'$location' => self::locationToTemplateVars($item['event-location']),
]);
return $return;
@ -984,7 +981,7 @@ class Event
* 'coordinates' => Latitude and longitude (e.g. '48.864716,2.349014').<br>
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function locationToArray(string $s = ''): array
private static function locationToTemplateVars(string $s = ''): array
{
if ($s == '') {
return [];

Wyświetl plik

@ -34,10 +34,11 @@ use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Post\Category;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Protocol\Activity;
@ -45,6 +46,7 @@ use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Delivery;
use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPSignature;
use Friendica\Util\Map;
use Friendica\Util\Network;
use Friendica\Util\Proxy;
@ -106,7 +108,7 @@ class Item
'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-gsid',
'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-gsid',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
'writable', 'self', 'cid', 'alias',
'writable', 'restrictions', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-ignore', 'event-id',
@ -166,6 +168,11 @@ class Item
const GRAVITY_COMMENT = 6;
const GRAVITY_UNKNOWN = 9;
// Restrictions
const CANT_REPLY = 1;
const CANT_LIKE = 2;
const CANT_ANNOUNCE = 4;
/**
* Update existing item entries
*
@ -689,38 +696,6 @@ class Item
return true;
}
/**
* Check if the item array is too old
*
* @param array $item Item record
* @return boolean item is too old
*/
public static function isTooOld(array $item): bool
{
// check for create date and expire time
$expire_interval = DI::config()->get('system', 'dbclean-expire-days', 0);
$user = DBA::selectFirst('user', ['expire'], ['uid' => $item['uid']]);
if (DBA::isResult($user) && ($user['expire'] > 0) && (($user['expire'] < $expire_interval) || ($expire_interval == 0))) {
$expire_interval = $user['expire'];
}
if (($expire_interval > 0) && !empty($item['created'])) {
$expire_date = time() - ($expire_interval * 86400);
$created_date = strtotime($item['created']);
if ($created_date < $expire_date) {
Logger::notice('Item created before expiration interval.', [
'created' => date('c', $created_date),
'expired' => date('c', $expire_date),
'$item' => $item
]);
return true;
}
}
return false;
}
/**
* Return the id of the given item array if it has been stored before
*
@ -789,7 +764,7 @@ class Item
{
$fields = [
'uid', 'uri', 'parent-uri', 'id', 'deleted',
'uri-id', 'parent-uri-id',
'uri-id', 'parent-uri-id', 'restrictions', 'verb',
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
'wall', 'private', 'origin', 'author-id'
];
@ -813,6 +788,11 @@ class Item
return [];
}
if (self::hasRestrictions($item, $parent['author-id'], $parent['restrictions'])) {
Logger::notice('Restrictions apply - ignoring item', ['restrictions' => $parent['restrictions'], 'verb' => $parent['verb'], 'uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
return 0;
}
if ($parent['uri-id'] == $parent['parent-uri-id']) {
return $parent;
}
@ -1032,7 +1012,7 @@ class Item
if (
!empty($item['direction']) && in_array($item['direction'], [Conversation::PUSH, Conversation::RELAY]) &&
empty($item['origin']) && self::isTooOld($item)
empty($item['origin']) && DI::contentItem()->isTooOld($item['created'], $item['uid'])
) {
Logger::info('Item is too old', ['item' => $item]);
return 0;
@ -1469,6 +1449,27 @@ class Item
return $post_user_id;
}
private static function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool
{
if (empty($restrictions) || ($author_id == $item['author-id'])) {
return false;
}
if (($restrictions & self::CANT_REPLY) && ($item['verb'] == Activity::POST)) {
return true;
}
if (($restrictions & self::CANT_ANNOUNCE) && ($item['verb'] == Activity::ANNOUNCE)) {
return true;
}
if (($restrictions & self::CANT_LIKE) && in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDMAYBE, Activity::ATTENDNO])) {
return true;
}
return false;
}
private static function reshareChannelPost(int $uri_id, int $reshare_id = 0)
{
if (!DI::config()->get('system', 'allow_relay_channels')) {
@ -3675,6 +3676,13 @@ class Item
}
if ($PostMedia->mimetype->type == 'video') {
if (($PostMedia->height ?? 0) > ($PostMedia->width ?? 0)) {
$height = min(DI::config()->get('system', 'max_video_height') ?: '100%', $PostMedia->height);
$width = 'auto';
} else {
$height = 'auto';
$width = '100%';
}
/// @todo Move the template to /content as well
$media = Renderer::replaceMacros(Renderer::getMarkupTemplate('video_top.tpl'), [
'$video' => [
@ -3683,6 +3691,8 @@ class Item
'name' => $PostMedia->name ?: $PostMedia->url,
'preview' => $preview_url,
'mime' => (string)$PostMedia->mimetype,
'height' => $height,
'width' => $width,
],
]);
if (($item['post-type'] ?? null) == Item::PT_VIDEO) {
@ -4117,9 +4127,12 @@ class Item
return is_numeric($hookData['item_id']) ? $hookData['item_id'] : 0;
}
$fetched_uri = ActivityPub\Processor::fetchMissingActivity($uri, [], '', $completion, $uid);
$curlResult = DI::httpClient()->head($uri, [HttpClientOptions::ACCEPT_CONTENT => HttpClientAccept::JSON_AS]);
if (HTTPSignature::isValidContentType($curlResult->getContentType(), $uri)) {
$fetched_uri = ActivityPub\Processor::fetchMissingActivity($uri, [], '', $completion, $uid);
}
if ($fetched_uri) {
if (!empty($fetched_uri)) {
$item_id = self::searchByLink($fetched_uri, $uid);
} else {
$item_id = Diaspora::fetchByURL($uri);

Wyświetl plik

@ -363,6 +363,7 @@ class Photo
$photo['backend-class'] = SystemResource::NAME;
$photo['backend-ref'] = $filename;
$photo['type'] = $mimetype;
$photo['filename'] = basename($filename);
$photo['cacheable'] = false;
return $photo;
@ -394,6 +395,7 @@ class Photo
$photo['backend-class'] = ExternalResource::NAME;
$photo['backend-ref'] = json_encode(['url' => $url, 'uid' => $uid]);
$photo['type'] = $mimetype;
$photo['filename'] = basename(parse_url($url, PHP_URL_PATH));
$photo['cacheable'] = true;
$photo['blurhash'] = $blurhash;
$photo['width'] = $width;
@ -608,9 +610,7 @@ class Photo
return false;
}
$type = Images::getMimeTypeByData($img_str, $image_url, $type);
$image = new Image($img_str, $type);
$image = new Image($img_str, $type, $image_url);
if ($image->isValid()) {
$image->scaleToSquare(300);
@ -619,9 +619,9 @@ class Photo
if ($maximagesize && ($filesize > $maximagesize)) {
Logger::info('Avatar exceeds image limit', ['uid' => $uid, 'cid' => $cid, 'maximagesize' => $maximagesize, 'size' => $filesize, 'type' => $image->getType()]);
if ($image->getType() == 'image/gif') {
if ($image->getImageType() == IMAGETYPE_GIF) {
$image->toStatic();
$image = new Image($image->asString(), 'image/png');
$image = new Image($image->asString(), image_type_to_mime_type(IMAGETYPE_PNG));
$filesize = strlen($image->asString());
Logger::info('Converted gif to a static png', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $image->getType()]);
@ -662,9 +662,9 @@ class Photo
$suffix = '?ts=' . time();
$image_url = DI::baseUrl() . '/photo/' . $resource_id . '-4.' . $image->getExt() . $suffix;
$thumb = DI::baseUrl() . '/photo/' . $resource_id . '-5.' . $image->getExt() . $suffix;
$micro = DI::baseUrl() . '/photo/' . $resource_id . '-6.' . $image->getExt() . $suffix;
$image_url = DI::baseUrl() . '/photo/' . $resource_id . '-4' . $image->getExt() . $suffix;
$thumb = DI::baseUrl() . '/photo/' . $resource_id . '-5' . $image->getExt() . $suffix;
$micro = DI::baseUrl() . '/photo/' . $resource_id . '-6' . $image->getExt() . $suffix;
} else {
$photo_failure = true;
}
@ -1060,9 +1060,7 @@ class Photo
return [];
}
$type = Images::getMimeTypeByData($img_str, $image_url, $type);
$image = new Image($img_str, $type);
$image = new Image($img_str, $type, $image_url);
$image = self::fitImageSize($image);
if (empty($image)) {
@ -1132,12 +1130,10 @@ class Photo
return [];
}
$filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
Logger::info('File upload', ['src' => $src, 'filename' => $filename, 'size' => $filesize, 'type' => $filetype]);
$imagedata = @file_get_contents($src);
$image = new Image($imagedata, $filetype);
$image = new Image($imagedata, $filetype, $filename);
if (!$image->isValid()) {
Logger::notice('Image is unvalid', ['files' => $files]);
return [];

Wyświetl plik

@ -43,7 +43,7 @@ class Counts
Activity::EMOJIREACT, Activity::ANNOUNCE, Activity::VIEW, Activity::READ])) {
return true;
}
$condition = ['thr-parent-id' => $uri_id, 'vid' => $vid, 'deleted' => false];
if ($body == $verb) {
@ -52,7 +52,7 @@ class Counts
} elseif ($verb == Activity::POST) {
$condition['gravity'] = Item::GRAVITY_COMMENT;
$body = '';
} elseif (($verb != Activity::POST) && (mb_strlen($body) == 1) && Smilies::isEmojiPost($body)) {
} elseif ($body && mb_strlen($body) == 1 && Smilies::isEmojiPost($body)) {
$condition['body'] = $body;
} else {
$body = '';

Wyświetl plik

@ -118,6 +118,7 @@ class Engagement
'searchtext' => $searchtext,
'size' => self::getContentSize($parent),
'created' => $parent['created'],
'network' => $parent['network'],
'restricted' => !in_array($item['network'], Protocol::FEDERATED) || ($parent['private'] != Item::PUBLIC),
'comments' => DBA::count('post', ['parent-uri-id' => $item['parent-uri-id'], 'gravity' => Item::GRAVITY_COMMENT]),
'activities' => DBA::count('post', [
@ -277,6 +278,9 @@ class Engagement
$body = self::addResharers($body, $item['uri-id']);
foreach ($receivers as $receiver) {
if (empty($receiver)) {
continue;
}
$contact = Contact::getByURL($receiver, false, ['nick', 'addr', 'contact-type']);
if (empty($contact)) {
continue;

Wyświetl plik

@ -134,15 +134,23 @@ class Link
Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]);
return [];
}
$fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]];
$img_str = $curlResult->getBodyString();
$image = new Image($img_str, Images::getMimeTypeByData($img_str));
if ($image->isValid()) {
$fields['mimetype'] = $image->getType();
$fields['width'] = $image->getWidth();
$fields['height'] = $image->getHeight();
$fields['blurhash'] = $image->getBlurHash();
if (!$curlResult->isSuccess()) {
Logger::notice('Fetching unsuccessful', ['url' => $url]);
return [];
}
$fields = ['mimetype' => $curlResult->getContentType()];
if (Images::isSupportedMimeType($fields['mimetype'])) {
$img_str = $curlResult->getBodyString();
$image = new Image($img_str, $fields['mimetype'], $url);
if ($image->isValid()) {
$fields['mimetype'] = $image->getType();
$fields['width'] = $image->getWidth();
$fields['height'] = $image->getHeight();
$fields['blurhash'] = $image->getBlurHash();
}
}
return $fields;

Wyświetl plik

@ -196,7 +196,7 @@ class Media
if ($curlResult->isSuccess()) {
if (empty($media['mimetype'])) {
$media['mimetype'] = $curlResult->getHeader('Content-Type')[0] ?? '';
$media['mimetype'] = $curlResult->getContentType() ?? '';
}
if (empty($media['size'])) {
$media['size'] = (int)($curlResult->getHeader('Content-Length')[0] ?? 0);
@ -365,7 +365,7 @@ class Media
*/
private static function addPage(array $media): array
{
$data = ParseUrl::getSiteinfoCached($media['url'], false);
$data = ParseUrl::getSiteinfoCached($media['url']);
$media['preview'] = $data['images'][0]['src'] ?? null;
$media['preview-height'] = $data['images'][0]['height'] ?? null;
$media['preview-width'] = $data['images'][0]['width'] ?? null;
@ -912,6 +912,8 @@ class Media
$body .= "\n[audio]" . $media['url'] . "[/audio]\n";
} elseif ($media['type'] == self::VIDEO) {
$body .= "\n[video]" . $media['url'] . "[/video]\n";
} else {
$body .= "\n[url]" . $media['url'] . "[/url]\n";
}
}

Wyświetl plik

@ -48,6 +48,9 @@ class SearchIndex
}
$item = Post::selectFirstPost(['created', 'owner-id', 'private', 'language', 'network', 'title', 'content-warning', 'body', 'quote-uri-id'], ['uri-id' => $uri_id]);
if (empty($item)) {
return;
}
$search = [
'uri-id' => $uri_id,

Wyświetl plik

@ -461,13 +461,12 @@ class Profile
$mention_label = DI::l10n()->t('Post to group');
$mention_url = 'compose/0?body=!' . $profile['addr'];
$network_label = DI::l10n()->t('View group');
$network_url = 'network/group/' . $cid;
} else {
$mention_label = DI::l10n()->t('Mention');
$mention_url = 'compose/0?body=@' . $profile['addr'];
$network_label = DI::l10n()->t('Network Posts');
$network_url = 'contact/' . $cid . '/conversations';
}
$network_url = 'contact/' . $cid . '/conversations';
$tpl = Renderer::getMarkupTemplate('profile/vcard.tpl');
$o .= Renderer::replaceMacros($tpl, [

Wyświetl plik

@ -826,26 +826,30 @@ class User
/**
* Update the day of the last activity of the given user
*
* @param integer $uid
* @param array $user
* @param bool $refresh_login
* @return void
*/
public static function updateLastActivity(int $uid)
public static function updateLastActivity(array $user, bool $refresh_login)
{
if (!$uid) {
return;
}
$user = self::getById($uid, ['last-activity']);
if (empty($user)) {
return;
}
$current_day = DateTimeFormat::utcNow('Y-m-d');
if (($user['last-activity'] == $current_day) && (!$refresh_login || DateTimeFormat::utc($user['login_date'], 'z-H') == DateTimeFormat::utcNow('z-H'))) {
return;
}
if ($user['last-activity'] != $current_day) {
self::update(['last-activity' => $current_day], $uid);
// Set the last activity for all identities of the user
DBA::update('user', ['last-activity' => $current_day], ['parent-uid' => $uid, 'verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]);
$fields = ['last-activity' => $current_day];
if ($refresh_login) {
$fields['login_date'] = DateTimeFormat::utcNow();
}
Logger::debug('Set last activity for user', ['uid' => $user['uid'], 'fields' => $fields]);
self::update($fields, $user['uid']);
// Set the last activity for all identities of the user
DBA::update('user', $fields, ['parent-uid' => $user['uid'], 'verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]);
if (!empty($user['parent-uid'])) {
self::update($fields, $user['parent-uid']);
DBA::update('user', $fields, ['parent-uid' => $user['parent-uid'], 'verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]);
}
}
@ -1403,9 +1407,7 @@ class User
$type = '';
}
$type = Images::getMimeTypeByData($img_str, $photo, $type);
$image = new Image($img_str, $type);
$image = new Image($img_str, $type, $photo);
if ($image->isValid()) {
$image->scaleToSquare(300);

Wyświetl plik

@ -77,6 +77,11 @@ class Inbox extends BaseApi
throw new \Friendica\Network\HTTPException\BadRequestException();
}
if (!HTTPSignature::isValidContentType($this->server['CONTENT_TYPE'] ?? '')) {
Logger::notice('Unexpected content type', ['content-type' => $this->server['CONTENT_TYPE'] ?? '', 'agent' => $this->server['HTTP_USER_AGENT'] ?? '']);
throw new \Friendica\Network\HTTPException\UnsupportedMediaTypeException();
}
if (DI::config()->get('debug', 'ap_inbox_log')) {
if (HTTPSignature::getSigner($postdata, $_SERVER)) {
$filename = 'signed-activitypub';

Wyświetl plik

@ -43,6 +43,7 @@ class Federation extends BaseAdmin
'birdsitelive' => ['name' => 'BirdsiteLIVE', 'color' => '#1b6ec2'], // Color from the page
'bookwyrm' => ['name' => 'BookWyrm', 'color' => '#00d1b2'], // Color from the page
'castopod' => ['name' => 'Castopod', 'color' => '#00564a'], // Background color from the page
'cherrypick' => ['name' => 'Cherrypick', 'color' => 'pink'], // Color from one of the instabces
'diaspora' => ['name' => 'Diaspora', 'color' => '#a1a1a1'], // logo is black and white, makes a gray
'calckey' => ['name' => 'firefish (Calckey)', 'color' => '#1c4a5c'], // Color from the page
'sharkey' => ['name' => 'Sharkey', 'color' => 'lightpink'], // Font color from the homepage
@ -58,6 +59,7 @@ class Federation extends BaseAdmin
'kbin' => ['name' => 'kbin', 'color' => '#61366b'], // Color from their main instance
'lemmy' => ['name' => 'Lemmy', 'color' => '#00c853'], // Green from the page
'mastodon' => ['name' => 'Mastodon', 'color' => '#1a9df9'], // blue from the Mastodon logo
'mbin' => ['name' => 'mbin', 'color' => '#3c3c3c'], // Color from one of their instances
'microblog' => ['name' => 'Microblog', 'color' => '#fdb52b'], // Color from the page
'misskey' => ['name' => 'Misskey', 'color' => '#ccfefd'], // Font color of the homepage
'mobilizon' => ['name' => 'Mobilizon', 'color' => '#ffd599'], // Background color of parts of the homepage

Wyświetl plik

@ -30,6 +30,8 @@ class PhpInfo extends BaseAdmin
{
self::checkAdminAccess();
self::checkFormSecurityTokenForbiddenOnError('phpinfo', 't');
phpinfo();
System::exit();
}

Wyświetl plik

@ -80,6 +80,7 @@ class Site extends BaseAdmin
$allowed_sites = (!empty($_POST['allowed_sites']) ? trim($_POST['allowed_sites']) : '');
$allowed_email = (!empty($_POST['allowed_email']) ? trim($_POST['allowed_email']) : '');
$disallowed_email = (!empty($_POST['disallowed_email']) ? trim($_POST['disallowed_email']) : '');
$forbidden_nicknames = (!empty($_POST['forbidden_nicknames']) ? strtolower(trim($_POST['forbidden_nicknames'])) : '');
$system_actor_name = (!empty($_POST['system_actor_name']) ? trim($_POST['system_actor_name']) : '');
$no_oembed_rich_content = !empty($_POST['no_oembed_rich_content']);
@ -255,6 +256,7 @@ class Site extends BaseAdmin
$transactionConfig->set('config', 'register_text' , $register_text);
$transactionConfig->set('system', 'allowed_sites' , $allowed_sites);
$transactionConfig->set('system', 'allowed_email' , $allowed_email);
$transactionConfig->set('system', 'disallowed_email' , $disallowed_email);
$transactionConfig->set('system', 'forbidden_nicknames' , $forbidden_nicknames);
$transactionConfig->set('system', 'system_actor_name' , $system_actor_name);
$transactionConfig->set('system', 'no_oembed_rich_content' , $no_oembed_rich_content);
@ -505,6 +507,7 @@ class Site extends BaseAdmin
'$abandon_days' => ['abandon_days', DI::l10n()->t('Accounts abandoned after x days'), DI::config()->get('system', 'account_abandon_days'), DI::l10n()->t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')],
'$allowed_sites' => ['allowed_sites', DI::l10n()->t('Allowed friend domains'), DI::config()->get('system', 'allowed_sites'), DI::l10n()->t('Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains')],
'$allowed_email' => ['allowed_email', DI::l10n()->t('Allowed email domains'), DI::config()->get('system', 'allowed_email'), DI::l10n()->t('Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains')],
'$disallowed_email' => ['disallowed_email', DI::l10n()->t('Disallowed email domains'), DI::config()->get('system', 'disallowed_email'), DI::l10n()->t('Comma separated list of domains which are rejected as email addresses for registrations to this site. Wildcards are accepted.')],
'$no_oembed_rich_content' => ['no_oembed_rich_content', DI::l10n()->t('No OEmbed rich content'), DI::config()->get('system', 'no_oembed_rich_content'), DI::l10n()->t('Don\'t show the rich content (e.g. embedded PDF), except from the domains listed below.')],
'$allowed_oembed' => ['allowed_oembed', DI::l10n()->t('Trusted third-party domains'), DI::config()->get('system', 'allowed_oembed'), DI::l10n()->t('Comma separated list of domains from which content is allowed to be embedded in posts like with OEmbed. All sub-domains of the listed domains are allowed as well.')],
'$block_public' => ['block_public', DI::l10n()->t('Block public'), DI::config()->get('system', 'block_public'), DI::l10n()->t('Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.')],

Wyświetl plik

@ -47,7 +47,7 @@ class Config extends BaseApi
'broughtby' => '',
'broughtbyurl' => '',
'timezone' => DI::config()->get('system', 'default_timezone'),
'closed' => (DI::config()->get('config', 'register_policy') == Register::CLOSED),
'closed' => Register::getPolicy() === Register::CLOSED,
'inviteonly' => (bool)DI::config()->get('system', 'invitation_only'),
'private' => (bool)DI::config()->get('system', 'block_public'),
'textlimit' => (string) DI::config()->get('config', 'api_import_size', DI::config()->get('config', 'max_import_size')),

Wyświetl plik

@ -0,0 +1,56 @@
<?php
/**
* @copyright Copyright (C) 2010-2024, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Api\Mastodon\Accounts;
use Friendica\Core\Protocol;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Module\BaseApi;
/**
* @see https://docs.joinmastodon.org/methods/accounts/#lookup
*/
class Lookup extends BaseApi
{
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
protected function rawContent(array $request = [])
{
$this->checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = $this->getRequest([
'acct' => '', // The username or Webfinger address to lookup.
], $request);
if (empty($request['acct'])) {
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
}
$contact = Contact::getByURL($request['acct'], null, ['id', 'network', 'failed', 'blocked']);
if (empty($contact) || ($contact['network'] == Protocol::PHANTOM) || $contact['failed'] || $contact['blocked']) {
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
}
$this->jsonExit(DI::mstdnAccount()->createFromContactId($contact['id'], $uid));
}
}

Wyświetl plik

@ -21,7 +21,6 @@
namespace Friendica\Module\Api\Mastodon\Apps;
use Friendica\Core\System;
use Friendica\DI;
use Friendica\Module\BaseApi;

Wyświetl plik

@ -21,7 +21,6 @@
namespace Friendica\Module\Api\Mastodon;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Module\BaseApi;

Wyświetl plik

@ -38,7 +38,7 @@ use Friendica\Util\Strings;
use Psr\Log\LoggerInterface;
/**
* @see https://docs.joinmastodon.org/api/rest/instances/
* @see https://docs.joinmastodon.org/methods/instance/
*/
class Instance extends BaseApi
{
@ -95,7 +95,7 @@ class Instance extends BaseApi
return new InstanceV2Entity\Configuration(
$statuses_config,
new InstanceV2Entity\MediaAttachmentsConfig(array_keys(Images::supportedTypes()), $image_size_limit, $image_matrix_limit),
new InstanceV2Entity\MediaAttachmentsConfig(Images::supportedMimeTypes(), $image_size_limit, $image_matrix_limit),
new InstanceV2Entity\Polls(),
new InstanceV2Entity\Accounts(),
);

Wyświetl plik

@ -0,0 +1,59 @@
<?php
/**
* @copyright Copyright (C) 2010-2024, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Api\Mastodon\Instance;
use DateTime;
use Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Model\User;
use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;
use Friendica\Object\Api\Mastodon;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* @see https://docs.joinmastodon.org/methods/instance/#extended_description
*/
class ExtendedDescription extends BaseApi
{
private IManageConfigValues $config;
public function __construct(\Friendica\Factory\Api\Mastodon\Error $errorFactory, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, IManageConfigValues $config, array $server, array $parameters = [])
{
parent::__construct($errorFactory, $app, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->config = $config;
}
/**
* @throws HTTPException\InternalServerErrorException
*/
protected function rawContent(array $request = [])
{
$account = User::getSystemAccount();
$this->jsonExit(new Mastodon\ExtendedDescription(new DateTime($account['updated']), $this->config->get('config', 'info')));
}
}

Wyświetl plik

@ -22,7 +22,6 @@
namespace Friendica\Module\Api\Mastodon\Instance;
use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\GServer;
use Friendica\Module\BaseApi;

Wyświetl plik

@ -21,10 +21,7 @@
namespace Friendica\Module\Api\Mastodon\Instance;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\System;
use Friendica\DI;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;

Wyświetl plik

@ -131,7 +131,7 @@ class InstanceV2 extends BaseApi
return new InstanceEntity\Configuration(
$statuses_config,
new InstanceEntity\MediaAttachmentsConfig(array_keys(Images::supportedTypes()), $image_size_limit, $image_matrix_limit),
new InstanceEntity\MediaAttachmentsConfig(Images::supportedMimeTypes(), $image_size_limit, $image_matrix_limit),
new InstanceEntity\Polls(),
new InstanceEntity\Accounts(),
);
@ -166,9 +166,9 @@ class InstanceV2 extends BaseApi
private function buildRegistrationsInfo(): InstanceEntity\Registrations
{
$register_policy = intval($this->config->get('config', 'register_policy'));
$enabled = ($register_policy != Register::CLOSED);
$approval_required = ($register_policy == Register::APPROVE);
$register_policy = Register::getPolicy();
$enabled = $register_policy !== Register::CLOSED;
$approval_required = $register_policy === Register::APPROVE;
return new InstanceEntity\Registrations($enabled, $approval_required);
}

Wyświetl plik

@ -82,7 +82,7 @@ class Markers extends BaseApi
$values->{$marker['timeline']} = [
'last_read_id' => $marker['last_read_id'],
'version' => $marker['version'],
'updated_at' => $marker['updated_at']
'updated_at' => DateTimeFormat::utc($marker['updated_at'], DateTimeFormat::JSON)
];
}
return $values;

Wyświetl plik

@ -21,7 +21,6 @@
namespace Friendica\Module\Api\Mastodon;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Module\BaseApi;
@ -39,15 +38,6 @@ class Mutes extends BaseApi
$this->checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
if (empty($this->parameters['id'])) {
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity());
}
$id = $this->parameters['id'];
if (!DBA::exists('contact', ['id' => $id, 'uid' => 0])) {
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
}
$request = $this->getRequest([
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id
@ -57,7 +47,7 @@ class Mutes extends BaseApi
$params = ['order' => ['cid' => true], 'limit' => $request['limit']];
$condition = ['cid' => $id, 'ignored' => true, 'uid' => $uid];
$condition = ['ignored' => true, 'uid' => $uid];
if (!empty($request['max_id'])) {
$condition = DBA::mergeConditions($condition, ["`cid` < ?", $request['max_id']]);
@ -74,6 +64,7 @@ class Mutes extends BaseApi
}
$followers = DBA::select('user-contact', ['cid'], $condition, $params);
$accounts = [];
while ($follower = DBA::fetch($followers)) {
self::setBoundaries($follower['cid']);
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);

Wyświetl plik

@ -21,7 +21,6 @@
namespace Friendica\Module\Api\Mastodon;
use Friendica\Core\System;
use Friendica\DI;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;

Wyświetl plik

@ -137,6 +137,10 @@ class Search extends BaseApi
private static function searchStatuses(int $uid, string $q, string $account_id, int $max_id, int $min_id, int $limit, int $offset)
{
if (Network::isValidHttpUrl($q)) {
// Unique post search, any offset greater than 0 should return empty result
if ($offset > 0) {
return [];
}
$q = Network::convertToIdn($q);
// If the user-specific search failed, we search and probe a public post
$item_id = Item::fetchByLink($q, $uid) ?: Item::fetchByLink($q);
@ -158,6 +162,10 @@ class Search extends BaseApi
$table = 'post-searchindex';
}
if (!empty($account_id)) {
$condition = DBA::mergeConditions($condition, ["`author-id` = ?", $account_id]);
}
if (!empty($max_id)) {
$condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $max_id]);
}

Wyświetl plik

@ -403,11 +403,10 @@ class Statuses extends BaseApi
Photo::setPermissionForResource($media[0]['resource-id'], $item['uid'], $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']);
$phototypes = Images::supportedTypes();
$ext = $phototypes[$media[0]['type']];
$ext = Images::getExtensionByMimeType($media[0]['type']);
$attachment = ['type' => Post\Media::IMAGE, 'mimetype' => $media[0]['type'],
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . $ext,
'size' => $media[0]['datasize'],
'name' => $media[0]['filename'] ?: $media[0]['resource-id'],
'description' => $media[0]['desc'] ?? '',
@ -415,7 +414,7 @@ class Statuses extends BaseApi
'height' => $media[0]['height']];
if (count($media) > 1) {
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . $ext;
$attachment['preview-width'] = $media[1]['width'];
$attachment['preview-height'] = $media[1]['height'];
}

Wyświetl plik

@ -129,7 +129,11 @@ class Context extends BaseApi
$display_quotes = self::appSupportsQuotes();
foreach (array_slice($ancestors, 0, $request['limit']) as $ancestor) {
$statuses['ancestors'][] = DI::mstdnStatus()->createFromUriId($ancestor, $uid, $display_quotes);
try {
$statuses['ancestors'][] = DI::mstdnStatus()->createFromUriId($ancestor, $uid, $display_quotes);
} catch (\Throwable $th) {
$this->logger->info('Post not fetchable', ['uri-id' => $ancestor, 'uid' => $uid, 'error' => $th]);
}
}
$descendants = array_diff(self::getChildren($id, $children), $deleted);
@ -137,7 +141,11 @@ class Context extends BaseApi
asort($descendants);
foreach (array_slice($descendants, 0, $request['limit']) as $descendant) {
$statuses['descendants'][] = DI::mstdnStatus()->createFromUriId($descendant, $uid, $display_quotes);
try {
$statuses['descendants'][] = DI::mstdnStatus()->createFromUriId($descendant, $uid, $display_quotes);
} catch (\Throwable $th) {
$this->logger->info('Post not fetchable', ['uri-id' => $descendant, 'uid' => $uid, 'error' => $th]);
}
}
$this->jsonExit($statuses);

Wyświetl plik

@ -155,13 +155,12 @@ class Update extends BaseApi
Photo::setPermissionForResource($media[0]['resource-id'], $uid, $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']);
$phototypes = Images::supportedTypes();
$ext = $phototypes[$media[0]['type']];
$ext = Images::getExtensionByMimeType($media[0]['type']);
$attachment = [
'type' => Post\Media::IMAGE,
'mimetype' => $media[0]['type'],
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . $ext,
'size' => $media[0]['datasize'],
'name' => $media[0]['filename'] ?: $media[0]['resource-id'],
'description' => $media[0]['desc'] ?? '',
@ -170,7 +169,7 @@ class Update extends BaseApi
];
if (count($media) > 1) {
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . $ext;
$attachment['preview-width'] = $media[1]['width'];
$attachment['preview-height'] = $media[1]['height'];
}

Wyświetl plik

@ -65,11 +65,7 @@ class Attach extends BaseModule
// error in Chrome for filenames with commas in them
header('Content-type: ' . $item['filetype']);
header('Content-length: ' . $item['filesize']);
if (isset($_GET['attachment']) && $_GET['attachment'] === '0') {
header('Content-disposition: filename="' . $item['filename'] . '"');
} else {
header('Content-disposition: attachment; filename="' . $item['filename'] . '"');
}
header('Content-disposition: attachment; filename="' . $item['filename'] . '"');
echo $data;
System::exit();

Wyświetl plik

@ -104,7 +104,7 @@ abstract class BaseAdmin extends BaseModule
'logsview' => ['admin/logs/view' , DI::l10n()->t('View Logs') , 'viewlogs'],
]],
'diagnostics' => [DI::l10n()->t('Diagnostics'), [
'phpinfo' => ['admin/phpinfo' , DI::l10n()->t('PHP Info') , 'phpinfo'],
'phpinfo' => ['admin/phpinfo?t=' . self::getFormSecurityToken('phpinfo'), DI::l10n()->t('PHP Info') , 'phpinfo'],
'probe' => ['probe' , DI::l10n()->t('probe address') , 'probe'],
'webfinger' => ['webfinger' , DI::l10n()->t('check webfinger') , 'webfinger'],
'babel' => ['babel' , DI::l10n()->t('Babel') , 'babel'],

Wyświetl plik

@ -42,7 +42,7 @@ class Bookmarklet extends BaseModule
if (!DI::userSession()->getLocalUserId()) {
$output = '<h2>' . DI::l10n()->t('Login') . '</h2>';
$output .= Login::form(DI::args()->getQueryString(), intval($config->get('config', 'register_policy')) === Register::CLOSED ? false : true);
$output .= Login::form(DI::args()->getQueryString(), Register::getPolicy() !== Register::CLOSED);
return $output;
}

Wyświetl plik

@ -142,7 +142,8 @@ class API extends BaseModule
{
$eventId = !empty($request['event_id']) ? intval($request['event_id']) : 0;
$uid = (int)$this->session->getLocalUserId();
$cid = !empty($request['cid']) ? intval($request['cid']) : 0;
// No overwriting event.cid on edit
$cid = !empty($request['cid']) && !$eventId ? intval($request['cid']) : 0;
$strStartDateTime = Strings::escapeHtml($request['start_text'] ?? '');
$strFinishDateTime = Strings::escapeHtml($request['finish_text'] ?? '');

Wyświetl plik

@ -141,13 +141,15 @@ class Circle extends BaseModule
protected function content(array $request = []): string
{
$change = false;
$change = false;
$relation = $request['rel'] ?? '';
if (!DI::userSession()->getLocalUserId()) {
throw new \Friendica\Network\HTTPException\ForbiddenException();
}
DI::page()['aside'] = Model\Circle::sidebarWidget('contact', 'circle', 'extended', ((DI::args()->getArgc() > 1) ? DI::args()->getArgv()[1] : 'everyone'));
DI::page()['aside'] .= Widget::contactRels($this->server['REQUEST_URI'], $relation);
// With no circle number provided we jump to the unassigned contacts as a starting point
// @TODO: Replace with parameter from router
@ -298,6 +300,9 @@ class Circle extends BaseModule
// Format the data of the circle members
foreach ($members as $member) {
if (!self::matchRelation($relation, $member['rel'])) {
continue;
}
if ($member['url']) {
$entry = Contact::getContactTemplateVars($member);
$entry['label'] = 'members';
@ -332,6 +337,9 @@ class Circle extends BaseModule
if (DBA::isResult($contacts)) {
// Format the data of the contacts who aren't in the contact circle
foreach ($contacts as $member) {
if (!self::matchRelation($relation, $member['rel'])) {
continue;
}
if (!in_array($member['id'], $preselected)) {
$entry = Contact::getContactTemplateVars($member);
$entry['label'] = 'contacts';
@ -366,4 +374,19 @@ class Circle extends BaseModule
return Renderer::replaceMacros($tpl, $context);
}
private static function matchRelation(string $relation, int $rel)
{
switch ($relation) {
case 'followers':
return($rel == Model\Contact::FOLLOWER);
case 'following':
return($rel == Model\Contact::SHARING);
case 'mutuals':
return($rel == Model\Contact::FRIEND);
case 'nothing':
return($rel == Model\Contact::NOTHING);
}
return true;
}
}

Wyświetl plik

@ -95,32 +95,32 @@ class Profile extends BaseModule
return;
}
Hook::callAll('contact_edit_post', $_POST);
Hook::callAll('contact_edit_post', $request);
$fields = [];
if (isset($_POST['hidden'])) {
$fields['hidden'] = !empty($_POST['hidden']);
if (isset($request['hidden'])) {
$fields['hidden'] = !empty($request['hidden']);
}
if (isset($_POST['notify_new_posts'])) {
$fields['notify_new_posts'] = !empty($_POST['notify_new_posts']);
if (isset($request['notify_new_posts'])) {
$fields['notify_new_posts'] = !empty($request['notify_new_posts']);
}
if (isset($_POST['fetch_further_information'])) {
$fields['fetch_further_information'] = intval($_POST['fetch_further_information']);
if (isset($request['fetch_further_information'])) {
$fields['fetch_further_information'] = intval($request['fetch_further_information']);
}
if (isset($_POST['remote_self'])) {
$fields['remote_self'] = intval($_POST['remote_self']);
if (isset($request['remote_self'])) {
$fields['remote_self'] = intval($request['remote_self']);
}
if (isset($_POST['ffi_keyword_denylist'])) {
$fields['ffi_keyword_denylist'] = $_POST['ffi_keyword_denylist'];
if (isset($request['ffi_keyword_denylist'])) {
$fields['ffi_keyword_denylist'] = $request['ffi_keyword_denylist'];
}
if (isset($_POST['poll'])) {
$priority = intval($_POST['poll']);
if (isset($request['poll'])) {
$priority = intval($request['poll']);
if ($priority > 5 || $priority < 0) {
$priority = 0;
}
@ -128,12 +128,16 @@ class Profile extends BaseModule
$fields['priority'] = $priority;
}
if (isset($_POST['info'])) {
$fields['info'] = $_POST['info'];
if (isset($request['info'])) {
$fields['info'] = $request['info'];
}
if (isset($_POST['channel_frequency'])) {
Contact\User::setChannelFrequency($cdata['user'], $this->session->getLocalUserId(), $_POST['channel_frequency']);
if (isset($request['channel_frequency'])) {
Contact\User::setChannelFrequency($cdata['user'], $this->session->getLocalUserId(), $request['channel_frequency']);
}
if (isset($request['channel_only'])) {
Contact\User::setChannelOnly($cdata['user'], $this->session->getLocalUserId(), $request['channel_only']);
}
if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => $this->session->getLocalUserId()])) {
@ -340,7 +344,8 @@ class Profile extends BaseModule
];
}
$channel_frequency = Contact\User::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
$channel_frequency = Contact\User::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
$channel_only = Contact\User::getChannelOnly($contact['id'], $this->session->getLocalUserId());
$poll_interval = null;
if ((($contact['network'] == Protocol::FEED) && !$this->config->get('system', 'adjust_poll_frequency')) || ($contact['network'] == Protocol::MAIL)) {
@ -432,6 +437,7 @@ class Profile extends BaseModule
'$frequency_always' => ['channel_frequency', $this->t('Display all posts of this contact'), Contact\User::FREQUENCY_ALWAYS, $this->t('All posts from this contact will appear on the "for you" channel'), $channel_frequency == Contact\User::FREQUENCY_ALWAYS],
'$frequency_reduced' => ['channel_frequency', $this->t('Display only few posts'), Contact\User::FREQUENCY_REDUCED, $this->t('When a contact creates a lot of posts in a short period, this setting reduces the number of displayed posts in every channel.'), $channel_frequency == Contact\User::FREQUENCY_REDUCED],
'$frequency_never' => ['channel_frequency', $this->t('Never display posts'), Contact\User::FREQUENCY_NEVER, $this->t('Posts from this contact will never be displayed in any channel'), $channel_frequency == Contact\User::FREQUENCY_NEVER],
'$channel_only' => ['channel_only', $this->t('Channel Only'), $channel_only, $this->t('If enabled, posts from this contact will only appear in channels, but not in the network stream.')],
]);
$arr = ['contact' => $contact, 'output' => $o];

Wyświetl plik

@ -65,8 +65,6 @@ class Network extends Timeline
/** @var int */
protected $circleId;
/** @var string */
protected $network;
/** @var string */
protected $dateFrom;
/** @var string */
protected $dateTo;

Wyświetl plik

@ -74,6 +74,8 @@ class Timeline extends BaseModule
protected $raw;
/** @var string */
protected $order;
/** @var string */
protected $network;
/** @var App\Mode $mode */
protected $mode;
@ -176,11 +178,11 @@ class Timeline extends BaseModule
protected function getNoSharerWidget(string $base): string
{
$path = $this->selectedTab;
if (!empty($this->accountTypeString)) {
$path .= '/' . $this->accountTypeString;
}
$query_parameters = [];
$query_parameters = [];
if (!empty($this->accountTypeString)) {
$query_parameters['accounttype'] = $this->accountTypeString;
}
if (!empty($this->minId)) {
$query_parameters['min_id'] = $this->minId;
}
@ -345,6 +347,13 @@ class Timeline extends BaseModule
AND NOT `cid` IN (SELECT `cid` FROM `contact-relation` WHERE `follows` AND `relation-cid` = ?))",
DateTimeFormat::utc('now - ' . $this->config->get('channel', 'sharer_interaction_days') . ' day'), $cid, $this->getMedianRelationThreadScore($cid, 4), $cid
];
} elseif ($this->selectedTab == ChannelEntity::QUIETSHARERS) {
$cid = Contact::getPublicIdByUserId($uid);
$condition = [
"`owner-id` IN (SELECT `cid` FROM `contact-relation` WHERE `follows` AND `relation-cid` = ? AND `post-score` <= ?)",
$cid, $this->getMedianPostScore($cid, 2)
];
} elseif ($this->selectedTab == ChannelEntity::IMAGE) {
$condition = ["`media-type` & ?", 1];
} elseif ($this->selectedTab == ChannelEntity::VIDEO) {
@ -365,6 +374,10 @@ class Timeline extends BaseModule
$this->setMaxMinByOrder($request);
if (!empty($this->network)) {
$condition = DBA::mergeConditions($condition, ['network' => $this->network]);
}
if (($this->selectedTab != ChannelEntity::LANGUAGE) && !is_numeric($this->selectedTab)) {
$condition = $this->addLanguageCondition($uid, $condition);
}
@ -634,6 +647,28 @@ class Timeline extends BaseModule
return $score;
}
private function getMedianPostScore(int $cid, int $divider): int
{
$cache_key = 'Channel:getPostScore:' . $cid . ':' . $divider;
$score = $this->cache->get($cache_key);
if (!empty($score)) {
return $score;
}
$condition = ["`relation-cid` = ? AND `post-score` > ?", $cid, 0];
$limit = $this->database->count('contact-relation', $condition) / $divider;
$relation = $this->database->selectToArray('contact-relation', ['post-score'], $condition, ['order' => ['post-score' => true], 'limit' => [$limit, 1]]);
$score = $relation[0]['post-score'] ?? 0;
if (empty($score)) {
return 0;
}
$this->cache->set($cache_key, $score, Duration::HALF_HOUR);
$this->logger->debug('Calculated median score', ['cid' => $cid, 'divider' => $divider, 'median' => $score]);
return $score;
}
/**
* Computes the displayed items.
*

Wyświetl plik

@ -43,10 +43,11 @@ class Babel extends BaseModule
}
$results = [];
if (!empty($_REQUEST['text'])) {
switch (($_REQUEST['type'] ?? '') ?: 'bbcode') {
if (!empty($request['text'])) {
self::checkFormSecurityTokenForbiddenOnError('babel');
switch (($request['type'] ?? '') ?: 'bbcode') {
case 'bbcode':
$bbcode = $_REQUEST['text'];
$bbcode = $request['text'];
$results[] = [
'title' => DI::l10n()->t('Source input'),
'content' => visible_whitespace($bbcode)
@ -136,7 +137,7 @@ class Babel extends BaseModule
];
break;
case 'diaspora':
$diaspora = trim($_REQUEST['text']);
$diaspora = trim($request['text']);
$results[] = [
'title' => DI::l10n()->t('Source input (Diaspora format)'),
'content' => visible_whitespace($diaspora),
@ -144,7 +145,7 @@ class Babel extends BaseModule
$markdown = XML::unescape($diaspora);
case 'markdown':
$markdown = $markdown ?? trim($_REQUEST['text']);
$markdown = $markdown ?? trim($request['text']);
$results[] = [
'title' => DI::l10n()->t('Source input (Markdown)'),
@ -169,7 +170,7 @@ class Babel extends BaseModule
];
break;
case 'html' :
$html = trim($_REQUEST['text']);
$html = trim($request['text']);
$results[] = [
'title' => DI::l10n()->t('Raw HTML input'),
'content' => visible_whitespace($html),
@ -239,7 +240,7 @@ class Babel extends BaseModule
];
break;
case 'twitter':
$json = trim($_REQUEST['text']);
$json = trim($request['text']);
if (file_exists('addon/twitter/twitter.php')) {
require_once 'addon/twitter/twitter.php';
@ -302,13 +303,14 @@ class Babel extends BaseModule
$tpl = Renderer::getMarkupTemplate('babel.tpl');
$o = Renderer::replaceMacros($tpl, [
'$title' => DI::l10n()->t('Babel Diagnostic'),
'$text' => ['text', DI::l10n()->t('Source text'), $_REQUEST['text'] ?? '', ''],
'$type_bbcode' => ['type', DI::l10n()->t('BBCode'), 'bbcode', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'bbcode'],
'$type_diaspora' => ['type', DI::l10n()->t('Diaspora'), 'diaspora', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'diaspora'],
'$type_markdown' => ['type', DI::l10n()->t('Markdown'), 'markdown', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'markdown'],
'$type_html' => ['type', DI::l10n()->t('HTML'), 'html', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'html'],
'$form_security_token' => self::getFormSecurityToken('babel'),
'$text' => ['text', DI::l10n()->t('Source text'), $request['text'] ?? '', ''],
'$type_bbcode' => ['type', DI::l10n()->t('BBCode'), 'bbcode', '', (($request['type'] ?? '') ?: 'bbcode') == 'bbcode'],
'$type_diaspora' => ['type', DI::l10n()->t('Diaspora'), 'diaspora', '', (($request['type'] ?? '') ?: 'bbcode') == 'diaspora'],
'$type_markdown' => ['type', DI::l10n()->t('Markdown'), 'markdown', '', (($request['type'] ?? '') ?: 'bbcode') == 'markdown'],
'$type_html' => ['type', DI::l10n()->t('HTML'), 'html', '', (($request['type'] ?? '') ?: 'bbcode') == 'html'],
'$flag_twitter' => file_exists('addon/twitter/twitter.php'),
'$type_twitter' => ['type', DI::l10n()->t('Twitter Source / Tweet URL (requires API key)'), 'twitter', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'twitter'],
'$type_twitter' => ['type', DI::l10n()->t('Twitter Source / Tweet URL (requires API key)'), 'twitter', '', (($request['type'] ?? '') ?: 'bbcode') == 'twitter'],
'$results' => $results,
'$submit' => DI::l10n()->t('Submit'),
]);

Wyświetl plik

@ -30,7 +30,6 @@ use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\PostUpdate;
use Friendica\Model\User;
use Friendica\Network\HTTPException;
@ -154,7 +153,7 @@ class Friendica extends BaseModule
Register::OPEN => 'REGISTER_OPEN'
];
$register_policy_int = $this->config->get('config', 'register_policy');
$register_policy_int = Register::getPolicy();
if ($register_policy_int !== Register::CLOSED && $this->config->get('config', 'invitation_only')) {
$register_policy = 'REGISTER_INVITATION';
} else {

Wyświetl plik

@ -73,7 +73,7 @@ class Home extends BaseModule
}
}
$login = Login::form(DI::args()->getQueryString(), $config->get('config', 'register_policy') === Register::CLOSED ? 0 : 1);
$login = Login::form(DI::args()->getQueryString(), Register::getPolicy() !== Register::CLOSED);
$content = '';
Hook::callAll('home_content', $content);

Wyświetl plik

@ -146,14 +146,14 @@ class Invite extends BaseModule
$dirLocation = Search::getGlobalDirectory();
if (strlen($dirLocation)) {
if ($config->get('config', 'register_policy') === Register::CLOSED) {
if (Register::getPolicy() === Register::CLOSED) {
$linkTxt = DI::l10n()->t('Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks.', $dirLocation . '/servers');
} else {
$linkTxt = DI::l10n()->t('To accept this invitation, please visit and register at %s or any other public Friendica website.', DI::baseUrl() . '/register')
. "\r\n" . "\r\n" . DI::l10n()->t('Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join.', $dirLocation . '/servers');
}
} else { // there is no global directory URL defined
if ($config->get('config', 'register_policy') === Register::CLOSED) {
if (Register::getPolicy() === Register::CLOSED) {
return DI::l10n()->t('Our apologies. This system is not currently configured to connect with other public sites or invite members.');
} else {
$linkTxt = DI::l10n()->t('To accept this invitation, please visit and register at %s.', DI::baseUrl() . '/register'

Wyświetl plik

@ -99,8 +99,7 @@ class Browser extends BaseModule
protected function map_files(array $record): array
{
$types = Images::supportedTypes();
$ext = $types[$record['type']];
$ext = Images::getExtensionByMimeType($record['type']);
$filename_e = $record['filename'];
// Take the largest picture that is smaller or equal 640 pixels
@ -118,7 +117,7 @@ class Browser extends BaseModule
return [
sprintf('%s/photos/%s/image/%s', $this->baseUrl, $this->app->getLoggedInUserNickname(), $record['resource-id']),
$filename_e,
sprintf('%s/photo/%s-%s.%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
sprintf('%s/photo/%s-%s%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
$record['desc'],
];
}

Wyświetl plik

@ -135,8 +135,6 @@ class Upload extends \Friendica\BaseModule
$this->return(401, $this->t('Invalid request.'), true);
}
$filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
$this->logger->info('File upload:', [
'src' => $src,
'filename' => $filename,
@ -145,7 +143,7 @@ class Upload extends \Friendica\BaseModule
]);
$imagedata = @file_get_contents($src);
$image = new Image($imagedata, $filetype);
$image = new Image($imagedata, $filetype, $filename);
if (!$image->isValid()) {
@unlink($src);

Wyświetl plik

@ -57,11 +57,11 @@ class Index extends BaseModeration
// Edit the entries from blocklist
$blocklist = [];
foreach ($request['domain'] as $id => $domain) {
foreach ((array)$request['domain'] as $id => $domain) {
// Trimming whitespaces as well as any lingering slashes
$domain = trim($domain);
$reason = trim($request['reason'][$id]);
if (empty($request['delete'][$id])) {
if (empty($request['delete'][$id]) && !empty($domain)) {
$blocklist[] = [
'domain' => $domain,
'reason' => $reason

Wyświetl plik

@ -24,7 +24,6 @@ namespace Friendica\Module;
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Model\Nodeinfo;
@ -65,7 +64,7 @@ class NodeInfo110 extends BaseModule
],
'services' => Nodeinfo::getServices(),
'usage' => Nodeinfo::getUsage(),
'openRegistrations' => intval($this->config->get('config', 'register_policy')) !== Register::CLOSED,
'openRegistrations' => Register::getPolicy() !== Register::CLOSED,
'metadata' => [
'nodeName' => $this->config->get('config', 'sitename'),
],

Wyświetl plik

@ -24,7 +24,6 @@ namespace Friendica\Module;
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Model\Nodeinfo;
@ -58,7 +57,7 @@ class NodeInfo120 extends BaseModule
'protocols' => ['dfrn', 'activitypub'],
'services' => Nodeinfo::getServices(),
'usage' => Nodeinfo::getUsage(),
'openRegistrations' => intval($this->config->get('config', 'register_policy')) !== Register::CLOSED,
'openRegistrations' => Register::getPolicy() !== Register::CLOSED,
'metadata' => [
'nodeName' => $this->config->get('config', 'sitename'),
],

Wyświetl plik

@ -24,7 +24,6 @@ namespace Friendica\Module;
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Model\Nodeinfo;
@ -59,7 +58,7 @@ class NodeInfo210 extends BaseModule
'organization' => Nodeinfo::getOrganization($this->config),
'protocols' => ['dfrn', 'activitypub'],
'services' => Nodeinfo::getServices(),
'openRegistrations' => intval($this->config->get('config', 'register_policy')) !== Register::CLOSED,
'openRegistrations' => Register::getPolicy() !== Register::CLOSED,
'usage' => Nodeinfo::getUsage(true),
];

Wyświetl plik

@ -32,7 +32,6 @@ use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\Model\Circle;
@ -175,7 +174,7 @@ class Ping extends BaseModule
$myurl = $this->session->getMyUrl();
$mail_count = $this->database->count('mail', ["`uid` = ? AND NOT `seen` AND `from-url` != ?", $this->session->getLocalUserId(), $myurl]);
if (intval($this->config->get('config', 'register_policy')) === Register::APPROVE && $this->session->isSiteAdmin()) {
if (Register::getPolicy() === Register::APPROVE && $this->session->isSiteAdmin()) {
$registrations = \Friendica\Model\Register::getPending();
$register_count = count($registrations);
}

Wyświetl plik

@ -21,10 +21,7 @@
namespace Friendica\Module\OAuth;
use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Module\BaseApi;
use Friendica\Module\Special\HTTPException;
use Psr\Http\Message\ResponseInterface;

Some files were not shown because too many files have changed in this diff Show More