Merge branch '2023.03-rc' into stable
|
@ -1,7 +1,7 @@
|
|||
codecov:
|
||||
branch: develop
|
||||
ci:
|
||||
- drone.friendi.ca
|
||||
- ci.friendi.ca
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
|
|
|
@ -6,9 +6,27 @@ root = true
|
|||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespaces = true
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
quote_type = single
|
||||
max_line_length = off
|
||||
|
||||
[*.js]
|
||||
quote_type = double
|
||||
ij_javascript_use_double_quotes = true
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.xml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[composer.json]
|
||||
indent_style = tab
|
||||
|
|
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -13,7 +13,7 @@ assignees: ''
|
|||
|
||||
### Describe the feature you'd like
|
||||
|
||||
<!-- A clear and concise description of waht you want to happen. -->
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
### Describe alternatives you've considered
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[main]
|
||||
host = https://www.transifex.com
|
||||
host = https://api.transifex.com
|
||||
|
||||
[friendica.messagespo]
|
||||
[o:Friendica:p:friendica:r:messagespo]
|
||||
file_filter = view/lang/<lang>/messages.po
|
||||
source_file = view/lang/C/messages.po
|
||||
source_lang = en
|
||||
|
|
|
@ -71,20 +71,19 @@ pipeline:
|
|||
else
|
||||
phpunit --configuration tests/phpunit.xml;
|
||||
fi
|
||||
|
||||
codecov:
|
||||
image: plugins/codecov
|
||||
image: friendicaci/codecov
|
||||
when:
|
||||
matrix:
|
||||
PHP_MAJOR_VERSION: 7.4
|
||||
PHP_VERSION: 7.4.18
|
||||
PHP_VERSION: 7.4.33
|
||||
repo:
|
||||
- friendica/friendica
|
||||
settings:
|
||||
token:
|
||||
from_secret: codecov-token
|
||||
files:
|
||||
- clover.xml
|
||||
commands:
|
||||
- codecov -R '.' -Z -f 'clover.xml'
|
||||
secrets:
|
||||
- source: codecov-token
|
||||
target: codecov_token
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
|
|
143
CHANGELOG
|
@ -1,3 +1,72 @@
|
|||
Version 2023.04 (2023-04-23)
|
||||
Friendica Core
|
||||
Updates to the translations AR, BG, CA, CS, DA, DE, EO, ES, ET, FR, GD, HU, IS, IT, JA, NL, PL, RU, SV
|
||||
Updates to the themes (frio, vier) [damianwajer, haheute, MrPetovan, xundeenergie]
|
||||
Updates to the documentation [haheute, HankG, MarekBenjamin, MrPetovan]
|
||||
General code cleanup [annando, MarekBenjamin, MrPetovan, nupplaphil]
|
||||
Fixed display of blocked contacts [annando]
|
||||
Fixed usage of environment variables [nupplaphil]
|
||||
Fixed paging on the Mastodon compatible API endpoints for timelines and statuses [HankG]
|
||||
Fixed updating of attached links via the API [HankG]
|
||||
Fixed federation issues with Diaspora*, gup.pe, Hubzilla and Peertube servers [annando]
|
||||
Fixed a bug with PubSubHubBub subscription [annando]
|
||||
Fixed a XSS vulnerability in Justified-Gallery JavaScript dependency (frio theme) [MrPetovan]
|
||||
Improved the translate ability of activities (singular/plural forms) [nupplaphil]
|
||||
Improved activity update handling [xundeenergie]
|
||||
Improved BBCode + Markdown parsing [annando]
|
||||
Improved known Fediverse statistics [annando]
|
||||
Improved automatic table optimization [HankG]
|
||||
Improved the performance of local JsonLD requests [MrPetovan]
|
||||
Improved the performance of local requests [annando]
|
||||
Improved the performance of the delivery of postings [annando]
|
||||
Improved the performance of homepage rel-me checks [annando]
|
||||
Improved supported characters for passwords [MrPetovan]
|
||||
Improved the ARIA support [MrPetovan]
|
||||
Improved PHP 8.2 compatibility [MrPetovan]
|
||||
Added emoticon reaction handling [annando]
|
||||
Added drag and drop image upload in frio themes [xundeenergie]
|
||||
Added scope change for comments to the API [annando]
|
||||
Added posting visibility to the API [HankG]
|
||||
Added delivery information to the Mastodon compatible API [HankG]
|
||||
Added notification summary option to the Mastodon compatible API [HankG]
|
||||
Added option to display activities as emoticons [annando]
|
||||
Added trending API updates [HankG]
|
||||
Added blocked/ignored filters to the Mastodon compatible API [HankG]
|
||||
Added ActivityPub C2S postings to the API [annando]
|
||||
Added dislike information for postings to the Mastodon compatible API [HankG, mkljczk]
|
||||
Added the possibility to deletion blocked servers [annando]
|
||||
Removed the GNUsocial import [annando]
|
||||
|
||||
Friendica Addons
|
||||
Updates to the translations AR, CS, DE, ES, HU, IS, IT, NL, PL, RU, SV
|
||||
mailstream
|
||||
Various modernization [mexon]
|
||||
Include post media [mexon]
|
||||
securemail
|
||||
Updated the phpseclib dependency [MrPetovan]
|
||||
twitter
|
||||
Improve remote-self handling [annando]
|
||||
impressum
|
||||
Avoide obfuscation on un-set email addresses [MrPestovan]
|
||||
notifyall
|
||||
Fixed a bug selecting the email addresses [nupplaphil]
|
||||
tumblr
|
||||
Fixed a bug addressing the tumblr blog via UUID [annando]
|
||||
Added support for NPF [annando]
|
||||
Improved the tumblr blog URI detection [annando]
|
||||
Improved the handling of multible images [annando]
|
||||
marked as UNSUPPORTED addons
|
||||
blockem, tictactoe, twitter
|
||||
|
||||
Closed Issues
|
||||
7037, 10974, 11513, 11535, 11825, 11986, 12489, 12490, 12507, 12515,
|
||||
12522, 12537, 12545, 12550, 12552, 12559, 12582, 12601, 12602, 12603,
|
||||
12607, 12608, 12616, 12617, 12620, 12624, 12625, 12629, 12654, 12658,
|
||||
12661, 12665, 12672, 12677, 12682, 12705, 12713, 12721, 12753, 12764,
|
||||
12779, 12792, 12793, 12803, 12809, 12828, 12835, 12842, 12846, 12847,
|
||||
12858, 12859, 12871, 12888, 12924, 12944, 12970, 12974, 12983, 12993,
|
||||
12995, 13002, 19996
|
||||
|
||||
Version 2023.01 (2023-01-15)
|
||||
Friendica Core
|
||||
Improved the global server updating if domains are blocked [MrPetovan]
|
||||
|
@ -30,7 +99,7 @@ Version 2022.12 (2022-12-20)
|
|||
Added a moderation section to the admin panel [annando]
|
||||
Added an option to make the calendar public [matthiasmoritz]
|
||||
Fixed a bug in the federation with Diaspora* [annando]
|
||||
Fixec a problem in the federation with GoTo Social and Owncast [annando]
|
||||
Fixed a problem in the federation with GoTo Social and Owncast [annando]
|
||||
Deprecated old themes (duepuntozero, quattro, smoothy)
|
||||
|
||||
NOTE: The Apache2 rewrite rule in the .htaccess-dist has been changed.
|
||||
|
@ -718,13 +787,13 @@ Version 2020.07 (2020-07-12)
|
|||
blockbot:
|
||||
The list of accepted user agents was enhanced [annando]
|
||||
Diaspora*:
|
||||
Enhanced conntector settings [MrPetovan]
|
||||
Enhanced connector settings [MrPetovan]
|
||||
PHP Mailer SMTP:
|
||||
Updated phpmailer version [dependabot]
|
||||
showmore_dyn:
|
||||
New addon to collapse long post depending on their actual height [wiwie]
|
||||
twitter:
|
||||
Enhaceed the handling of mobile twitter URLs [annando]
|
||||
Enhanced the handling of mobile twitter URLs [annando]
|
||||
Enhanced the handling of quoted tweets [MrPetovan]
|
||||
added HTML error code handling [MrPetovan]
|
||||
various:
|
||||
|
@ -962,7 +1031,7 @@ Version 2019.09 (2019-09-29)
|
|||
|
||||
Version 2019.06 (2019-06-23)
|
||||
Friendica Core:
|
||||
Update to the tranlation (CS, DE, EN-GB, EN-US, ET, FR, IT, PL, PT-BR, SV) [translation teams]
|
||||
Update to the translation (CS, DE, EN-GB, EN-US, ET, FR, IT, PL, PT-BR, SV) [translation teams]
|
||||
Update to the documentation [nupplaphil, realkinetix, MrPetovan]
|
||||
Update to the themes (frio, vier) [BinkaDroid, MrPetovan, tobiasd]
|
||||
Enhancements to the API [annando, MrPetovan]
|
||||
|
@ -982,7 +1051,7 @@ Version 2019.06 (2019-06-23)
|
|||
Fixed an issue with the File to Folder feature [MrPetovan]
|
||||
Fixed an issue with the legacy storage engine [fabrixxm]
|
||||
Fixed an issue with the theme and addon path items [MrPetovan]
|
||||
Fixed an issue occuring when the BasePath was not set [tobiasd]
|
||||
Fixed an issue occurring when the BasePath was not set [tobiasd]
|
||||
Fixed an issue with additionally opened Sessions [MrPetovan]
|
||||
Fixed an issue with legacy loglevel mapping [nupplaphil]
|
||||
Fixed contact suggestions [annando]
|
||||
|
@ -1008,7 +1077,7 @@ Version 2019.06 (2019-06-23)
|
|||
Remove support for defunct F-Droid Friendica app [MrPetovan]
|
||||
|
||||
Friendica Addons:
|
||||
Update to the tranlation (ET, SV, ZH_CN) [translation teams]
|
||||
Update to the translation (ET, SV, ZH_CN) [translation teams]
|
||||
botdetection:
|
||||
Added a new addon for preventing access by bots [nupplaphil, annando]
|
||||
buffer:
|
||||
|
@ -1046,7 +1115,7 @@ Version 2019.03 (2019-03-22)
|
|||
Update to the themes (duepuntozero, frio, smoothy, quattro, vier) [lxiter, MrPetovan, nupplaphil, rabuzarus, tobiasd]
|
||||
Enhancements to the API [jasonscheng]
|
||||
Enhancements to the Vagrant development VM [JeroenED]
|
||||
Enhancements to the storage of gender, sexual preferences and maritial status [JeroenED]
|
||||
Enhancements to the storage of gender, sexual preferences and marital status [JeroenED]
|
||||
Enhancements to the wording of notifications [MrPetovan]
|
||||
Enhancements to the display of contacts in the profile [MrPetovan]
|
||||
Enhancements to the handling of local links [lxiter]
|
||||
|
@ -1075,7 +1144,7 @@ Version 2019.03 (2019-03-22)
|
|||
Fixed an issue with sending out notification mails to the admin [nupplaphil]
|
||||
Fixed an the issue, that the API was ignoring the globalsilence setting [nupplaphil]
|
||||
Fixed issues with the autolinker of URLs in postings [MrPetovan]
|
||||
Fixed an issue resulting in multible emails after successful updates of the database [nupplaphil]
|
||||
Fixed an issue resulting in multiple emails after successful updates of the database [nupplaphil]
|
||||
Fixed a timeout issue during detection process of the remote profile [annando]
|
||||
Fixed an issue with postings from blocked servers [annando, MrPetovan]
|
||||
Fixed an issue with the paging of stored folders [MrPetovan]
|
||||
|
@ -1107,7 +1176,7 @@ Version 2019.03 (2019-03-22)
|
|||
forumdirectory:
|
||||
Fixed a theming issue with frio [rabuzarus]
|
||||
js_upload:
|
||||
Fixed a missing extionsion index [nupplaphil]
|
||||
Fixed a missing extension index [nupplaphil]
|
||||
mailstream:
|
||||
Fixed a curl issue [MrPetovan]
|
||||
piwik:
|
||||
|
@ -1327,7 +1396,7 @@ Version 2018.09 (2018-09-23)
|
|||
added addons:
|
||||
mastodoncustomemojis [MrPetovan]
|
||||
deprecated addons:
|
||||
notimeline, retriver, remote_permissions, widgets
|
||||
notimeline, retriever, remote_permissions, widgets
|
||||
|
||||
Directory:
|
||||
Enhancements of the health summary [andyhee]
|
||||
|
@ -1353,7 +1422,7 @@ Version 2018.05 (2018-06-01)
|
|||
Enhancements to the relay system [annando]
|
||||
Enhancements to the handling of URL that contain unicode characters [annando]
|
||||
Enhancements to the Vagrant VM configuration [fabrixxm, tobiasd]
|
||||
Enhancementa to the Babel module [MrPetovan]
|
||||
Enhancements to the Babel module [MrPetovan]
|
||||
Enhancements to the display of the [code] elements [MrPetovan]
|
||||
Enhancements to the federation (OStatus, diaspora) [annando]
|
||||
Enhancements to the PHP7.2 compatibility [Alkarex, MrPetovan, Quix0r]
|
||||
|
@ -1382,7 +1451,7 @@ Version 2018.05 (2018-06-01)
|
|||
Fixed a bug that made edited mentions and hashtags plaintext [annando]
|
||||
Fixed a bug that caused the /display page to receive constandly new updates [annando]
|
||||
Fixed wrong version of a dependency preventing the usage of PHP 5.6 [MrPetovan]
|
||||
Fixed a bug in OpenID authentification [Quix0r]
|
||||
Fixed a bug in OpenID authentication [Quix0r]
|
||||
Fixed a bug in the item deletion [annando]
|
||||
Fixed a bug that prevented public comments from being distributed [annando]
|
||||
Fixed a bug that caused empty profile pictures for public contacts [annando]
|
||||
|
@ -1481,7 +1550,7 @@ Version 3.6 (2018-03-23)
|
|||
Enhancements to the probing of pump.io profiles [annando]
|
||||
Enhancements to the handling of BBCode tags [MrPetovan]
|
||||
Enhancements to the OEmbed handling [MrPetovan]
|
||||
Fixed a bug that triggered the display of activities on the cummunity page [annando]
|
||||
Fixed a bug that triggered the display of activities on the community page [annando]
|
||||
Fixed a bug with personal notes [annando]
|
||||
Fixed a display issue of long postings when using the showmore option [annando]
|
||||
Fixed a bug that caused Twidere to crash on reload [annando]
|
||||
|
@ -1489,7 +1558,7 @@ Version 3.6 (2018-03-23)
|
|||
Fixed a bug in URL completion for feed fragments [annando]
|
||||
Fixed a bug in the notification system about new registrations [annando]
|
||||
Fixed the display of dislikes [annando]
|
||||
Fixed the display of orphans childs in threads [MrPetovan]
|
||||
Fixed the display of orphan children in threads [MrPetovan]
|
||||
Fixed some SQL problems [annando]
|
||||
Fixed the CLI config script [tobiasd]
|
||||
Fixed the forum selection on the network display [annando]
|
||||
|
@ -1543,7 +1612,7 @@ Version 3.6 (2018-03-23)
|
|||
all bridges don't relay postings anymore that are posted to a public forum [annando]
|
||||
DAV addon marked unsupported [tobiasd]
|
||||
communityhome addon marked unsupported [MrPetovan]
|
||||
yourls addon makrked unsupported [MrPetovan]
|
||||
yourls addon marked unsupported [MrPetovan]
|
||||
Current Weather: fixing a problem with the weathermap link [zeroadam]
|
||||
NSFW added config examples, reworked the description, now ignores the CW from Mastodon [andyhee, annando, rebeka-catalina]
|
||||
Twitter support 280 chars limit [annando]
|
||||
|
@ -1738,7 +1807,7 @@ Version 3.5.1 (2017-03-12)
|
|||
Improvements to the documentation [Hypolite, tobiasd, rabuzarus, beardyunixer, eelcomaljaars]
|
||||
Improvements to the BBCode / Markdown conversation [Hypolite]
|
||||
Improvements to the OStatus protocol implementation [annando]
|
||||
Improvements to the installation wizzard [tobiasd]
|
||||
Improvements to the installation wizard [tobiasd]
|
||||
Improvements to the Diaspora connectivity [annando, Hypolite]
|
||||
Work on PHP7 compatibility [ddorian1]
|
||||
Code cleanup [Hypolite, Quix0r]
|
||||
|
@ -1800,11 +1869,11 @@ Version 3.5 (2016-09-13)
|
|||
Improvements on the themes (quattro, vier, frost) [rabuzarus, fabrixxm, stieben, annando, Quix0r, tobiasd]
|
||||
Improvements to the ACL dialog [fabrixxm, rabuzarus]
|
||||
Improvements to the database structure and optimization of queries [annando]
|
||||
Improvements to the UI (contacts, hotkeys, remember me, ARIA, code hightlighting) [rabuzarus, annando, tobiasd]
|
||||
Improvements to the UI (contacts, hotkeys, remember me, ARIA, code highlighting) [rabuzarus, annando, tobiasd]
|
||||
Improvements to the background process (poller, worker) [annando]
|
||||
Improvements to the admin panel [tobiasd, annando, fabrixxm]
|
||||
Improvements to the performance [annando]
|
||||
Improvements to the installation wizzard (language selection, RINO version, check required PHP modules, default theme is now vier) [tobiasd]
|
||||
Improvements to the installation wizard (language selection, RINO version, check required PHP modules, default theme is now vier) [tobiasd]
|
||||
Improvements to the relocation of nodes and accounts [annando]
|
||||
Improvements to the DDoS detection [annando]
|
||||
Improvements to the calendar/events module [annando, rabuzarus]
|
||||
|
@ -1829,7 +1898,7 @@ Version 3.5 (2016-09-13)
|
|||
GNU Social Connector [annando]
|
||||
LDAP [Olivier Mehani]
|
||||
smileybutton [rabuzarus]
|
||||
retriver [mexon]
|
||||
retriever [mexon]
|
||||
mailstream [mexon]
|
||||
forumdirectory [tobiasd]
|
||||
NEW notifyall (port from Hubzilla) [rabuzarus, tobiasd]
|
||||
|
@ -1884,7 +1953,7 @@ Version 3.4.3 (2015-12-22)
|
|||
'Reload active themes' in theme admin page (fabrixxm)
|
||||
Install routine checks for ImageMagick and GIF support (fabrixxm)
|
||||
Install routine checks for availability of "mcrypt_create_iv()" function, needed for RINO2 (fabrixxm)
|
||||
Only suported themes are shown in admin page (annando)
|
||||
Only supported themes are shown in admin page (annando)
|
||||
Optimized SQL queries (annando)
|
||||
System perform an optimize pass on tables in cron, with maximum table size and minimum fragmentation level settings (annando)
|
||||
New access keys in profile and contact pages (rabuzarus, annando)
|
||||
|
@ -1899,9 +1968,9 @@ Version 3.4.3 (2015-12-22)
|
|||
New hook 'template_vars' (fabrixxm)
|
||||
$baseurl variable is passed to all templates by default (fabrixxm)
|
||||
OStatus delivery code is moved in new function (annando)
|
||||
Doxygen config file and initial documetation of code (rabuzarus)
|
||||
Doxygen config file and initial documentation of code (rabuzarus)
|
||||
Full rewrite of util/php2po.php (fabrixxm)
|
||||
Bugfixs:
|
||||
Bugfixes:
|
||||
Remote self works again (annando)
|
||||
Fix feeds mistakenly recognized as OStatus (issue #1914) (annando)
|
||||
Report invalid feeds to user (issue #1913) (annando)
|
||||
|
@ -1916,8 +1985,8 @@ Version 3.4.3 (2015-12-22)
|
|||
Fix rapid repeated requests to GNUSocial instance (issue #2038) (annando)
|
||||
Fix install routine css when mod_rewrite doesn't works (issue #2071) (fabrixxm)
|
||||
Fix code to be compliant with minimum required PHP version (issue #2066) (fabrixxm, rabuzarus)
|
||||
Fix feedback after succesfull registration (issue #2060) (annando)
|
||||
Fix mention completition popup with TinyMCE (issue #1920) (fabrixxm)
|
||||
Fix feedback after successful registration (issue #2060) (annando)
|
||||
Fix mention completion popup with TinyMCE (issue #1920) (fabrixxm)
|
||||
Fix photo cache and proxy when installed in subfolder (ddorian1)
|
||||
Fix bbcode conversion of the about text for the profile (issue #1607) (annando)
|
||||
|
||||
|
@ -1927,7 +1996,7 @@ Version 3.4.2 (2015-09-29)
|
|||
Updates to the documentation (tobiasd, silke, annando)
|
||||
Updates to the translations (tobiasd & translation teams)
|
||||
Updates to themes frost-mobile, vier, duepuntozero, quattro (annando, tobiasd)
|
||||
Enancements of the communications via OStatus and Diaspora protocols (annando)
|
||||
Enhancements of the communications via OStatus and Diaspora protocols (annando)
|
||||
Option to automatically follow OStatus contacts was moved from addon to the core (annando)
|
||||
Add tool to import OStatus contacts from an old account (annando)
|
||||
SALMON slaps with OStatus were reworked (annando)
|
||||
|
@ -1944,7 +2013,7 @@ Version 3.4.2 (2015-09-29)
|
|||
The global directory is queried in the background to update local DB and improve similar searches in the future. (annando)
|
||||
By communication over the Diaspora protocol, red#matrix sources are now correctly identified, hubzilla is detected (annando)
|
||||
Adopt limitation of usage of "-" in username to avoid conflicts with GNU Social and Diaspora (annando)
|
||||
The [url] tag now also suppots ftp, mailto, gopher links (annando)
|
||||
The [url] tag now also supports ftp, mailto, gopher links (annando)
|
||||
An "inspect queue" module was added to the admin panel (tobiasd)
|
||||
Fix some missing SQL data escapes (fabrixxm)
|
||||
Improved the accessibility of the web UI for better screen reader compatibility (annando)
|
||||
|
@ -1972,7 +2041,7 @@ Version 3.4.1 (2015-07-06)
|
|||
Implement server-to-server encryption (RINO) using php-encryption library as "RINO 2", deprecate "RINO 1" (issue #1655) (fabrixxm)
|
||||
Fix connection with Diaspora "freelove" account (issue #1572) (annando)
|
||||
Various SQL speedups (annando)
|
||||
Port of Javascript DatePicker input from RedMatrix (rabuzarus)
|
||||
Port of JavaScript DatePicker input from RedMatrix (rabuzarus)
|
||||
Port of RedMatrix archive widget (rabuzarus)
|
||||
Load profile owner settings for theme on profile page (rabuzarus)
|
||||
Move HTML code from php into templates (rabuzarus)
|
||||
|
@ -1985,7 +2054,7 @@ Version 3.4.1 (2015-07-06)
|
|||
use correct contact when automatically add @-replies
|
||||
add attachment links as enclosures
|
||||
send salmon notifications to every mentioned person
|
||||
better thread completition
|
||||
better thread completion
|
||||
support for bookmarks
|
||||
support for events and questions
|
||||
link to items using GUID
|
||||
|
@ -1996,7 +2065,7 @@ Version 3.4.1 (2015-07-06)
|
|||
Add fake fields to API response for better Twitter API compatibility (annando)
|
||||
Fix search in local directory (issue #1657) (annando)
|
||||
Improve OEmbed (issue #1640) (annando)
|
||||
Fix double html encodig in site administration page for sitename and register text (issue #1628) (annando)
|
||||
Fix double html encoding in site administration page for sitename and register text (issue #1628) (annando)
|
||||
Fix remote subscription from GNU Social (annando)
|
||||
Fix "{0}" in notifications (issue #1642) (annando)
|
||||
Fix desktop notification (fabrixxm)
|
||||
|
@ -2005,7 +2074,7 @@ Version 3.4.1 (2015-07-06)
|
|||
Fix emoticons alt text (tobias)
|
||||
Improve threaded display in Vier theme (annando)
|
||||
Use field templates in photo edit form (fabrixxm)
|
||||
Alllow deletion of any user but yourself (issue #1625) (fabrixxm)
|
||||
Allow deletion of any user but yourself (issue #1625) (fabrixxm)
|
||||
Install wizard load htconfig template from template/ folder, remove localized htconfig templates (fabrixxm)
|
||||
Add contact detail to non-js contact drop confirm dialog (issue #1629) (fabrixxm)
|
||||
Return geo coord in API (annando)
|
||||
|
@ -2024,7 +2093,7 @@ Version 3.4 (2015-04-05)
|
|||
Optionally, "like" and "dislike" activities don't update thread timestamp (annando)
|
||||
Updated markdown libraries (annando)
|
||||
Updated jQuery (StefOfficiel)
|
||||
Cache zrl verification requests to prevent DSoS (issue #1453) (annando)
|
||||
Cache zrl verification requests to prevent DDoS (issue #1453) (annando)
|
||||
"Verify SSL" options affects also VERIFYHOST (annando)
|
||||
Better handling of hashtags (annando)
|
||||
Updated translations (translation teams, tobias)
|
||||
|
@ -2062,7 +2131,7 @@ Version 3.3.3 (2015-02-24)
|
|||
Share-it button support (annando)
|
||||
More reliable reshare from Diaspora (annando)
|
||||
Load more images via proxy (annando)
|
||||
util/typo.php uses "php -l" insead of "eval()" to validate code (fabrixxm)
|
||||
util/typo.php uses "php -l" instead of "eval()" to validate code (fabrixxm)
|
||||
Use $_SERVER array in cli script instead of $argv/$argc (issue #1218) (annando)
|
||||
Updated vagrant setup script (silke)
|
||||
API: support to star/unstar items (fabrixxm)
|
||||
|
@ -2083,7 +2152,7 @@ Version 3.3.3 (2015-02-24)
|
|||
|
||||
Version 3.3.2 (2014-12-26)
|
||||
|
||||
Set default value for all not-null fields (fixes SQL warinigs) (annando)
|
||||
Set default value for all not-null fields (fixes SQL warnings) (annando)
|
||||
Fix item filters in network page (issue #1222) (fabrixxm)
|
||||
Remove reference to an ex Friendica hub from documentation (beardyunixer, tobiasd)
|
||||
API throttling (annando)
|
||||
|
@ -2129,7 +2198,7 @@ Version 3.3 (2014-10-06)
|
|||
|
||||
Interaction
|
||||
ignoring of threads
|
||||
for selected contects one can now get notifications when they post something, useful e.g. for forums
|
||||
for selected contacts one can now get notifications when they post something, useful e.g. for forums
|
||||
After a new friendica contact is added, the user is directed to the contact page of the new contact. (Instead of the remote profile)
|
||||
many improvement on all connectors, new app.net connector
|
||||
the algorithm for shortening postings when posting to limited platforms was improved
|
||||
|
@ -2141,7 +2210,7 @@ Version 3.3 (2014-10-06)
|
|||
updated the following libraries: smarty 3.1.19, fullcalendar 1.6.4, jquery 1.11, jgrowl 1.3.0
|
||||
added modernizer 2.8.3, better browser support
|
||||
updates to the DB structure for better performance
|
||||
preperations to use PDO in a later release
|
||||
preparations to use PDO in a later release
|
||||
new notification system
|
||||
web interface translations updated, addon translations now also possible separately from the main UI and done for CS, IT, RO, DE
|
||||
vagrant support added for developers
|
||||
|
@ -2179,7 +2248,7 @@ Version 3.2
|
|||
small fixed
|
||||
edit profile photo link
|
||||
better caching of pictures
|
||||
threadening for outgoing emails
|
||||
threading for outgoing emails
|
||||
mail import
|
||||
oembed thumbnails
|
||||
SN subscriptions & more SN like behaviour if snautofollow addon is used
|
||||
|
@ -2199,7 +2268,7 @@ Version 3.2
|
|||
improving the install.php script
|
||||
addons now can be members only
|
||||
item object now contains the "edited" information left for the theme designers to show this info in a pretty way
|
||||
improvments to the user-import from exported account files
|
||||
improvements to the user-import from exported account files
|
||||
It's now possible to authenticate an ejabberd server against friendica.
|
||||
bugtracker moved to github
|
||||
improvements to MySQL queries
|
||||
|
|
15
CREDITS.txt
|
@ -74,8 +74,11 @@ CrystalStiletto
|
|||
Cyboulette
|
||||
Cyryl Sochacki
|
||||
czarnystokrotek
|
||||
daingewuvzeevisiddfddd
|
||||
Damian Wajer
|
||||
Damien Goutte-Gattat
|
||||
Daniel Dupriest
|
||||
Daniel Siepmann
|
||||
Daria Początek
|
||||
David
|
||||
David Martín Miranda
|
||||
|
@ -101,6 +104,7 @@ erik
|
|||
Erkan Yilmaz
|
||||
Eugene Veresk
|
||||
Extarys
|
||||
F1per 3y
|
||||
Fabian Dost
|
||||
Fabio Comuni
|
||||
Farida Khalaf
|
||||
|
@ -126,6 +130,7 @@ GunChleoc
|
|||
guzzisti
|
||||
Haakon Meland Eriksen
|
||||
Hank Grabowski
|
||||
Hannes Heute
|
||||
Hans Meine
|
||||
Hauke
|
||||
Hauke Altmann
|
||||
|
@ -138,7 +143,7 @@ Ilmari
|
|||
ImgBotApp
|
||||
irhen
|
||||
Jakob
|
||||
Jakobus Schürz (admin)
|
||||
Jakob Schürz
|
||||
Jens Tautenhahn
|
||||
jensp
|
||||
Jeroen De Meerleer
|
||||
|
@ -153,6 +158,7 @@ John Mortensen
|
|||
Jonatan Nyberg
|
||||
Jonny Tischbein
|
||||
Josef Moravek
|
||||
Josh Soref
|
||||
juanman
|
||||
julia.domagalska
|
||||
Julio Cova
|
||||
|
@ -185,6 +191,7 @@ Marcin Klessa
|
|||
Marcin Mikołajczak
|
||||
Marcus Müller
|
||||
Marek Bachmann
|
||||
MarekBenjamin
|
||||
Marie Olive
|
||||
Mariusz Pisz
|
||||
marmor
|
||||
|
@ -209,6 +216,7 @@ mytbk
|
|||
nathilia-peirce
|
||||
Nicola Spanti
|
||||
Nicolas Derive
|
||||
nnsrymni
|
||||
nobody
|
||||
nupplaPhil
|
||||
Olaf Conradi
|
||||
|
@ -227,6 +235,7 @@ Pavel Morozov
|
|||
PerigGouanvic
|
||||
peter
|
||||
Peter Liebetrau
|
||||
Petr Kučera
|
||||
peturisfeld
|
||||
Phigger Phigger
|
||||
Philipp
|
||||
|
@ -244,7 +253,7 @@ Rafael Kalachev
|
|||
Rain Hawk
|
||||
Rainulf Pineda
|
||||
Ralf Thees
|
||||
Ralph
|
||||
ralph van der honing
|
||||
Ratten
|
||||
rcmaniac
|
||||
RealKinetix
|
||||
|
@ -257,6 +266,7 @@ Rik 4
|
|||
RJ Madsen
|
||||
Roger Meyer
|
||||
Roland Häder
|
||||
Ruud Schilders
|
||||
rwa
|
||||
Ryan Voots
|
||||
S.Krumbholz
|
||||
|
@ -338,6 +348,7 @@ Wil Tur
|
|||
Wouter Broers
|
||||
Xiaofei Xu
|
||||
XMPPはいいぞ
|
||||
xundeenergie
|
||||
Yasen Pramatarov
|
||||
Yasmine A
|
||||
ylms
|
||||
|
|
12
README.md
|
@ -17,18 +17,18 @@ Have a look at the [installation documentation](doc/Install.md) for further info
|
|||
|
||||
### Friendica Screenshots
|
||||
|
||||
| ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profle-1.png?raw=true "Frio theme in mobile browser") ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profle-2.png?raw=true "Frio theme in mobile browser")
|
||||
| ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profile-1.png?raw=true "Frio theme in mobile browser") ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profile-2.png?raw=true "Frio theme in mobile browser")
|
||||
|:--:|
|
||||
|*Frio theme, mobile browser. Timeline and composer view.*|
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profle-1.png?raw=true "Frio theme in desktop browser")
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profile-1.png?raw=true "Frio theme in desktop browser")
|
||||
|*Frio theme, desktop browser. Timeline view, contact info popped up, control menu open.*|
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profle-2.png?raw=true "Frio theme in desktop browser")
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profile-2.png?raw=true "Frio theme in desktop browser")
|
||||
|*Frio theme, desktop browser. Menu open for controlling individual posts.*|
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profle-3.png?raw=true "Frio theme in desktop browser")
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-3.png?raw=true "Frio theme in desktop browser")
|
||||
|*Frio theme, desktop browser. Profile view, notification menu open.*|
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profle-2.png?raw=true "Frio theme in desktop browser")
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-2.png?raw=true "Frio theme in desktop browser")
|
||||
|*Number of new posts, in total and by group.*|
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profle-1.png?raw=true "Frio theme in desktop browser")
|
||||
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-1.png?raw=true "Frio theme in desktop browser")
|
||||
|*Calender with popup of event.*|
|
||||
|![Frio theme default colour in standard browser on tablet](images/screenshots/friendica-frio-default-profile-1.png?raw=true "Frio theme default colour in standard browser on tablet")
|
||||
|*Notifications menu and private messages counter, standard browser on tablet.*|
|
||||
|
|
2
VERSION
|
@ -1 +1 @@
|
|||
2023.01
|
||||
2023.03-rc
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -82,6 +82,10 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['auth_ejabb
|
|||
|
||||
\Friendica\DI::init($dice);
|
||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
||||
|
||||
// Check the database structure and possibly fixes it
|
||||
\Friendica\Core\Update::check(\Friendica\DI::basePath(), true);
|
||||
|
||||
$appMode = $dice->create(Mode::class);
|
||||
|
||||
if ($appMode->isNormal()) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
dir=$(cd "${0%[/\\]*}" > /dev/null; pwd)
|
||||
|
||||
if [[ -d /proc/cygdrive && $(which php) == $(readlink -n /proc/cygdrive)/* ]]; then
|
||||
# We are in Cgywin using Windows php, so the path must be translated
|
||||
# We are in Cygwin using Windows php, so the path must be translated
|
||||
dir=$(cygpath -m "$dir");
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -33,6 +33,7 @@ if (php_sapi_name() !== 'cli') {
|
|||
use Dice\Dice;
|
||||
use Friendica\App\Mode;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Update;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
|
@ -63,7 +64,6 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['daemon']])
|
|||
|
||||
DI::init($dice);
|
||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
||||
$a = DI::app();
|
||||
|
||||
if (DI::mode()->isInstall()) {
|
||||
die("Friendica isn't properly installed yet.\n");
|
||||
|
@ -71,7 +71,7 @@ if (DI::mode()->isInstall()) {
|
|||
|
||||
DI::mode()->setExecutor(Mode::DAEMON);
|
||||
|
||||
DI::config()->load();
|
||||
DI::config()->reload();
|
||||
|
||||
if (empty(DI::config()->get('system', 'pidfile'))) {
|
||||
die(<<<TXT
|
||||
|
@ -115,7 +115,7 @@ if (is_readable($pidfile)) {
|
|||
}
|
||||
|
||||
if (empty($pid) && in_array($mode, ['stop', 'status'])) {
|
||||
DI::config()->set('system', 'worker_daemon_mode', false);
|
||||
DI::keyValue()->set('worker_daemon_mode', false);
|
||||
die("Pidfile wasn't found. Is the daemon running?\n");
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ if ($mode == 'status') {
|
|||
|
||||
unlink($pidfile);
|
||||
|
||||
DI::config()->set('system', 'worker_daemon_mode', false);
|
||||
DI::keyValue()->set('worker_daemon_mode', false);
|
||||
die("Daemon process $pid isn't running.\n");
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ if ($mode == 'stop') {
|
|||
|
||||
Logger::notice('Worker daemon process was killed', ['pid' => $pid]);
|
||||
|
||||
DI::config()->set('system', 'worker_daemon_mode', false);
|
||||
DI::keyValue()->set('worker_daemon_mode', false);
|
||||
die("Worker daemon process $pid was killed.\n");
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ if (!$foreground) {
|
|||
DBA::connect();
|
||||
}
|
||||
|
||||
DI::config()->set('system', 'worker_daemon_mode', true);
|
||||
DI::keyValue()->set('worker_daemon_mode', true);
|
||||
|
||||
// Just to be sure that this script really runs endlessly
|
||||
set_time_limit(0);
|
||||
|
@ -193,6 +193,9 @@ $last_cron = 0;
|
|||
|
||||
// Now running as a daemon.
|
||||
while (true) {
|
||||
// Check the database structure and possibly fixes it
|
||||
Update::check(DI::basePath(), true);
|
||||
|
||||
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
|
||||
Logger::info('Forcing cron worker call.', ['pid' => $pid]);
|
||||
$do_cron = true;
|
||||
|
@ -244,5 +247,6 @@ while (true) {
|
|||
}
|
||||
|
||||
function shutdown() {
|
||||
posix_kill(posix_getpid(), SIGTERM);
|
||||
posix_kill(posix_getpid(), SIGHUP);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ function show_syntax() {
|
|||
echo -e "\t\"testfile\" is the name of a test file, for example lib/template.php" >&2
|
||||
echo -e "\nDatabase environment variables:\n" >&2
|
||||
echo -e "\t\"MYSQL_HOST\" Mysql Hostname (Default: localhost)" >&2
|
||||
echo -e "\t\"MYSQL_USDRNAME\" Mysql Username (Default: friendica)" >&2
|
||||
echo -e "\t\"MYSQL_USERNAME\" Mysql Username (Default: friendica)" >&2
|
||||
echo -e "\t\"MYSQL_DATABASE\" Mysql Database (Default: test)" >&2
|
||||
echo -e "\nOther environment variables:\n" >&2
|
||||
echo -e "\t\"TEST_SELECTION\" test a specific group of tests, can be one of: $TESTS" >&2
|
||||
|
@ -65,7 +65,7 @@ else
|
|||
exit 3
|
||||
fi
|
||||
|
||||
echo "Installing depdendencies"
|
||||
echo "Installing dependencies"
|
||||
${PHP} "$COMPOSER" install
|
||||
|
||||
PHPUNIT="${BASEDIR}/vendor/bin/phpunit"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -58,20 +58,17 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['worker']])
|
|||
|
||||
DI::init($dice);
|
||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
||||
$a = DI::app();
|
||||
|
||||
DI::mode()->setExecutor(Mode::WORKER);
|
||||
|
||||
// Check the database structure and possibly fixes it
|
||||
Update::check($a->getBasePath(), true, DI::mode());
|
||||
Update::check(DI::basePath(), true);
|
||||
|
||||
// Quit when in maintenance
|
||||
if (!DI::mode()->has(App\Mode::MAINTENANCEDISABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DI::baseUrl()->saveByURL(DI::config()->get('system', 'url'));
|
||||
|
||||
$spawn = array_key_exists('s', $options) || array_key_exists('spawn', $options);
|
||||
|
||||
if ($spawn) {
|
||||
|
|
|
@ -24,15 +24,19 @@
|
|||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-posix": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"asika/simple-console": "^1.0",
|
||||
"bacon/bacon-qr-code": "^2.0.0",
|
||||
"divineomega/password_exposed": "^2.8",
|
||||
"enyo/dropzone": "^5.9",
|
||||
"ezyang/htmlpurifier": "^4.7",
|
||||
"friendica/json-ld": "^1.0",
|
||||
"geekwright/po": "^2.0",
|
||||
"guzzlehttp/guzzle": "^6.5",
|
||||
"guzzlehttp/oauth-subscriber": "^0.6",
|
||||
"kornrunner/blurhash": "^1.2",
|
||||
"league/html-to-markdown": "^4.8",
|
||||
"level-2/dice": "^4",
|
||||
"lightopenid/lightopenid": "dev-master",
|
||||
|
@ -48,6 +52,7 @@
|
|||
"phpseclib/phpseclib": "^3.0",
|
||||
"pragmarx/google2fa": "^5.0",
|
||||
"pragmarx/recovery": "^0.2",
|
||||
"psr/clock": "^1.0",
|
||||
"psr/container": "^1.0",
|
||||
"psr/log": "^1.1",
|
||||
"seld/cli-prompt": "^1.0",
|
||||
|
@ -70,9 +75,7 @@
|
|||
"npm-asset/moment": "^2.24",
|
||||
"npm-asset/perfect-scrollbar": "0.6.16",
|
||||
"npm-asset/textcomplete": "^0.18.2",
|
||||
"npm-asset/typeahead.js": "^0.11.1",
|
||||
"kornrunner/blurhash": "^1.2",
|
||||
"psr/clock": "^1.0"
|
||||
"npm-asset/typeahead.js": "^0.11.1"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
|
@ -132,7 +135,13 @@
|
|||
"test": "phpunit",
|
||||
"lint": "find . -name \\*.php -not -path './vendor/*' -not -path './view/asset/*' -print0 | xargs -0 -n1 php -l",
|
||||
"cs:install": "@composer install --working-dir=bin/dev/php-cs-fixer",
|
||||
"cs:check": ["@cs:install", "bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --diff"],
|
||||
"cs:fix": ["@cs:install", "bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix"]
|
||||
"cs:check": [
|
||||
"@cs:install",
|
||||
"bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --diff"
|
||||
],
|
||||
"cs:fix": [
|
||||
"@cs:install",
|
||||
"bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
468
composer.lock
generated
|
@ -40,5 +40,6 @@ return [
|
|||
'system' => [
|
||||
'default_timezone' => 'UTC',
|
||||
'language' => 'en',
|
||||
'url' => 'https://friendica.local',
|
||||
],
|
||||
];
|
||||
|
|
84
database.sql
|
@ -1,6 +1,6 @@
|
|||
-- ------------------------------------------
|
||||
-- Friendica 2022.12 (Giant Rhubarb)
|
||||
-- DB_UPDATE_VERSION 1502
|
||||
-- Friendica 2023.03-rc (Giant Rhubarb)
|
||||
-- DB_UPDATE_VERSION 1518
|
||||
-- ------------------------------------------
|
||||
|
||||
|
||||
|
@ -34,6 +34,7 @@ CREATE TABLE IF NOT EXISTS `gserver` (
|
|||
`last_poco_query` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`last_contact` datetime DEFAULT '0001-01-01 00:00:00' COMMENT 'Last successful connection request',
|
||||
`last_failure` datetime DEFAULT '0001-01-01 00:00:00' COMMENT 'Last failed connection request',
|
||||
`blocked` boolean COMMENT 'Server is blocked',
|
||||
`failed` boolean COMMENT 'Connection failed',
|
||||
`next_contact` datetime DEFAULT '0001-01-01 00:00:00' COMMENT 'Next connection request',
|
||||
PRIMARY KEY(`id`),
|
||||
|
@ -70,7 +71,7 @@ CREATE TABLE IF NOT EXISTS `user` (
|
|||
`verified` boolean NOT NULL DEFAULT '0' COMMENT 'user is verified through email',
|
||||
`blocked` boolean NOT NULL DEFAULT '0' COMMENT '1 for user is blocked',
|
||||
`blockwall` boolean NOT NULL DEFAULT '0' COMMENT 'Prohibit contacts to post to the profile page of the user',
|
||||
`hidewall` boolean NOT NULL DEFAULT '0' COMMENT 'Hide profile details from unkown viewers',
|
||||
`hidewall` boolean NOT NULL DEFAULT '0' COMMENT 'Hide profile details from unknown viewers',
|
||||
`blocktags` boolean NOT NULL DEFAULT '0' COMMENT 'Prohibit contacts to tag the post of this user',
|
||||
`unkmail` boolean NOT NULL DEFAULT '0' COMMENT 'Permit unknown people to send private mails to this user',
|
||||
`cntunkmail` int unsigned NOT NULL DEFAULT 10 COMMENT '',
|
||||
|
@ -339,22 +340,6 @@ CREATE TABLE IF NOT EXISTS `account-user` (
|
|||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Remote and local accounts';
|
||||
|
||||
--
|
||||
-- TABLE addon
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `addon` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT '',
|
||||
`name` varchar(50) NOT NULL DEFAULT '' COMMENT 'addon base (file)name',
|
||||
`version` varchar(50) NOT NULL DEFAULT '' COMMENT 'currently unused',
|
||||
`installed` boolean NOT NULL DEFAULT '0' COMMENT 'currently always 1',
|
||||
`hidden` boolean NOT NULL DEFAULT '0' COMMENT 'currently unused',
|
||||
`timestamp` int unsigned NOT NULL DEFAULT 0 COMMENT 'file timestamp to check for reloads',
|
||||
`plugin_admin` boolean NOT NULL DEFAULT '0' COMMENT '1 = has admin config, 0 = has no admin config',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `installed_name` (`installed`,`name`),
|
||||
UNIQUE INDEX `name` (`name`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='registered addons';
|
||||
|
||||
--
|
||||
-- TABLE apcontact
|
||||
--
|
||||
|
@ -499,8 +484,8 @@ CREATE TABLE IF NOT EXISTS `cache` (
|
|||
--
|
||||
CREATE TABLE IF NOT EXISTS `config` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT '',
|
||||
`cat` varbinary(50) NOT NULL DEFAULT '' COMMENT '',
|
||||
`k` varbinary(50) NOT NULL DEFAULT '' COMMENT '',
|
||||
`cat` varbinary(50) NOT NULL DEFAULT '' COMMENT 'The category of the entry',
|
||||
`k` varbinary(50) NOT NULL DEFAULT '' COMMENT 'The key of the entry',
|
||||
`v` mediumtext COMMENT '',
|
||||
PRIMARY KEY(`id`),
|
||||
UNIQUE INDEX `cat_k` (`cat`,`k`)
|
||||
|
@ -579,6 +564,27 @@ CREATE TABLE IF NOT EXISTS `delayed-post` (
|
|||
FOREIGN KEY (`wid`) REFERENCES `workerqueue` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Posts that are about to be distributed at a later time';
|
||||
|
||||
--
|
||||
-- TABLE delivery-queue
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `delivery-queue` (
|
||||
`gsid` int unsigned NOT NULL COMMENT 'Target server',
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Delivered post',
|
||||
`created` datetime COMMENT '',
|
||||
`command` varbinary(32) COMMENT '',
|
||||
`cid` int unsigned COMMENT 'Target contact',
|
||||
`uid` mediumint unsigned COMMENT 'Delivering user',
|
||||
`failed` tinyint DEFAULT 0 COMMENT 'Number of times the delivery has failed',
|
||||
PRIMARY KEY(`uri-id`,`gsid`),
|
||||
INDEX `gsid_created` (`gsid`,`created`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `cid` (`cid`),
|
||||
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Delivery data for posts for the batch processing';
|
||||
|
||||
--
|
||||
-- TABLE diaspora-contact
|
||||
--
|
||||
|
@ -602,7 +608,7 @@ CREATE TABLE IF NOT EXISTS `diaspora-contact` (
|
|||
`gsid` int unsigned COMMENT 'Global Server ID',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`interacting_count` int unsigned DEFAULT 0 COMMENT 'Number of contacts this contact interactes with',
|
||||
`interacting_count` int unsigned DEFAULT 0 COMMENT 'Number of contacts this contact interacts with',
|
||||
`interacted_count` int unsigned DEFAULT 0 COMMENT 'Number of contacts that interacted with this contact',
|
||||
`post_count` int unsigned DEFAULT 0 COMMENT 'Number of posts and comments',
|
||||
PRIMARY KEY(`uri-id`),
|
||||
|
@ -803,6 +809,7 @@ CREATE TABLE IF NOT EXISTS `inbox-entry-receiver` (
|
|||
CREATE TABLE IF NOT EXISTS `inbox-status` (
|
||||
`url` varbinary(383) NOT NULL COMMENT 'URL of the inbox',
|
||||
`uri-id` int unsigned COMMENT 'Item-uri id of inbox url',
|
||||
`gsid` int unsigned COMMENT 'ID of the related server',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Creation date of this entry',
|
||||
`success` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last successful delivery',
|
||||
`failure` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last failed delivery',
|
||||
|
@ -811,7 +818,9 @@ CREATE TABLE IF NOT EXISTS `inbox-status` (
|
|||
`shared` boolean NOT NULL DEFAULT '0' COMMENT 'Is it a shared inbox?',
|
||||
PRIMARY KEY(`url`),
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
INDEX `gsid` (`gsid`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Status of ActivityPub inboxes';
|
||||
|
||||
--
|
||||
|
@ -839,6 +848,16 @@ CREATE TABLE IF NOT EXISTS `intro` (
|
|||
FOREIGN KEY (`suggest-cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
|
||||
|
||||
--
|
||||
-- TABLE key-value
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `key-value` (
|
||||
`k` varbinary(50) NOT NULL COMMENT '',
|
||||
`v` mediumtext COMMENT '',
|
||||
`updated_at` int unsigned NOT NULL COMMENT 'timestamp of the last update',
|
||||
PRIMARY KEY(`k`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='A key value storage';
|
||||
|
||||
--
|
||||
-- TABLE locks
|
||||
--
|
||||
|
@ -861,7 +880,7 @@ CREATE TABLE IF NOT EXISTS `mail` (
|
|||
`guid` varbinary(255) NOT NULL DEFAULT '' COMMENT 'A unique identifier for this private message',
|
||||
`from-name` varchar(255) NOT NULL DEFAULT '' COMMENT 'name of the sender',
|
||||
`from-photo` varbinary(383) NOT NULL DEFAULT '' COMMENT 'contact photo link of the sender',
|
||||
`from-url` varbinary(383) NOT NULL DEFAULT '' COMMENT 'profile linke of the sender',
|
||||
`from-url` varbinary(383) NOT NULL DEFAULT '' COMMENT 'profile link of the sender',
|
||||
`contact-id` varbinary(255) COMMENT 'contact.id',
|
||||
`author-id` int unsigned COMMENT 'Link to the contact table with uid=0 of the author of the mail',
|
||||
`convid` int unsigned COMMENT 'conv.id',
|
||||
|
@ -1439,7 +1458,7 @@ CREATE TABLE IF NOT EXISTS `post-user` (
|
|||
`event-id` int unsigned COMMENT 'Used to link to the event.id',
|
||||
`unseen` boolean NOT NULL DEFAULT '1' COMMENT 'post has not been seen',
|
||||
`hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide the post from the user',
|
||||
`notification-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`notification-type` smallint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`wall` boolean NOT NULL DEFAULT '0' COMMENT 'This item was posted to the wall of uid',
|
||||
`origin` boolean NOT NULL DEFAULT '0' COMMENT 'item originated at this site',
|
||||
`psid` int unsigned COMMENT 'ID of the permission set of this post',
|
||||
|
@ -1551,7 +1570,7 @@ CREATE TABLE IF NOT EXISTS `post-user-notification` (
|
|||
--
|
||||
CREATE TABLE IF NOT EXISTS `process` (
|
||||
`pid` int unsigned NOT NULL COMMENT 'The ID of the process',
|
||||
`hostname` varchar(32) NOT NULL COMMENT 'The name of the host the process is ran on',
|
||||
`hostname` varchar(255) NOT NULL COMMENT 'The name of the host the process is ran on',
|
||||
`command` varbinary(32) NOT NULL DEFAULT '' COMMENT '',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
PRIMARY KEY(`pid`,`hostname`),
|
||||
|
@ -1674,15 +1693,20 @@ CREATE TABLE IF NOT EXISTS `register` (
|
|||
CREATE TABLE IF NOT EXISTS `report` (
|
||||
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
|
||||
`uid` mediumint unsigned COMMENT 'Reporting user',
|
||||
`reporter-id` int unsigned COMMENT 'Reporting contact',
|
||||
`cid` int unsigned NOT NULL COMMENT 'Reported contact',
|
||||
`comment` text COMMENT 'Report',
|
||||
`category` varchar(20) COMMENT 'Category of the report (spam, violation, other)',
|
||||
`rules` text COMMENT 'Violated rules',
|
||||
`forward` boolean COMMENT 'Forward the report to the remote server',
|
||||
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
|
||||
`status` tinyint unsigned COMMENT 'Status of the report',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `cid` (`cid`),
|
||||
INDEX `reporter-id` (`reporter-id`),
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`reporter-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
|
||||
|
||||
|
@ -2825,7 +2849,9 @@ CREATE VIEW `account-view` AS SELECT
|
|||
`apcontact`.`statuses_count` AS `ap-statuses_count`,
|
||||
`gserver`.`site_name` AS `site_name`,
|
||||
`gserver`.`platform` AS `platform`,
|
||||
`gserver`.`version` AS `version`
|
||||
`gserver`.`version` AS `version`,
|
||||
`gserver`.`blocked` AS `server-blocked`,
|
||||
`gserver`.`failed` AS `server-failed`
|
||||
FROM `contact`
|
||||
LEFT JOIN `item-uri` ON `item-uri`.`id` = `contact`.`uri-id`
|
||||
LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `contact`.`uri-id`
|
||||
|
@ -2929,7 +2955,9 @@ CREATE VIEW `account-user-view` AS SELECT
|
|||
`apcontact`.`statuses_count` AS `ap-statuses_count`,
|
||||
`gserver`.`site_name` AS `site_name`,
|
||||
`gserver`.`platform` AS `platform`,
|
||||
`gserver`.`version` AS `version`
|
||||
`gserver`.`version` AS `version`,
|
||||
`gserver`.`blocked` AS `server-blocked`,
|
||||
`gserver`.`failed` AS `server-failed`
|
||||
FROM `contact` AS `ucontact`
|
||||
INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0
|
||||
LEFT JOIN `item-uri` ON `item-uri`.`id` = `ucontact`.`uri-id`
|
||||
|
|
|
@ -908,6 +908,13 @@ Identical to [the Twitter Media Object](https://developer.twitter.com/en/docs/tw
|
|||
<td>Resource ID (32 hex chars)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>media-id</code></td>
|
||||
<td>String (Integer) </td>
|
||||
<td>ID used for attaching images to a Mastodon Post Status</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><code>created</code></td>
|
||||
<td>String (Date)</td>
|
||||
|
@ -1001,6 +1008,14 @@ Mutually exclusive with <code>data</code> <code>datasize</code>.
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>scales</code></td>
|
||||
<td>Array of Photo Scales</td>
|
||||
<td>
|
||||
List of the various resized versions of the Photo
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>datasize</code></td>
|
||||
<td>Integer</td>
|
||||
|
@ -1040,6 +1055,58 @@ Mutually exclusive with <code>link</code>.
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
## Photo Scale
|
||||
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute</th>
|
||||
<th>Type</th>
|
||||
<th align="center">Nullable</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td><code>id</code></td>
|
||||
<td>String (Integer)</td>
|
||||
<td>Row ID of this photo scale</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>scale</code></td>
|
||||
<td>Integer</td>
|
||||
<td>Scale number</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>link</code></td>
|
||||
<td>String (URL)</td>
|
||||
<td>URL to this scale's image</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>height</code></td>
|
||||
<td>Integer</td>
|
||||
<td>Image height in pixels</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>width</code></td>
|
||||
<td>Integer</td>
|
||||
<td>Image width in pixels</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>size</code></td>
|
||||
<td>Integer</td>
|
||||
<td>Image size in bytes</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Photo List Item
|
||||
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
|
@ -1103,6 +1170,40 @@ Mutually exclusive with <code>link</code>.
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Photo Album
|
||||
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td><code>name</code></td>
|
||||
<td>String</td>
|
||||
<td>The name of the photo album</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>created</code></td>
|
||||
<td>String (Date)</td>
|
||||
<td>The creation date of the album. Format <code>YYYY-MM-DD HH:MM:SS</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>count</code></td>
|
||||
<td>Integer</td>
|
||||
<td>The number of images in the album</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Private message
|
||||
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
|
|
|
@ -163,7 +163,7 @@ Add or remove an activity from an item.
|
|||
* `attendmaybe`
|
||||
|
||||
To remove an activity, prepend the verb with "un", eg. "unlike" or "undislike"
|
||||
Attend verbs disable eachother: that means that if "attendyes" was added to an item, adding "attendno" remove previous "attendyes".
|
||||
Attend verbs disable each other: that means that if "attendyes" was added to an item, adding "attendno" remove previous "attendyes".
|
||||
Attend verbs should be used only with event-related items (there is no check at the moment).
|
||||
|
||||
#### Parameters
|
||||
|
@ -305,7 +305,7 @@ Returns [Private Messages](help/API-Entities#Private+message) matching the provi
|
|||
#### Parameters
|
||||
|
||||
* `searchstring`: string for which the API call should search as '%searchstring%' in field 'body' of all messages of the authenticated user (caption ignored)
|
||||
* `getText` (optional): `plain`|`html` If ommited, the title is prepended to the plaintext body in the `text` attribute of the private message objects.
|
||||
* `getText` (optional): `plain`|`html` If omitted, the title is prepended to the plaintext body in the `text` attribute of the private message objects.
|
||||
* `getUserObjects` (optional): `true`|`false` If `false`, the `sender` and `recipient` attributes of the private message object are absent.
|
||||
|
||||
#### Return values
|
||||
|
@ -646,7 +646,7 @@ On error:
|
|||
|
||||
* 403 FORBIDDEN: if not authenticated
|
||||
* 400 BADREQUEST: "no albumname specified", "album not available"
|
||||
* 500 INTERNALSERVERERROR: "problem with deleting item occured", "unknown error - deleting from database failed"
|
||||
* 500 INTERNALSERVERERROR: "problem with deleting item occurred", "unknown error - deleting from database failed"
|
||||
|
||||
### POST api/friendica/photoalbum/update
|
||||
|
||||
|
@ -676,8 +676,92 @@ On error:
|
|||
* 400 BADREQUEST: "no albumname specified", "no new albumname specified", "album not available"
|
||||
* 500 INTERNALSERVERERROR: "unknown error - updating in database failed"
|
||||
|
||||
### GET api/friendica/photoalbums
|
||||
|
||||
Get a list of photo albums for the user
|
||||
|
||||
#### Parameters
|
||||
|
||||
None
|
||||
#### Return values
|
||||
|
||||
On success a list of photo album objects:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "Wall Photos",
|
||||
"created": "2023-01-22 02:03:19",
|
||||
"count": 4
|
||||
},
|
||||
{
|
||||
"name": "Profile photos",
|
||||
"created": "2022-11-20 14:40:06",
|
||||
"count": 1
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### GET api/friendica/photoalbum
|
||||
|
||||
Get a list of images in a photo album
|
||||
#### Parameters
|
||||
|
||||
* `album` (Required): name of the album to be deleted
|
||||
* `limit` (Optional): Maximum number of items to get, defaults to 50, max 500
|
||||
* `offset`(Optional): Offset in results to page through total items, defaults to 0
|
||||
* `latest_first` (Optional): Reverse the order so the most recent images are first, defaults to false
|
||||
|
||||
#### Return values
|
||||
|
||||
On success:
|
||||
|
||||
* JSON return with the list of Photo items
|
||||
|
||||
**Example:**
|
||||
`https://<server>/api/friendica/photoalbum?album=Wall Photos&limit=10&offset=2`
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"created": "2023-02-14 14:31:06",
|
||||
"edited": "2023-02-14 14:31:14",
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"album": "Wall Photos",
|
||||
"filename": "image.png",
|
||||
"type": "image/png",
|
||||
"height": 835,
|
||||
"width": 693,
|
||||
"datasize": 119523,
|
||||
"profile": 0,
|
||||
"allow_cid": "",
|
||||
"deny_cid": "",
|
||||
"allow_gid": "",
|
||||
"deny_gid": "",
|
||||
"id": "899184972463eb9b2ae3dc2580502826",
|
||||
"scale": 0,
|
||||
"media-id": 52,
|
||||
"scales": [
|
||||
{
|
||||
"id": 52,
|
||||
"scale": 0,
|
||||
"link": "https://<server>/photo/899184972463eb9b2ae3dc2580502826-0.png",
|
||||
"width": 693,
|
||||
"height": 835,
|
||||
"size": 119523
|
||||
},
|
||||
...
|
||||
],
|
||||
"thumb": "https://<server>/photo/899184972463eb9b2ae3dc2580502826-2.png"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
### GET api/friendica/profile/show
|
||||
|
||||
Returns the [Profile](help/API-Entities#Profile) data of the authenticated user.
|
||||
|
@ -715,6 +799,129 @@ General description of profile data in API returns:
|
|||
|
||||
---
|
||||
|
||||
### POST api/friendica/statuses/:id/dislike
|
||||
|
||||
Marks the given status as disliked by this user
|
||||
|
||||
#### Path Parameter
|
||||
|
||||
* `id`: the status ID that is being marked
|
||||
|
||||
#### Return values
|
||||
|
||||
A Mastodon [Status Entity](https://docs.joinmastodon.org/entities/Status/)
|
||||
|
||||
#### Example:
|
||||
`https://<server_name>/api/friendica/statuses/341/dislike`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "341",
|
||||
"created_at": "2023-02-23T01:50:00.000Z",
|
||||
"in_reply_to_id": null,
|
||||
"in_reply_to_status": null,
|
||||
"in_reply_to_account_id": null,
|
||||
"sensitive": false,
|
||||
"spoiler_text": "",
|
||||
"visibility": "public",
|
||||
"language": "en",
|
||||
...
|
||||
"account": {
|
||||
"id": "8",
|
||||
"username": "testuser2",
|
||||
...
|
||||
},
|
||||
"media_attachments": [],
|
||||
"mentions": [],
|
||||
"tags": [],
|
||||
"emojis": [],
|
||||
"card": null,
|
||||
"poll": null,
|
||||
"friendica": {
|
||||
"title": "",
|
||||
"dislikes_count": 1,
|
||||
"disliked": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### GET api/friendica/statuses/:id/disliked_by
|
||||
|
||||
Returns the list of accounts that have disliked the status as known by the current server
|
||||
|
||||
#### Path Parameter
|
||||
|
||||
* `id`: the status ID that is being marked
|
||||
|
||||
#### Return values
|
||||
|
||||
A list of [Mastodon Account](https://docs.joinmastodon.org/entities/Account/) objects
|
||||
in the body and next/previous link headers in the header
|
||||
|
||||
#### Example:
|
||||
`https://<server_name>/api/friendica/statuses/341/disliked_by`
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "6",
|
||||
"username": "testuser1",
|
||||
...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
|
||||
### POST api/friendica/statuses/:id/undislike
|
||||
|
||||
Removes the dislike mark (if it exists) on this status for this user
|
||||
|
||||
#### Path Parameter
|
||||
|
||||
* `id`: the status ID that is being marked
|
||||
|
||||
#### Return values
|
||||
|
||||
A Mastodon [Status Entity](https://docs.joinmastodon.org/entities/Status/)
|
||||
|
||||
#### Example:
|
||||
`https://<server_name>/api/friendica/statuses/341/undislike`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "341",
|
||||
"created_at": "2023-02-23T01:50:00.000Z",
|
||||
"in_reply_to_id": null,
|
||||
"in_reply_to_status": null,
|
||||
"in_reply_to_account_id": null,
|
||||
"sensitive": false,
|
||||
"spoiler_text": "",
|
||||
"visibility": "public",
|
||||
"language": "en",
|
||||
...
|
||||
"account": {
|
||||
"id": "8",
|
||||
"username": "testuser2",
|
||||
...
|
||||
},
|
||||
"media_attachments": [],
|
||||
"mentions": [],
|
||||
"tags": [],
|
||||
"emojis": [],
|
||||
"card": null,
|
||||
"poll": null,
|
||||
"friendica": {
|
||||
"title": "",
|
||||
"dislikes_count": 0,
|
||||
"disliked": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deprecated endpoints
|
||||
|
||||
- POST api/statuses/mediap
|
||||
|
|
|
@ -30,6 +30,101 @@ For supported apps please have a look at the [FAQ](help/FAQ#clients)
|
|||
## Entities
|
||||
|
||||
These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/entities/).
|
||||
With some additional extensions listed below.
|
||||
|
||||
### Instance (Version 2) Entities
|
||||
Extensions to the [Mastodon Instance::V2 Entities](https://docs.joinmastodon.org/entities/Instance/)
|
||||
* `friendica`: Friendica specific properties of the V2 Instance including:
|
||||
* `version`: The Friendica version string
|
||||
* `codename`: The Friendica version code name
|
||||
* `db_version`: The database schema version number
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"domain": "friendicadevtest1.myportal.social",
|
||||
"title": "Friendica Social Network",
|
||||
"version": "2.8.0 (compatible; Friendica 2023.03-dev)",
|
||||
...
|
||||
"friendica": {
|
||||
"version": "2023.03-dev",
|
||||
"codename": "Giant Rhubarb",
|
||||
"db_version": 1516
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Notification Entities
|
||||
Extensions to the [Mastodon Notification Entities](https://docs.joinmastodon.org/entities/Notification/)
|
||||
* `dismissed`: whether the object has been dismissed or not
|
||||
|
||||
### Status Entities
|
||||
Extensions to the [Mastodon Status Entities](https://docs.joinmastodon.org/entities/Status/)
|
||||
* `in_reply_to_status`: A fully populated Mastodon Status entity for the replied to status or null it is a post rather than a response
|
||||
* `friendica`: Friendica specific properties of a status including:
|
||||
* `title`: The Friendica title for a post, or empty if the status is a comment
|
||||
* `delivery_data`: Information about the state of federating a message from the server
|
||||
* `delivery_queue_count`: Total number of remote servers that the status needs to be federated to.
|
||||
* `delivery_queue_done`: Total number of remote servers that have successfully been federated to so far.
|
||||
* `delivery_queue_failed`: Total number of remote servers that have we failed to federate to so far.
|
||||
* `dislikes_count`: The number of dislikes that a status has accumulated according to the server.
|
||||
* `disliked`: Whether the API user disliked the status.
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"id": "358",
|
||||
"created_at": "2023-02-23T02:45:46.000Z",
|
||||
"in_reply_to_id": "356",
|
||||
"in_reply_to_status": {
|
||||
"id": "356",
|
||||
"created_at": "2023-02-23T02:45:35.000Z",
|
||||
"in_reply_to_id": null,
|
||||
"in_reply_to_status": null,
|
||||
"in_reply_to_account_id": null,
|
||||
...
|
||||
"content": "A post from testuser1",
|
||||
...
|
||||
"account": {
|
||||
"id": "6",
|
||||
"username": "testuser1",
|
||||
"acct": "testuser1",
|
||||
"display_name": "testuser1",
|
||||
...
|
||||
},
|
||||
...
|
||||
"friendica": {
|
||||
"title": "",
|
||||
"dislikes_count": 0
|
||||
}
|
||||
},
|
||||
"in_reply_to_account_id": "6",
|
||||
...
|
||||
"replies_count": 0,
|
||||
"reblogs_count": 0,
|
||||
"favourites_count": 0,
|
||||
...
|
||||
"content": "A reply from testuser2",
|
||||
...
|
||||
"account": {
|
||||
"id": "8",
|
||||
"username": "testuser2",
|
||||
"acct": "testuser2",
|
||||
"display_name": "testuser2",
|
||||
...
|
||||
},
|
||||
...
|
||||
"friendica": {
|
||||
"title": "",
|
||||
"delivery_data": {
|
||||
"delivery_queue_count": 10,
|
||||
"delivery_queue_done": 3,
|
||||
"delivery_queue_failed": 0
|
||||
},
|
||||
"dislikes_count": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Implemented endpoints
|
||||
|
||||
|
@ -73,8 +168,8 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
- `:id` is a follow request ID, not a regular account id
|
||||
- Returns a [Relationship](https://docs.joinmastodon.org/entities/relationship) object.
|
||||
|
||||
- [`GET /api/v1/followed_tags'](https://docs.joinmastodon.org/methods/followed_tags/)
|
||||
- [`GET /api/v1/instance`](https://docs.joinmastodon.org/methods/instance#fetch-instance)
|
||||
- [`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/peers`](https://docs.joinmastodon.org/methods/instance#list-of-connected-domains)
|
||||
- [`GET /api/v1/lists`](https://docs.joinmastodon.org/methods/timelines/lists/)
|
||||
|
@ -92,6 +187,10 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
- [`PUT /api/v1/media/:id`](https://docs.joinmastodon.org/methods/statuses/media/)
|
||||
- [`GET /api/v1/mutes`](https://docs.joinmastodon.org/methods/accounts/mutes/)
|
||||
- [`GET /api/v1/notifications`](https://docs.joinmastodon.org/methods/notifications/)
|
||||
- Additional field `include_all` to return read and unread statuses, defaults to `false`
|
||||
- Additional field `summary` returns a count of all of the statuses that match the type filter
|
||||
- Additional field `with_muted` Pleroma extension to return notifications from muted users, defaults to `false`
|
||||
- Does not support the `type` field, which is the mirror image of the supported `exclude_types` field
|
||||
- [`GET /api/v1/notifications/:id`](https://docs.joinmastodon.org/methods/notifications/)
|
||||
- [`POST /api/v1/notifications/clear`](https://docs.joinmastodon.org/methods/notifications/)
|
||||
- [`POST /api/v1/notifications/:id/dismiss`](https://docs.joinmastodon.org/methods/notifications/)
|
||||
|
@ -106,11 +205,22 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
- [`DELETE /api/v1/scheduled_statuses/:id`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
- [`GET /api/v1/scheduled_statuses/:id`](https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/)
|
||||
- [`GET /api/v1/search`](https://docs.joinmastodon.org/methods/search/)
|
||||
- [`PUT /api/v1/statuses`](https://docs.joinmastodon.org/methods/statuses/#edit)
|
||||
- Does not support `polls` argument as Friendica does not have polls
|
||||
- Additional fields `friendica` for Friendica specific parameters:
|
||||
- `title`: Explicitly sets the title for a post status, ignored if used on a comment status. For post statuses the legacy behavior is to use any "spoiler text" as the title if it is provided. If both the title and spoiler text are provided for a post status then they will each be used for their respective roles. If no title is provided then the legacy behavior will persist. If you want to create a post with no title but spoiler text then explicitly set the title but set it to an empty string `""`.
|
||||
- [`POST /api/v1/statuses`](https://docs.joinmastodon.org/methods/statuses/#create)
|
||||
- Does not support `polls` argument as Friendica does not have polls
|
||||
- Additionally to the static values `public`, `unlisted` and `private`, the `visibility` parameter can contain a numeric value with a group id.
|
||||
- Additional field `quote_id` for the post that is being quote reshared
|
||||
- Additional fields `friendica` for Friendica specific parameters:
|
||||
- `title`: Explicitly sets the title for a post status, ignored if used on a comment status. For post statuses the legacy behavior is to use any "spoiler text" as the title if it is provided. If both the title and spoiler text are provided for a post status then they will each be used for their respective roles. If no title is provided then the legacy behavior will persist. If you want to create a post with no title but spoiler text then explicitly set the title but set it to an empty string `""`.
|
||||
- [`GET /api/v1/statuses/:id`](https://docs.joinmastodon.org/methods/statuses/#get)
|
||||
- [`DELETE /api/v1/statuses/:id`](https://docs.joinmastodon.org/methods/statuses/#delete)
|
||||
- [`GET /api/v1/statuses/:id/context`](https://docs.joinmastodon.org/methods/statuses/#context)
|
||||
- Additional support for paging using `min_id`, `max_id`, `since_id` parameters
|
||||
- Additional support for previous/next Link Headers to support paging
|
||||
- Additional flag `show_all` to allow including posts from blocked and ignored/muted users, defaults to `false`
|
||||
- [`GET /api/v1/statuses/:id/reblogged_by`](https://docs.joinmastodon.org/methods/statuses/#reblogged_by)
|
||||
- [`GET /api/v1/statuses/:id/favourited_by`](https://docs.joinmastodon.org/methods/statuses/#favourited_by)
|
||||
- [`POST /api/v1/statuses/:id/favourite`](https://docs.joinmastodon.org/methods/statuses/#favourite)
|
||||
|
@ -132,19 +242,30 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
- [`GET /api/v1/tags/:id/unfollow`](https://docs.joinmastodon.org/methods/tags/#unfollow)
|
||||
- [`GET /api/v1/timelines/direct`](https://docs.joinmastodon.org/methods/timelines/)
|
||||
- [`GET /api/v1/timelines/home`](https://docs.joinmastodon.org/methods/timelines/)
|
||||
- Additional field `with_muted` Pleroma extension to return notifications from muted users, defaults to `false`
|
||||
- Additional field `exclude_replies` to only return post statuses not replies/comments, defaults to `false`
|
||||
- [`GET /api/v1/timelines/list/:id`](https://docs.joinmastodon.org/methods/timelines/)
|
||||
- Additional field `with_muted` Pleroma extension to return notifications from muted users, defaults to `false`
|
||||
- Additional field `exclude_replies` to only return post statuses not replies/comments, defaults to `false`
|
||||
- [`GET /api/v1/timelines/public`](https://docs.joinmastodon.org/methods/timelines/)
|
||||
- Additional field `with_muted` Pleroma extension to return notifications from muted users, defaults to `false`
|
||||
- Additional field `exclude_replies` to only return post statuses not replies/comments, defaults to `false`
|
||||
- [`GET /api/v1/timelines/tag/:hashtag`](https://docs.joinmastodon.org/methods/timelines/)
|
||||
- Additional field `with_muted` Pleroma extension to return notifications from muted users, defaults to `false`
|
||||
- Additional field `exclude_replies` to only return post statuses not replies/comments, defaults to `false`
|
||||
- Does not support the `any[]`, `all[]`, or `none[]` query parameters
|
||||
- [`GET /api/v1/trends`](https://docs.joinmastodon.org/methods/instance/trends/)
|
||||
- [`GET /api/v1/trends/links`](https://github.com/mastodon/mastodon/pull/16917)
|
||||
- [`GET /api/v1/trends/statuses`](https://docs.joinmastodon.org/methods/trends/#statuses)
|
||||
- [`GET /api/v1/trends/tags`](https://docs.joinmastodon.org/methods/trends/#tags)
|
||||
- Additional field `friendica_local` to return local trending tags instead of global tags, defaults to `false`
|
||||
- [`GET /api/v2/instance`](https://docs.joinmastodon.org/methods/instance/#v2)
|
||||
- [`GET /api/v2/search`](https://docs.joinmastodon.org/methods/search/)
|
||||
|
||||
|
||||
## Currently unimplemented endpoints
|
||||
|
||||
These emdpoints are planned to be implemented somewhere in the future.
|
||||
These endpoints are planned to be implemented somewhere in the future.
|
||||
|
||||
- [`POST /api/v1/accounts/:id/remove_from_followers`](https://github.com/mastodon/mastodon/pull/16864)
|
||||
- [`GET /api/v1/accounts/familiar_followers`](https://github.com/mastodon/mastodon/pull/17700)
|
||||
|
|
|
@ -10,7 +10,7 @@ Not all Friendica sites allow open registration.
|
|||
If registration is allowed, you will see a "Register" link immediately below the login prompt on the site's home page.
|
||||
Following this link will take you to the site registration page.
|
||||
The strength of our network is that lots of different sites are all completely compatible with each other.
|
||||
If the site you're visting doesn't allow registration, or you think you might prefer another one, there is a [list of public servers here](https://dir.friendica.social/servers) and hopefully you will find one that meets your needs.
|
||||
If the site you're visiting doesn't allow registration, or you think you might prefer another one, there is a [list of public servers here](https://dir.friendica.social/servers) and hopefully you will find one that meets your needs.
|
||||
|
||||
If you'd like to have your own server, you can do that too.
|
||||
Visit [the Friendica website](http://friendi.ca/) to download the code with setup instructions.
|
||||
|
|
|
@ -100,7 +100,7 @@ See doxygen documentation of `IWritableStorage` interface for details about each
|
|||
|
||||
## Register a storage backend class
|
||||
|
||||
Each backend must be registered in the system when the plugin is installed, to be aviable.
|
||||
Each backend must be registered in the system when the plugin is installed, to be available.
|
||||
|
||||
`DI::facStorage()->register(string $class)` is used to register the backend class.
|
||||
|
||||
|
@ -140,18 +140,18 @@ abstract class StorageTest
|
|||
|
||||
There are two intended types of exceptions for storages
|
||||
|
||||
### `ReferenceStorageExecption`
|
||||
### `ReferenceStorageException`
|
||||
|
||||
This storage exception should be used in case the caller tries to use an invalid references.
|
||||
This could happen in case the caller tries to delete or update an unknown reference.
|
||||
The implementation of the storage backend must not ignore invalid references.
|
||||
|
||||
Avoid throwing the common `StorageExecption` instead of the `ReferenceStorageException` at this particular situation!
|
||||
Avoid throwing the common `StorageException` instead of the `ReferenceStorageException` at this particular situation!
|
||||
|
||||
### `StorageException`
|
||||
|
||||
This is the common exception in case unexpected errors happen using the storage backend.
|
||||
If there's a predecessor to this exception (e.g. you caught an exception and are throwing this execption), you should add the predecessor for transparency reasons.
|
||||
If there's a predecessor to this exception (e.g. you caught an exception and are throwing this exception), you should add the predecessor for transparency reasons.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -320,7 +320,7 @@ The file is `addon/samplestorage/samplestorage.php`
|
|||
<?php
|
||||
/**
|
||||
* Name: Sample Storage Addon
|
||||
* Description: A sample addon which implements an unusefull storage backend
|
||||
* Description: A sample addon which implements a very limited storage backend
|
||||
* Version: 1.0.0
|
||||
* Author: Alice <https://alice.social/~alice>
|
||||
*/
|
||||
|
|
|
@ -44,7 +44,7 @@ Uninstalling an addon automatically unregisters any hook it registered, but if y
|
|||
|
||||
The install and uninstall functions will be called (i.e. re-installed) if the addon changes after installation.
|
||||
Therefore your uninstall should not destroy data and install should consider that data may already exist.
|
||||
Future extensions may provide for "setup" amd "remove".
|
||||
Future extensions may provide for "setup" and "remove".
|
||||
|
||||
## PHP addon hooks
|
||||
|
||||
|
@ -60,25 +60,14 @@ This *should* be 'addon/*addon_name*/*addon_name*.php' in most cases and can be
|
|||
`$function` is a string and is the name of the function which will be executed when the hook is called.
|
||||
|
||||
### Arguments
|
||||
Your hook callback functions will be called with at least one and possibly two arguments
|
||||
Your hook callback functions will be called with at most one argument
|
||||
|
||||
function <addon>_<hookname>(App $a, &$b) {
|
||||
function <addon>_<hookname>(&$b) {
|
||||
|
||||
}
|
||||
|
||||
If you wish to make changes to the calling data, you must declare them as reference variables (with `&`) during function declaration.
|
||||
|
||||
#### $a
|
||||
$a is the Friendica `App` class.
|
||||
It contains a wealth of information about the current state of Friendica:
|
||||
|
||||
* which module has been called,
|
||||
* configuration information,
|
||||
* the page contents at the point the hook was invoked,
|
||||
* profile and user information, etc.
|
||||
|
||||
It is recommeded you call this `$a` to match its usage elsewhere.
|
||||
|
||||
#### $b
|
||||
$b can be called anything you like.
|
||||
This is information specific to the hook currently being processed, and generally contains information that is being immediately processed or acted on that you can use, display, or alter.
|
||||
|
@ -88,7 +77,7 @@ Remember to declare it with `&` if you wish to alter it.
|
|||
|
||||
Your addon can provide user-specific settings via the `addon_settings` PHP hook, but it can also provide node-wide settings in the administration page of your addon.
|
||||
|
||||
Simply declare a `<addon>_addon_admin(App $a)` function to display the form and a `<addon>_addon_admin_post(App $a)` function to process the data from the form.
|
||||
Simply declare a `<addon>_addon_admin()` function to display the form and a `<addon>_addon_admin_post()` function to process the data from the form.0
|
||||
|
||||
## Global stylesheets
|
||||
|
||||
|
@ -102,7 +91,7 @@ function <addon>_install()
|
|||
}
|
||||
|
||||
|
||||
function <addon>_head(App $a)
|
||||
function <addon>_head()
|
||||
{
|
||||
\Friendica\DI::page()->registerStylesheet(__DIR__ . '/relative/path/to/addon/stylesheet.css');
|
||||
}
|
||||
|
@ -124,7 +113,7 @@ function <addon>_install()
|
|||
...
|
||||
}
|
||||
|
||||
function <addon>_footer(App $a)
|
||||
function <addon>_footer()
|
||||
{
|
||||
\Friendica\DI::page()->registerFooterScript(__DIR__ . '/relative/path/to/addon/script.js');
|
||||
}
|
||||
|
@ -135,7 +124,7 @@ function <addon>_footer(App $a)
|
|||
### JavaScript hooks
|
||||
|
||||
The main Friendica script provides hooks via events dispatched on the `document` property.
|
||||
In your Javascript file included as described above, add your event listener like this:
|
||||
In your JavaScript file included as described above, add your event listener like this:
|
||||
|
||||
```js
|
||||
document.addEventListener(name, callback);
|
||||
|
@ -144,7 +133,7 @@ document.addEventListener(name, callback);
|
|||
- *name* is the name of the hook and corresponds to a known Friendica JavaScript hook.
|
||||
- *callback* is a JavaScript anonymous function to execute.
|
||||
|
||||
More info about Javascript event listeners: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
|
||||
More info about JavaScript event listeners: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
|
||||
|
||||
#### Current JavaScript hooks
|
||||
|
||||
|
@ -167,9 +156,9 @@ DI::args()->get(1); // = 'arg1'
|
|||
DI::args()->get(2); // = 'arg2'
|
||||
```
|
||||
|
||||
To display a module page, you need to declare the function `<addon>_content(App $a)`, which defines and returns the page body content.
|
||||
They may also contain `<addon>_post(App $a)` which is called before the `<addon>_content` function and typically handles the results of POST forms.
|
||||
You may also have `<addon>_init(App $a)` which is called before `<addon>_content` and should include common logic to your module.
|
||||
To display a module page, you need to declare the function `<addon>_content()`, which defines and returns the page body content.
|
||||
They may also contain `<addon>_post()` which is called before the `<addon>_content` function and typically handles the results of POST forms.
|
||||
You may also have `<addon>_init()` which is called before `<addon>_content` and should include common logic to your module.
|
||||
|
||||
## Templates
|
||||
|
||||
|
@ -209,7 +198,7 @@ Called when a user attempts to login.
|
|||
|
||||
### logged_in
|
||||
Called after a user has successfully logged in.
|
||||
`$b` contains the `$a->user` array.
|
||||
`$b` contains the `App->user` array.
|
||||
|
||||
### display_item
|
||||
Called when formatting a post for display.
|
||||
|
@ -275,7 +264,7 @@ $data = [
|
|||
##### With multiple submit buttons
|
||||
```php
|
||||
$data = [
|
||||
'addon' => 'catavar',
|
||||
'addon' => 'catavatar',
|
||||
'title' => DI::l10n()->t('Cat Avatar Settings'),
|
||||
'html' => $html,
|
||||
'submit' => [
|
||||
|
@ -360,7 +349,7 @@ Called prior to output of profile edit page.
|
|||
### profile_advanced
|
||||
Called when the HTML is generated for the Advanced profile, corresponding to the Profile tab within a person's profile page.
|
||||
`$b` is the HTML string representation of the generated profile.
|
||||
The profile array details are in `$a->profile`.
|
||||
The profile array details are in `App->profile`.
|
||||
|
||||
### directory_item
|
||||
Called from the Directory page when formatting an item for display.
|
||||
|
@ -413,7 +402,7 @@ Called prior to output of personal XRD file.
|
|||
|
||||
### home_content
|
||||
Called prior to output home page content, shown to unlogged users.
|
||||
`$b` is the HTML sring of section region.
|
||||
`$b` is the HTML string of section region.
|
||||
|
||||
### contact_edit
|
||||
Called when editing contact details on an individual from the Contacts page.
|
||||
|
@ -436,7 +425,7 @@ Called after HTML content functions have completed.
|
|||
|
||||
### footer
|
||||
Called after HTML content functions have completed.
|
||||
Deferred Javascript files should be registered using this hook.
|
||||
Deferred JavaScript files should be registered using this hook.
|
||||
`$b` is (string) HTML of footer div/element.
|
||||
|
||||
### avatar_lookup
|
||||
|
|
|
@ -653,7 +653,7 @@ On Mastodon this field is used for the content warning.
|
|||
<tr>
|
||||
<td>Custom inline styles<br>
|
||||
<br>
|
||||
[style=text-shadow: 0 0 4px #CC0000;]You can change all the CSS properties of this block.[/style]</td>
|
||||
<td>You can change all <span style="text-shadow: 0 0 4px #cc0000;;">the CSS properties of this inline text.</span></td>
|
||||
You can change all the [style=text-shadow: 0 0 4px #CC0000;]CSS properties[/style] of this inline text.</td>
|
||||
<td>You can change all the <span style="text-shadow: 0 0 4px #cc0000;;">CSS properties</span> of this inline text.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -39,7 +39,7 @@ You can use several servers to create an account:
|
|||
|
||||
### 1. Basics
|
||||
|
||||
At first you have to get the current version. You can either pull it from [Github](https://github.com) like so:
|
||||
At first you have to get the current version. You can either pull it from [GitHub](https://github.com) like so:
|
||||
|
||||
$> cd /var/www/virtual/YOURSPACE/html/addon; git pull
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Composer requires PHP CLI and the following examples assume it's available syste
|
|||
|
||||
#### From Archive
|
||||
|
||||
If you just unpacked a Friendica release archive, you don't have to use Commposer at all, all the required libraries are already bundled in the archive.
|
||||
If you just unpacked a Friendica release archive, you don't have to use Composer at all, all the required libraries are already bundled in the archive.
|
||||
|
||||
#### Installing with Git
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ key = value
|
|||
<tr>
|
||||
<td><pre>
|
||||
[config]
|
||||
register_policty = REGISTER_CLOSED
|
||||
register_policy = REGISTER_CLOSED
|
||||
</pre></td>
|
||||
<td><pre>
|
||||
'config' => [
|
||||
|
|
|
@ -47,7 +47,7 @@ function doSomething(\Friendica\Contact\Introductions\Collection\Introductions $
|
|||
}
|
||||
|
||||
/** @var $intros \Friendica\Contact\Introductions\Collection\Introductions */
|
||||
$intros = \Friendica\DI::intro()->selecForUser(Session::getLocalUser());
|
||||
$intros = \Friendica\DI::intro()->selectForUser(Session::getLocalUser());
|
||||
|
||||
doSomething($intros);
|
||||
```
|
||||
|
|
|
@ -95,7 +95,7 @@ Please remove all the `require_once` mentions of the former file, as they will p
|
|||
## Miscellaneous tips
|
||||
|
||||
When you are done with moving the class, please run `php bin/console.php typo` from the Friendica base directory to check for obvious mistakes.
|
||||
Howevever, this tool isn't bullet-proof, and a staging install of Friendica is recommended to test your class move without impairing your production server if you host one.
|
||||
However, this tool isn't bullet-proof, and a staging install of Friendica is recommended to test your class move without impairing your production server if you host one.
|
||||
|
||||
Most of Friendica processes are run in the background, so make sure to turn on your debug log to check for errors that wouldn't show up while simply browsing Friendica.
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ For documentation we use the standard of *one sentence per line* for the `md` fi
|
|||
|
||||
#### Check with [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer)
|
||||
|
||||
This tool checks your files against a variety of coding standards, including PSR-2, and ouputs a report of all the standard violations.
|
||||
This tool checks your files against a variety of coding standards, including PSR-2, and outputs a report of all the standard violations.
|
||||
You can simply install it through PEAR: `pear install PHP_CodeSniffer`
|
||||
Once it is installed and available in your PATH, here's the command to run before committing your work:
|
||||
|
||||
|
@ -109,7 +109,7 @@ Here's the command to automatically fix the files you created/modified:
|
|||
|
||||
$> phpcbf --standard=ruleset.xml <file or directory>
|
||||
|
||||
If the command-line tools `diff` and `patch` are unavailabe for you, `phpcbf` can use slightly slower PHP equivalents by using the `--no-patch` argument.
|
||||
If the command-line tools `diff` and `patch` are unavailable for you, `phpcbf` can use slightly slower PHP equivalents by using the `--no-patch` argument.
|
||||
|
||||
### Code documentation
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ Friendica Documentation and Resources
|
|||
|
||||
* [Get started](help/Developers-Intro)
|
||||
* Set up development environment
|
||||
* [Help on Github](help/Github)
|
||||
* [Help on GitHub](help/GitHub)
|
||||
* [Help on Vagrant](help/Vagrant)
|
||||
* [Bugs and Issues](help/Bugs-and-Issues)
|
||||
* Code structure
|
||||
|
@ -69,7 +69,7 @@ Friendica Documentation and Resources
|
|||
* Ways to get Support
|
||||
* Friendica Support Forum: [@helpers@forum.friendi.ca](https://forum.friendi.ca/~helpers)
|
||||
* [Mailing List Archive](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca) you can subscribe to the list by sending an email to ``support-request(at)friendi.ca?subject=subscribe``
|
||||
* Community chat rooms (the IRC, Matrix and XMPP rooms are bridget) these public chats are logged [from IRC](https://gnusociarg.nsupdate.info/2021/%23friendica/) and [Matrix](https://view.matrix.org/alias/%23friendi.ca:matrix.org/)
|
||||
* Community chat rooms (the IRC, Matrix and XMPP rooms are bridged) these public chats are logged [from IRC](https://gnusociarg.nsupdate.info/2021/%23friendica/) and [Matrix](https://view.matrix.org/alias/%23friendi.ca:matrix.org/)
|
||||
* XMPP/Jabber MUC: support(at)forum.friendi.ca
|
||||
* IRC: #friendica at [libera.chat](https://web.libera.chat/?channels=#friendica)
|
||||
* Matrix: [#friendi.ca](https://matrix.to/#/#friendi.ca:matrix.org) or [#friendica-en](https://matrix.to/#/#friendica-en:matrix.org) at matrix.org
|
||||
|
|
|
@ -81,6 +81,6 @@ Please refer to external documentation for a more detailed explanation how to se
|
|||
|
||||
### Database
|
||||
|
||||
There are scripts like [tuning-primer.sh](http://www.day32.com/MySQL/) and [mysqltuner.pl](http://mysqltuner.pl) that analyze your database server and give hints on values that could be changed.
|
||||
There are scripts like [tuning-primer.sh](https://github.com/BMDan/tuning-primer.sh) and [mysqltuner.pl](https://github.com/major/MySQLTuner-perl/blob/master/mysqltuner.pl) that analyze your database server and give hints on values that could be changed.
|
||||
|
||||
Please enable the slow query log. This helps to find performance problems.
|
||||
|
|
|
@ -51,10 +51,13 @@ For alternative server configurations (such as Nginx server and MariaDB database
|
|||
### Alternative Installation Methods
|
||||
|
||||
This guide will walk you through the manual installation process of Friendica.
|
||||
If this is nothing for you, you might be interested in
|
||||
If this is nothing for you, you might be interested in the following:
|
||||
|
||||
* the [Friendica Docker image](https://github.com/friendica/docker) or
|
||||
* how to [install Friendica with YunoHost](https://github.com/YunoHost-Apps/friendica_ynh).
|
||||
* the [Friendica Docker image](https://github.com/friendica/docker)
|
||||
* how to [install Friendica with YunoHost](https://github.com/YunoHost-Apps/friendica_ynh)
|
||||
* [Tutorial: Creating a Friendica Server with Ubuntu 22.04](https://nequalsonelifestyle.com/2022/07/30/creating-friendica-server-ubuntu/)
|
||||
* [Setting Up Friendica Daemon as a Systemd Service Tutorial](https://nequalsonelifestyle.com/2022/08/04/setting-up-friendica-daemon-systemd-service/)
|
||||
* [Setting up Friendica on Unraid](https://www.jenovarain.com/2023/03/setting-up-friendica-on-unraid/) (NAS)
|
||||
|
||||
### Get Friendica
|
||||
|
||||
|
@ -228,7 +231,7 @@ Copy `.htaccess-dist` to `.htaccess` (be careful under Windows) to have working
|
|||
|
||||
Example:
|
||||
|
||||
cp .htacces-dist .htaccess
|
||||
cp .htaccess-dist .htaccess
|
||||
|
||||
*Note*: Do **not** rename the `.htaccess-dist` file as it is tracked by GIT and renaming will cause a dirty working directory.
|
||||
|
||||
|
@ -350,7 +353,7 @@ Often this will need to be resolved with your hosting provider or (if self-hoste
|
|||
First check your file permissions.
|
||||
Your website and all contents must generally be world-readable.
|
||||
|
||||
Ensure that mod-rewite is installed and working, and that your `.htaccess` file
|
||||
Ensure that mod-rewrite is installed and working, and that your `.htaccess` file
|
||||
is being used. To verify the latter, create a file `test.out` containing the
|
||||
word "test" in the top directory of Friendica, make it world readable and point
|
||||
your web browser to
|
||||
|
@ -463,9 +466,11 @@ After that, restart mysql and try again.
|
|||
|
||||
### Your worker never or rarely runs
|
||||
|
||||
Friendica is coded to always play nice. It checks whether the host machine is idle enough and if it _seems_ to be overloaded, it intermittently refuses to process the worker queue.
|
||||
Friendica is coded to always play nice.
|
||||
It checks whether the host machine is idle enough and if it _seems_ to be overloaded, it intermittently refuses to process the worker queue.
|
||||
|
||||
Such checks originate from the days of single-user single-core machines and involves thresholds that you should adjust based on the number of exclusive CPU cores you have. See this issue for more information:
|
||||
Such checks originate from the days of single-user single-core machines and involves thresholds that you should adjust based on the number of exclusive CPU cores you have.
|
||||
See this issue for more information:
|
||||
|
||||
* https://github.com/friendica/friendica/issues/10131
|
||||
|
||||
|
@ -482,28 +487,40 @@ You tried to upload an image up to 100kB and it failed.
|
|||
|
||||
You may not have the ownership or file mode set correctly if you are using the file system storage backend.
|
||||
|
||||
Change the backend to database. If this solves it, that is what needs to be fixed.
|
||||
Change the backend to database.
|
||||
If this solves it, that is what needs to be fixed.
|
||||
|
||||
Verify in your PHP ini:
|
||||
|
||||
* `file_uploads`: should be `1`
|
||||
* `upload_tmp_dir`: should be writable (falls back to system default temp) and not blocked by `open_basedir`
|
||||
|
||||
### Error uploading large files
|
||||
|
||||
You may find `413 Request Entity Too Large` or `500 Internal Error` in the network inspector of the browser if the file is too large, for example if it is a video.
|
||||
|
||||
First try to upload a very small file, up to 100kB. If that succeeds, you will need to increase limits at multiple places, including on any web proxy that you are using.
|
||||
First try to upload a very small file, up to 100kB.
|
||||
If that succeeds, you will need to increase limits at multiple places, including on any web proxy that you are using.
|
||||
Which one applies to you depends on your installation.
|
||||
|
||||
In your PHP ini:
|
||||
|
||||
* `upload_max_filesize`: defaults to 2MB
|
||||
* `post_max_size`: defaults to 8MB, must be greater than `upload_max_filesize`
|
||||
* `memory_limit`: defaults to 128MB, must be greater than `post_max_size`
|
||||
* `max_input_time`: time limit of an upload, defaults to -1, meaning it uses `max_execution_time` instead
|
||||
* `max_execution_time`: defaults to 30 seconds, should be enough if you also set `max_input_time`
|
||||
|
||||
You should verify whether you changed them in the _right file_ by checking the web interface at the end of the overview on the `Admin` panel.
|
||||
|
||||
For Apache2:
|
||||
In your Apache2 config:
|
||||
|
||||
* `LimitRequestBody`: defaults to unlimited
|
||||
* `FcgidMaxRequestLen`: defaults to 128kB
|
||||
* `SSLRenegBufferSize`: defaults to 128kB, only if your site uses TLS and perhaps only when using `SSLVerifyClient` or `SSLVerifyDepth`
|
||||
* Remove `LoadModule reqtimeout_module modules / mod_reqtimeout.so` or adjust `RequestReadTimeout`: defaults to 20 seconds and >= 500 byte/second
|
||||
|
||||
For nginx:
|
||||
In your nginx config:
|
||||
|
||||
* `client_max_body_size`: defaults to 1MB
|
||||
|
||||
|
@ -511,7 +528,28 @@ If you are using the database backend for storage, increase this in your SQL con
|
|||
|
||||
* `max_allowed_packet`: defaults to 32MB
|
||||
|
||||
If you use the ModSecurity WAF:
|
||||
In your ModSecurity WAF config:
|
||||
|
||||
* `SecRequestBodyLimit`: defaults to 12MB
|
||||
* `SecRequestBodyNoFilesLimit`: defaults to 128kB, should not apply to Friendica
|
||||
|
||||
In the end, you will need to restart all services that you have changed configuration for.
|
||||
If you don't know which ones these are, just reboot.
|
||||
|
||||
### Diaspora support is not activated
|
||||
|
||||
You get this error when you try to add a Diaspora contact.
|
||||
|
||||
You can enable it from the web interface in `Admin -> Site -> Policies -> Enable diaspora* support`.
|
||||
You may also set it manually in the config file or in the database within the `diaspora_enabled` key of the `system` category.
|
||||
|
||||
### Upgrade failed due to DB migration timeout
|
||||
|
||||
Altering of a table may fail if it contains a large number of rows.
|
||||
First verify the existing timeout (50s by default):
|
||||
|
||||
`show global variables like "innodb_lock_wait_timeout";`
|
||||
|
||||
Then increase it:
|
||||
|
||||
`set global innodb_lock_wait_timeout=600;`
|
||||
|
|
|
@ -50,12 +50,12 @@ This will take you through a similar process.
|
|||
|
||||
Connect to users of alternate networks
|
||||
---
|
||||
### Across the Federation and Fedivese
|
||||
You can also use your Identity Address or other people's Identity Addresses to become friends across the so-called Federation/Fedivese of open source social media.
|
||||
### Across the Federation and Fediverse
|
||||
You can also use your Identity Address or other people's Identity Addresses to become friends across the so-called Federation/Fediverse of open source social media.
|
||||
Currently, Friendica supports connections with people on diaspora*, Red, Hubzilla, GNU Social, StatusNet, Mastodon, Pleroma, socialhome, and ganggo platforms.
|
||||
|
||||
If you know (for instance) "alice" on gnusocial.net (a GNU Social site) you could put alice@gnusocial.net into your Contact page and become friends across networks.
|
||||
Likwise you can put in the URL to Alice's gnusocial.net page, if you wish.
|
||||
Likewise you can put in the URL to Alice's gnusocial.net page, if you wish.
|
||||
Note: Some versions of GNU Social software may require the full URL to your profile and may not work with the identity address.
|
||||
|
||||
People on these networks can also initiate contact with you, if they know your contact details.
|
||||
|
@ -74,7 +74,7 @@ Create an email contact with for example Alice on Gmail, enter her email in foll
|
|||
In order to avoid abuse or spam, you must have an email from Alice with the correct email address in your email inbox.
|
||||
|
||||
Subscribing to mailing lists is done in the same way, but without the use of the "mailto:" prefix.
|
||||
To subscribe to a mailing list, enter the email in following example format "mailling-list@list-server.net".
|
||||
To subscribe to a mailing list, enter the email in following example format "mailing-list@list-server.net".
|
||||
|
||||
### Syndication feeds
|
||||
You can "follow" almost anybody or any website that produces a syndication feed (RSS/Atom,etc.).
|
||||
|
|
|
@ -19,7 +19,7 @@ Friendica contacts
|
|||
---
|
||||
Friendica will recreate your account on the new server, with your contacts and groups.
|
||||
A message is sent to Friendica contacts, to inform them about your move:
|
||||
If your contacts are runnning on an updated server, your details on their side will be automatically updated.
|
||||
If your contacts are running on an updated server, your details on their side will be automatically updated.
|
||||
|
||||
GNU Social contacts
|
||||
---
|
||||
|
|
|
@ -4,7 +4,7 @@ If you're not already logged in, do so in the frame below.
|
|||
Once you've logged in (or if you are already logged in), you'll now be looking at your profile page.
|
||||
|
||||
This is a bit like a Facebook wall.
|
||||
It's where all your status messgages are kept, and where your friends come to post on your wall.
|
||||
It's where all your status messages are kept, and where your friends come to post on your wall.
|
||||
|
||||
To write your status, simply click on the Pencil & Paper icon in the top right (in the Frio theme), or click in the box that says "share" (other themes).
|
||||
When you do this, the posting dialog box will appear or the share box will expand.
|
||||
|
|
|
@ -104,12 +104,12 @@ Default is false.
|
|||
#### File storage backend
|
||||
|
||||
Set the backend used by Friendica to store uploaded file data.
|
||||
Two storage backends are avaiable with Friendica:
|
||||
Two storage backends are available with Friendica:
|
||||
|
||||
- **Database** : Data is stored in a dedicated table in database (`storage`)
|
||||
- **Filesystem** : Data is stored as file on the filesystem.
|
||||
|
||||
More storage backends can be avaiable from third-party addons.
|
||||
More storage backends can be available from third-party addons.
|
||||
If you use those, please refer to the documentation of those addons for further information.
|
||||
|
||||
Default value is 'Database (legacy)': it's the legacy way used to store data directly in database.
|
||||
|
|
|
@ -52,5 +52,5 @@ The same rules apply as with names that spaces within tags are represented by th
|
|||
It is therefore not possible to create a tag whose target contains an underscore.
|
||||
|
||||
Topical tags are also not linked if they are purely numeric, e.g. #1.
|
||||
If you wish to use a numerica hashtag, please add some descriptive text such as #2012-elections.
|
||||
If you wish to use a numeric hashtag, please add some descriptive text such as #2012-elections.
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ If 2FA is already enabled and you want to add another device, you must re-config
|
|||
### 1. Download an authenticator app
|
||||
|
||||
Any authenticator app should work with Friendica.
|
||||
Notheless, we recommend:
|
||||
Nonetheless, we recommend:
|
||||
|
||||
- For iOS, [Matt Rubin's MIT-licensed Authenticator app](https://mattrubin.me/authenticator).
|
||||
- For Android, [andOTP](https://github.com/andOTP/andOTP).
|
||||
|
@ -68,7 +68,7 @@ Instead, if you enabled two-factor authentication, you have to generate app-spec
|
|||
|
||||
You can generate as many app-specific passwords as you want, they will be shown once to you just after you generated it.
|
||||
Just copy and paste it in your third-party app in the Friendica account password input field at this point.
|
||||
We recommend generating a single app-specific password for each separate third-party app you are using, using a meaningul description of the target app (like "Frienqa on my Fairphone 2").
|
||||
We recommend generating a single app-specific password for each separate third-party app you are using, using a meaningful description of the target app (like "Frienqa on my Fairphone 2").
|
||||
|
||||
You can also revoke any and all app-specific password you generated this way.
|
||||
This may log you out of the third-party application(s) you used the revoked app-specific password to log in with.
|
||||
|
|
|
@ -31,7 +31,7 @@ The mysql database is called "friendica", the mysql user and password both are "
|
|||
Your local working directory is set up as a shared directory with the VM (/vagrant).
|
||||
7. Check the changes in your browser in the VM.
|
||||
Find the Friendica log file `/vagrant/logfile.out` on the VM or in the `logfile.out` in you local Friendica directory.
|
||||
8. Commit and push your changes directly back to Github.
|
||||
8. Commit and push your changes directly back to GitHub.
|
||||
|
||||
If you want to stop vagrant after finishing your work, run the following command
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ Database Tables
|
|||
| [2fa_trusted_browser](help/database/db_2fa_trusted_browser) | Two-factor authentication trusted browsers |
|
||||
| [account-suggestion](help/database/db_account-suggestion) | Account suggestion |
|
||||
| [account-user](help/database/db_account-user) | Remote and local accounts |
|
||||
| [addon](help/database/db_addon) | registered addons |
|
||||
| [apcontact](help/database/db_apcontact) | ActivityPub compatible contacts - used in the ActivityPub implementation |
|
||||
| [application](help/database/db_application) | OAuth application |
|
||||
| [application-marker](help/database/db_application-marker) | Timeline marker |
|
||||
|
@ -23,6 +22,7 @@ Database Tables
|
|||
| [contact-relation](help/database/db_contact-relation) | Contact relations |
|
||||
| [conv](help/database/db_conv) | private messages |
|
||||
| [delayed-post](help/database/db_delayed-post) | Posts that are about to be distributed at a later time |
|
||||
| [delivery-queue](help/database/db_delivery-queue) | Delivery data for posts for the batch processing |
|
||||
| [diaspora-contact](help/database/db_diaspora-contact) | Diaspora compatible contacts - used in the Diaspora implementation |
|
||||
| [diaspora-interaction](help/database/db_diaspora-interaction) | Signed Diaspora Interaction |
|
||||
| [endpoint](help/database/db_endpoint) | ActivityPub endpoints - used in the ActivityPub implementation |
|
||||
|
@ -40,6 +40,7 @@ Database Tables
|
|||
| [inbox-status](help/database/db_inbox-status) | Status of ActivityPub inboxes |
|
||||
| [intro](help/database/db_intro) | |
|
||||
| [item-uri](help/database/db_item-uri) | URI and GUID for items |
|
||||
| [key-value](help/database/db_key-value) | A key value storage |
|
||||
| [locks](help/database/db_locks) | |
|
||||
| [mail](help/database/db_mail) | private messages |
|
||||
| [mailacct](help/database/db_mailacct) | Mail account data for fetching mails |
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
Table addon
|
||||
===========
|
||||
|
||||
registered addons
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------------ | --------------------------------------------- | ------------ | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| name | addon base (file)name | varchar(50) | NO | | | |
|
||||
| version | currently unused | varchar(50) | NO | | | |
|
||||
| installed | currently always 1 | boolean | NO | | 0 | |
|
||||
| hidden | currently unused | boolean | NO | | 0 | |
|
||||
| timestamp | file timestamp to check for reloads | int unsigned | NO | | 0 | |
|
||||
| plugin_admin | 1 = has admin config, 0 = has no admin config | boolean | NO | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| -------------- | --------------- |
|
||||
| PRIMARY | id |
|
||||
| installed_name | installed, name |
|
||||
| name | UNIQUE, name |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
|
@ -7,10 +7,10 @@ Fields
|
|||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ----- | ----------- | ------------- | ---- | --- | ------- | -------------- |
|
||||
| ----- | ------------------------- | ------------- | ---- | --- | ------- | -------------- |
|
||||
| id | | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| cat | | varbinary(50) | NO | | | |
|
||||
| k | | varbinary(50) | NO | | | |
|
||||
| cat | The category of the entry | varbinary(50) | NO | | | |
|
||||
| k | The key of the entry | varbinary(50) | NO | | | |
|
||||
| v | | mediumtext | YES | | NULL | |
|
||||
|
||||
Indexes
|
||||
|
|
39
doc/database/db_delivery-queue.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
Table delivery-queue
|
||||
===========
|
||||
|
||||
Delivery data for posts for the batch processing
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | --------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||
| gsid | Target server | int unsigned | NO | PRI | NULL | |
|
||||
| uri-id | Delivered post | int unsigned | NO | PRI | NULL | |
|
||||
| created | | datetime | YES | | NULL | |
|
||||
| command | | varbinary(32) | YES | | NULL | |
|
||||
| cid | Target contact | int unsigned | YES | | NULL | |
|
||||
| uid | Delivering user | mediumint unsigned | YES | | NULL | |
|
||||
| failed | Number of times the delivery has failed | tinyint | YES | | 0 | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------ | ------------- |
|
||||
| PRIMARY | uri-id, gsid |
|
||||
| gsid_created | gsid, created |
|
||||
| uid | uid |
|
||||
| cid | cid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
||||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| gsid | [gserver](help/database/db_gserver) | id |
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
|
||||
Return to [database documentation](help/database)
|
|
@ -27,7 +27,7 @@ Fields
|
|||
| gsid | Global Server ID | int unsigned | YES | | NULL | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| interacting_count | Number of contacts this contact interactes with | int unsigned | YES | | 0 | |
|
||||
| interacting_count | Number of contacts this contact interacts with | int unsigned | YES | | 0 | |
|
||||
| interacted_count | Number of contacts that interacted with this contact | int unsigned | YES | | 0 | |
|
||||
| post_count | Number of posts and comments | int unsigned | YES | | 0 | |
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ Fields
|
|||
| last_poco_query | | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| last_contact | Last successful connection request | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| last_failure | Last failed connection request | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
| blocked | Server is blocked | boolean | YES | | NULL | |
|
||||
| failed | Connection failed | boolean | YES | | NULL | |
|
||||
| next_contact | Next connection request | datetime | YES | | 0001-01-01 00:00:00 | |
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ Fields
|
|||
| -------- | ------------------------------------ | -------------- | ---- | --- | ------------------- | ----- |
|
||||
| url | URL of the inbox | varbinary(383) | NO | PRI | NULL | |
|
||||
| uri-id | Item-uri id of inbox url | int unsigned | YES | | NULL | |
|
||||
| gsid | ID of the related server | int unsigned | YES | | NULL | |
|
||||
| created | Creation date of this entry | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| success | Date of the last successful delivery | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| failure | Date of the last failed delivery | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
@ -24,6 +25,7 @@ Indexes
|
|||
| ------- | ------ |
|
||||
| PRIMARY | url |
|
||||
| uri-id | uri-id |
|
||||
| gsid | gsid |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
@ -31,5 +33,6 @@ Foreign Keys
|
|||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||
| gsid | [gserver](help/database/db_gserver) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
23
doc/database/db_key-value.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
Table key-value
|
||||
===========
|
||||
|
||||
A key value storage
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ---------- | ---------------------------- | ------------- | ---- | --- | ------- | ----- |
|
||||
| k | | varbinary(50) | NO | PRI | NULL | |
|
||||
| v | | mediumtext | YES | | NULL | |
|
||||
| updated_at | timestamp of the last update | int unsigned | NO | | NULL | |
|
||||
|
||||
Indexes
|
||||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| PRIMARY | k |
|
||||
|
||||
|
||||
Return to [database documentation](help/database)
|
|
@ -13,7 +13,7 @@ Fields
|
|||
| guid | A unique identifier for this private message | varbinary(255) | NO | | | |
|
||||
| from-name | name of the sender | varchar(255) | NO | | | |
|
||||
| from-photo | contact photo link of the sender | varbinary(383) | NO | | | |
|
||||
| from-url | profile linke of the sender | varbinary(383) | NO | | | |
|
||||
| from-url | profile link of the sender | varbinary(383) | NO | | | |
|
||||
| contact-id | contact.id | varbinary(255) | YES | | NULL | |
|
||||
| author-id | Link to the contact table with uid=0 of the author of the mail | int unsigned | YES | | NULL | |
|
||||
| convid | conv.id | int unsigned | YES | | NULL | |
|
||||
|
|
|
@ -34,7 +34,7 @@ Fields
|
|||
| event-id | Used to link to the event.id | int unsigned | YES | | NULL | |
|
||||
| unseen | post has not been seen | boolean | NO | | 1 | |
|
||||
| hidden | Marker to hide the post from the user | boolean | NO | | 0 | |
|
||||
| notification-type | | tinyint unsigned | NO | | 0 | |
|
||||
| notification-type | | smallint unsigned | NO | | 0 | |
|
||||
| wall | This item was posted to the wall of uid | boolean | NO | | 0 | |
|
||||
| origin | item originated at this site | boolean | NO | | 0 | |
|
||||
| psid | ID of the permission set of this post | int unsigned | YES | | NULL | |
|
||||
|
|
|
@ -9,7 +9,7 @@ Fields
|
|||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------------------------------------ | ------------- | ---- | --- | ------------------- | ----- |
|
||||
| pid | The ID of the process | int unsigned | NO | PRI | NULL | |
|
||||
| hostname | The name of the host the process is ran on | varchar(32) | NO | PRI | NULL | |
|
||||
| hostname | The name of the host the process is ran on | varchar(255) | NO | PRI | NULL | |
|
||||
| command | | varbinary(32) | NO | | | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
|
||||
|
|
|
@ -7,11 +7,14 @@ Fields
|
|||
------
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| ----------- | ----------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
|
||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||
| uid | Reporting user | mediumint unsigned | YES | | NULL | |
|
||||
| reporter-id | Reporting contact | int unsigned | YES | | NULL | |
|
||||
| cid | Reported contact | int unsigned | NO | | NULL | |
|
||||
| comment | Report | text | YES | | NULL | |
|
||||
| category | Category of the report (spam, violation, other) | varchar(20) | YES | | NULL | |
|
||||
| rules | Violated rules | text | YES | | NULL | |
|
||||
| forward | Forward the report to the remote server | boolean | YES | | NULL | |
|
||||
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
|
||||
| status | Status of the report | tinyint unsigned | YES | | NULL | |
|
||||
|
@ -20,10 +23,11 @@ Indexes
|
|||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------- | ------ |
|
||||
| ----------- | ----------- |
|
||||
| PRIMARY | id |
|
||||
| uid | uid |
|
||||
| cid | cid |
|
||||
| reporter-id | reporter-id |
|
||||
|
||||
Foreign Keys
|
||||
------------
|
||||
|
@ -31,6 +35,7 @@ Foreign Keys
|
|||
| Field | Target Table | Target Field |
|
||||
|-------|--------------|--------------|
|
||||
| uid | [user](help/database/db_user) | uid |
|
||||
| reporter-id | [contact](help/database/db_contact) | id |
|
||||
| cid | [contact](help/database/db_contact) | id |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
@ -32,7 +32,7 @@ Fields
|
|||
| verified | user is verified through email | boolean | NO | | 0 | |
|
||||
| blocked | 1 for user is blocked | boolean | NO | | 0 | |
|
||||
| blockwall | Prohibit contacts to post to the profile page of the user | boolean | NO | | 0 | |
|
||||
| hidewall | Hide profile details from unkown viewers | boolean | NO | | 0 | |
|
||||
| hidewall | Hide profile details from unknown viewers | boolean | NO | | 0 | |
|
||||
| blocktags | Prohibit contacts to tag the post of this user | boolean | NO | | 0 | |
|
||||
| unkmail | Permit unknown people to send private mails to this user | boolean | NO | | 0 | |
|
||||
| cntunkmail | | int unsigned | NO | | 10 | |
|
||||
|
|
|
@ -38,17 +38,14 @@ $function ist ein String und der Name der Funktion, die ausgeführt wird, wenn d
|
|||
Argumente
|
||||
---
|
||||
|
||||
Deine Hook-Callback-Funktion wird mit mindestens einem und bis zu zwei Argumenten aufgerufen
|
||||
Deine Hook-Callback-Funktion wird mit höchstens einem Argumenten aufgerufen
|
||||
|
||||
function myhook_function(App $a, &$b) {
|
||||
function myhook_function(&$b) {
|
||||
|
||||
}
|
||||
|
||||
Wenn du Änderungen an den aufgerufenen Daten vornehmen willst, musst du diese als Referenzvariable (mit "&") während der Funktionsdeklaration deklarieren.
|
||||
|
||||
$a ist die Friendica "App"-Klasse, die eine Menge an Informationen über den aktuellen Friendica-Status beinhaltet, u.a. welche Module genutzt werden, Konfigurationsinformationen, Inhalte der Seite zum Zeitpunkt des Hook-Aufrufs.
|
||||
Es ist empfohlen, diese Funktion "$a" zu nennen, um seine Nutzung an den Gebrauch an anderer Stelle anzugleichen.
|
||||
|
||||
$b kann frei benannt werden.
|
||||
Diese Information ist speziell auf den Hook bezogen, der aktuell bearbeitet wird, und beinhaltet normalerweise Daten, die du sofort nutzen, anzeigen oder bearbeiten kannst.
|
||||
Achte darauf, diese mit "&" zu deklarieren, wenn du sie bearbeiten willst.
|
||||
|
@ -70,9 +67,9 @@ DI::args()->get(1); // = 'arg1'
|
|||
DI::args()->get(2); // = 'arg2'
|
||||
```
|
||||
|
||||
Deine Modulfunktionen umfassen oft die Funktion addon_name_content(App $a), welche den Seiteninhalt definiert und zurückgibt.
|
||||
Sie können auch addon_name_post(App $a) umfassen, welches vor der content-Funktion aufgerufen wird und normalerweise die Resultate der POST-Formulare handhabt.
|
||||
Du kannst ebenso addon_name_init(App $a) nutzen, was oft frühzeitig aufgerufen wird und das Modul initialisert.
|
||||
Deine Modulfunktionen umfassen oft die Funktion `addon_name_content()`, welche den Seiteninhalt definiert und zurückgibt.
|
||||
Sie können auch `addon_name_post()` umfassen, welches vor der content-Funktion aufgerufen wird und normalerweise die Resultate der POST-Formulare handhabt.
|
||||
Du kannst ebenso `addon_name_init()` nutzen, was oft frühzeitig aufgerufen wird und das Modul initialisert.
|
||||
|
||||
|
||||
Derzeitige Hooks
|
||||
|
@ -86,7 +83,7 @@ Derzeitige Hooks
|
|||
'user_record' => die erfolgreiche Authentifizierung muss auch einen gültigen Nutzereintrag aus der Datenbank zurückgeben
|
||||
|
||||
**'logged_in'** - wird aufgerufen, sobald ein Nutzer sich erfolgreich angemeldet hat.
|
||||
$b beinhaltet den $a->Nutzer-Array
|
||||
$b beinhaltet den `App->user`
|
||||
|
||||
|
||||
**'display_item'** - wird aufgerufen, wenn ein Beitrag für die Anzeige formatiert wird.
|
||||
|
@ -122,7 +119,7 @@ Derzeitige Hooks
|
|||
|
||||
**'profile_advanced'** - wird aufgerufen, wenn die HTML-Ausgabe für das "Advanced profile" generiert wird; stimmt mit dem "Profil"-Tab auf der Profilseite der Nutzer überein.
|
||||
$b ist die HTML-Ausgabe (String) des erstellten Profils
|
||||
(Die Details des Profil-Arrays sind in $a->profile)
|
||||
(Die Details des Profil-Arrays sind in `App->profile`)
|
||||
|
||||
**'directory_item'** - wird von der Verzeichnisseite aufgerufen, wenn ein Item für die Anzeige formatiert wird.
|
||||
$b ist ein Array
|
||||
|
|
|
@ -612,8 +612,8 @@ Dieses Feld wird von Mastodon für die Inhaltswarnung (content warning) verw
|
|||
<tr>
|
||||
<td>Benutzerdefinierte Inline-Styles<br>
|
||||
<br>
|
||||
[style=text-shadow: 0 0 4px #CC0000;]Du kannst alle CSS-Eigenschaften eines Blocks ändern-[/style]</td>
|
||||
<td>Du kannst alle <span style="text-shadow: 0 0 4px #cc0000;;">CSS-Eigenschaften dieses Inline-Textes ändern-</span></td>
|
||||
Du kannst alle [style=text-shadow: 0 0 4px #CC0000;]CSS-Eigenschaften[/style] dieses Inline-Textes ändern-</td>
|
||||
<td>Du kannst alle <span style="text-shadow: 0 0 4px #cc0000;;">CSS-Eigenschaften</span> dieses Inline-Textes ändern-</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Der Quellcode von Friendica Red ist [hier](https://github.com/friendica/red) zu
|
|||
|
||||
Addons findest Du auf [dieser Seite](https://github.com/friendica/friendica-addons).
|
||||
|
||||
Wenn Du neue Themen suchst, findest Du sie auf [Friendica-Themes.com](http://friendica-themes.com/).
|
||||
Wenn Du neue Themen suchst, findest Du sie auf [github.com/bkil/friendica-themes](https://github.com/bkil/friendica-themes).
|
||||
|
||||
<a name="adminaccount1"></a>
|
||||
### Ich habe meine E-Mail Adresse geändern und jetzt ist das Admin Panel verschwunden?
|
||||
|
|
|
@ -95,6 +95,6 @@ Nutze externe Dokumente, um eine detailiertere Erklärung für die Einrichtung e
|
|||
|
||||
### Database
|
||||
|
||||
Es gibt Skripte wie [tuning-primer.sh](http://www.day32.com/MySQL/) und [mysqltuner.pl](http://mysqltuner.pl), die den Datenbankserver analysieren und Hinweise darauf geben, welche Werte verändert werden könnten.
|
||||
Es gibt Skripte wie [tuning-primer.sh](https://github.com/BMDan/tuning-primer.sh) und [mysqltuner.pl](https://github.com/major/MySQLTuner-perl/blob/master/mysqltuner.pl), die den Datenbankserver analysieren und Hinweise darauf geben, welche Werte verändert werden könnten.
|
||||
|
||||
Aktivere hierfür die "Slow query" Log-Datei, um Performanceprobleme zu erkennen.
|
||||
|
|
|
@ -9,7 +9,7 @@ Depending on the theme you are using, there might be an additional link from the
|
|||
|
||||
## Event Overview
|
||||
|
||||
The overview page shows the calendar of the current month, plus a few days days at the beginning and the end.
|
||||
The overview page shows the calendar of the current month, plus a few days at the beginning and the end.
|
||||
Listed are all events for this month, created by you, or shared with you by your contacts,
|
||||
This includes birthday reminders for contacts who share their birthday with you.
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ Form Templates
|
|||
To guarantee a consistent look and feel for input forms, i.e. in the settings sections, there are templates for the basic form fields.
|
||||
They are initialized with an array of data, depending on the tyle of the field.
|
||||
|
||||
All of these take an array holding the values, e.g. for a one line text input field, which is required and should be used to type email addesses use something along the lines of:
|
||||
All of these take an array holding the values, e.g. for a one line text input field, which is required and should be used to type email addresses use something along the lines of:
|
||||
|
||||
'$adminmail' => array('adminmail', DI::l10n()->t('Site administrator email address'), $adminmail, DI::l10n()->t('Your account email address must match this in order to use the web admin panel.'), 'required', '', 'email'),
|
||||
|
||||
|
@ -70,7 +70,7 @@ Field parameter:
|
|||
|
||||
### field_custom.tpl
|
||||
|
||||
A customizeable template to include a custom element in the form with the usual surroundings,
|
||||
A customizable template to include a custom element in the form with the usual surroundings,
|
||||
Field parameter:
|
||||
|
||||
0. Name of the field,
|
||||
|
@ -88,7 +88,7 @@ Field parameter:
|
|||
2. Current value of the variable,
|
||||
3. Help text for the input box,
|
||||
4. Should be set to the translation of "Required" to mark this field as required,
|
||||
5. if set to "autofocus" modern browser will put the cursur into this box once the page is loaded,
|
||||
5. if set to "autofocus" modern browser will put the cursor into this box once the page is loaded,
|
||||
6. if set, it will be used for the input type, default is `text` (possible types: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#%3Cinput%3E_types).
|
||||
|
||||
### field_intcheckbox.tpl
|
||||
|
|
|
@ -12,7 +12,7 @@ So, how to work on the UI of friendica.
|
|||
You can either directly edit an existing theme.
|
||||
But you might loose your changes when the theme is updated by the friendica team.
|
||||
|
||||
If you are almost happy with an existing theme, the easiest way to cover your needs is to create a new theme, inheritating most of the properties of the parent theme and change just minor stuff.
|
||||
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.
|
||||
|
@ -33,7 +33,7 @@ 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 allowes the user to change certain things of the theme dynamically.
|
||||
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
|
||||
|
@ -50,7 +50,7 @@ if you want to override any template within your theme create your version of th
|
|||
|
||||
any template that exists there will be used instead of the default one.
|
||||
|
||||
### Javascript
|
||||
### JavaScript
|
||||
|
||||
The same rule applies to the JavaScript files found in
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ In */etc/fail2ban/jail.local* create a section for Friendica:
|
|||
bantime = 900
|
||||
filter = friendica
|
||||
port = http,https
|
||||
logpath = /var/log/friend.log
|
||||
logpath = /var/log/friendica.log
|
||||
logencoding = utf-8
|
||||
|
||||
And create a filter definition in */etc/fail2ban/filter.d/friendica.conf*:
|
||||
|
|
|
@ -7,7 +7,7 @@ Friendica translations
|
|||
|
||||
The Friendica translation process is based on `gettext` PO files.
|
||||
|
||||
Basic worflow:
|
||||
Basic workflow:
|
||||
1. `xgettext` is used to collect translation strings across the project in the authoritative PO file located in `view/lang/C/messages.po`.
|
||||
2. This file makes translations strings available at [the Transifex Friendica page](https://www.transifex.com/Friendica/friendica/dashboard/).
|
||||
3. The translation itself is done at Transifex by volunteers.
|
||||
|
@ -24,6 +24,16 @@ For addons, we add support for a language when if we already support the languag
|
|||
|
||||
## Add new translation strings
|
||||
|
||||
### Supported gettext version
|
||||
|
||||
We currently support the gettext version 0.19.8.1 and actively check new translation strings with this version.
|
||||
|
||||
If you don't use this version, it's possible that our checks fail (f.e. because of tiny differences at linebreaks).
|
||||
In case you do have a Docker environment, you can easily update the translations with the following command:
|
||||
```shell
|
||||
docker run --rm -v $PWD:/data -w /data friendicaci/transifex bin/run_xgettext.sh
|
||||
```
|
||||
|
||||
### Core
|
||||
|
||||
Once you have added new translation strings in your code changes, please run `bin/run_xgettext.sh` from the base Friendica directory and commit the updated `view/lang/C/messages.po` to your branch.
|
||||
|
|
|
@ -10,4 +10,3 @@
|
|||
<directory>.</directory>
|
||||
</files>
|
||||
</docblox>
|
||||
|
||||
|
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 408 KiB After Width: | Height: | Size: 408 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 498 KiB After Width: | Height: | Size: 498 KiB |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 300 B |
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -45,6 +45,9 @@ $a->runFrontend(
|
|||
$dice->create(\Friendica\Core\PConfig\Capability\IManagePersonalConfigValues::class),
|
||||
$dice->create(\Friendica\Security\Authentication::class),
|
||||
$dice->create(\Friendica\App\Page::class),
|
||||
$dice->create(\Friendica\Content\Nav::class),
|
||||
$dice->create(Friendica\Module\Special\HTTPException::class),
|
||||
new \Friendica\Util\HTTPInputData($_SERVER),
|
||||
$start_time
|
||||
$start_time,
|
||||
$_SERVER
|
||||
);
|
||||
|
|
862
mod/item.php
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
* This is the POST destination for most all locally posted
|
||||
* text stuff. This function handles status, wall-to-wall status,
|
||||
* local comments, and remote coments that are posted on this site
|
||||
* local comments, and remote comments that are posted on this site
|
||||
* (as opposed to being delivered in a feed).
|
||||
* Also processed here are posts and comments coming through the
|
||||
* statusnet/twitter API.
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\PageInfo;
|
||||
use Friendica\Content\Conversation;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
|
@ -38,45 +38,26 @@ use Friendica\Core\System;
|
|||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Conversation;
|
||||
use Friendica\Model\FileTag;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\ItemURI;
|
||||
use Friendica\Model\Notification;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Object\EMail\ItemCCEMail;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Security\Security;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\ParseUrl;
|
||||
|
||||
function item_post(App $a) {
|
||||
if (!DI::userSession()->isAuthenticated()) {
|
||||
$uid = DI::userSession()->getLocalUserId();
|
||||
|
||||
if (!$uid) {
|
||||
throw new HTTPException\ForbiddenException();
|
||||
}
|
||||
|
||||
$uid = DI::userSession()->getLocalUserId();
|
||||
|
||||
if (!empty($_REQUEST['dropitems'])) {
|
||||
$arr_drop = explode(',', $_REQUEST['dropitems']);
|
||||
foreach ($arr_drop as $item) {
|
||||
Item::deleteForUser(['id' => $item], $uid);
|
||||
}
|
||||
|
||||
$json = ['success' => 1];
|
||||
System::jsonExit($json);
|
||||
item_drop($uid, $_REQUEST['dropitems']);
|
||||
}
|
||||
|
||||
Hook::callAll('post_local_start', $_REQUEST);
|
||||
|
||||
Logger::debug('postvars', ['_REQUEST' => $_REQUEST]);
|
||||
|
||||
$return_path = $_REQUEST['return'] ?? '';
|
||||
$preview = intval($_REQUEST['preview'] ?? 0);
|
||||
|
||||
|
@ -86,48 +67,107 @@ function item_post(App $a) {
|
|||
* after it's been previewed
|
||||
*/
|
||||
if (!$preview && !empty($_REQUEST['post_id_random'])) {
|
||||
if (!empty($_SESSION['post-random']) && $_SESSION['post-random'] == $_REQUEST['post_id_random']) {
|
||||
if (DI::session()->get('post-random') == $_REQUEST['post_id_random']) {
|
||||
Logger::warning('duplicate post');
|
||||
item_post_return(DI::baseUrl(), $return_path);
|
||||
} else {
|
||||
$_SESSION['post-random'] = $_REQUEST['post_id_random'];
|
||||
DI::session()->set('post-random', $_REQUEST['post_id_random']);
|
||||
}
|
||||
}
|
||||
|
||||
// Is this a reply to something?
|
||||
$parent_item_id = intval($_REQUEST['parent'] ?? 0);
|
||||
$thr_parent_uri = trim($_REQUEST['parent_uri'] ?? '');
|
||||
if (empty($_REQUEST['post_id'])) {
|
||||
item_insert($uid, $_REQUEST, $preview, $return_path);
|
||||
} else {
|
||||
item_edit($uid, $_REQUEST, $preview, $return_path);
|
||||
}
|
||||
}
|
||||
|
||||
$parent_item = null;
|
||||
$toplevel_item = null;
|
||||
$toplevel_item_id = 0;
|
||||
$toplevel_user_id = null;
|
||||
|
||||
$objecttype = null;
|
||||
$profile_uid = DI::userSession()->getLocalUserId();
|
||||
$posttype = ($_REQUEST['post_type'] ?? '') ?: Item::PT_ARTICLE;
|
||||
|
||||
if ($parent_item_id || $thr_parent_uri) {
|
||||
if ($parent_item_id) {
|
||||
$parent_item = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $parent_item_id]);
|
||||
} elseif ($thr_parent_uri) {
|
||||
$parent_item = Post::selectFirst(Item::ITEM_FIELDLIST, ['uri' => $thr_parent_uri, 'uid' => $profile_uid]);
|
||||
function item_drop(int $uid, string $dropitems)
|
||||
{
|
||||
$arr_drop = explode(',', $dropitems);
|
||||
foreach ($arr_drop as $item) {
|
||||
Item::deleteForUser(['id' => $item], $uid);
|
||||
}
|
||||
|
||||
// if this isn't the top-level parent of the conversation, find it
|
||||
if (DBA::isResult($parent_item)) {
|
||||
// The URI and the contact is taken from the direct parent which needn't to be the top parent
|
||||
$thr_parent_uri = $parent_item['uri'];
|
||||
$toplevel_item = $parent_item;
|
||||
System::jsonExit(['success' => 1]);
|
||||
}
|
||||
|
||||
if ($parent_item['gravity'] != Item::GRAVITY_PARENT) {
|
||||
$toplevel_item = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $toplevel_item['parent']]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!DBA::isResult($toplevel_item)) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Unable to locate original post.'));
|
||||
function item_edit(int $uid, array $request, bool $preview, string $return_path)
|
||||
{
|
||||
$post = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $request['post_id'], 'uid' => $uid]);
|
||||
if (!DBA::isResult($post)) {
|
||||
if ($return_path) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Unable to locate original post.'));
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
throw new HTTPException\NotFoundException(DI::l10n()->t('Unable to locate original post.'));
|
||||
}
|
||||
|
||||
$post['edit'] = $post;
|
||||
$post['file'] = Post\Category::getTextByURIId($post['uri-id'], $post['uid']);
|
||||
|
||||
Post\Media::deleteByURIId($post['uri-id'], [Post\Media::AUDIO, Post\Media::VIDEO, Post\Media::IMAGE, Post\Media::HTML]);
|
||||
$post = item_process($post, $request, $preview, $return_path);
|
||||
|
||||
$fields = [
|
||||
'title' => $post['title'],
|
||||
'body' => $post['body'],
|
||||
'attach' => $post['attach'],
|
||||
'file' => $post['file'],
|
||||
'location' => $post['location'],
|
||||
'coord' => $post['coord'],
|
||||
'edited' => DateTimeFormat::utcNow(),
|
||||
'changed' => DateTimeFormat::utcNow()
|
||||
];
|
||||
|
||||
$fields['body'] = Item::setHashtags($fields['body']);
|
||||
|
||||
$quote_uri_id = Item::getQuoteUriId($fields['body'], $post['uid']);
|
||||
if (!empty($quote_uri_id)) {
|
||||
$fields['quote-uri-id'] = $quote_uri_id;
|
||||
$fields['body'] = BBCode::removeSharedData($post['body']);
|
||||
}
|
||||
|
||||
Item::update($fields, ['id' => $post['id']]);
|
||||
Item::updateDisplayCache($post['uri-id']);
|
||||
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
throw new HTTPException\OKException(DI::l10n()->t('Post updated.'));
|
||||
}
|
||||
|
||||
function item_insert(int $uid, array $request, bool $preview, string $return_path)
|
||||
{
|
||||
$post = ['uid' => $uid];
|
||||
$post = DI::contentItem()->initializePost($post);
|
||||
|
||||
$post['edit'] = null;
|
||||
$post['post-type'] = $request['post_type'] ?? '';
|
||||
$post['wall'] = $request['wall'] ?? true;
|
||||
$post['pubmail'] = $request['pubmail_enable'] ?? false;
|
||||
$post['created'] = $request['created_at'] ?? DateTimeFormat::utcNow();
|
||||
$post['edited'] = $post['changed'] = $post['commented'] = $post['created'];
|
||||
$post['app'] = '';
|
||||
$post['inform'] = '';
|
||||
$post['postopts'] = '';
|
||||
$post['file'] = '';
|
||||
|
||||
if (!empty($request['parent'])) {
|
||||
$parent_item = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $request['parent']]);
|
||||
if ($parent_item) {
|
||||
// if this isn't the top-level parent of the conversation, find it
|
||||
if ($parent_item['gravity'] != Item::GRAVITY_PARENT) {
|
||||
$toplevel_item = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $parent_item['parent']]);
|
||||
} else {
|
||||
$toplevel_item = $parent_item;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($toplevel_item)) {
|
||||
if ($return_path) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Unable to locate original post.'));
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
throw new HTTPException\NotFoundException(DI::l10n()->t('Unable to locate original post.'));
|
||||
|
@ -136,561 +176,39 @@ function item_post(App $a) {
|
|||
// When commenting on a public post then store the post for the current user
|
||||
// This enables interaction like starring and saving into folders
|
||||
if ($toplevel_item['uid'] == 0) {
|
||||
$stored = Item::storeForUserByUriId($toplevel_item['uri-id'], DI::userSession()->getLocalUserId(), ['post-reason' => Item::PR_ACTIVITY]);
|
||||
Logger::info('Public item stored for user', ['uri-id' => $toplevel_item['uri-id'], 'uid' => $uid, 'stored' => $stored]);
|
||||
if ($stored) {
|
||||
$toplevel_item = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $stored]);
|
||||
}
|
||||
$stored = Item::storeForUserByUriId($toplevel_item['uri-id'], $post['uid'], ['post-reason' => Item::PR_ACTIVITY]);
|
||||
Logger::info('Public item stored for user', ['uri-id' => $toplevel_item['uri-id'], 'uid' => $post['uid'], 'stored' => $stored]);
|
||||
}
|
||||
|
||||
$toplevel_item_id = $toplevel_item['id'];
|
||||
$toplevel_user_id = $toplevel_item['uid'];
|
||||
|
||||
$objecttype = Activity\ObjectType::COMMENT;
|
||||
}
|
||||
|
||||
if ($toplevel_item_id) {
|
||||
Logger::info('mod_item: item_post', ['parent' => $toplevel_item_id]);
|
||||
}
|
||||
|
||||
$post_id = intval($_REQUEST['post_id'] ?? 0);
|
||||
$app = strip_tags($_REQUEST['source'] ?? '');
|
||||
$extid = strip_tags($_REQUEST['extid'] ?? '');
|
||||
$object = $_REQUEST['object'] ?? '';
|
||||
|
||||
// Don't use "defaults" here. It would turn 0 to 1
|
||||
if (!isset($_REQUEST['wall'])) {
|
||||
$wall = 1;
|
||||
$post['parent'] = $toplevel_item['id'];
|
||||
$post['gravity'] = Item::GRAVITY_COMMENT;
|
||||
$post['thr-parent'] = $parent_item['uri'];
|
||||
$post['wall'] = $toplevel_item['wall'];
|
||||
} else {
|
||||
$wall = $_REQUEST['wall'];
|
||||
$parent_item = [];
|
||||
$post['parent'] = 0;
|
||||
$post['gravity'] = Item::GRAVITY_PARENT;
|
||||
$post['thr-parent'] = $post['uri'];
|
||||
}
|
||||
|
||||
// Ensure that the user id in a thread always stay the same
|
||||
if (!is_null($toplevel_user_id) && in_array($toplevel_user_id, [DI::userSession()->getLocalUserId(), 0])) {
|
||||
$profile_uid = $toplevel_user_id;
|
||||
}
|
||||
$post = DI::contentItem()->getACL($post, $parent_item, $request);
|
||||
|
||||
// Allow commenting if it is an answer to a public post
|
||||
$allow_comment = DI::userSession()->getLocalUserId() && $toplevel_item_id && in_array($toplevel_item['private'], [Item::PUBLIC, Item::UNLISTED]) && in_array($toplevel_item['network'], Protocol::FEDERATED);
|
||||
$post['pubmail'] = $post['pubmail'] && !$post['private'];
|
||||
|
||||
// Now check that valid personal details have been provided
|
||||
if (!Security::canWriteToUserWall($profile_uid) && !$allow_comment) {
|
||||
Logger::warning('Permission denied.', ['local' => DI::userSession()->getLocalUserId(), 'toplevel_item_id' => $toplevel_item_id, 'network' => $toplevel_item['network']]);
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Permission denied.'));
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));
|
||||
}
|
||||
|
||||
// Init post instance
|
||||
$orig_post = null;
|
||||
|
||||
// is this an edited post?
|
||||
if ($post_id > 0) {
|
||||
$orig_post = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $post_id]);
|
||||
}
|
||||
|
||||
$user = User::getById($profile_uid, ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid']);
|
||||
if (!DBA::isResult($user) && !$toplevel_item_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$categories = '';
|
||||
$postopts = '';
|
||||
$emailcc = '';
|
||||
$body = $_REQUEST['body'] ?? '';
|
||||
$has_attachment = $_REQUEST['has_attachment'] ?? 0;
|
||||
|
||||
// If we have a speparate attachment, we need to add it to the body.
|
||||
if (!empty($has_attachment)) {
|
||||
$attachment_type = $_REQUEST['attachment_type'] ?? '';
|
||||
$attachment_title = $_REQUEST['attachment_title'] ?? '';
|
||||
$attachment_text = $_REQUEST['attachment_text'] ?? '';
|
||||
|
||||
$attachment_url = hex2bin($_REQUEST['attachment_url'] ?? '');
|
||||
$attachment_img_src = hex2bin($_REQUEST['attachment_img_src'] ?? '');
|
||||
|
||||
$attachment_img_width = $_REQUEST['attachment_img_width'] ?? 0;
|
||||
$attachment_img_height = $_REQUEST['attachment_img_height'] ?? 0;
|
||||
|
||||
// Fetch the basic attachment data
|
||||
$attachment = ParseUrl::getSiteinfoCached($attachment_url);
|
||||
unset($attachment['keywords']);
|
||||
|
||||
// Overwrite the basic data with possible changes from the frontend
|
||||
$attachment['type'] = $attachment_type;
|
||||
$attachment['title'] = $attachment_title;
|
||||
$attachment['text'] = $attachment_text;
|
||||
$attachment['url'] = $attachment_url;
|
||||
|
||||
if (!empty($attachment_img_src)) {
|
||||
$attachment['images'] = [
|
||||
0 => [
|
||||
'src' => $attachment_img_src,
|
||||
'width' => $attachment_img_width,
|
||||
'height' => $attachment_img_height
|
||||
]
|
||||
];
|
||||
} else {
|
||||
unset($attachment['images']);
|
||||
}
|
||||
|
||||
$att_bbcode = "\n" . PageInfo::getFooterFromData($attachment);
|
||||
$body .= $att_bbcode;
|
||||
} elseif (preg_match("/\[attachment\](.*?)\[\/attachment\]/ism", $body, $matches)) {
|
||||
$body = preg_replace("/\[attachment].*?\[\/attachment\]/ism", PageInfo::getFooterFromUrl($matches[1]), $body);
|
||||
}
|
||||
|
||||
// Convert links with empty descriptions to links without an explicit description
|
||||
$body = preg_replace('#\[url=([^\]]*?)\]\[/url\]#ism', '[url]$1[/url]', $body);
|
||||
|
||||
if (!empty($orig_post)) {
|
||||
$str_group_allow = $orig_post['allow_gid'];
|
||||
$str_contact_allow = $orig_post['allow_cid'];
|
||||
$str_group_deny = $orig_post['deny_gid'];
|
||||
$str_contact_deny = $orig_post['deny_cid'];
|
||||
$location = $orig_post['location'];
|
||||
$coord = $orig_post['coord'];
|
||||
$verb = $orig_post['verb'];
|
||||
$objecttype = $orig_post['object-type'];
|
||||
$app = $orig_post['app'];
|
||||
$categories = Post\Category::getTextByURIId($orig_post['uri-id'], $orig_post['uid']);
|
||||
$title = trim($_REQUEST['title'] ?? '');
|
||||
$body = trim($body);
|
||||
$private = $orig_post['private'];
|
||||
$pubmail_enabled = $orig_post['pubmail'];
|
||||
$network = $orig_post['network'];
|
||||
$guid = $orig_post['guid'];
|
||||
$extid = $orig_post['extid'];
|
||||
} else {
|
||||
$aclFormatter = DI::aclFormatter();
|
||||
$str_contact_allow = isset($_REQUEST['contact_allow']) ? $aclFormatter->toString($_REQUEST['contact_allow']) : $user['allow_cid'] ?? '';
|
||||
$str_group_allow = isset($_REQUEST['group_allow']) ? $aclFormatter->toString($_REQUEST['group_allow']) : $user['allow_gid'] ?? '';
|
||||
$str_contact_deny = isset($_REQUEST['contact_deny']) ? $aclFormatter->toString($_REQUEST['contact_deny']) : $user['deny_cid'] ?? '';
|
||||
$str_group_deny = isset($_REQUEST['group_deny']) ? $aclFormatter->toString($_REQUEST['group_deny']) : $user['deny_gid'] ?? '';
|
||||
|
||||
$visibility = $_REQUEST['visibility'] ?? '';
|
||||
if ($visibility === 'public') {
|
||||
// The ACL selector introduced in version 2019.12 sends ACL input data even when the Public visibility is selected
|
||||
$str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = '';
|
||||
} else if ($visibility === 'custom') {
|
||||
// Since we know from the visibility parameter the item should be private, we have to prevent the empty ACL
|
||||
// case that would make it public. So we always append the author's contact id to the allowed contacts.
|
||||
// See https://github.com/friendica/friendica/issues/9672
|
||||
$str_contact_allow .= $aclFormatter->toString(Contact::getPublicIdByUserId($uid));
|
||||
}
|
||||
|
||||
$title = trim($_REQUEST['title'] ?? '');
|
||||
$location = trim($_REQUEST['location'] ?? '');
|
||||
$coord = trim($_REQUEST['coord'] ?? '');
|
||||
$verb = trim($_REQUEST['verb'] ?? '');
|
||||
$emailcc = trim($_REQUEST['emailcc'] ?? '');
|
||||
$body = trim($body);
|
||||
$network = trim(($_REQUEST['network'] ?? '') ?: Protocol::DFRN);
|
||||
$guid = System::createUUID();
|
||||
|
||||
$postopts = $_REQUEST['postopts'] ?? '';
|
||||
|
||||
if (strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) {
|
||||
$private = Item::PRIVATE;
|
||||
} elseif (DI::pConfig()->get($profile_uid, 'system', 'unlisted')) {
|
||||
$private = Item::UNLISTED;
|
||||
} else {
|
||||
$private = Item::PUBLIC;
|
||||
}
|
||||
|
||||
// If this is a comment, set the permissions from the parent.
|
||||
|
||||
if ($toplevel_item) {
|
||||
// for non native networks use the network of the original post as network of the item
|
||||
if (($toplevel_item['network'] != Protocol::DIASPORA)
|
||||
&& ($toplevel_item['network'] != Protocol::OSTATUS)
|
||||
&& ($network == '')) {
|
||||
$network = $toplevel_item['network'];
|
||||
}
|
||||
|
||||
$str_contact_allow = $toplevel_item['allow_cid'] ?? '';
|
||||
$str_group_allow = $toplevel_item['allow_gid'] ?? '';
|
||||
$str_contact_deny = $toplevel_item['deny_cid'] ?? '';
|
||||
$str_group_deny = $toplevel_item['deny_gid'] ?? '';
|
||||
$private = $toplevel_item['private'];
|
||||
|
||||
$wall = $toplevel_item['wall'];
|
||||
}
|
||||
|
||||
$pubmail_enabled = ($_REQUEST['pubmail_enable'] ?? false) && !$private;
|
||||
|
||||
if (!strlen($body)) {
|
||||
if ($preview) {
|
||||
System::jsonExit(['preview' => '']);
|
||||
}
|
||||
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Empty post discarded.'));
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
throw new HTTPException\BadRequestException(DI::l10n()->t('Empty post discarded.'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($categories)) {
|
||||
// get the "fileas" tags for this post
|
||||
$filedas = FileTag::fileToArray($categories);
|
||||
}
|
||||
|
||||
$list_array = explode(',', trim($_REQUEST['category'] ?? ''));
|
||||
$categories = FileTag::arrayToFile($list_array, 'category');
|
||||
|
||||
if (!empty($filedas) && is_array($filedas)) {
|
||||
// append the fileas stuff to the new categories list
|
||||
$categories .= FileTag::arrayToFile($filedas);
|
||||
}
|
||||
|
||||
// get contact info for poster
|
||||
|
||||
$author = null;
|
||||
$self = false;
|
||||
$contact_id = 0;
|
||||
|
||||
if (DI::userSession()->getLocalUserId() && ((DI::userSession()->getLocalUserId() == $profile_uid) || $allow_comment)) {
|
||||
$self = true;
|
||||
$author = DBA::selectFirst('contact', [], ['uid' => DI::userSession()->getLocalUserId(), 'self' => true]);
|
||||
} elseif (!empty(DI::userSession()->getRemoteContactID($profile_uid))) {
|
||||
$author = DBA::selectFirst('contact', [], ['id' => DI::userSession()->getRemoteContactID($profile_uid)]);
|
||||
}
|
||||
|
||||
if (DBA::isResult($author)) {
|
||||
$contact_id = $author['id'];
|
||||
}
|
||||
|
||||
// get contact info for owner
|
||||
if ($profile_uid == DI::userSession()->getLocalUserId() || $allow_comment) {
|
||||
$contact_record = $author ?: [];
|
||||
} else {
|
||||
$contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]) ?: [];
|
||||
}
|
||||
|
||||
// Personal notes must never be altered to a forum post.
|
||||
if ($posttype != Item::PT_PERSONAL_NOTE) {
|
||||
// Look for any tags and linkify them
|
||||
$item = [
|
||||
'uid' => DI::userSession()->getLocalUserId() ? DI::userSession()->getLocalUserId() : $profile_uid,
|
||||
'gravity' => $toplevel_item_id ? Item::GRAVITY_COMMENT : Item::GRAVITY_PARENT,
|
||||
'network' => $network,
|
||||
'body' => $body,
|
||||
'postopts' => $postopts,
|
||||
'private' => $private,
|
||||
'allow_cid' => $str_contact_allow,
|
||||
'allow_gid' => $str_group_allow,
|
||||
'deny_cid' => $str_contact_deny,
|
||||
'deny_gid' => $str_group_deny,
|
||||
];
|
||||
|
||||
$item = DI::contentItem()->expandTags($item);
|
||||
|
||||
$body = $item['body'];
|
||||
$inform = $item['inform'];
|
||||
$postopts = $item['postopts'];
|
||||
$private = $item['private'];
|
||||
$str_contact_allow = $item['allow_cid'];
|
||||
$str_group_allow = $item['allow_gid'];
|
||||
$str_contact_deny = $item['deny_cid'];
|
||||
$str_group_deny = $item['deny_gid'];
|
||||
} else {
|
||||
$inform = '';
|
||||
}
|
||||
|
||||
/*
|
||||
* When a photo was uploaded into the message using the (profile wall) ajax
|
||||
* uploader, The permissions are initially set to disallow anybody but the
|
||||
* owner from seeing it. This is because the permissions may not yet have been
|
||||
* set for the post. If it's private, the photo permissions should be set
|
||||
* appropriately. But we didn't know the final permissions on the post until
|
||||
* now. So now we'll look for links of uploaded messages that are in the
|
||||
* post and set them to the same permissions as the post itself.
|
||||
*/
|
||||
|
||||
$match = null;
|
||||
|
||||
if (!$preview && Photo::setPermissionFromBody($body, $uid, $contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)) {
|
||||
$objecttype = Activity\ObjectType::IMAGE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next link in any attachment references we find in the post.
|
||||
*/
|
||||
$match = [];
|
||||
|
||||
/// @todo these lines should be moved to Model/Attach (Once it exists)
|
||||
if (!$preview && preg_match_all("/\[attachment\](.*?)\[\/attachment\]/", $body, $match)) {
|
||||
$attaches = $match[1];
|
||||
if (count($attaches)) {
|
||||
foreach ($attaches as $attach) {
|
||||
// Ensure to only modify attachments that you own
|
||||
$srch = '<' . intval($contact_id) . '>';
|
||||
|
||||
$condition = [
|
||||
'allow_cid' => $srch,
|
||||
'allow_gid' => '',
|
||||
'deny_cid' => '',
|
||||
'deny_gid' => '',
|
||||
'id' => $attach,
|
||||
];
|
||||
if (!Attach::exists($condition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fields = ['allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow,
|
||||
'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny];
|
||||
$condition = ['id' => $attach];
|
||||
Attach::update($fields, $condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// embedded bookmark or attachment in post? set bookmark flag
|
||||
|
||||
$data = BBCode::getAttachmentData($body);
|
||||
$match = [];
|
||||
if ((preg_match_all("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", $body, $match, PREG_SET_ORDER) || isset($data['type']))
|
||||
&& ($posttype != Item::PT_PERSONAL_NOTE)) {
|
||||
$posttype = Item::PT_PAGE;
|
||||
$objecttype = Activity\ObjectType::BOOKMARK;
|
||||
}
|
||||
|
||||
$body = DI::bbCodeVideo()->transform($body);
|
||||
|
||||
$body = BBCode::scaleExternalImages($body);
|
||||
|
||||
// Setting the object type if not defined before
|
||||
if (!$objecttype) {
|
||||
$objecttype = Activity\ObjectType::NOTE; // Default value
|
||||
$objectdata = BBCode::getAttachedData($body);
|
||||
|
||||
if ($objectdata['type'] == 'link') {
|
||||
$objecttype = Activity\ObjectType::BOOKMARK;
|
||||
} elseif ($objectdata['type'] == 'video') {
|
||||
$objecttype = Activity\ObjectType::VIDEO;
|
||||
} elseif ($objectdata['type'] == 'photo') {
|
||||
$objecttype = Activity\ObjectType::IMAGE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$attachments = '';
|
||||
$match = [];
|
||||
|
||||
if (preg_match_all('/(\[attachment\]([0-9]+)\[\/attachment\])/',$body,$match)) {
|
||||
foreach ($match[2] as $mtch) {
|
||||
$fields = ['id', 'filename', 'filesize', 'filetype'];
|
||||
$attachment = Attach::selectFirst($fields, ['id' => $mtch]);
|
||||
if ($attachment !== false) {
|
||||
if (strlen($attachments)) {
|
||||
$attachments .= ',';
|
||||
}
|
||||
$attachments .= Post\Media::getAttachElement(DI::baseUrl() . '/attach/' . $attachment['id'],
|
||||
$attachment['filesize'], $attachment['filetype'], $attachment['filename'] ?? '');
|
||||
}
|
||||
$body = str_replace($match[1],'',$body);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strlen($verb)) {
|
||||
$verb = Activity::POST;
|
||||
}
|
||||
|
||||
if ($network == '') {
|
||||
$network = Protocol::DFRN;
|
||||
}
|
||||
|
||||
$gravity = ($toplevel_item_id ? Item::GRAVITY_COMMENT : Item::GRAVITY_PARENT);
|
||||
|
||||
// even if the post arrived via API we are considering that it
|
||||
// originated on this site by default for determining relayability.
|
||||
|
||||
// Don't use "defaults" here. It would turn 0 to 1
|
||||
if (!isset($_REQUEST['origin'])) {
|
||||
$origin = 1;
|
||||
} else {
|
||||
$origin = $_REQUEST['origin'];
|
||||
}
|
||||
|
||||
$uri = Item::newURI($guid);
|
||||
|
||||
// Fallback so that we alway have a parent uri
|
||||
if (!$thr_parent_uri || !$toplevel_item_id) {
|
||||
$thr_parent_uri = $uri;
|
||||
}
|
||||
|
||||
$datarray = [
|
||||
'uid' => $profile_uid,
|
||||
'wall' => $wall,
|
||||
'gravity' => $gravity,
|
||||
'network' => $network,
|
||||
'contact-id' => $contact_id,
|
||||
'owner-name' => $contact_record['name'] ?? '',
|
||||
'owner-link' => $contact_record['url'] ?? '',
|
||||
'owner-avatar' => $contact_record['thumb'] ?? '',
|
||||
'author-name' => $author['name'],
|
||||
'author-link' => $author['url'],
|
||||
'author-avatar' => $author['thumb'],
|
||||
'created' => empty($_REQUEST['created_at']) ? DateTimeFormat::utcNow() : $_REQUEST['created_at'],
|
||||
'received' => DateTimeFormat::utcNow(),
|
||||
'extid' => $extid,
|
||||
'guid' => $guid,
|
||||
'uri' => $uri,
|
||||
'title' => $title,
|
||||
'body' => $body,
|
||||
'app' => $app,
|
||||
'location' => $location,
|
||||
'coord' => $coord,
|
||||
'file' => $categories,
|
||||
'inform' => $inform,
|
||||
'verb' => $verb,
|
||||
'post-type' => $posttype,
|
||||
'object-type' => $objecttype,
|
||||
'allow_cid' => $str_contact_allow,
|
||||
'allow_gid' => $str_group_allow,
|
||||
'deny_cid' => $str_contact_deny,
|
||||
'deny_gid' => $str_group_deny,
|
||||
'private' => $private,
|
||||
'pubmail' => $pubmail_enabled,
|
||||
'attach' => $attachments,
|
||||
'thr-parent' => $thr_parent_uri,
|
||||
'postopts' => $postopts,
|
||||
'origin' => $origin,
|
||||
'object' => $object,
|
||||
'attachments' => $_REQUEST['attachments'] ?? [],
|
||||
/*
|
||||
* These fields are for the convenience of addons...
|
||||
* 'self' if true indicates the owner is posting on their own wall
|
||||
* If parent is 0 it is a top-level post.
|
||||
*/
|
||||
'parent' => $toplevel_item_id,
|
||||
'self' => $self,
|
||||
// This triggers posts via API and the mirror functions
|
||||
'api_source' => false,
|
||||
// This field is for storing the raw conversation data
|
||||
'protocol' => Conversation::PARCEL_DIRECT,
|
||||
'direction' => Conversation::PUSH,
|
||||
];
|
||||
|
||||
// These cannot be part of above initialization ...
|
||||
$datarray['edited'] = $datarray['created'];
|
||||
$datarray['commented'] = $datarray['created'];
|
||||
$datarray['changed'] = $datarray['created'];
|
||||
$datarray['owner-id'] = Contact::getIdForURL($datarray['owner-link']);
|
||||
$datarray['author-id'] = Contact::getIdForURL($datarray['author-link']);
|
||||
|
||||
$datarray['edit'] = $orig_post;
|
||||
|
||||
// Check for hashtags in the body and repair or add hashtag links
|
||||
if ($preview || $orig_post) {
|
||||
$datarray['body'] = Item::setHashtags($datarray['body']);
|
||||
}
|
||||
|
||||
// preview mode - prepare the body for display and send it via json
|
||||
if ($preview) {
|
||||
// We set the datarray ID to -1 because in preview mode the dataray
|
||||
// doesn't have an ID.
|
||||
$datarray['id'] = -1;
|
||||
$datarray['uri-id'] = -1;
|
||||
$datarray['author-network'] = Protocol::DFRN;
|
||||
$datarray['author-updated'] = '';
|
||||
$datarray['author-gsid'] = 0;
|
||||
$datarray['author-uri-id'] = ItemURI::getIdByURI($datarray['author-link']);
|
||||
$datarray['owner-updated'] = '';
|
||||
$datarray['has-media'] = false;
|
||||
$datarray['quote-uri-id'] = Item::getQuoteUriId($datarray['body'], $datarray['uid']);
|
||||
$datarray['body'] = BBCode::removeSharedData($datarray['body']);
|
||||
|
||||
$o = DI::conversation()->create([array_merge($contact_record, $datarray)], 'search', false, true);
|
||||
|
||||
System::jsonExit(['preview' => $o]);
|
||||
}
|
||||
|
||||
Hook::callAll('post_local',$datarray);
|
||||
|
||||
if (!empty($_REQUEST['scheduled_at'])) {
|
||||
$scheduled_at = DateTimeFormat::convert($_REQUEST['scheduled_at'], 'UTC', $a->getTimeZone());
|
||||
if ($scheduled_at > DateTimeFormat::utcNow()) {
|
||||
unset($datarray['created']);
|
||||
unset($datarray['edited']);
|
||||
unset($datarray['commented']);
|
||||
unset($datarray['received']);
|
||||
unset($datarray['changed']);
|
||||
unset($datarray['edit']);
|
||||
unset($datarray['self']);
|
||||
unset($datarray['api_source']);
|
||||
|
||||
Post\Delayed::add($datarray['uri'], $datarray, Worker::PRIORITY_HIGH, Post\Delayed::PREPARED_NO_HOOK, $scheduled_at);
|
||||
item_post_return(DI::baseUrl(), $return_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($datarray['cancel'])) {
|
||||
Logger::info('mod_item: post cancelled by addon.');
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
$json = ['cancel' => 1];
|
||||
if (!empty($_REQUEST['jsreload'])) {
|
||||
$json['reload'] = DI::baseUrl() . '/' . $_REQUEST['jsreload'];
|
||||
}
|
||||
|
||||
System::jsonExit($json);
|
||||
}
|
||||
|
||||
$datarray['uri-id'] = ItemURI::getIdByURI($datarray['uri']);
|
||||
|
||||
$quote_uri_id = Item::getQuoteUriId($datarray['body'], $datarray['uid']);
|
||||
if (!empty($quote_uri_id)) {
|
||||
$datarray['quote-uri-id'] = $quote_uri_id;
|
||||
$datarray['body'] = BBCode::removeSharedData($datarray['body']);
|
||||
}
|
||||
|
||||
if ($orig_post) {
|
||||
$fields = [
|
||||
'title' => $datarray['title'],
|
||||
'body' => $datarray['body'],
|
||||
'attach' => $datarray['attach'],
|
||||
'file' => $datarray['file'],
|
||||
'edited' => DateTimeFormat::utcNow(),
|
||||
'changed' => DateTimeFormat::utcNow()
|
||||
];
|
||||
|
||||
Item::update($fields, ['id' => $post_id]);
|
||||
Item::updateDisplayCache($datarray['uri-id']);
|
||||
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
throw new HTTPException\OKException(DI::l10n()->t('Post updated.'));
|
||||
}
|
||||
|
||||
unset($datarray['edit']);
|
||||
unset($datarray['self']);
|
||||
unset($datarray['api_source']);
|
||||
|
||||
$post_id = Item::insert($datarray);
|
||||
$post = item_process($post, $request, $preview, $return_path);
|
||||
|
||||
$post_id = Item::insert($post);
|
||||
if (!$post_id) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Item wasn\'t stored.'));
|
||||
if ($return_path) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Item wasn\'t stored.'));
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
throw new HTTPException\InternalServerErrorException(DI::l10n()->t('Item wasn\'t stored.'));
|
||||
}
|
||||
|
||||
$datarray = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $post_id]);
|
||||
|
||||
if (!DBA::isResult($datarray)) {
|
||||
$post = Post::selectFirst(Item::ITEM_FIELDLIST, ['id' => $post_id]);
|
||||
if (!$post) {
|
||||
Logger::error('Item couldn\'t be fetched.', ['post_id' => $post_id]);
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
|
@ -699,52 +217,9 @@ function item_post(App $a) {
|
|||
throw new HTTPException\InternalServerErrorException(DI::l10n()->t('Item couldn\'t be fetched.'));
|
||||
}
|
||||
|
||||
Tag::storeFromBody($datarray['uri-id'], $datarray['body']);
|
||||
$recipients = explode(',', $request['emailcc'] ?? '');
|
||||
|
||||
if (!\Friendica\Content\Feature::isEnabled($uid, 'explicit_mentions') && ($datarray['gravity'] == Item::GRAVITY_COMMENT)) {
|
||||
Tag::createImplicitMentions($datarray['uri-id'], $datarray['thr-parent-id']);
|
||||
}
|
||||
|
||||
// These notifications are sent if someone else is commenting other your wall
|
||||
if ($contact_record != $author) {
|
||||
if ($toplevel_item_id) {
|
||||
DI::notify()->createFromArray([
|
||||
'type' => Notification\Type::COMMENT,
|
||||
'otype' => Notification\ObjectType::ITEM,
|
||||
'verb' => Activity::POST,
|
||||
'uid' => $profile_uid,
|
||||
'cid' => $datarray['author-id'],
|
||||
'item' => $datarray,
|
||||
'link' => DI::baseUrl() . '/display/' . urlencode($datarray['guid']),
|
||||
]);
|
||||
} elseif (empty($forum_contact)) {
|
||||
DI::notify()->createFromArray([
|
||||
'type' => Notification\Type::WALL,
|
||||
'otype' => Notification\ObjectType::ITEM,
|
||||
'verb' => Activity::POST,
|
||||
'uid' => $profile_uid,
|
||||
'cid' => $datarray['author-id'],
|
||||
'item' => $datarray,
|
||||
'link' => DI::baseUrl() . '/display/' . urlencode($datarray['guid']),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Hook::callAll('post_local_end', $datarray);
|
||||
|
||||
if (strlen($emailcc) && $profile_uid == DI::userSession()->getLocalUserId()) {
|
||||
$recipients = explode(',', $emailcc);
|
||||
if (count($recipients)) {
|
||||
foreach ($recipients as $recipient) {
|
||||
$address = trim($recipient);
|
||||
if (!strlen($address)) {
|
||||
continue;
|
||||
}
|
||||
DI::emailer()->send(new ItemCCEMail(DI::app(), DI::l10n(), DI::baseUrl(),
|
||||
$datarray, $address, $author['thumb'] ?? ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
DI::contentItem()->postProcessPost($post, $recipients);
|
||||
|
||||
Logger::debug('post_complete');
|
||||
|
||||
|
@ -752,6 +227,95 @@ function item_post(App $a) {
|
|||
// NOTREACHED
|
||||
}
|
||||
|
||||
function item_process(array $post, array $request, bool $preview, string $return_path): array
|
||||
{
|
||||
$post['self'] = true;
|
||||
$post['api_source'] = false;
|
||||
$post['attach'] = '';
|
||||
$post['title'] = trim($request['title'] ?? '');
|
||||
$post['body'] = $request['body'] ?? '';
|
||||
$post['location'] = trim($request['location'] ?? '');
|
||||
$post['coord'] = trim($request['coord'] ?? '');
|
||||
|
||||
$post = DI::contentItem()->addCategories($post, $request['category'] ?? '');
|
||||
|
||||
// Add the attachment to the body.
|
||||
if (!empty($request['has_attachment'])) {
|
||||
$post['body'] .= DI::contentItem()->storeAttachmentFromRequest($request);
|
||||
}
|
||||
|
||||
$post = DI::contentItem()->finalizePost($post);
|
||||
|
||||
if (!strlen($post['body'])) {
|
||||
if ($preview) {
|
||||
System::jsonExit(['preview' => '']);
|
||||
}
|
||||
|
||||
if ($return_path) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Empty post discarded.'));
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
throw new HTTPException\BadRequestException(DI::l10n()->t('Empty post discarded.'));
|
||||
}
|
||||
|
||||
// preview mode - prepare the body for display and send it via json
|
||||
if ($preview) {
|
||||
// We have to preset some fields, so that the conversation can be displayed
|
||||
$post['id'] = -1;
|
||||
$post['uri-id'] = -1;
|
||||
$post['author-network'] = Protocol::DFRN;
|
||||
$post['author-updated'] = '';
|
||||
$post['author-gsid'] = 0;
|
||||
$post['author-uri-id'] = ItemURI::getIdByURI($post['author-link']);
|
||||
$post['owner-updated'] = '';
|
||||
$post['has-media'] = false;
|
||||
$post['quote-uri-id'] = Item::getQuoteUriId($post['body'], $post['uid']);
|
||||
$post['body'] = BBCode::removeSharedData(Item::setHashtags($post['body']));
|
||||
$post['writable'] = true;
|
||||
|
||||
$o = DI::conversation()->create([$post], Conversation::MODE_SEARCH, false, true);
|
||||
|
||||
System::jsonExit(['preview' => $o]);
|
||||
}
|
||||
|
||||
Hook::callAll('post_local',$post);
|
||||
|
||||
unset($post['edit']);
|
||||
unset($post['self']);
|
||||
unset($post['api_source']);
|
||||
|
||||
if (!empty($request['scheduled_at'])) {
|
||||
$scheduled_at = DateTimeFormat::convert($request['scheduled_at'], 'UTC', DI::app()->getTimeZone());
|
||||
if ($scheduled_at > DateTimeFormat::utcNow()) {
|
||||
unset($post['created']);
|
||||
unset($post['edited']);
|
||||
unset($post['commented']);
|
||||
unset($post['received']);
|
||||
unset($post['changed']);
|
||||
|
||||
Post\Delayed::add($post['uri'], $post, Worker::PRIORITY_HIGH, Post\Delayed::PREPARED_NO_HOOK, $scheduled_at);
|
||||
item_post_return(DI::baseUrl(), $return_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($post['cancel'])) {
|
||||
Logger::info('mod_item: post cancelled by addon.');
|
||||
if ($return_path) {
|
||||
DI::baseUrl()->redirect($return_path);
|
||||
}
|
||||
|
||||
$json = ['cancel' => 1];
|
||||
if (!empty($request['jsreload'])) {
|
||||
$json['reload'] = DI::baseUrl() . '/' . $request['jsreload'];
|
||||
}
|
||||
|
||||
System::jsonExit($json);
|
||||
}
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
function item_post_return($baseurl, $return_path)
|
||||
{
|
||||
if ($return_path) {
|
||||
|
@ -804,6 +368,22 @@ function item_content(App $a)
|
|||
|
||||
Contact\User::setBlocked($item['author-id'], DI::userSession()->getLocalUserId(), true);
|
||||
|
||||
if (DI::mode()->isAjax()) {
|
||||
// ajax return: [<item id>, 0 (no perm) | <owner id>]
|
||||
System::jsonExit([intval($args->get(2)), DI::userSession()->getLocalUserId()]);
|
||||
} else {
|
||||
item_redirect_after_action($item, $args->get(3));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'ignore':
|
||||
$item = Post::selectFirstForUser(DI::userSession()->getLocalUserId(), ['guid', 'author-id', 'parent', 'gravity'], ['id' => $args->get(2)]);
|
||||
if (empty($item['author-id'])) {
|
||||
throw new HTTPException\NotFoundException('Item not found');
|
||||
}
|
||||
|
||||
Contact\User::setIgnored($item['author-id'], DI::userSession()->getLocalUserId(), true);
|
||||
|
||||
if (DI::mode()->isAjax()) {
|
||||
// ajax return: [<item id>, 0 (no perm) | <owner id>]
|
||||
System::jsonExit([intval($args->get(2)), DI::userSession()->getLocalUserId()]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -58,7 +58,6 @@ function message_init(App $a)
|
|||
|
||||
$head_tpl = Renderer::getMarkupTemplate('message-head.tpl');
|
||||
DI::page()['htmlhead'] .= Renderer::replaceMacros($head_tpl, [
|
||||
'$baseurl' => DI::baseUrl()->get(true),
|
||||
'$base' => $base
|
||||
]);
|
||||
}
|
||||
|
@ -70,12 +69,13 @@ function message_post(App $a)
|
|||
return;
|
||||
}
|
||||
|
||||
$sender_id = DI::userSession()->getLocalUserId();
|
||||
$replyto = !empty($_REQUEST['replyto']) ? trim($_REQUEST['replyto']) : '';
|
||||
$subject = !empty($_REQUEST['subject']) ? trim($_REQUEST['subject']) : '';
|
||||
$body = !empty($_REQUEST['body']) ? Strings::escapeHtml(trim($_REQUEST['body'])) : '';
|
||||
$recipient = !empty($_REQUEST['recipient']) ? intval($_REQUEST['recipient']) : 0;
|
||||
|
||||
$ret = Mail::send($recipient, $body, $subject, $replyto);
|
||||
$ret = Mail::send($sender_id, $recipient, $body, $subject, $replyto);
|
||||
$norecip = false;
|
||||
|
||||
switch ($ret) {
|
||||
|
@ -178,7 +178,6 @@ function message_content(App $a)
|
|||
|
||||
$tpl = Renderer::getMarkupTemplate('msg-header.tpl');
|
||||
DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, [
|
||||
'$baseurl' => DI::baseUrl()->get(true),
|
||||
'$nickname' => $a->getLoggedInUserNickname(),
|
||||
'$linkurl' => DI::l10n()->t('Please enter a link URL:')
|
||||
]);
|
||||
|
@ -284,7 +283,6 @@ function message_content(App $a)
|
|||
|
||||
$tpl = Renderer::getMarkupTemplate('msg-header.tpl');
|
||||
DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, [
|
||||
'$baseurl' => DI::baseUrl()->get(true),
|
||||
'$nickname' => $a->getLoggedInUserNickname(),
|
||||
'$linkurl' => DI::l10n()->t('Please enter a link URL:')
|
||||
]);
|
||||
|
@ -438,7 +436,7 @@ function render_messages(array $msg, string $t): string
|
|||
$to_name_e = $rr['name'];
|
||||
|
||||
if (is_null($rr['url'])) {
|
||||
// contact-id is pointing to a non existing contact
|
||||
// contact-id is pointing to a nonexistent contact
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Conversation;
|
||||
use Friendica\Content\Nav;
|
||||
use Friendica\Content\Pager;
|
||||
use Friendica\Database\DBA;
|
||||
|
@ -84,7 +85,7 @@ function notes_content(App $a, bool $update = false)
|
|||
|
||||
$count = count($notes);
|
||||
|
||||
$o .= DI::conversation()->create($notes, 'notes', $update);
|
||||
$o .= DI::conversation()->create($notes, Conversation::MODE_NOTES, $update);
|
||||
}
|
||||
|
||||
$o .= $pager->renderMinimal($count);
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Content\Text\HTML;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Module\Security\Login;
|
||||
use Friendica\Util\XML;
|
||||
|
||||
function oexchange_init(App $a)
|
||||
{
|
||||
if ((DI::args()->getArgc() <= 1) || (DI::args()->getArgv()[1] != 'xrd')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$baseURL = DI::baseUrl()->get();
|
||||
|
||||
$xml = null;
|
||||
|
||||
XML::fromArray([
|
||||
'XRD' => [
|
||||
'@attributes' => [
|
||||
'xmlns' => 'http://docs.oasis-open.org/ns/xri/xrd-1.0',
|
||||
],
|
||||
'Subject' => $baseURL,
|
||||
'1:Property' => [
|
||||
'@attributes' => [
|
||||
'type' => 'http://www.oexchange.org/spec/0.8/prop/vendor',
|
||||
],
|
||||
'Friendica'
|
||||
],
|
||||
'2:Property' => [
|
||||
'@attributes' => [
|
||||
'type' => 'http://www.oexchange.org/spec/0.8/prop/title',
|
||||
],
|
||||
'Friendica Social Network'
|
||||
],
|
||||
'3:Property' => [
|
||||
'@attributes' => [
|
||||
'type' => 'http://www.oexchange.org/spec/0.8/prop/name',
|
||||
],
|
||||
'Friendica'
|
||||
],
|
||||
'4:Property' => [
|
||||
'@attributes' => [
|
||||
'type' => 'http://www.oexchange.org/spec/0.8/prop/prompt',
|
||||
],
|
||||
'Send to Friendica'
|
||||
],
|
||||
'1:link' => [
|
||||
'@attributes' => [
|
||||
'rel' => 'icon',
|
||||
'type' => 'image/png',
|
||||
'href' => $baseURL . '/images/friendica-16.png'
|
||||
]
|
||||
],
|
||||
'2:link' => [
|
||||
'@attributes' => [
|
||||
'rel' => 'icon32',
|
||||
'type' => 'image/png',
|
||||
'href' => $baseURL . '/images/friendica-32.png'
|
||||
]
|
||||
],
|
||||
'3:link' => [
|
||||
'@attributes' => [
|
||||
'rel' => 'http://www.oexchange.org/spec/0.8/rel/offer',
|
||||
'type' => 'text/html',
|
||||
'href' => $baseURL . '/oexchange'
|
||||
]
|
||||
],
|
||||
],
|
||||
], $xml);
|
||||
|
||||
System::httpExit($xml->saveXML(), Response::TYPE_XML, 'application/xrd+xml');
|
||||
}
|
||||
|
||||
function oexchange_content(App $a)
|
||||
{
|
||||
if (!DI::userSession()->getLocalUserId()) {
|
||||
$o = Login::form();
|
||||
return $o;
|
||||
}
|
||||
|
||||
if ((DI::args()->getArgc() > 1) && DI::args()->getArgv()[1] === 'done') {
|
||||
return;
|
||||
}
|
||||
|
||||
$url = !empty($_REQUEST['url']) ? trim($_REQUEST['url']) : '';
|
||||
$title = !empty($_REQUEST['title']) ? trim($_REQUEST['title']) : '';
|
||||
$description = !empty($_REQUEST['description']) ? trim($_REQUEST['description']) : '';
|
||||
$tags = !empty($_REQUEST['tags']) ? trim($_REQUEST['tags']) : '';
|
||||
|
||||
$s = BBCode::embedURL($url, true, $title, $description, $tags);
|
||||
|
||||
if (!strlen($s)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post = [];
|
||||
|
||||
$post['return'] = '/oexchange/done';
|
||||
$post['body'] = HTML::toBBCode($s);
|
||||
|
||||
$_REQUEST = $post;
|
||||
require_once 'mod/item.php';
|
||||
item_post($a);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -31,6 +31,7 @@ use Friendica\Core\Logger;
|
|||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
|
@ -61,7 +62,7 @@ function photos_init(App $a)
|
|||
Nav::setSelected('home');
|
||||
|
||||
if (DI::args()->getArgc() > 1) {
|
||||
$owner = User::getOwnerDataByNick(DI::args()->getArgv()[1]);
|
||||
$owner = Profile::load(DI::app(), DI::args()->getArgv()[1], false);
|
||||
if (!isset($owner['account_removed']) || $owner['account_removed']) {
|
||||
throw new HTTPException\NotFoundException(DI::l10n()->t('User not found.'));
|
||||
}
|
||||
|
@ -110,12 +111,6 @@ function photos_init(App $a)
|
|||
]);
|
||||
}
|
||||
|
||||
if (empty(DI::page()['aside'])) {
|
||||
DI::page()['aside'] = '';
|
||||
}
|
||||
|
||||
DI::page()['aside'] .= Widget\VCard::getHTML($owner);
|
||||
|
||||
if (!empty($photo_albums_widget)) {
|
||||
DI::page()['aside'] .= $photo_albums_widget;
|
||||
}
|
||||
|
@ -719,7 +714,7 @@ function photos_content(App $a)
|
|||
// When PHP is configured with upload_max_filesize less than maximagesize provide this lower limit.
|
||||
$maximagesize_bytes = (is_numeric($mis_bytes) && ($mis_bytes < $umf_bytes) ? $mis_bytes : $umf_bytes);
|
||||
|
||||
// @todo We may be want to use appropriate binary prefixed dynamicly
|
||||
// @todo We may be want to use appropriate binary prefixed dynamically
|
||||
$usage_message = DI::l10n()->t('The maximum accepted image size is %s', Strings::formatBytes($maximagesize_bytes));
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('photos_upload.tpl');
|
||||
|
@ -923,7 +918,7 @@ function photos_content(App $a)
|
|||
|
||||
if ($order_field === 'created') {
|
||||
$params = ['order' => [$order_field]];
|
||||
} elseif (!empty($order_field)) {
|
||||
} elseif (!empty($order_field) && DBStructure::existsColumn('photo', [$order_field])) {
|
||||
$params = ['order' => [$order_field => true]];
|
||||
} else {
|
||||
$params = [];
|
||||
|
@ -936,11 +931,17 @@ function photos_content(App $a)
|
|||
$nxt = null;
|
||||
foreach ($prvnxt as $z => $entry) {
|
||||
if ($entry['resource-id'] == $ph[0]['resource-id']) {
|
||||
$prv = $z - 1;
|
||||
$nxt = $z + 1;
|
||||
$prv = $order_field === 'created' ? $z - 1 : $z + 1;
|
||||
$nxt = $order_field === 'created' ? $z + 1 : $z - 1;
|
||||
if ($prv < 0) {
|
||||
$prv = count($prvnxt) - 1;
|
||||
}
|
||||
if ($nxt < 0) {
|
||||
$nxt = count($prvnxt) - 1;
|
||||
}
|
||||
if ($prv >= count($prvnxt)) {
|
||||
$prv = 0;
|
||||
}
|
||||
if ($nxt >= count($prvnxt)) {
|
||||
$nxt = 0;
|
||||
}
|
||||
|
@ -1138,7 +1139,7 @@ function photos_content(App $a)
|
|||
'$preview' => DI::l10n()->t('Preview'),
|
||||
'$loading' => DI::l10n()->t('Loading...'),
|
||||
'$qcomment' => $qcomment,
|
||||
'$rand_num' => Crypto::randomDigits(12)
|
||||
'$rand_num' => Crypto::randomDigits(12),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -1193,7 +1194,7 @@ function photos_content(App $a)
|
|||
'$submit' => DI::l10n()->t('Submit'),
|
||||
'$preview' => DI::l10n()->t('Preview'),
|
||||
'$qcomment' => $qcomment,
|
||||
'$rand_num' => Crypto::randomDigits(12)
|
||||
'$rand_num' => Crypto::randomDigits(12),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -1267,7 +1268,7 @@ function photos_content(App $a)
|
|||
'$submit' => DI::l10n()->t('Submit'),
|
||||
'$preview' => DI::l10n()->t('Preview'),
|
||||
'$qcomment' => $qcomment,
|
||||
'$rand_num' => Crypto::randomDigits(12)
|
||||
'$rand_num' => Crypto::randomDigits(12),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -30,7 +30,7 @@ use Friendica\Model\Contact;
|
|||
|
||||
function update_contact_content(App $a)
|
||||
{
|
||||
if (!empty(DI::args()->get(1)) && (!empty($_GET['force']) || !DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'no_auto_update'))) {
|
||||
if (!empty(DI::args()->get(1)) && !empty($_GET['force'])) {
|
||||
$contact = Contact::getById(DI::args()->get(1), ['id', 'deleted']);
|
||||
if (DBA::isResult($contact) && empty($contact['deleted'])) {
|
||||
DI::page()['aside'] = '';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|
|
@ -32,5 +32,9 @@ Please check software documentation to know how modify these examples to make th
|
|||
Sample systemd unit files to start worker.php periodically.
|
||||
|
||||
Please place them in the correct location for your system, typically this is `/etc/systemd/system/friendicaworker.timer` and `/etc/systemd/system/friendicaworker.service`.
|
||||
Please report problems and improvements to `!helpers@forum.friendi.ca` and `@utzer@social.yl.ms` or open an issue in [the Github Friendica page](https://github.com/friendica/friendica/issues).
|
||||
Please report problems and improvements to `!helpers@forum.friendi.ca` and `@utzer@social.yl.ms` or open an issue in [the GitHub Friendica page](https://github.com/friendica/friendica/issues).
|
||||
This is for usage of systemd instead of cron to start the worker periodically, the solution is a work-in-progress and can surely be improved.
|
||||
|
||||
## `phpstorm-code-style.xml`
|
||||
|
||||
PHP Storm Code Style settings, used for this codebase
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Bookmarklet-share2friendica
|
||||
|
||||
Javascript bookmarklet to share websites with your friendica account
|
||||
JavaScript bookmarklet to share websites with your friendica account
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installing
|
||||
|
||||
Open the file bookmarklet-share2friendica.js and change 'YourFriendicaDoomain.tld" with your friendica domain
|
||||
Open the file bookmarklet-share2friendica.js and change 'YourFriendicaDomain.tld" with your friendica domain
|
||||
|
||||
If you friendica is at https://myfriend.myfami.ly/ , the original ...
|
||||
```javascript
|
||||
|
@ -20,7 +20,7 @@ javascript:(function(){f='https://myfriend.myfami.ly/bookmarklet/?url='+encodeUR
|
|||
|
||||
*Please copy the whole script, not only the part mentioned here!*
|
||||
|
||||
Then create a new bookmark, give it a name like "share2Friendica" and paste the script in the address field. Save it. Now you can click on that bookmarklet every time you want to share a website, you are currently reading. A new small window will open where title is prefilled and the website you want to share is put as attachement in the body of the new post.
|
||||
Then create a new bookmark, give it a name like "share2Friendica" and paste the script in the address field. Save it. Now you can click on that bookmarklet every time you want to share a website, you are currently reading. A new small window will open where title is prefilled and the website you want to share is put as attachment in the body of the new post.
|
||||
|
||||
## Additional notes if it doesn't work
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!-- styling for this page is done in the home.css file //-->
|
||||
|
||||
<!-- Some node specifiv welcome message //-->
|
||||
<!-- Some node specific welcome message //-->
|
||||
<p>Welcome to this <a href="https://friendi.ca">Friendica</a> node!</p>
|
||||
|
||||
<!-- Some general notes about Friendica, the other networks and difficulty to run //-->
|
||||
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
<div id="c3" class="homeinfobox">
|
||||
<h4>Is it hard to run Friendica?</h4>
|
||||
<p>No, not at all! You need a LAMP server, most shared hosting services that offer MySQL, PHP and the ability to run cron jobs will do just fine. If you have your own (virtual) server, for a small Friendica server something like a Raspberry2B is sufficenent from the specs.</p>
|
||||
<p>No, not at all! You need a LAMP server, most shared hosting services that offer MySQL, PHP and the ability to run cron jobs will do just fine. If you have your own (virtual) server, for a small Friendica server something like a Raspberry2B is sufficient from the specs.</p>
|
||||
<p><a href="https://github.com/friendica/friendica">Get the source</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
50
mods/local.config.ci.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2023, 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
return [
|
||||
'database' => [
|
||||
'hostname' => 'localhost',
|
||||
'username' => 'friendica',
|
||||
'password' => 'friendica',
|
||||
'database' => 'friendica',
|
||||
'charset' => 'utf8mb4',
|
||||
],
|
||||
|
||||
// ****************************************************************
|
||||
// The configuration below will be overruled by the admin panel.
|
||||
// Changes made below will only have an effect if the database does
|
||||
// not contain any configuration for the friendica system.
|
||||
// ****************************************************************
|
||||
|
||||
'config' => [
|
||||
'admin_email' => 'admin@friendica.local',
|
||||
'sitename' => 'Friendica Social Network',
|
||||
'register_policy' => \Friendica\Module\Register::OPEN,
|
||||
'register_text' => '',
|
||||
],
|
||||
'system' => [
|
||||
'default_timezone' => 'UTC',
|
||||
'language' => 'en',
|
||||
'url' => 'https://friendica.local',
|
||||
// don't start unexpected worker.php processes during test!
|
||||
'worker_dont_fork' => true,
|
||||
],
|
||||
];
|
|
@ -29,7 +29,6 @@ return [
|
|||
// ****************************************************************
|
||||
|
||||
'config' => [
|
||||
'hostname' => '192.168.56.10',
|
||||
'admin_email' => 'admin@friendica.local',
|
||||
'sitename' => 'Friendica Social Network',
|
||||
'register_policy' => \Friendica\Module\Register::OPEN,
|
||||
|
@ -39,6 +38,6 @@ return [
|
|||
'default_timezone' => 'UTC',
|
||||
'language' => 'en',
|
||||
'basepath' => '/vagrant',
|
||||
'ssl_policy' => \Friendica\App\BaseURL::SSL_POLICY_SELFSIGN,
|
||||
'url' => 'https://192.168.56.10',
|
||||
],
|
||||
];
|
||||
|
|
34
mods/phpstorm-code-style.xml
Normal file
|
@ -0,0 +1,34 @@
|
|||
<code_scheme name="Default" version="173">
|
||||
<Markdown>
|
||||
<option name="WRAP_TEXT_IF_LONG" value="false" />
|
||||
<option name="WRAP_TEXT_INSIDE_BLOCKQUOTES" value="false" />
|
||||
</Markdown>
|
||||
<PHPCodeStyleSettings>
|
||||
<option name="ALIGN_KEY_VALUE_PAIRS" value="true" />
|
||||
<option name="ALIGN_PHPDOC_PARAM_NAMES" value="true" />
|
||||
<option name="ALIGN_PHPDOC_COMMENTS" value="true" />
|
||||
<option name="ALIGN_ASSIGNMENTS" value="true" />
|
||||
<option name="COMMA_AFTER_LAST_ARRAY_ELEMENT" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
|
||||
<option name="PHPDOC_WRAP_LONG_LINES" value="true" />
|
||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
||||
<option name="ELSE_IF_STYLE" value="SEPARATE" />
|
||||
<option name="VARIABLE_NAMING_STYLE" value="CAMEL_CASE" />
|
||||
<option name="ALIGN_CLASS_CONSTANTS" value="true" />
|
||||
<option name="FORCE_SHORT_DECLARATION_ARRAY_STYLE" value="true" />
|
||||
</PHPCodeStyleSettings>
|
||||
<codeStyleSettings language="PHP">
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
|
@ -22,7 +22,7 @@ the requested URL.
|
|||
Enjoy!
|
||||
|
||||
On Debian Jessie with lighttpd 1.4.35-4 there was a problem encountered
|
||||
between curl (which is used by Friendica in the background) and lighttp.
|
||||
between curl (which is used by Friendica in the background) and lighttpd.
|
||||
This problem caused requests being served with an error code of 417 in
|
||||
the logs and no delivery of postings from the contacts.
|
||||
|
||||
|
@ -30,7 +30,7 @@ One can solve the issue by adding
|
|||
|
||||
server.reject-expect-100-with-417 = "disable"
|
||||
|
||||
to the lighttpd configuratiion file (e.g. in the beginning with the
|
||||
to the lighttpd configuration file (e.g. in the beginning with the
|
||||
other 'server.xxx' settings.
|
||||
|
||||
---------------( config starts )-----------------
|
||||
|
|
|
@ -30,12 +30,29 @@
|
|||
##
|
||||
# This configuration assumes your domain is example.net
|
||||
# You have a separate subdomain friendica.example.net
|
||||
# You want all Friendica traffic to be https using letsencrypt with cerbot
|
||||
# You want all Friendica traffic to be https using letsencrypt with certbot
|
||||
# You have an SSL certificate and key for your subdomain
|
||||
# You have PHP FastCGI Process Manager (php7.4-fpm) running on localhost
|
||||
# You have Friendica installed in /var/www/friendica
|
||||
##
|
||||
|
||||
##
|
||||
# by https://syshero.org/2018-04-13-nginx-unique-request-identifier/
|
||||
# if X-Request-ID is set, NGINX will forward the same value to the next upstream
|
||||
# if the header is not set, NGINX will generate a random request identifier and add it to the request.
|
||||
#
|
||||
# To guarantee backward compatibility, map to format the $request_id variable to a format that matches any old setups.
|
||||
##
|
||||
|
||||
map $request_id $formatted_id {
|
||||
"~*(?<p1>[0-9a-f]{8})(?<p2>[0-9a-f]{4})(?<p3>[0-9a-f]{4})(?<p4>[0-9a-f]{4})(?<p5>.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}";
|
||||
}
|
||||
|
||||
map $http_x_request_id $uuid {
|
||||
default "${request_id}";
|
||||
~* "${http_x_request_id}";
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name friendica.example.net;
|
||||
|
@ -60,6 +77,9 @@ server {
|
|||
client_max_body_size 20m;
|
||||
client_body_buffer_size 128k;
|
||||
|
||||
# add the request id header to show it in the HTTP header output
|
||||
add_header X-Request-ID $uuid;
|
||||
|
||||
# rewrite to front controller as default rule
|
||||
location / {
|
||||
try_files $uri /index.php?pagename=$uri&$args;
|
||||
|
@ -106,6 +126,8 @@ server {
|
|||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
|
||||
fastcgi_param HTTP_X_REQUEST_ID $uuid;
|
||||
|
||||
fastcgi_buffers 16 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,25 @@
|
|||
# -----
|
||||
...
|
||||
|
||||
|
||||
##
|
||||
# by https://syshero.org/2018-04-13-nginx-unique-request-identifier/
|
||||
# if X-Request-ID is set, NGINX will forward the same value to the next upstream
|
||||
# if the header is not set, NGINX will generate a random request identifier and add it to the request.
|
||||
#
|
||||
# To guarantee backward compatibility, map to format the $request_id variable to a format that matches any old setups.
|
||||
##
|
||||
|
||||
map $request_id $formatted_id {
|
||||
"~*(?<p1>[0-9a-f]{8})(?<p2>[0-9a-f]{4})(?<p3>[0-9a-f]{4})(?<p4>[0-9a-f]{4})(?<p5>.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}";
|
||||
}
|
||||
|
||||
map $http_x_request_id $uuid {
|
||||
default "${request_id}";
|
||||
~* "${http_x_request_id}";
|
||||
}
|
||||
|
||||
|
||||
server {
|
||||
|
||||
...
|
||||
|
@ -30,6 +49,7 @@ server {
|
|||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Forwarded "for=$proxy_add_x_forwarded_for; proto=$scheme";
|
||||
proxy_set_header X-Request-ID $uuid;
|
||||
}
|
||||
|
||||
...
|
||||
|
|
|
@ -20,6 +20,24 @@
|
|||
# http://wiki.nginx.org/Configuration
|
||||
##
|
||||
|
||||
##
|
||||
# by https://syshero.org/2018-04-13-nginx-unique-request-identifier/
|
||||
# if X-Request-ID is set, NGINX will forward the same value to the next upstream
|
||||
# if the header is not set, NGINX will generate a random request identifier and add it to the request.
|
||||
#
|
||||
# To guarantee backward compatibility, map to format the $request_id variable to a format that matches any old setups.
|
||||
##
|
||||
|
||||
map $request_id $formatted_id {
|
||||
"~*(?<p1>[0-9a-f]{8})(?<p2>[0-9a-f]{4})(?<p3>[0-9a-f]{4})(?<p4>[0-9a-f]{4})(?<p5>.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}";
|
||||
}
|
||||
|
||||
map $http_x_request_id $uuid {
|
||||
default "${request_id}";
|
||||
~* "${http_x_request_id}";
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# This configuration assumes your domain is example.net
|
||||
# You have a separate subdomain friendica.example.net
|
||||
|
@ -80,6 +98,9 @@ server {
|
|||
client_max_body_size 20m;
|
||||
client_body_buffer_size 128k;
|
||||
|
||||
# add the request id header to show it in the HTTP header output
|
||||
add_header X-Request-ID $uuid;
|
||||
|
||||
# rewrite to front controller as default rule
|
||||
location / {
|
||||
try_files $uri /index.php?pagename=$uri&$args;
|
||||
|
@ -125,6 +146,7 @@ server {
|
|||
include fastcgi_params;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param HTTP_X_REQUEST_ID $uuid;
|
||||
|
||||
fastcgi_buffers 16 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Contact: mailto:info@friendi.ca
|
||||
|
||||
Expires: Sat, 30 Sept 2023 23:59 +0000
|
||||
Expires: 2023-12-31T23:59:59Z
|
||||
|
||||
Preferred-Languages: en
|
||||
|
||||
|
|
14
spec/zot.txt
|
@ -45,7 +45,7 @@ is a superset of salmon).
|
|||
zot:key
|
||||
*******
|
||||
|
||||
A suitable randomly generated encyption key of length 32 octets for encrypting
|
||||
A suitable randomly generated encryption key of length 32 octets for encrypting
|
||||
the salmon packet. This is then encrypted with the sender's private key and
|
||||
base64url encoded.
|
||||
|
||||
|
@ -59,7 +59,7 @@ key and base64url encoded.
|
|||
zot:env_key
|
||||
***********
|
||||
|
||||
A suitable randomly generated encyption key of length 32 octets for encrypting
|
||||
A suitable randomly generated encryption key of length 32 octets for encrypting
|
||||
the envelope. This is then encrypted with the recipient's public key and
|
||||
base64url encoded. For bulk deliveries, it is encrypted with the site bulk
|
||||
delivery public key.
|
||||
|
@ -127,7 +127,7 @@ MUST be present.
|
|||
Z-To: zot:bob@example.com, zot:alice@example.com, mailto:dave@example.com
|
||||
Z-Bcc: zot:https://example.com/profile/richard
|
||||
|
||||
are valid entries. Adresses are comma separated and individual entries MUST NOT
|
||||
are valid entries. Addresses are comma separated and individual entries MUST NOT
|
||||
contain commas. There MAY be any number of ASCII space characters between
|
||||
entries for legibility. Header lines are terminated with a linefeed character
|
||||
(ASCII 0x0A).
|
||||
|
@ -136,8 +136,8 @@ This specification provides the following protocol address prefixes
|
|||
for use in Z-To: or Z-Bcc: elements:
|
||||
|
||||
zot: - normal zot delivery using webfinger or LRDD resolvable address
|
||||
dfrn: - legacy DFRN mode delivery using webfinger or LRDD resovable address
|
||||
ostatus: - normal OStatus delivery using webfinger or LRDD resovable address
|
||||
dfrn: - legacy DFRN mode delivery using webfinger or LRDD resolvable address
|
||||
ostatus: - normal OStatus delivery using webfinger or LRDD resolvable address
|
||||
diaspora: - Diaspora network delivery using webfinger address
|
||||
facebook: - Facebook profile page URL
|
||||
twitter: - Twitter personal page URL without AJAX '#!' fragment
|
||||
|
@ -289,7 +289,7 @@ systems MAY reject foreign messages.
|
|||
*******************************
|
||||
|
||||
This section of the document is considered separate from the delivery
|
||||
specification precding it and represents a different protocol, which is
|
||||
specification preceding it and represents a different protocol, which is
|
||||
currently incomplete. This will be split off into another document in the
|
||||
future, but is presented here as a synergistic component of the Zot network
|
||||
model.
|
||||
|
@ -353,7 +353,7 @@ Salmon Magic Envelope
|
|||
Atom Activity Stream Draft
|
||||
http://activitystrea.ms/specs/atom/1.0/
|
||||
|
||||
Activty Stream Base Schema
|
||||
Activity Stream Base Schema
|
||||
http://activitystrea.ms/head/activity-schema.html
|
||||
|
||||
WebFinger Protocol
|
||||
|
|
110
src/App.php
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -25,11 +25,11 @@ use Exception;
|
|||
use Friendica\App\Arguments;
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\Capabilities\ICanCreateResponses;
|
||||
use Friendica\Content\Nav;
|
||||
use Friendica\Core\Config\Factory\Config;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Database\Definition\DbaDefinition;
|
||||
use Friendica\Database\Definition\ViewDefinition;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\Maintenance;
|
||||
use Friendica\Security\Authentication;
|
||||
use Friendica\Core\Config\ValueObject\Cache;
|
||||
|
@ -64,7 +64,7 @@ class App
|
|||
{
|
||||
const PLATFORM = 'Friendica';
|
||||
const CODENAME = 'Giant Rhubarb';
|
||||
const VERSION = '2023.01';
|
||||
const VERSION = '2023.03-rc';
|
||||
|
||||
// Allow themes to control internal parameters
|
||||
// by changing App values in theme.php
|
||||
|
@ -73,8 +73,6 @@ class App
|
|||
'videoheight' => 350,
|
||||
];
|
||||
|
||||
private $user_id = 0;
|
||||
private $nickname = '';
|
||||
private $timezone = '';
|
||||
private $profile_owner = 0;
|
||||
private $contact_id = 0;
|
||||
|
@ -136,64 +134,39 @@ class App
|
|||
private $session;
|
||||
|
||||
/**
|
||||
* Set the user ID
|
||||
*
|
||||
* @param int $user_id
|
||||
* @return void
|
||||
* @deprecated 2022.03
|
||||
* @see IHandleUserSessions::isAuthenticated()
|
||||
*/
|
||||
public function setLoggedInUserId(int $user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nickname
|
||||
*
|
||||
* @param int $user_id
|
||||
* @return void
|
||||
*/
|
||||
public function setLoggedInUserNickname(string $nickname)
|
||||
{
|
||||
$this->nickname = $nickname;
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool
|
||||
{
|
||||
return $this->session->getLocalUserId() && $this->user_id && ($this->user_id == $this->session->getLocalUserId());
|
||||
return $this->session->isAuthenticated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current user has admin role.
|
||||
*
|
||||
* @return bool true if user is an admin
|
||||
* @throws Exception
|
||||
* @deprecated 2022.03
|
||||
* @see IHandleUserSessions::isSiteAdmin()
|
||||
*/
|
||||
public function isSiteAdmin(): bool
|
||||
{
|
||||
return
|
||||
$this->session->getLocalUserId()
|
||||
&& $this->database->exists('user', [
|
||||
'uid' => $this->getLoggedInUserId(),
|
||||
'email' => User::getAdminEmailList()
|
||||
]);
|
||||
return $this->session->isSiteAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the user id
|
||||
* @return int User id
|
||||
* @deprecated 2022.03
|
||||
* @see IHandleUserSessions::getLocalUserId()
|
||||
*/
|
||||
public function getLoggedInUserId(): int
|
||||
{
|
||||
return $this->user_id;
|
||||
return $this->session->getLocalUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the user nick name
|
||||
* @return string User's nickname
|
||||
* @deprecated 2022.03
|
||||
* @see IHandleUserSessions::getLocalUserNickname()
|
||||
*/
|
||||
public function getLoggedInUserNickname(): string
|
||||
{
|
||||
return $this->nickname;
|
||||
return $this->session->getLocalUserNickname();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -324,8 +297,7 @@ class App
|
|||
*/
|
||||
public function getBasePath(): string
|
||||
{
|
||||
// Don't use the basepath of the config table for basepath (it should always be the config-file one)
|
||||
return $this->config->getCache()->get('system', 'basepath');
|
||||
return $this->config->get('system', 'basepath');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -385,10 +357,8 @@ class App
|
|||
$this->profiler->reset();
|
||||
|
||||
if ($this->mode->has(App\Mode::DBAVAILABLE)) {
|
||||
$this->profiler->update($this->config);
|
||||
|
||||
Core\Hook::loadHooks();
|
||||
$loader = (new Config())->createConfigFileLoader($this->getBasePath(), $_SERVER);
|
||||
$loader = (new Config())->createConfigFileManager($this->getBasePath(), $_SERVER);
|
||||
Core\Hook::callAll('load_config', $loader);
|
||||
|
||||
// Hooks are now working, reload the whole definitions with hook enabled
|
||||
|
@ -421,7 +391,7 @@ class App
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the current theme name. May be overriden by the mobile theme name.
|
||||
* Returns the current theme name. May be overridden by the mobile theme name.
|
||||
*
|
||||
* @return string Current theme name or empty string in installation phase
|
||||
* @throws Exception
|
||||
|
@ -562,7 +532,7 @@ class App
|
|||
/**
|
||||
* Provide a sane default if nothing is chosen or the specified theme does not exist.
|
||||
*
|
||||
* @return string Current theme's stylsheet path
|
||||
* @return string Current theme's stylesheet path
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getCurrentThemeStylesheetPath(): string
|
||||
|
@ -570,25 +540,6 @@ class App
|
|||
return Core\Theme::getStylesheetPath($this->getCurrentTheme());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base url for use in cmdline programs which don't have
|
||||
* $_SERVER variables
|
||||
*/
|
||||
public function checkURL()
|
||||
{
|
||||
$url = $this->config->get('system', 'url');
|
||||
|
||||
// if the url isn't set or the stored url is radically different
|
||||
// than the currently visited url, store the current value accordingly.
|
||||
// "Radically different" ignores common variations such as http vs https
|
||||
// and www.example.com vs example.com.
|
||||
// We will only change the url to an ip address if there is no existing setting
|
||||
|
||||
if (empty($url) || (!Util\Strings::compareLink($url, $this->baseURL->get())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $this->baseURL->getHostname()))) {
|
||||
$this->config->set('system', 'url', $this->baseURL->get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frontend App script
|
||||
*
|
||||
|
@ -601,13 +552,15 @@ class App
|
|||
* @param IManagePersonalConfigValues $pconfig
|
||||
* @param Authentication $auth The Authentication backend of the node
|
||||
* @param App\Page $page The Friendica page printing container
|
||||
* @param ModuleHTTPException $httpException The possible HTTP Exception container
|
||||
* @param HTTPInputData $httpInput A library for processing PHP input streams
|
||||
* @param float $start_time The start time of the overall script execution
|
||||
* @param array $server The $_SERVER array
|
||||
*
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, HTTPInputData $httpInput, float $start_time)
|
||||
public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, Nav $nav, ModuleHTTPException $httpException, HTTPInputData $httpInput, float $start_time, array $server)
|
||||
{
|
||||
$this->profiler->set($start_time, 'start');
|
||||
$this->profiler->set(microtime(true), 'classinit');
|
||||
|
@ -623,10 +576,12 @@ class App
|
|||
|
||||
if (!$this->mode->isInstall()) {
|
||||
// Force SSL redirection
|
||||
if ($this->baseURL->checkRedirectHttps()) {
|
||||
System::externalRedirect($this->baseURL->get() . '/' . $this->args->getQueryString());
|
||||
if ($this->config->get('system', 'force_ssl') &&
|
||||
(empty($server['HTTPS']) || $server['HTTPS'] === 'off') &&
|
||||
!empty($server['REQUEST_METHOD']) &&
|
||||
$server['REQUEST_METHOD'] === 'GET') {
|
||||
System::externalRedirect($this->baseURL . '/' . $this->args->getQueryString());
|
||||
}
|
||||
|
||||
Core\Hook::callAll('init_1');
|
||||
}
|
||||
|
||||
|
@ -686,8 +641,7 @@ class App
|
|||
if ($this->mode->isInstall() && $moduleName !== 'install') {
|
||||
$this->baseURL->redirect('install');
|
||||
} else {
|
||||
$this->checkURL();
|
||||
Core\Update::check($this->getBasePath(), false, $this->mode);
|
||||
Core\Update::check($this->getBasePath(), false);
|
||||
Core\Addon::loadAddons();
|
||||
Core\Hook::loadHooks();
|
||||
}
|
||||
|
@ -741,17 +695,17 @@ class App
|
|||
$httpinput = $httpInput->process();
|
||||
$input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST);
|
||||
|
||||
// Let the module run it's internal process (init, get, post, ...)
|
||||
// Let the module run its internal process (init, get, post, ...)
|
||||
$timestamp = microtime(true);
|
||||
$response = $module->run($input);
|
||||
$response = $module->run($httpException, $input);
|
||||
$this->profiler->set(microtime(true) - $timestamp, 'content');
|
||||
if ($response->getHeaderLine(ICanCreateResponses::X_HEADER) === ICanCreateResponses::TYPE_HTML) {
|
||||
$page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $this->session->getLocalUserId());
|
||||
$page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId());
|
||||
} else {
|
||||
$page->exit($response);
|
||||
}
|
||||
} catch (HTTPException $e) {
|
||||
(new ModuleHTTPException())->rawContent($e);
|
||||
$httpException->rawContent($e);
|
||||
}
|
||||
$page->logRuntime($this->config, 'runFrontend');
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
|