Compare commits

...

240 commits

Author SHA1 Message Date
Michael Vogel
8446de2aa6
Merge pull request #11685 from MrPetovan/bug/11638-gserver_site_name-length
Add explicit gserver.site_name string truncate in Model\GServer
2022-06-25 12:39:06 +02:00
aa133b5437 Add explicit gserver.site_name string truncate in Model\GServer
- Avoids "Data too long for column 'site_name'" database errors
2022-06-25 06:25:48 -04:00
Philipp
aa596df098
Merge pull request #11686 from MrPetovan/bug/11636-emailer-message-id-check
Fix off-by-one error in Message ID header count check in Util\Emailer
2022-06-25 11:58:23 +02:00
a2afb101cd Fix off-by-one error in Message ID header count check in Util\Emailer 2022-06-25 05:35:24 -04:00
b9fe8ee38f
Merge pull request #11683 from MrPetovan/bug/fatal-errors
Fix a couple Fatal Errors
2022-06-25 11:20:33 +02:00
c75dbfd3d7 Update default value for LocalRelationship->priority to avoid null values
- Address https://github.com/friendica/friendica/issues/11630#issuecomment-1166192993
2022-06-25 05:06:22 -04:00
636b84b41c Update return value type-hint of GServer::getProtocol
- Address https://github.com/friendica/friendica/issues/11630#issuecomment-1164880874
2022-06-25 05:06:22 -04:00
c5b46fe748
Merge pull request #11681 from Quix0r/fixes/item-guidfromuri-allow-null
Allowing Item::getFromUri()'s 2nd parameter a null value
2022-06-24 10:15:26 -04:00
4cdc0ef267
Merge pull request #11680 from nupplaphil/feat/log_forward
Respect Forwarded-For headers
2022-06-24 10:12:19 -04:00
82bb36e13d
Changes:
- Made Item::guidFromUri()'s $host parameter optional (allowing null)
- added some type-hints
- added documentation
- this may fix reported issue in #11630
2022-06-24 03:17:57 +02:00
417b0072bb
Move documentation :-) 2022-06-23 23:24:15 +02:00
2dc38e5632
Move documentation :-) 2022-06-23 23:23:36 +02:00
5bf5b5e6c9
adaptions :-) 2022-06-23 23:01:09 +02:00
12ba37e8d2
add more doc 2022-06-23 22:46:46 +02:00
13783089e7
Add copyright 2022-06-23 22:44:17 +02:00
d441b90bda
Respect Forwarded-For headers 2022-06-23 22:42:35 +02:00
dbc1ebbb5c
Merge pull request #11679 from Quix0r/rewrites/autotest
Rewrite of autotest.sh
2022-06-23 12:41:14 -04:00
3aeeac5d98
Rewrite:
- rewrote autotest.sh and moved it to bin/dev/ as this is clearly a developer
  script
- the rewrite's goal is towards Shell/POSIX-compliance (e.g. ${VAR} and not $VAR)
2022-06-23 17:36:56 +02:00
d322e9288b
Merge pull request #11677 from Quix0r/rewrites/type-hints-doc-001
Rewrites/type hints doc 001
2022-06-23 11:34:52 -04:00
657a8a7cb5
Changes:
- documented null value
- two ' to much!
2022-06-23 17:30:17 +02:00
202857ba7d
No need to log $tid here 2022-06-23 17:30:17 +02:00
fd8f4269ff
Reformatted code 2022-06-23 17:30:17 +02:00
5699b03e8d
Changes:
- added some nodes to OpenSearch descriptor
- still no UTF-8 encoding!
- added some type-hints
2022-06-23 17:30:16 +02:00
a49fb9cbf9
Changes:
- added some type-hints
- added documentation
2022-06-23 17:30:16 +02:00
84d3eecc33
Changes:
- added some type-hints
- changed double-quotes to single
2022-06-23 17:30:15 +02:00
57e741f2cf
More type-hints added 2022-06-23 17:30:15 +02:00
182c3db9b8
Changes:
- added type-hints
- added missing documentation
2022-06-23 17:30:15 +02:00
b8353a6eb7
Changes:
- reformatted some array
- added missing documentation
- added type-hints
- changed double-quotes to single
2022-06-23 17:30:14 +02:00
c6c936a80f
Added more type-hints 2022-06-23 17:30:14 +02:00
3f74a59f73
Added some type-hints 2022-06-23 17:30:14 +02:00
69a68be800
Added some missing type-hints 2022-06-23 17:30:13 +02:00
f889aeffb3
Changes:
- changed double-quotes to single
- added type-hints
2022-06-23 17:30:13 +02:00
d8ff966d21
Throw IAE again (should never become visible) 2022-06-23 17:30:13 +02:00
35c78ce14c
Ops, cannot return Thread? 2022-06-23 17:30:12 +02:00
c2e26b4f49
Changed:
- Introduced InvalidArgumentException (should never come)
- added type-hints
2022-06-23 17:30:12 +02:00
2f3705f471
Continued:
- renamed varibales to $camelCase
- added type-hints
- updated documentation
2022-06-23 17:30:11 +02:00
0322456f70
Merge pull request #11678 from Quix0r/fixes/send-contact-accept-id-string
Fix for Transmitter::sendContactAccept() wrong 2nd parameter type
2022-06-23 11:05:38 -04:00
0ddb315b23
$id in Transmitter::sendContactAccept() is a string, see Introduction class 2022-06-23 16:48:00 +02:00
bf600905d3
Merge pull request #11676 from Quix0r/fixes/array-element-missing
Maybe this fixes missing array element
2022-06-23 09:06:59 -04:00
859af16cca
Merge pull request #11675 from Quix0r/features/smarty-sub-directories
Enabled sub-directories for compiled/cache Smarty3 files
2022-06-23 09:06:06 -04:00
636fef26f1
Maybe this fixes missing array element 2022-06-23 07:40:49 +02:00
589d0360a4
So simple ... Ops! 2022-06-23 04:58:45 +02:00
69676c9f7b
Changes:
- enabled sub-directories for compiled/cached files which avoids large+slow
  directory descriptors
- changed some double-quotes to single
2022-06-23 04:24:55 +02:00
b2aee2cf29
Merge pull request #11674 from nupplaphil/dep/guzzle
Bump guzzlehttp/guzzle from 6.5.5 to 6.5.8
2022-06-22 15:07:42 -04:00
Philipp
e3aed8099c
Merge pull request #9 from nupplaphil/dependabot/composer/guzzlehttp/guzzle-6.5.8
Bump guzzlehttp/guzzle from 6.5.5 to 6.5.8
2022-06-22 20:23:38 +02:00
c824ba43d5
Merge pull request #11673 from Quix0r/bugs/returned-type-array-bool
Fixed: ?? didn't work here as bool won't be seen as null
2022-06-22 13:29:39 -04:00
7eefb9aed8
Changed:
- empty() is maybe superflous here, still I would prefer a code style that is
  written explicitly and not rely on "magic casting"
2022-06-22 18:57:01 +02:00
15d8341d9a
Converted multiple single-comment (//) to multi-line comment block (/* */) 2022-06-22 18:06:35 +02:00
b996712ef7
Images::getInfoFromURL[Cached]() will both return empty arrays on error and
that needs to be reflected here, too.
2022-06-22 17:20:59 +02:00
eb231bc548
Fixed: ?? didn't work here as bool won't be seen as null 2022-06-22 17:09:53 +02:00
Philipp
78bf7f187c
Merge pull request #11669 from MrPetovan/bug/11666-email-subject-double-encode 2022-06-22 16:51:23 +02:00
b96daeeeef
Merge pull request #11670 from Quix0r/fixes/more-type-hints-004
Fixes/more type hints 004
2022-06-22 10:49:20 -04:00
d5441da49a
Fixed:
- TypeError: "Argument 1 passed to Friendica\Util\XML::escape() must be of the
  type string, null given, called in src/Util/XML.php line 171
2022-06-22 16:20:26 +02:00
101cd2dd10
Changes:
- added some documentation
- fixed some documentation
- changed more double-quotes to singl
2022-06-22 16:14:14 +02:00
ba45e59313
Changes:
- added more type-hints
- added missing documentation
- Email::send() now returns what mail() returns (bool)
2022-06-22 14:36:48 +02:00
ee8d0ad619
Changes:
- added more type-hints
- added some documentation
2022-06-22 14:36:47 +02:00
feec96cbc4
Return empty array on error (I hope it works this way). 2022-06-22 14:36:47 +02:00
2dd7d465e8
Changes:
- added more type-hints
- updated documentation
- changed double-quotes to single
2022-06-22 14:36:47 +02:00
74ab7648c6
Changes:
- addHubLink()'s 2nd parameter is DOMElement
- added more type-hints
- converted double-quotes to single
2022-06-22 14:36:46 +02:00
12add2fb64
$data can turn into bool here 2022-06-22 14:36:46 +02:00
08f55f0358
Ops, forgot to rename these, too. 2022-06-22 14:36:46 +02:00
abd0d9f3fd
Changes
- added type-hints
- added some documentation
- added default: block for unknown 'rel' value
- changed return type void to empty array
2022-06-22 14:36:45 +02:00
dfa95ea58d
Changes:
- added type-hints
- added documentation
2022-06-22 14:36:45 +02:00
84bfc37bf1
Changes:
- added more type-hints
- added missing documentation
2022-06-22 14:36:45 +02:00
fa973d3b0f
Merge pull request #11671 from MrPetovan/bug/fatal-errors
Add expected type-hint to BoundariesPager::renderFull
2022-06-22 14:30:39 +02:00
e9f7bb477d Add expected type-hint to BoundariesPager::renderFull
- Address https://github.com/friendica/friendica/issues/11630#issuecomment-1162634199
2022-06-22 07:49:45 -04:00
7295138f8d Remove type-hint inconsistent with expected return value in Database->getVariable 2022-06-22 07:47:15 -04:00
d68f307337 Remove email subject encoding from ItemCCEmail constructor
- It was wrongly re-encoded in Emailer::send
2022-06-21 21:12:09 -04:00
a05baaf249
Merge pull request #11668 from Quix0r/renames/logger
Renamings in logger class to make them more clear
2022-06-21 20:52:19 -04:00
2f358607c7
Changes:
- renamed Logger::getLogger() to getInstance() (@MrPetovan)
2022-06-22 01:50:10 +02:00
dependabot[bot]
6443713af1
Bump guzzlehttp/guzzle from 6.5.5 to 6.5.8
Bumps [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) from 6.5.5 to 6.5.8.
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/6.5.8/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/6.5.5...6.5.8)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 20:47:00 +00:00
cdcfb4064b
Changes:
- added type-hints
- added missing documentation
- renamed Logger::getWorker() to Logger::getLogger() as there is no worker class
  returned but the actual (inner) logger
2022-06-21 21:22:16 +02:00
1c57ea7f75
Merge pull request #11665 from Quix0r/rewrites/dba-array-string-table
Rewrites/dba array string table
2022-06-21 15:15:57 -04:00
8092188991
Added important comment from @nupplaphil@github.com 2022-06-21 21:12:59 +02:00
f38ad168f5
Reverted and improved TODO:
------
@nupplaphil: There is no easy possibility to add a logger here, that's why there
isn't any yet and instead a placeholder.. This execution point is a critical
state during a testrun, and tbh I'd like to leave here no further logic (yet)
because I spent hours debugging cases, where transactions weren't fully closed
and strange/unpredictable errors occur (sometimes -mainly during debugging other
errors :) ...)
-----
2022-06-21 19:21:25 +02:00
80c8ec17c2
Fixed documentation 2022-06-21 18:43:25 +02:00
0332a57bfd
Rewrote to suggestions from @MrPetovan (I tried to maintain the old way of
['scheme' => 'table'] with my version).
2022-06-21 18:13:01 +02:00
3b8d9a7248
Use protected $this->logger instead 2022-06-21 17:54:48 +02:00
9ccb113530
Ops, autorun.sh is there but looks like lesser "multi-project" friendly as
MYSQL_* must be defined. I might still use my version as that is
project-specific.
2022-06-21 17:48:10 +02:00
dcedd2e5d9
Ops, WWORD ... 2022-06-21 13:54:03 +02:00
5e57ad4d44
Added simple wrapper script to run PHPUnit tests for you. To use this, you need
to set at least 4 variables in your ~/.bashrc (recommended):

export FRIENDICA_MYSQL_HOST="localhost"
export FRIENDICA_MYSQL_DATABASE="friendica_test"
export FRIENDICA_MYSQL_USER="friendica_test"
export FRIENDICA_MYSQL_PASSWWORD="friendica_test"

Then you can put ./bin/dev/run_tests.sh into your .git/hooks/pre-commit file
2022-06-21 13:47:40 +02:00
5fe428d3e4
Fixed:
- PHPUnit\Framework\Error\Notice:  Undefined index: language in /.../src/Util/EMailer/MailBuilder.php on line 122
2022-06-21 13:47:40 +02:00
a7651fa1d5
Changes:
- let's at least log the error message, yes it does flood your logfile
2022-06-21 13:47:40 +02:00
1080a840f5
Changes:
- Database->$driver can no longer be NULL, an empty string is fine anyway
2022-06-21 13:47:39 +02:00
945cd1a2c2
Fixed:
- since $table can be now schema.table, this needs being taken care off
- maybe this foreach(explode()) is a bit an overkill as only 1 or 2 entries
  can be found in it
2022-06-21 13:47:39 +02:00
0d81a08e3c
WIP: Properly some fixes? Also why is DROP VIEW IF EXISTS is being killed? 2022-06-21 13:47:39 +02:00
44a9ec9b17
Rewrite:
- avoid having array|string for $table to have a "string" type-hint for $table
- you now have to do it for yourself by giving 'schema.table' as parameter
2022-06-21 13:47:38 +02:00
f62c28008a
Removed comment 2022-06-21 13:47:38 +02:00
cefffde691
Changes:
- added type-hints
- added some missing documentation
2022-06-21 13:47:37 +02:00
f1867463a0
Changes:
- added more type-hints
2022-06-21 13:47:37 +02:00
77c37ff2db
Fixed:
- Uncaught Exception TypeError: "Argument 3 passed to
  Friendica\Protocol\DFRN::createActivity() must be of the type string, null
  given, called ..."
2022-06-21 13:47:37 +02:00
e6ddb167f6
Merge pull request #11664 from tobiasd/20220621-fr
update FR translations THX kalon33
2022-06-21 07:43:12 -04:00
4650ff53d9
Merge pull request #11662 from MrPetovan/bug/11661-splitattachment-null
Ensure parameter 4 of Post\Media::splitAttachment is a boolean value
2022-06-21 06:48:52 +02:00
fff6e30782
update FR translations THX kalon33 2022-06-21 06:45:14 +02:00
d2ca812647
Merge pull request #11660 from Quix0r/fixes/more-type-hints-003
More type-hints - Batch 003
2022-06-20 21:53:17 -04:00
3e522ed512
Fixed:
- prevent NULL from being handled over to XML::escape()
- still I wonder that an object can be? It is a string-only accepting method
2022-06-21 01:42:37 +02:00
95f9eb34ac
Fixed indenting 2022-06-21 01:29:33 +02:00
ee9bc338a5
Merge pull request #11663 from Quix0r/composer/upgrade
Updated composer.phar
2022-06-20 19:17:13 -04:00
b6fa022a73
Changes:
- added type-hints
- added some documentation
- marked some generic methods to be moved to Util\Strings class instead
2022-06-20 23:50:24 +02:00
6a98ffa330
Updated composer.phar 2022-06-20 22:55:21 +02:00
fbae0b8bcf
Changes:
- renamed ItemArrayFromMail() to getItemArrayFromMail() to follow naming-convetion
- added missing type-hints
- added missing documentation
2022-06-20 21:22:46 +02:00
ea22e88896
Added documentation 2022-06-20 21:02:34 +02:00
752953e472
Changes:
- as @MrPetovan pointed out, $actor can be NULL earlier and used later as NULL
- added some missing type-hints
- added missing documentation
- the added @TODO points out to avoid true|false|null for a boolean
2022-06-20 21:00:19 +02:00
88eacbf66e Ensure parameter 4 of Post\Media::splitAttachment is a boolean value 2022-06-20 14:34:02 -04:00
0c12e947dd
Changes:
- null was 2nd argument's value before, an empty string is basically the same here
2022-06-20 20:01:59 +02:00
feb87e8dc3
Changes:
- let's start throwing exceptions on e.g. invalid arguments instead of returning
  FALSE
2022-06-20 19:09:08 +02:00
4fb03cf163
Changes:
- fixed a null value handled over to Friendica\Model\APContact::getByURL()
- added missing type-hints
2022-06-20 19:05:02 +02:00
e96a548286
Changes:
- dumped default value for $input
- added unknown 'platform' which prevents an "Undefined index: platform in
  /var/www/.../src/Model/GServer.php on line 940" error
2022-06-20 18:56:22 +02:00
e5cc7a5ab1
Fixes:
- Strings::isHex() should not be misused for checking on NULL
2022-06-20 08:25:45 +02:00
6743de63f5
Changed:
- DBA::exists() should only be used for checking if records exists.
- if you want to check if a table exists, please ALWAYS use
  DBStructure::existsTable() instead
2022-06-20 08:20:07 +02:00
cc750d743b
Changes:
- some methods now need to return bool to be compatible
- added some missing type-hints
2022-06-20 08:12:54 +02:00
9c80dd35e5
Both declarations must be the same 2022-06-20 08:07:12 +02:00
13a5a30b28
Merge pull request #11659 from MrPetovan/bug/11511-relocate-quote-identifier
Add missing identifier quote in Database->replaceInTableFields
2022-06-20 06:26:33 +02:00
cd3b01fd82
Changed:
- cannot have type-hints :-(
2022-06-20 03:48:34 +02:00
94a594eeb2
Ops, wrong type-hint 2022-06-20 03:36:36 +02:00
ec96f2252e
Changes:
- added type-hints
- added some missing documentation
2022-06-20 03:10:23 +02:00
14bf72e4fe
Changes:
- added some documentation
- added type-hints
2022-06-20 02:48:05 +02:00
97904ea7dd
Changes:
- added type-hints
- added missing documentation
2022-06-20 02:48:02 +02:00
a0c8fc6d6e
Changes:
- added more type-hints
2022-06-20 02:48:02 +02:00
7528b79469
Merge pull request #11657 from Quix0r/fixes/post-media-size-bigint
Size "mediumint" wasn't enough
2022-06-19 20:23:29 -04:00
d48e40c1bf Add missing identifier quote in Database->replaceInTableFields
- This caused hyphenated table names to fail the replace query
2022-06-19 20:06:12 -04:00
d276f2c62b
Changes:
- added type-hints
- changed some double-quotes to single
2022-06-20 01:00:29 +02:00
8c38265b37
Changes:
- `url` to `varbinary(1024)`
 - `preview` to `varbinary(512)`

as the previous once (half length) were not enough in real-life scenarios
2022-06-19 23:09:29 +02:00
2512449751
Incremented again 2022-06-19 15:36:16 +02:00
9f24a4b60e
Fixed documentation/SQL dump with ./bin/console dbstructure dump 2022-06-19 15:36:16 +02:00
96954e2b18
Size "mediumint" wasn't enough:
https://digitalcourage.video/static/webseed/5a039eb2-9fbc-441d-a772-59ae3ee65c15-1080.mp4 has 6758472669 Bytes

So let's go REALLY big.
2022-06-19 15:36:15 +02:00
622b978a84
Merge pull request #11655 from Quix0r/fixes/more-type-hints-002
More type-hints and documentation added
2022-06-19 09:27:29 -04:00
5a553df7d8
Incremented database version 2022-06-19 14:41:36 +02:00
ed3c53a5f8
Ops, not here wanted. :-( 2022-06-19 14:06:32 +02:00
bff57bb030
Changes:
- added type-hints
- added returned type-hints in interface (I checked all)
2022-06-19 14:00:31 +02:00
777872e6fa
Merge pull request #11658 from tobiasd/20220619-accesskey
Accesskey was used twice
2022-06-19 07:09:20 -04:00
c0d7f8944d
Some calls saved 2022-06-19 11:26:10 +02:00
60f8c2d795
Changes:
- added missing type-hints
- added documentation for a method
2022-06-19 10:50:09 +02:00
5f6943b008
Changes:
- MySQL index on BLOB/TEXT can only be partial (e.g.: `column`(length))
2022-06-19 10:50:06 +02:00
5792a01a01
Contact::getAccountType()'s parameter is never a string, ops 2022-06-19 09:36:24 +02:00
f3599fa3e9
Changes:
- dbstructure(null) is no longer possible, an empty string does it
2022-06-19 09:13:10 +02:00
065dad79ca
updated the Accesskey documentation accordingly 2022-06-19 06:33:21 +02:00
a063a89c57
Accesskey was used twice
The accesskey on the User Settings pages for the _account settings_ and the _two factor authentication_ were the same. This PR is assinging a new one to the 2FA.
2022-06-19 06:30:00 +02:00
b6bfe72083
Wrong returned type, has to be array 2022-06-19 02:40:07 +02:00
7bb0cb5323
Changes:
- added more type-hints
- DBStructure::existsTable() does no longer need array support for table name
  because this is no longer used (good work!)
2022-06-19 02:11:12 +02:00
2c5685c89c
Changes:
- changed to proper "use Foo\Bar;"
- added doctag
- added return type as this is fixed
2022-06-19 01:11:30 +02:00
d7d2ad77ff
Ops, also this! 2022-06-18 23:31:52 +02:00
39f2d197ea
Changed to suggestings (back to original) + fixed typo in scalar type 2022-06-18 23:30:37 +02:00
6f1d52cf71
Changed back to suggestions by @MrPetovan 2022-06-18 23:24:08 +02:00
2f961b11bf
Naming-convention:
- variables should start lower-case: $image
2022-06-18 23:16:34 +02:00
fa14a02a19
Changes:
- added type-hints
- added documentation
- changed double-quotes to single
2022-06-18 23:12:52 +02:00
f3b57008b5
Proper type is string 2022-06-18 18:41:16 +02:00
41f34c4261
Maybe fix for:
"Argument 1 passed to Friendica\Model\ItemURI::getIdByURI() must be of the type string, null given, called in Processor.php line 1219"
2022-06-18 18:30:50 +02:00
9691bb06fb
Changes:
- added more type-hints
- added missing documentation
2022-06-18 18:21:29 +02:00
94eb426151
Nodeinfo::getOrganization() doesn't need configuration object being inserted
when you have DI::config() around.
2022-06-18 17:56:33 +02:00
c29c49797a
Added missing type-hints 2022-06-18 17:52:46 +02:00
4e437190c5
Renamed variable, no need for "orig_" prefix 2022-06-18 17:50:11 +02:00
a1a81cdc6b
Continued:
- changed some double-quotes to single
- added missing type-hints
- added missing documentation
- fixed indenting a bit
2022-06-18 17:46:34 +02:00
8fc710f82a
Continued:
- added more type-hints
- added some missing documentation
- Return the result from DBA::delete() to let other methods know about it
2022-06-18 17:22:50 +02:00
8ba3f13fae
Changes:
- added more type-hints
- added missing documentation
2022-06-18 17:09:46 +02:00
7ec07178c8
Changes:
- added missing type-hints
- added missing documentation
2022-06-18 16:59:23 +02:00
e90ad0c1cd
Merge pull request #11653 from Quix0r/fixes/more-type-hints
More type-hints added
2022-06-18 10:33:33 -04:00
b2e5993314
Merge pull request #11654 from Quix0r/fixes/post-media-url-size
post-media has too small sizes for video files
2022-06-18 10:28:00 -04:00
92a1d14e5e
Updated documentation and SQL dump, according to woodpecker tests 2022-06-18 16:02:33 +02:00
8756d92316
Continued:
- prevents a "Return value of Friendica\Core\Worker::workerProcess() must be of the type array, bool returned"
2022-06-18 15:57:31 +02:00
8aaf99c61d
Sizes increased for:
- video files that have sizes var being int allowes
- URLs that might be longer (e.g. magnet: URLs) than varbinary(511) allows
2022-06-18 15:31:47 +02:00
bd3a7b9877
Ops, needs to be a variable:
Error: "Cannot pass parameter 2 by reference" at /var/www/.../src/Module/DFRN/Poll.php line 36
2022-06-18 09:59:19 +02:00
69cda4f760
Fixed TypeError: "Argument 1 passed to Friendica\Core\System::httpExit() must be
of the type string, null given, called in /var/www/.../src/Module/DFRN/Poll.php
on line 37"
2022-06-18 05:42:02 +02:00
7cbb818c93
Set type-hint for parameter $data to SimpleXMLElement as $fields in dispatch()
is the same and being handled over.
2022-06-18 05:19:24 +02:00
89302d0843
Some outside code relies on returned "false" 2022-06-18 05:06:18 +02:00
aaf5c323b6
Fixed indenting 2022-06-18 05:04:14 +02:00
adb4aea6ad
Changes:
- added some type-hints
- replaced most double-quotes (only Diaspora.php, later more) with single
- added some documentation
- normalized indenting in Diaspora.php (I hope I got all?)
2022-06-18 05:03:10 +02:00
51f43278d6
Fixed incompatible types 2022-06-17 18:00:36 +02:00
88c40f3336 Ops, wrong type again 2022-06-17 17:18:31 +02:00
a770634b95 Ops, wrong type 2022-06-17 17:18:31 +02:00
36d56a4041 Continued:
- changed back to 'return false;' as other methods heavily rely on false instead
  of an empty array as pointed out by @heluecht@pirati.ca
- $fetched_contact should be initialized as an empty array, let's not make this
  code more crazier than it already is (see APContact::getByURL())
2022-06-17 17:18:31 +02:00
c467bff79f Some more type-hints added 2022-06-17 17:18:31 +02:00
4f3321cc9f Nore fixes 2022-06-17 17:18:31 +02:00
10bb7d5625 Possible fix for
Uncaught Exception TypeError: "Return value of
Friendica\Model\APContact::getByURL() must be of the type array, bool returned"
2022-06-17 17:18:31 +02:00
fdd237a090 Fix for "Uncaught Exception TypeError: "Argument 1 passed to
Friendica\Model\APContact::unarchiveInbox() must be of the type string, null
given" error message
2022-06-17 17:18:31 +02:00
605e7d55b3 Continued:
- added more type-hints
- some methods in Diaspora returned void but integer was documented so I
  changed it to -1 to have a proper type-hint
2022-06-17 17:18:31 +02:00
0c9aff8a09 Also need to declare $profile or otherwise an invocation of
Receiver::getReceiverForActor() will fail.
2022-06-17 17:18:31 +02:00
af8cd5ca86 Worker::getWaitingJobForPID() can also return FALSE on failure ... :-( 2022-06-17 17:18:31 +02:00
227bab43a8 Ops, wrong type-hint here, must be string ($nickname can never be an integer). 2022-06-17 17:18:31 +02:00
f7c1eaa858 Continued:
- added type-hints
- removed out-dated documentation
- added some missing documentation
2022-06-17 17:18:31 +02:00
e484b6d6dc Continued:
- added more type-hints
- added some documentation
- Contact::getAccountType() should only process string, not null
2022-06-17 17:18:31 +02:00
45b5f67bca Fix for non-existing record system.mobile_theme in config table 2022-06-17 17:18:31 +02:00
5c9ce790bf Fixed:
- $object_data['actor'] can be null, but Receiver::getReceivers()'s 2nd
  parameter expect it to be string
2022-06-17 17:18:31 +02:00
33768ea1c6 Some fixes:
- $gsid's default value cannot sadly be 0, it now must be null to allow some
  code work
- added some more type-hints
- documented a bit more
2022-06-17 17:18:31 +02:00
4e53666c70 Added more type-hints 2022-06-17 17:18:31 +02:00
7560dccc08 Added again more type-hints 2022-06-17 17:18:31 +02:00
2766c7d9cf Continued:
- added more type-hints
- added some missing documentation
2022-06-17 17:18:31 +02:00
a587217f47 Fixed "Argument 4 passed to Friendica\Protocol\DFRN::processVerbs() must be of the type bool" 2022-06-17 17:18:31 +02:00
dd54e52575 MrPetovan brought the right one up:
> Since this is depending on remote systems, the log can quickly fill with unactionable messages.
2022-06-17 17:18:31 +02:00
c351099c5a Ops, bad type-hint here 2022-06-17 17:18:31 +02:00
2c5595c358 Another incompatible method declaration fixed + type-hints added 2022-06-17 17:18:31 +02:00
40d7f29a11 Continued:
- more type-hints
- fixed incompatible method declarations
2022-06-17 17:18:31 +02:00
1edc6b3c3b Added more type-hints for "App" classes 2022-06-17 17:18:31 +02:00
42b04f397b Added more type-hints 2022-06-17 17:18:31 +02:00
aa5f0d5ec1 Added more type-hints and documented a few methods 2022-06-17 17:18:31 +02:00
97e27cb523 Added more type-hints 2022-06-17 17:18:31 +02:00
c2e889cfae Added more type-hints 2022-06-17 17:18:31 +02:00
a8a21c7fb6
Merge pull request #11652 from Quix0r/fixes/causer-id
Misspelled braces causing "undefined index 'causer-id'" message
2022-06-17 10:12:22 -04:00
5106bb2881
Added parenthesis 2022-06-17 09:41:11 +02:00
a903dbd77e
Wrong braces causing 'undefined index causer-id'. See #11632 2022-06-16 23:00:16 +02:00
51b31a846f
Merge pull request #11649 from Quix0r/fixes/return-type-fetch-content
Fixes incompatible returned type from HTTPSignature::fetch() method
2022-06-16 13:16:06 -04:00
6035de6883
Continued:
- added more type-hints
- also cannot return FALSE when array is set
2022-06-16 19:06:41 +02:00
341d8860d1
Merge pull request #11647 from Quix0r/fixes/type-error-exception
Followup PR for bad #11624 PR
2022-06-16 11:53:15 -04:00
51a7b5c584
Made also this one sweeter (null-coalscing) 2022-06-16 17:36:47 +02:00
0e1f734b03
Also make this null-coalscing 2022-06-16 17:35:01 +02:00
e8fee5644b
Ops, syntax errors get unnoticed with a simple editor. :-( 2022-06-16 17:10:02 +02:00
624e4c192c
Changed to null-coalscing style (??) as sugguested by @MrPetovan 2022-06-16 16:59:54 +02:00
962b06bf41
Added check as suggested by @MrPetovan for empty $message. 2022-06-16 16:54:51 +02:00
f2b7326650
This will 2 things:
1) The first change prevents "expensive" code in HTML::toBBcode() to be executed
   just for an empty string which makes no sense.
2) The above change was maybe flawed as $apcontact['about'] would have never
   been created, not even empty which could have side effects

Thanks to @annando to make me rethink this part of code.
2022-06-16 16:54:50 +02:00
7814ba4fc4
Fixes for bad invocations of HTML::toBBCode() (1st parameter is now string) 2022-06-16 16:54:50 +02:00
b200874f17
Ops:
- wrong way around (!empty($foo)) is proper
- also needed to be checked on $acitivty['content']
2022-06-16 16:54:50 +02:00
b1e4c0931a
Fixes and type-hints:
- added more checked type-hints as they prevent bad method invocations
- fixed TypeError for HTML::toBBCode() invocations with NULL as first (wrong)
  argument, thanks to @tobias@social.diekershoff.de pointing this out.
2022-06-16 16:54:49 +02:00
bb57d45237
Merge pull request #11645 from Quix0r/fixes/e-notice_use
Fixed possible "Trying to access array offset on value of type bool" E_NOTICE
2022-06-16 08:45:50 -04:00
e9af4b5bb9
Shorter code, thanks to @annando pointing this out 2022-06-16 13:29:30 +02:00
65da5246ca
Fixed possibble "Trying to access array offset on value of type bool" E_NOTICE
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-16 10:07:41 +02:00
13ef86d4a3
Merge pull request #11644 from Quix0r/fixes/file-permissions
Fixed file permissions
2022-06-16 10:02:31 +02:00
58c48977ec
These files should never have executable files 2022-06-16 09:14:23 +02:00
fd0d4aedee
Font files should NEVER be executable
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-16 09:13:48 +02:00
207bf58801
Merge pull request #11624 from Quix0r/fixes/type-hints
Added more known type-hints
2022-06-15 16:32:25 -04:00
5fa954208a
Changes:
- ops, wasn't actually fixing `return;` to proper `return '';`
- added more type-hints
- added TODO ($uid is unused)
2022-06-15 22:28:33 +02:00
a3fa95e8e4
Changes:
- added more type-hints
- changed `return;` to `return '';` when `string` was requested as returned type-hint
  (thanks to @MrPetovan)
2022-06-15 22:05:38 +02:00
34aee64349
Added more type-hints
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-15 21:52:51 +02:00
143e4c4a18
Added more known type-hints
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-15 21:52:50 +02:00
98954dd14e
Merge pull request #11643 from annando/avatar-path
You can now store the avatar in a separate folder and host
2022-06-15 06:25:31 +02:00
726c4dff7d You can now store the avatar in a separate folder and host 2022-06-15 03:59:26 +00:00
f839cd3826
Merge pull request #11642 from annando/platform-default
Some more default avatars
2022-06-13 16:31:34 -04:00
b816ae4db5 Some more default avatars 2022-06-13 20:07:54 +00:00
Michael Vogel
1eadcb4855
Merge pull request #11641 from tobiasd/20220613-lng
AR, FR and HU translation updates
2022-06-13 17:42:10 +02:00
6d6f356446
AR translation updates THX ButterflyOfFire 2022-06-13 14:27:14 +02:00
7614ace843
added HU translation THX Balázs Úr 2022-06-13 14:27:14 +02:00
cc77052817
update FR translations THX kalon33 2022-06-13 14:27:06 +02:00
663296b107
Merge pull request #11639 from annando/platform-default
Use platform specific default avatar pictures
2022-06-13 07:59:49 -04:00
70b9a8114d Improve license comment 2022-06-13 10:30:21 +00:00
d9fb081db9 Using separate avatars for different peertube account types 2022-06-13 10:27:46 +00:00
a47f1efec3 use correct image for Pleroma 2022-06-13 10:18:17 +00:00
c1a64b77c0 Improved license text 2022-06-13 10:03:34 +00:00
a5b5f9316d Updated database.sql and messages.po 2022-06-13 05:46:37 +00:00
e0a0c57c44 Use platform specific default avatar pictures 2022-06-13 05:18:54 +00:00
05a76a3dc2
initial CHANGELOG for the 2022.09 release 2022-06-11 10:07:04 +02:00
13d7242463
pump version to 2022.09-dev 2022-06-11 10:06:02 +02:00
223 changed files with 8150 additions and 6576 deletions

8
.gitignore vendored
View file

@ -90,3 +90,11 @@ venv/
#ignore avatar picture cache path #ignore avatar picture cache path
/avatar /avatar
#Ignore autotest results
autotest-results.xml
#ignore phpunit result cache
tests/.phpunit.result.cache
#ignore .php_cs (local copy)
.php_cs

View file

@ -1,3 +1,11 @@
Version 2022.09 (unreleased)
Friendica Core
Friendica Addons
Closed Issues
Version 2022.06 (2022-06-11) Version 2022.06 (2022-06-11)
Friendica Core Friendica Core
Added DA DK translation, updates to the translations DE, FR, HU, PL, RU, ZH CN [translation teams] Added DA DK translation, updates to the translations DE, FR, HU, PL, RU, ZH CN [translation teams]

View file

@ -1 +1 @@
2022.06 2022.09-dev

Binary file not shown.

View file

@ -15,33 +15,34 @@
# - TEST_SELECTION= ... Specify which tests are used to run (based on the test-labeling) # - TEST_SELECTION= ... Specify which tests are used to run (based on the test-labeling)
# - XDEBUG_CONFIG= ... Set some XDEBUG specific environment settings for development # - XDEBUG_CONFIG= ... Set some XDEBUG specific environment settings for development
DATABASENAME=${MYSQL_DATABASE:-test} DATABASE_NAME=${FRIENDICA_MYSQL_DATABASE:-test}
DATABASEUSER=${MYSQL_USERNAME:-friendica} DATABASE_USER=${FRIENDICA_MYSQL_USERNAME:-friendica}
DATABASEHOST=${MYSQL_HOST:-localhost} DATABASE_HOST=${FRIENDICA_MYSQL_HOST:-localhost}
BASEDIR=$PWD DATABASE_PASSWORD=${FRIENDICA_MYSQL_PASSWORD:-friendica}
BASEDIR=${PWD}
DBCONFIGS="mysql mariadb" DBCONFIGS="mysql mariadb"
TESTS="REDIS MEMCACHE MEMCACHED APCU NODB" TESTS="REDIS MEMCACHE MEMCACHED APCU NODB"
export MYSQL_DATABASE="$DATABASENAME" export MYSQL_DATABASE="${DATABASE_NAME}"
export MYSQL_USERNAME="$DATABASEUSER" export MYSQL_USERNAME="${DATABASE_USER}"
export MYSQL_PASSWORD="friendica" export MYSQL_PASSWORD="${DATABASE_PASSWORD}"
if [ -z "$PHP_EXE" ]; then if [ -z "${PHP_EXE}" ]; then
PHP_EXE=php PHP_EXE=php
fi fi
PHP=$(which "$PHP_EXE") PHP=$(which "${PHP_EXE}")
# Use the Friendica internal composer # Use the Friendica internal composer
COMPOSER="$BASEDIR/bin/composer.phar" COMPOSER="${BASEDIR}/bin/composer.phar"
set -e set -e
_XDEBUG_CONFIG=$XDEBUG_CONFIG _XDEBUG_CONFIG=${XDEBUG_CONFIG}
unset XDEBUG_CONFIG unset XDEBUG_CONFIG
function show_syntax() { function show_syntax() {
echo -e "Syntax: ./autotest.sh [dbconfigname] [testfile]\n" >&2 echo -e "Syntax: ./autotest.sh [dbconfigname] [testfile]\n" >&2
echo -e "\t\"dbconfigname\" can be one of: $DBCONFIGS" >&2 echo -e "\t\"dbconfigname\" can be one of: ${DBCONFIGS}" >&2
echo -e "\t\"testfile\" is the name of a test file, for example lib/template.php" >&2 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 "\nDatabase environment variables:\n" >&2
echo -e "\t\"MYSQL_HOST\" Mysql Hostname (Default: localhost)" >&2 echo -e "\t\"MYSQL_HOST\" Mysql Hostname (Default: localhost)" >&2
@ -57,22 +58,22 @@ function show_syntax() {
echo -e "\nIf no arguments are specified, all tests will be run with all database configs" >&2 echo -e "\nIf no arguments are specified, all tests will be run with all database configs" >&2
} }
if [ -x "$PHP" ]; then if [ -x "${PHP}" ]; then
echo "Using PHP executable $PHP" echo "Using PHP executable ${PHP}"
else else
echo "Could not find PHP executable $PHP_EXE" >&2 echo "Could not find PHP executable ${PHP_EXE}" >&2
exit 3 exit 3
fi fi
echo "Installing depdendencies" echo "Installing depdendencies"
$PHP "$COMPOSER" install ${PHP} "$COMPOSER" install
PHPUNIT="$BASEDIR/vendor/bin/phpunit" PHPUNIT="${BASEDIR}/vendor/bin/phpunit"
if [ -x "$PHPUNIT" ]; then if [ -x "${PHPUNIT}" ]; then
echo "Using PHPUnit executable $PHPUNIT" echo "Using PHPUnit executable ${PHPUNIT}"
else else
echo "Could not find PHPUnit executable after composer $PHPUNIT" >&2 echo "Could not find PHPUnit executable after composer ${PHPUNIT}" >&2
exit 3 exit 3
fi fi
@ -83,8 +84,8 @@ fi
if [ "$1" ]; then if [ "$1" ]; then
FOUND=0 FOUND=0
for DBCONFIG in $DBCONFIGS; do for DBCONFIG in ${DBCONFIGS}; do
if [ "$1" = "$DBCONFIG" ]; then if [ "$1" = "${DBCONFIG}" ]; then
FOUND=1 FOUND=1
break break
fi fi
@ -103,13 +104,13 @@ fi
function cleanup_config() { function cleanup_config() {
if [ -n "$DOCKER_CONTAINER_ID" ]; then if [ -n "${DOCKER_CONTAINER_ID}" ]; then
echo "Kill the docker $DOCKER_CONTAINER_ID" echo "Kill the docker ${DOCKER_CONTAINER_ID}"
docker stop "$DOCKER_CONTAINER_ID" docker stop "${DOCKER_CONTAINER_ID}"
docker rm -f "$DOCKER_CONTAINER_ID" docker rm -f "${DOCKER_CONTAINER_ID}"
fi fi
cd "$BASEDIR" cd "${BASEDIR}"
# Restore existing config # Restore existing config
if [ -f config/local.config-autotest-backup.php ]; then if [ -f config/local.config-autotest-backup.php ]; then
@ -122,77 +123,77 @@ trap cleanup_config EXIT
function execute_tests() { function execute_tests() {
DB=$1 DB=$1
echo "Setup environment for $DB testing ..." echo "Setup environment for ${DB} testing ..."
# back to root folder # back to root folder
cd "$BASEDIR" cd "${BASEDIR}"
# backup current config # backup current config
if [ -f config/local.config.php ]; then if [ -f config/local.config.php ]; then
mv config/local.config.php config/local.config-autotest-backup.php mv config/local.config.php config/local.config-autotest-backup.php
fi fi
if [ -z "$NOINSTALL" ]; then if [ -z "${NOINSTALL}" ]; then
#drop database #drop database
if [ "$DB" == "mysql" ]; then if [ "${DB}" == "mysql" ]; then
if [ -n "$USEDOCKER" ]; then if [ -n "${USEDOCKER}" ]; then
echo "Fire up the mysql docker" echo "Fire up the mysql docker"
DOCKER_CONTAINER_ID=$(docker run \ DOCKER_CONTAINER_ID=$(docker run \
-e MYSQL_ROOT_PASSWORD=friendica \ -e MYSQL_ROOT_PASSWORD=friendica \
-e MYSQL_USER="$DATABASEUSER" \ -e MYSQL_USER="${DATABASE_USER}" \
-e MYSQL_PASSWORD=friendica \ -e MYSQL_PASSWORD=friendica \
-e MYSQL_DATABASE="$DATABASENAME" \ -e MYSQL_DATABASE="${DATABASE_NAME}" \
-d mysql) -d mysql)
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID") DATABASE_HOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "${DOCKER_CONTAINER_ID}")
else else
if [ -z "$DRONE" ]; then # no need to drop the DB when we are on CI if [ -z "${DRONE}" ]; then # no need to drop the DB when we are on CI
if [ "mysql" != "$(mysql --version | grep -o mysql)" ]; then if [ "mysql" != "$(mysql --version | grep -o mysql)" ]; then
echo "Your mysql binary is not provided by mysql" echo "Your mysql binary is not provided by mysql"
echo "To use the docker container set the USEDOCKER environment variable" echo "To use the docker container set the USEDOCKER environment variable"
exit 3 exit 3
fi fi
mysql -u "$DATABASEUSER" -pfriendica -e "DROP DATABASE IF EXISTS $DATABASENAME" -h $DATABASEHOST || true mysql -u "${DATABASE_USER}" -pfriendica -e "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
mysql -u "$DATABASEUSER" -pfriendica -e "CREATE DATABASE $DATABASENAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h $DATABASEHOST mysql -u "${DATABASE_USER}" -pfriendica -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
else else
DATABASEHOST=mysql DATABASE_HOST=mysql
fi fi
fi fi
echo "Waiting for MySQL $DATABASEHOST initialization..." echo "Waiting for MySQL ${DATABASE_HOST} initialization..."
if ! bin/wait-for-connection $DATABASEHOST 3306 300; then if ! bin/wait-for-connection ${DATABASE_HOST} 3306 300; then
echo "[ERROR] Waited 300 seconds, no response" >&2 echo "[ERROR] Waited 300 seconds, no response" >&2
exit 1 exit 1
fi fi
echo "MySQL is up." echo "MySQL is up."
fi fi
if [ "$DB" == "mariadb" ]; then if [ "${DB}" == "mariadb" ]; then
if [ -n "$USEDOCKER" ]; then if [ -n "${USEDOCKER}" ]; then
echo "Fire up the mariadb docker" echo "Fire up the mariadb docker"
DOCKER_CONTAINER_ID=$(docker run \ DOCKER_CONTAINER_ID=$(docker run \
-e MYSQL_ROOT_PASSWORD=friendica \ -e MYSQL_ROOT_PASSWORD=friendica \
-e MYSQL_USER="$DATABASEUSER" \ -e MYSQL_USER="${DATABASE_USER}" \
-e MYSQL_PASSWORD=friendica \ -e MYSQL_PASSWORD=friendica \
-e MYSQL_DATABASE="$DATABASENAME" \ -e MYSQL_DATABASE="${DATABASE_NAME}" \
-d mariadb) -d mariadb)
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID") DATABASE_HOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "${DOCKER_CONTAINER_ID}")
else else
if [ -z "$DRONE" ]; then # no need to drop the DB when we are on CI if [ -z "${DRONE}" ]; then # no need to drop the DB when we are on CI
if [ "MariaDB" != "$(mysql --version | grep -o MariaDB)" ]; then if [ "MariaDB" != "$(mysql --version | grep -o MariaDB)" ]; then
echo "Your mysql binary is not provided by mysql" echo "Your mysql binary is not provided by mysql"
echo "To use the docker container set the USEDOCKER environment variable" echo "To use the docker container set the USEDOCKER environment variable"
exit 3 exit 3
fi fi
mysql -u "$DATABASEUSER" -pfriendica -e "DROP DATABASE IF EXISTS $DATABASENAME" -h $DATABASEHOST || true mysql -u "${DATABASE_USER}" -pfriendica -e "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
mysql -u "$DATABASEUSER" -pfriendica -e "CREATE DATABASE $DATABASENAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h $DATABASEHOST mysql -u "${DATABASE_USER}" -pfriendica -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
else else
DATABASEHOST=mariadb DATABASE_HOST=mariadb
fi fi
fi fi
echo "Waiting for MariaDB $DATABASEHOST initialization..." echo "Waiting for MariaDB ${DATABASE_HOST} initialization..."
if ! bin/wait-for-connection $DATABASEHOST 3306 300; then if ! bin/wait-for-connection ${DATABASE_HOST} 3306 300; then
echo "[ERROR] Waited 300 seconds, no response" >&2 echo "[ERROR] Waited 300 seconds, no response" >&2
exit 1 exit 1
fi fi
@ -200,28 +201,28 @@ function execute_tests() {
echo "MariaDB is up." echo "MariaDB is up."
fi fi
if [ -n "$USEDOCKER" ]; then if [ -n "${USEDOCKER}" ]; then
echo "Initialize database..." echo "Initialize database..."
docker exec $DOCKER_CONTAINER_ID mysql -u root -pfriendica -e 'CREATE DATABASE IF NOT EXISTS $DATABASENAME;' docker exec ${DOCKER_CONTAINER_ID} mysql -u root -pfriendica -e "CREATE DATABASE IF NOT EXISTS ${DATABASE_NAME};"
fi fi
export MYSQL_HOST="$DATABASEHOST" export MYSQL_HOST="${DATABASE_HOST}"
#call installer #call installer
echo "Installing Friendica..." echo "Installing Friendica..."
"$PHP" ./bin/console.php autoinstall --dbuser="$DATABASEUSER" --dbpass=friendica --dbdata="$DATABASENAME" --dbhost="$DATABASEHOST" --url=https://friendica.local --admin=admin@friendica.local "${PHP}" ./bin/console.php autoinstall --dbuser="${DATABASE_USER}" --dbpass=friendica --dbdata="${DATABASE_NAME}" --dbhost="${DATABASE_HOST}" --url=https://friendica.local --admin=admin@friendica.local
fi fi
#test execution #test execution
echo "Testing..." echo "Testing..."
rm -fr "coverage-html" rm -fr "coverage-html"
mkdir "coverage-html" mkdir "coverage-html"
if [[ "$_XDEBUG_CONFIG" ]]; then if [[ "${_XDEBUG_CONFIG}" ]]; then
export XDEBUG_CONFIG=$_XDEBUG_CONFIG export XDEBUG_CONFIG=${_XDEBUG_CONFIG}
fi fi
COVER='' COVER=''
if [ -z "$NOCOVERAGE" ]; then if [ -z "${NOCOVERAGE}" ]; then
COVER="--coverage-clover tests/autotest-clover.xml" COVER="--coverage-clover tests/autotest-clover.xml"
else else
echo "No coverage" echo "No coverage"
@ -229,51 +230,51 @@ function execute_tests() {
# per default, there is no cache installed # per default, there is no cache installed
GROUP='--exclude-group REDIS,MEMCACHE,MEMCACHED,APCU' GROUP='--exclude-group REDIS,MEMCACHE,MEMCACHED,APCU'
if [ "$TEST_SELECTION" == "REDIS" ]; then if [ "${TEST_SELECTION}" == "REDIS" ]; then
GROUP="--group REDIS" GROUP="--group REDIS"
fi fi
if [ "$TEST_SELECTION" == "MEMCACHE" ]; then if [ "${TEST_SELECTION}" == "MEMCACHE" ]; then
GROUP="--group MEMCACHE" GROUP="--group MEMCACHE"
fi fi
if [ "$TEST_SELECTION" == "MEMCACHED" ]; then if [ "${TEST_SELECTION}" == "MEMCACHED" ]; then
GROUP="--group MEMCACHED" GROUP="--group MEMCACHED"
fi fi
if [ "$TEST_SELECTION" == "APCU" ]; then if [ "${TEST_SELECTION}" == "APCU" ]; then
GROUP="--group APCU" GROUP="--group APCU"
fi fi
if [ "$TEST_SELECTION" == "NODB" ]; then if [ "${TEST_SELECTION}" == "NODB" ]; then
GROUP="--exclude-group DB,SLOWDB" GROUP="--exclude-group DB,SLOWDB"
fi fi
INPUT="$BASEDIR/tests" INPUT="${BASEDIR}/tests"
if [ -n "$2" ]; then if [ -n "$2" ]; then
INPUT="$INPUT/$2" INPUT="${INPUT}/$2"
fi fi
echo "${PHPUNIT[@]}" --configuration tests/phpunit.xml $GROUP $COVER --log-junit "autotest-results.xml" "$INPUT" "$3" echo "${PHPUNIT[@]}" --configuration tests/phpunit.xml ${GROUP} ${COVER} --log-junit "autotest-results.xml" "${INPUT}" "$3"
"${PHPUNIT[@]}" --configuration tests/phpunit.xml $GROUP $COVER --log-junit "autotest-results.xml" "$INPUT" "$3" "${PHPUNIT[@]}" --configuration tests/phpunit.xml ${GROUP} ${COVER} --log-junit "autotest-results.xml" "${INPUT}" "$3"
RESULT=$? RESULT=$?
if [ -n "$DOCKER_CONTAINER_ID" ]; then if [ -n "${DOCKER_CONTAINER_ID}" ]; then
echo "Kill the docker $DOCKER_CONTAINER_ID" echo "Kill the docker ${DOCKER_CONTAINER_ID}"
docker stop $DOCKER_CONTAINER_ID docker stop ${DOCKER_CONTAINER_ID}
docker rm -f $DOCKER_CONTAINER_ID docker rm -f ${DOCKER_CONTAINER_ID}
unset $DOCKER_CONTAINER_ID unset ${DOCKER_CONTAINER_ID}
fi fi
} }
# #
# Start the test execution # Start the test execution
# #
if [ -z "$1" ] && [ -n "$TEST_SELECTION" ]; then if [ -z "$1" ] && [ -n "${TEST_SELECTION}" ]; then
# run all known database configs # run all known database configs
for DBCONFIG in $DBCONFIGS; do for DBCONFIG in ${DBCONFIGS}; do
execute_tests "$DBCONFIG" execute_tests "${DBCONFIG}"
done done
else else
FILENAME="$2" FILENAME="$2"
if [ -n "$2" ] && [ ! -f "tests/$FILENAME" ] && [ "${FILENAME:0:2}" != "--" ]; then if [ -n "$2" ] && [ ! -f "tests/${FILENAME}" ] && [ "${FILENAME:0:2}" != "--" ]; then
FILENAME="../$FILENAME" FILENAME="../${FILENAME}"
fi fi
execute_tests "$1" "$FILENAME" "$3" execute_tests "$1" "${FILENAME}" "$3"
fi fi

View file

@ -31,7 +31,7 @@ use Friendica\Model\Contact;
define('FRIENDICA_PLATFORM', 'Friendica'); define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'Giant Rhubarb'); define('FRIENDICA_CODENAME', 'Giant Rhubarb');
define('FRIENDICA_VERSION', '2022.06'); define('FRIENDICA_VERSION', '2022.09-dev');
define('DFRN_PROTOCOL_VERSION', '2.23'); define('DFRN_PROTOCOL_VERSION', '2.23');
define('NEW_TABLE_STRUCTURE_VERSION', 1288); define('NEW_TABLE_STRUCTURE_VERSION', 1288);
@ -87,8 +87,8 @@ define('PRIORITIES', [PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORIT
/* @}*/ /* @}*/
// Normally this constant is defined - but not if "pcntl" isn't installed // Normally this constant is defined - but not if "pcntl" isn't installed
if (!defined("SIGTERM")) { if (!defined('SIGTERM')) {
define("SIGTERM", 15); define('SIGTERM', 15);
} }
/** /**
@ -117,6 +117,7 @@ function local_user()
if (!empty($_SESSION['authenticated']) && !empty($_SESSION['uid'])) { if (!empty($_SESSION['authenticated']) && !empty($_SESSION['uid'])) {
return intval($_SESSION['uid']); return intval($_SESSION['uid']);
} }
return false; return false;
} }
@ -169,7 +170,7 @@ function remote_user()
* *
* @param string $s - Text of notice * @param string $s - Text of notice
*/ */
function notice($s) function notice(string $s)
{ {
if (empty($_SESSION)) { if (empty($_SESSION)) {
return; return;
@ -189,7 +190,7 @@ function notice($s)
* *
* @param string $s - Text of notice * @param string $s - Text of notice
*/ */
function info($s) function info(string $s)
{ {
if (empty($_SESSION)) { if (empty($_SESSION)) {
return; return;

204
composer.lock generated
View file

@ -545,12 +545,12 @@
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": {
"DivineOmega\\PasswordExposed\\": "src/"
},
"files": [ "files": [
"src/PasswordExposedFunction.php" "src/PasswordExposedFunction.php"
] ],
"psr-4": {
"DivineOmega\\PasswordExposed\\": "src/"
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -587,12 +587,12 @@
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-0": {
"HTMLPurifier": "library/"
},
"files": [ "files": [
"library/HTMLPurifier.composer.php" "library/HTMLPurifier.composer.php"
], ],
"psr-0": {
"HTMLPurifier": "library/"
},
"exclude-from-classmap": [ "exclude-from-classmap": [
"/library/HTMLPurifier/Language/" "/library/HTMLPurifier/Language/"
] ]
@ -839,24 +839,24 @@
}, },
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "6.5.5", "version": "6.5.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/guzzle.git", "url": "https://github.com/guzzle/guzzle.git",
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981",
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"guzzlehttp/promises": "^1.0", "guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.6.1", "guzzlehttp/psr7": "^1.9",
"php": ">=5.5", "php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.17.0" "symfony/polyfill-intl-idn": "^1.17"
}, },
"require-dev": { "require-dev": {
"ext-curl": "*", "ext-curl": "*",
@ -873,22 +873,52 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
},
"files": [ "files": [
"src/functions_include.php" "src/functions_include.php"
] ],
"psr-4": {
"GuzzleHttp\\": "src/"
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{ {
"name": "Michael Dowling", "name": "Michael Dowling",
"email": "mtdowling@gmail.com", "email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling" "homepage": "https://github.com/mtdowling"
},
{
"name": "Jeremy Lindblom",
"email": "jeremeamia@gmail.com",
"homepage": "https://github.com/jeremeamia"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
} }
], ],
"description": "Guzzle is a PHP HTTP client library", "description": "Guzzle is a PHP HTTP client library",
@ -902,7 +932,21 @@
"rest", "rest",
"web service" "web service"
], ],
"time": "2020-06-16T21:01:06+00:00" "funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
"type": "tidelift"
}
],
"time": "2022-06-20T22:16:07+00:00"
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
@ -931,12 +975,12 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [ "files": [
"src/functions_include.php" "src/functions_include.php"
] ],
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -986,16 +1030,16 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "1.8.3", "version": "1.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85" "reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/1afdd860a2566ed3c2b0b4a3de6e23434a79ec85", "url": "https://api.github.com/repos/guzzle/psr7/zipball/e98e3e6d4f86621a9b75f623996e6bbdeb4b9318",
"reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85", "reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1016,16 +1060,16 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.7-dev" "dev-master": "1.9-dev"
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [ "files": [
"src/functions_include.php" "src/functions_include.php"
] ],
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -1088,7 +1132,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-10-05T13:56:00+00:00" "time": "2022-06-20T21:43:03+00:00"
}, },
{ {
"name": "league/html-to-markdown", "name": "league/html-to-markdown",
@ -1471,12 +1515,12 @@
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"classmap": [
"Mobile_Detect.php"
],
"psr-0": { "psr-0": {
"Detection": "namespaced/" "Detection": "namespaced/"
} },
"classmap": [
"Mobile_Detect.php"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -1611,12 +1655,12 @@
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": {
"FastRoute\\": "src/"
},
"files": [ "files": [
"src/functions.php" "src/functions.php"
] ],
"psr-4": {
"FastRoute\\": "src/"
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -3803,16 +3847,16 @@
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
"version": "v1.23.0", "version": "v1.26.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git", "url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "65bd267525e82759e7d8c4e8ceea44f398838e65" "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/65bd267525e82759e7d8c4e8ceea44f398838e65", "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
"reference": "65bd267525e82759e7d8c4e8ceea44f398838e65", "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3826,7 +3870,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.23-dev" "dev-main": "1.26-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -3834,12 +3878,12 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
},
"files": [ "files": [
"bootstrap.php" "bootstrap.php"
] ],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -3883,20 +3927,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-05-27T09:27:20+00:00" "time": "2022-05-24T11:49:31+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.23.0", "version": "v1.26.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
"reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3908,7 +3952,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.23-dev" "dev-main": "1.26-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -3916,12 +3960,12 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"files": [ "files": [
"bootstrap.php" "bootstrap.php"
], ],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"classmap": [ "classmap": [
"Resources/stubs" "Resources/stubs"
] ]
@ -3964,7 +4008,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-02-19T12:13:01+00:00" "time": "2022-05-24T11:49:31+00:00"
}, },
{ {
"name": "symfony/polyfill-php56", "name": "symfony/polyfill-php56",
@ -4033,16 +4077,16 @@
}, },
{ {
"name": "symfony/polyfill-php72", "name": "symfony/polyfill-php72",
"version": "v1.23.0", "version": "v1.26.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php72.git", "url": "https://github.com/symfony/polyfill-php72.git",
"reference": "9a142215a36a3888e30d0a9eeea9766764e96976" "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
"reference": "9a142215a36a3888e30d0a9eeea9766764e96976", "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4051,7 +4095,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.23-dev" "dev-main": "1.26-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -4059,12 +4103,12 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
},
"files": [ "files": [
"bootstrap.php" "bootstrap.php"
] ],
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -4102,7 +4146,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-05-27T09:17:38+00:00" "time": "2022-05-24T11:49:31+00:00"
}, },
{ {
"name": "ua-parser/uap-php", "name": "ua-parser/uap-php",
@ -4865,12 +4909,12 @@
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
},
"files": [ "files": [
"src/DeepCopy/deep_copy.php" "src/DeepCopy/deep_copy.php"
] ],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -5618,11 +5662,11 @@
} }
}, },
"autoload": { "autoload": {
"classmap": [
"src/"
],
"files": [ "files": [
"src/Framework/Assert/Functions.php" "src/Framework/Assert/Functions.php"
],
"classmap": [
"src/"
] ]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -6586,12 +6630,12 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [ "files": [
"bootstrap.php" "bootstrap.php"
] ],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2022.06 (Giant Rhubarb) -- Friendica 2022.09-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1469 -- DB_UPDATE_VERSION 1472
-- ------------------------------------------ -- ------------------------------------------
@ -1216,13 +1216,13 @@ CREATE TABLE IF NOT EXISTS `post-link` (
CREATE TABLE IF NOT EXISTS `post-media` ( CREATE TABLE IF NOT EXISTS `post-media` (
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID', `id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri', `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
`url` varbinary(511) NOT NULL COMMENT 'Media URL', `url` varbinary(1024) NOT NULL COMMENT 'Media URL',
`type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Media type', `type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Media type',
`mimetype` varchar(60) COMMENT '', `mimetype` varchar(60) COMMENT '',
`height` smallint unsigned COMMENT 'Height of the media', `height` smallint unsigned COMMENT 'Height of the media',
`width` smallint unsigned COMMENT 'Width of the media', `width` smallint unsigned COMMENT 'Width of the media',
`size` int unsigned COMMENT 'Media size', `size` bigint unsigned COMMENT 'Media size',
`preview` varbinary(255) COMMENT 'Preview URL', `preview` varbinary(512) COMMENT 'Preview URL',
`preview-height` smallint unsigned COMMENT 'Height of the preview picture', `preview-height` smallint unsigned COMMENT 'Height of the preview picture',
`preview-width` smallint unsigned COMMENT 'Width of the preview picture', `preview-width` smallint unsigned COMMENT 'Width of the preview picture',
`description` text COMMENT '', `description` text COMMENT '',
@ -1234,7 +1234,7 @@ CREATE TABLE IF NOT EXISTS `post-media` (
`publisher-name` varchar(255) COMMENT 'Name of the publisher of the media', `publisher-name` varchar(255) COMMENT 'Name of the publisher of the media',
`publisher-image` varbinary(255) COMMENT 'Image of the publisher of the media', `publisher-image` varbinary(255) COMMENT 'Image of the publisher of the media',
PRIMARY KEY(`id`), PRIMARY KEY(`id`),
UNIQUE INDEX `uri-id-url` (`uri-id`,`url`), UNIQUE INDEX `uri-id-url` (`uri-id`,`url`(512)),
INDEX `uri-id-id` (`uri-id`,`id`), INDEX `uri-id-id` (`uri-id`,`id`),
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Attached media'; ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Attached media';

View file

@ -82,6 +82,7 @@ General
../settings ../settings
--------- ---------
* o - Account * o - Account
* 2 - Two-factor authentication
* p - Profiles * p - Profiles
* t - Additional features * t - Additional features
* w - Social Networks * w - Social Networks

View file

@ -10,13 +10,13 @@ Fields
| --------------- | --------------------------------------------------------- | ----------------- | ---- | --- | ------- | -------------- | | --------------- | --------------------------------------------------------- | ----------------- | ---- | --- | ------- | -------------- |
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment | | id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | | | uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | |
| url | Media URL | varbinary(511) | NO | | NULL | | | url | Media URL | varbinary(1024) | NO | | NULL | |
| type | Media type | tinyint unsigned | NO | | 0 | | | type | Media type | tinyint unsigned | NO | | 0 | |
| mimetype | | varchar(60) | YES | | NULL | | | mimetype | | varchar(60) | YES | | NULL | |
| height | Height of the media | smallint unsigned | YES | | NULL | | | height | Height of the media | smallint unsigned | YES | | NULL | |
| width | Width of the media | smallint unsigned | YES | | NULL | | | width | Width of the media | smallint unsigned | YES | | NULL | |
| size | Media size | int unsigned | YES | | NULL | | | size | Media size | bigint unsigned | YES | | NULL | |
| preview | Preview URL | varbinary(255) | YES | | NULL | | | preview | Preview URL | varbinary(512) | YES | | NULL | |
| preview-height | Height of the preview picture | smallint unsigned | YES | | NULL | | | preview-height | Height of the preview picture | smallint unsigned | YES | | NULL | |
| preview-width | Width of the preview picture | smallint unsigned | YES | | NULL | | | preview-width | Width of the preview picture | smallint unsigned | YES | | NULL | |
| description | | text | YES | | NULL | | | description | | text | YES | | NULL | |
@ -31,11 +31,11 @@ Fields
Indexes Indexes
------------ ------------
| Name | Fields | | Name | Fields |
| ---------- | ------------------- | | ---------- | ------------------------ |
| PRIMARY | id | | PRIMARY | id |
| uri-id-url | UNIQUE, uri-id, url | | uri-id-url | UNIQUE, uri-id, url(512) |
| uri-id-id | uri-id, id | | uri-id-id | uri-id, id |
Foreign Keys Foreign Keys
------------ ------------

BIN
images/default/corgidon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
images/default/diaspora.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1000px"
height="1000px"
viewBox="0 0 1000 1000"
version="1.1"
id="SVGRoot"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="GoToSocial_icon1.svg"
inkscape:export-xdpi="95.999992"
inkscape:export-ydpi="95.999992">
<defs
id="defs5117">
<inkscape:path-effect
effect="spiro"
id="path-effect5760"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5756"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5752"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect5748"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.70710678"
inkscape:cx="460.72691"
inkscape:cy="522.20279"
inkscape:document-units="px"
inkscape:current-layer="layer3"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata5120">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="background"
inkscape:groupmode="layer"
id="layer1"
style="display:inline">
<rect
style="fill:#d0d0d0;fill-opacity:1;stroke:none;stroke-width:1.51092136;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
id="rect5876"
width="1000.0042"
height="1000"
x="0"
y="0" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="sloth"
style="display:inline">
<g
id="g5890"
transform="translate(-10)">
<path
sodipodi:nodetypes="ssscccs"
inkscape:connector-curvature="0"
id="path5762"
d="M 861.29285,497.07031 C 861.65556,665.3247 774.21642,807.40548 511.60027,807.86794 270.63622,808.29226 154.54309,691.2756 155.19024,504.19228 155.7289,348.47535 251.17288,227.4551 422.3176,205.3802 c -35.32036,-75.85452 52.24232,-96.94648 73.77615,-32.00508 13.73451,-37.63439 108.24345,-49.1716 62.21106,24.77055 147.95052,3.75658 302.58353,111.28061 302.98804,298.92464 z"
style="display:inline;fill:#767676;fill-opacity:1;stroke:none;stroke-width:2.57058167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<path
sodipodi:nodetypes="sssssss"
inkscape:connector-curvature="0"
id="path5780"
d="m 809.15213,517.31679 c -4.83374,150.52526 -109.85544,235.22815 -297.81171,235.31839 -179.6675,0.0863 -290.56109,-70.98245 -298.50223,-235.31839 -4.6366,-95.95095 54.62861,-181.84442 144.83016,-194.18834 80.92123,-11.07393 99.7402,21.01802 153.67207,21.01802 59.21658,0 83.64871,-35.09608 162.84221,-21.85479 87.78391,14.67763 137.90533,103.6017 134.9695,195.02511 z"
style="display:inline;fill:#e8e8e8;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<path
sodipodi:nodetypes="scssscs"
inkscape:connector-curvature="0"
id="path5780-9"
d="m 809.15213,517.31679 c -1.32872,41.37724 -10.22787,77.78081 -26.33906,108.8204 -46.60931,-39.48031 -99.53509,-10.7281 -171.50115,-39.43334 -44.77145,-17.85808 -51.41659,-56.56453 -51.21999,-81.3542 0.54836,-69.14384 48.17003,-93.45758 95.53601,-97.60875 55.74677,-4.88566 124.5246,36.1482 151.01547,66.79433 2.11531,14.01083 2.97167,28.36512 2.50872,42.78156 z"
style="display:inline;fill:#a1a1a1;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<ellipse
ry="50.575684"
rx="37.800804"
cy="502.64291"
cx="646.85773"
id="path5816"
style="fill:#767676;fill-opacity:1;stroke:none;stroke-width:1.51185882;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<path
sodipodi:nodetypes="scssscs"
inkscape:connector-curvature="0"
id="path5780-9-1"
d="m 212.51463,517.3246 c 1.32872,41.37724 10.22787,77.78081 26.33906,108.8204 46.60931,-39.48031 99.57415,-10.73591 171.54021,-39.44115 44.77145,-17.85808 51.41659,-56.56453 51.21999,-81.3542 -0.54836,-69.14384 -48.20909,-93.44977 -95.57507,-97.60094 -55.74677,-4.88566 -124.5246,36.1482 -151.01547,66.79433 -2.11531,14.01083 -2.97167,28.36512 -2.50872,42.78156 z"
style="display:inline;fill:#a1a1a1;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<ellipse
transform="scale(-1,1)"
ry="50.575684"
rx="37.800804"
cy="502.64294"
cx="-374.84808"
id="path5816-0"
style="display:inline;fill:#767676;fill-opacity:1;stroke:none;stroke-width:1.51185882;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<path
sodipodi:nodetypes="sssss"
inkscape:connector-curvature="0"
id="path5862"
d="m 543.96613,556.96185 c 0,11.0622 -14.51648,20.02988 -32.42347,20.02988 -17.90698,0 -32.42347,-8.96769 -32.42347,-20.02988 0,-11.0622 14.14619,-15.58638 32.05318,-15.58638 17.90698,0 32.79376,4.52417 32.79376,15.58638 z"
style="display:inline;fill:#767676;fill-opacity:1;stroke:none;stroke-width:1.60515046;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<path
sodipodi:nodetypes="sssss"
inkscape:connector-curvature="0"
id="path5865"
d="m 552.00195,620.36132 c 7.06643,13.89391 -19.38375,21.24024 -40.2832,21.24024 -20.89945,0 -47.71708,-7.02219 -41.50391,-21.24024 5.71775,-13.08435 20.11619,0.73243 41.01563,0.73243 20.89944,0 34.43888,-13.1835 40.77148,-0.73243 z"
style="display:inline;fill:#767676;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<ellipse
transform="rotate(-6.669407)"
ry="24.882849"
rx="19.511755"
cy="560.95673"
cx="600.24731"
id="path5818"
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.53898752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<ellipse
transform="rotate(-6.6694071)"
ry="24.882849"
rx="19.511755"
cy="529.32086"
cx="329.69714"
id="path5818-8"
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.53898752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
images/default/hometown.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/default/mastodon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
images/default/pleroma.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

BIN
images/default/plume.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -47,7 +47,7 @@ function fbrowser_content(App $a)
} }
// Needed to match the correct template in a module that uses a different theme than the user/site/default // Needed to match the correct template in a module that uses a different theme than the user/site/default
$theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? null); $theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? '');
if ($theme && is_file("view/theme/$theme/config.php")) { if ($theme && is_file("view/theme/$theme/config.php")) {
$a->setCurrentTheme($theme); $a->setCurrentTheme($theme);
} }

View file

@ -187,7 +187,7 @@ function photos_post(App $a)
} }
if (DI::args()->getArgc() > 3 && DI::args()->getArgv()[2] === 'album') { if (DI::args()->getArgc() > 3 && DI::args()->getArgv()[2] === 'album') {
if (!Strings::isHex(DI::args()->getArgv()[3])) { if (!Strings::isHex(DI::args()->getArgv()[3] ?? '')) {
DI::baseUrl()->redirect('photos/' . $user['nickname'] . '/album'); DI::baseUrl()->redirect('photos/' . $user['nickname'] . '/album');
} }
$album = hex2bin(DI::args()->getArgv()[3]); $album = hex2bin(DI::args()->getArgv()[3]);
@ -892,7 +892,7 @@ function photos_content(App $a)
return; return;
} }
$selname = Strings::isHex($datum) ? hex2bin($datum) : ''; $selname = (!is_null($datum) && Strings::isHex($datum)) ? hex2bin($datum) : '';
$albumselect = ''; $albumselect = '';
@ -954,7 +954,7 @@ function photos_content(App $a)
// Display a single photo album // Display a single photo album
if ($datatype === 'album') { if ($datatype === 'album') {
// if $datum is not a valid hex, redirect to the default page // if $datum is not a valid hex, redirect to the default page
if (!Strings::isHex($datum)) { if (is_null($datum) || !Strings::isHex($datum)) {
DI::baseUrl()->redirect('photos/' . $user['nickname']. '/album'); DI::baseUrl()->redirect('photos/' . $user['nickname']. '/album');
} }
$album = hex2bin($datum); $album = hex2bin($datum);

View file

@ -157,9 +157,9 @@ function wall_upload_post(App $a, $desktopmode = true)
" - size: " . $filesize . " - type: " . $filetype); " - size: " . $filesize . " - type: " . $filetype);
$imagedata = @file_get_contents($src); $imagedata = @file_get_contents($src);
$Image = new Image($imagedata, $filetype); $image = new Image($imagedata, $filetype);
if (!$Image->isValid()) { if (!$image->isValid()) {
$msg = DI::l10n()->t('Unable to process image.'); $msg = DI::l10n()->t('Unable to process image.');
@unlink($src); @unlink($src);
if ($r_json) { if ($r_json) {
@ -170,18 +170,18 @@ function wall_upload_post(App $a, $desktopmode = true)
System::exit(); System::exit();
} }
$Image->orient($src); $image->orient($src);
@unlink($src); @unlink($src);
$max_length = DI::config()->get('system', 'max_image_length'); $max_length = DI::config()->get('system', 'max_image_length');
if ($max_length > 0) { if ($max_length > 0) {
$Image->scaleDown($max_length); $image->scaleDown($max_length);
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
Logger::info("File upload: Scaling picture to new size " . $max_length); Logger::info("File upload: Scaling picture to new size " . $max_length);
} }
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
$maximagesize = DI::config()->get('system', 'maximagesize'); $maximagesize = DI::config()->get('system', 'maximagesize');
@ -190,10 +190,10 @@ function wall_upload_post(App $a, $desktopmode = true)
foreach ([5120, 2560, 1280, 640] as $pixels) { foreach ([5120, 2560, 1280, 640] as $pixels) {
if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) { if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) {
Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]); Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]);
$Image->scaleDown($pixels); $image->scaleDown($pixels);
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
} }
} }
if ($filesize > $maximagesize) { if ($filesize > $maximagesize) {
@ -220,7 +220,7 @@ function wall_upload_post(App $a, $desktopmode = true)
$defperm = '<' . $default_cid . '>'; $defperm = '<' . $default_cid . '>';
$r = Photo::store($Image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0, Photo::DEFAULT, $defperm); $r = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0, Photo::DEFAULT, $defperm);
if (!$r) { if (!$r) {
$msg = DI::l10n()->t('Image upload failed.'); $msg = DI::l10n()->t('Image upload failed.');
@ -233,16 +233,16 @@ function wall_upload_post(App $a, $desktopmode = true)
} }
if ($width > 640 || $height > 640) { if ($width > 640 || $height > 640) {
$Image->scaleDown(640); $image->scaleDown(640);
$r = Photo::store($Image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, Photo::DEFAULT, $defperm); $r = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, Photo::DEFAULT, $defperm);
if ($r) { if ($r) {
$smallest = 1; $smallest = 1;
} }
} }
if ($width > 320 || $height > 320) { if ($width > 320 || $height > 320) {
$Image->scaleDown(320); $image->scaleDown(320);
$r = Photo::store($Image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, Photo::DEFAULT, $defperm); $r = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, Photo::DEFAULT, $defperm);
if ($r && ($smallest == 0)) { if ($r && ($smallest == 0)) {
$smallest = 2; $smallest = 2;
} }
@ -264,8 +264,8 @@ function wall_upload_post(App $a, $desktopmode = true)
$picture["height"] = $photo["height"]; $picture["height"] = $photo["height"];
$picture["type"] = $photo["type"]; $picture["type"] = $photo["type"];
$picture["albumpage"] = DI::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $resource_id; $picture["albumpage"] = DI::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $resource_id;
$picture["picture"] = DI::baseUrl() . "/photo/{$resource_id}-0." . $Image->getExt(); $picture["picture"] = DI::baseUrl() . "/photo/{$resource_id}-0." . $image->getExt();
$picture["preview"] = DI::baseUrl() . "/photo/{$resource_id}-{$smallest}." . $Image->getExt(); $picture["preview"] = DI::baseUrl() . "/photo/{$resource_id}-{$smallest}." . $image->getExt();
if ($r_json) { if ($r_json) {
System::jsonExit(['picture' => $picture]); System::jsonExit(['picture' => $picture]);
@ -280,7 +280,7 @@ function wall_upload_post(App $a, $desktopmode = true)
System::jsonExit(['ok' => true]); System::jsonExit(['ok' => true]);
} }
echo "\n\n" . '[url=' . DI::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $resource_id . '][img]' . DI::baseUrl() . "/photo/{$resource_id}-{$smallest}.".$Image->getExt()."[/img][/url]\n\n"; echo "\n\n" . '[url=' . DI::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $resource_id . '][img]' . DI::baseUrl() . "/photo/{$resource_id}-{$smallest}." . $image->getExt() . "[/img][/url]\n\n";
System::exit(); System::exit();
// NOTREACHED // NOTREACHED
} }

View file

@ -145,7 +145,7 @@ class App
$this->nickname = $nickname; $this->nickname = $nickname;
} }
public function isLoggedIn() public function isLoggedIn(): bool
{ {
return local_user() && $this->user_id && ($this->user_id == local_user()); return local_user() && $this->user_id && ($this->user_id == local_user());
} }
@ -155,7 +155,7 @@ class App
* *
* @return bool true if user is an admin * @return bool true if user is an admin
*/ */
public function isSiteAdmin() public function isSiteAdmin(): bool
{ {
$admin_email = $this->config->get('config', 'admin_email'); $admin_email = $this->config->get('config', 'admin_email');
@ -166,18 +166,18 @@ class App
/** /**
* Fetch the user id * Fetch the user id
* @return int * @return int User id
*/ */
public function getLoggedInUserId() public function getLoggedInUserId(): int
{ {
return $this->user_id; return $this->user_id;
} }
/** /**
* Fetch the user nick name * Fetch the user nick name
* @return string * @return string User's nickname
*/ */
public function getLoggedInUserNickname() public function getLoggedInUserNickname(): string
{ {
return $this->nickname; return $this->nickname;
} }
@ -198,7 +198,7 @@ class App
* *
* @return int * @return int
*/ */
public function getProfileOwner():int public function getProfileOwner(): int
{ {
return $this->profile_owner; return $this->profile_owner;
} }
@ -219,7 +219,7 @@ class App
* *
* @return int * @return int
*/ */
public function getContactId():int public function getContactId(): int
{ {
return $this->contact_id; return $this->contact_id;
} }
@ -241,7 +241,7 @@ class App
* *
* @return int * @return int
*/ */
public function getTimeZone():string public function getTimeZone(): string
{ {
return $this->timezone; return $this->timezone;
} }
@ -260,9 +260,9 @@ class App
/** /**
* Fetch workerqueue information * Fetch workerqueue information
* *
* @return array * @return array Worker queue
*/ */
public function getQueue() public function getQueue(): array
{ {
return $this->queue ?? []; return $this->queue ?? [];
} }
@ -270,8 +270,8 @@ class App
/** /**
* Fetch a specific workerqueue field * Fetch a specific workerqueue field
* *
* @param string $index * @param string $index Work queue record to fetch
* @return mixed * @return mixed Work queue item or NULL if not found
*/ */
public function getQueueValue(string $index) public function getQueueValue(string $index)
{ {
@ -306,9 +306,9 @@ class App
/** /**
* The basepath of this app * The basepath of this app
* *
* @return string * @return string Base path from configuration
*/ */
public function getBasePath() public function getBasePath(): string
{ {
// Don't use the basepath of the config table for basepath (it should always be the config-file one) // 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->getCache()->get('system', 'basepath');
@ -396,10 +396,10 @@ class App
/** /**
* Returns the current theme name. May be overriden by the mobile theme name. * Returns the current theme name. May be overriden by the mobile theme name.
* *
* @return string * @return string Current theme name or empty string in installation phase
* @throws Exception * @throws Exception
*/ */
public function getCurrentTheme() public function getCurrentTheme(): string
{ {
if ($this->mode->isInstall()) { if ($this->mode->isInstall()) {
return ''; return '';
@ -425,10 +425,10 @@ class App
/** /**
* Returns the current mobile theme name. * Returns the current mobile theme name.
* *
* @return string * @return string Mobile theme name or empty string if installer
* @throws Exception * @throws Exception
*/ */
public function getCurrentMobileTheme() public function getCurrentMobileTheme(): string
{ {
if ($this->mode->isInstall()) { if ($this->mode->isInstall()) {
return ''; return '';
@ -441,12 +441,22 @@ class App
return $this->currentMobileTheme; return $this->currentMobileTheme;
} }
public function setCurrentTheme($theme) /**
* Setter for current theme name
*
* @param string $theme Name of current theme
*/
public function setCurrentTheme(string $theme)
{ {
$this->currentTheme = $theme; $this->currentTheme = $theme;
} }
public function setCurrentMobileTheme($theme) /**
* Setter for current mobile theme name
*
* @param string $theme Name of current mobile theme
*/
public function setCurrentMobileTheme(string $theme)
{ {
$this->currentMobileTheme = $theme; $this->currentMobileTheme = $theme;
} }
@ -525,10 +535,10 @@ class App
/** /**
* Provide a sane default if nothing is chosen or the specified theme does not exist. * Provide a sane default if nothing is chosen or the specified theme does not exist.
* *
* @return string * @return string Current theme's stylsheet path
* @throws Exception * @throws Exception
*/ */
public function getCurrentThemeStylesheetPath() public function getCurrentThemeStylesheetPath(): string
{ {
return Core\Theme::getStylesheetPath($this->getCurrentTheme()); return Core\Theme::getStylesheetPath($this->getCurrentTheme());
} }
@ -730,7 +740,7 @@ class App
* *
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public function redirect($toUrl) public function redirect(string $toUrl)
{ {
if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) { if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
Core\System::externalRedirect($toUrl); Core\System::externalRedirect($toUrl);

View file

@ -78,7 +78,7 @@ class Arguments
/** /**
* @return string The whole command of this call * @return string The whole command of this call
*/ */
public function getCommand() public function getCommand(): string
{ {
return $this->command; return $this->command;
} }
@ -94,7 +94,7 @@ class Arguments
/** /**
* @return array All arguments of this call * @return array All arguments of this call
*/ */
public function getArgv() public function getArgv(): array
{ {
return $this->argv; return $this->argv;
} }
@ -102,7 +102,7 @@ class Arguments
/** /**
* @return string The used HTTP method * @return string The used HTTP method
*/ */
public function getMethod() public function getMethod(): string
{ {
return $this->method; return $this->method;
} }
@ -110,7 +110,7 @@ class Arguments
/** /**
* @return int The count of arguments of this call * @return int The count of arguments of this call
*/ */
public function getArgc() public function getArgc(): int
{ {
return $this->argc; return $this->argc;
} }
@ -145,7 +145,7 @@ class Arguments
* *
* @return bool if the argument position exists * @return bool if the argument position exists
*/ */
public function has(int $position) public function has(int $position): bool
{ {
return array_key_exists($position, $this->argv); return array_key_exists($position, $this->argv);
} }
@ -158,7 +158,7 @@ class Arguments
* *
* @return Arguments The determined arguments * @return Arguments The determined arguments
*/ */
public function determine(array $server, array $get) public function determine(array $server, array $get): Arguments
{ {
// removing leading / - maybe a nginx problem // removing leading / - maybe a nginx problem
$server['QUERY_STRING'] = ltrim($server['QUERY_STRING'] ?? '', '/'); $server['QUERY_STRING'] = ltrim($server['QUERY_STRING'] ?? '', '/');

View file

@ -107,7 +107,7 @@ class BaseURL
* *
* @return string * @return string
*/ */
public function getHostname() public function getHostname(): string
{ {
return $this->hostname; return $this->hostname;
} }
@ -117,7 +117,7 @@ class BaseURL
* *
* @return string * @return string
*/ */
public function getScheme() public function getScheme(): string
{ {
return $this->scheme; return $this->scheme;
} }
@ -127,7 +127,7 @@ class BaseURL
* *
* @return int * @return int
*/ */
public function getSSLPolicy() public function getSSLPolicy(): int
{ {
return $this->sslPolicy; return $this->sslPolicy;
} }
@ -137,7 +137,7 @@ class BaseURL
* *
* @return string * @return string
*/ */
public function getUrlPath() public function getUrlPath(): string
{ {
return $this->urlPath; return $this->urlPath;
} }
@ -151,7 +151,7 @@ class BaseURL
* *
* @return string * @return string
*/ */
public function get($ssl = false) public function get(bool $ssl = false): string
{ {
if ($this->sslPolicy === self::SSL_POLICY_SELFSIGN && $ssl) { if ($this->sslPolicy === self::SSL_POLICY_SELFSIGN && $ssl) {
return Network::switchScheme($this->url); return Network::switchScheme($this->url);
@ -168,8 +168,9 @@ class BaseURL
* @param string? $urlPath * @param string? $urlPath
* *
* @return bool true, if successful * @return bool true, if successful
* @TODO Find proper types
*/ */
public function save($hostname = null, $sslPolicy = null, $urlPath = null) public function save($hostname = null, $sslPolicy = null, $urlPath = null): bool
{ {
$currHostname = $this->hostname; $currHostname = $this->hostname;
$currSSLPolicy = $this->sslPolicy; $currSSLPolicy = $this->sslPolicy;
@ -224,11 +225,11 @@ class BaseURL
/** /**
* Save the current url as base URL * Save the current url as base URL
* *
* @param $url * @param string $url
* *
* @return bool true, if the save was successful * @return bool true, if the save was successful
*/ */
public function saveByURL($url) public function saveByURL(string $url): bool
{ {
$parsed = @parse_url($url); $parsed = @parse_url($url);
@ -421,7 +422,7 @@ class BaseURL
* *
* @return string The cleaned url * @return string The cleaned url
*/ */
public function remove(string $origURL) public function remove(string $origURL): string
{ {
// Remove the hostname from the url if it is an internal link // Remove the hostname from the url if it is an internal link
$nurl = Strings::normaliseLink($origURL); $nurl = Strings::normaliseLink($origURL);
@ -445,7 +446,7 @@ class BaseURL
* *
* @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node * @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node
*/ */
public function redirect($toUrl = '', $ssl = false) public function redirect(string $toUrl = '', bool $ssl = false)
{ {
if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) { if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
throw new HTTPException\InternalServerErrorException("'$toUrl is not a relative path, please use System::externalRedirectTo"); throw new HTTPException\InternalServerErrorException("'$toUrl is not a relative path, please use System::externalRedirectTo");
@ -458,8 +459,8 @@ class BaseURL
/** /**
* Returns the base url as string * Returns the base url as string
*/ */
public function __toString() public function __toString(): string
{ {
return $this->get(); return (string) $this->get();
} }
} }

View file

@ -130,7 +130,7 @@ class Mode
* *
* @throws \Exception * @throws \Exception
*/ */
public function determine(BasePath $basepath, Database $database, Cache $configCache) public function determine(BasePath $basepath, Database $database, Cache $configCache): Mode
{ {
$mode = 0; $mode = 0;
@ -178,7 +178,7 @@ class Mode
* *
* @return Mode returns the determined mode * @return Mode returns the determined mode
*/ */
public function determineRunMode(bool $isBackend, array $server, Arguments $args, MobileDetect $mobileDetect) public function determineRunMode(bool $isBackend, array $server, Arguments $args, MobileDetect $mobileDetect): Mode
{ {
foreach (self::BACKEND_CONTENT_TYPES as $type) { foreach (self::BACKEND_CONTENT_TYPES as $type) {
if (strpos(strtolower($server['HTTP_ACCEPT'] ?? ''), $type) !== false) { if (strpos(strtolower($server['HTTP_ACCEPT'] ?? ''), $type) !== false) {
@ -201,7 +201,7 @@ class Mode
* *
* @return bool returns true, if the mode is set * @return bool returns true, if the mode is set
*/ */
public function has($mode) public function has(int $mode): bool
{ {
return ($this->mode & $mode) > 0; return ($this->mode & $mode) > 0;
} }
@ -227,7 +227,7 @@ class Mode
* *
* @return int Execution Mode * @return int Execution Mode
*/ */
public function getExecutor() public function getExecutor(): int
{ {
return $this->executor; return $this->executor;
} }
@ -235,9 +235,9 @@ class Mode
/** /**
* Install mode is when the local config file is missing or the DB schema hasn't been installed yet. * Install mode is when the local config file is missing or the DB schema hasn't been installed yet.
* *
* @return bool * @return bool Whether installation mode is active (local/database configuration files present or not)
*/ */
public function isInstall() public function isInstall(): bool
{ {
return !$this->has(Mode::LOCALCONFIGPRESENT) || return !$this->has(Mode::LOCALCONFIGPRESENT) ||
!$this->has(MODE::DBCONFIGAVAILABLE); !$this->has(MODE::DBCONFIGAVAILABLE);
@ -248,7 +248,7 @@ class Mode
* *
* @return bool * @return bool
*/ */
public function isNormal() public function isNormal(): bool
{ {
return $this->has(Mode::LOCALCONFIGPRESENT) && return $this->has(Mode::LOCALCONFIGPRESENT) &&
$this->has(Mode::DBAVAILABLE) && $this->has(Mode::DBAVAILABLE) &&
@ -261,7 +261,7 @@ class Mode
* *
* @return bool Is it a backend call * @return bool Is it a backend call
*/ */
public function isBackend() public function isBackend(): bool
{ {
return $this->isBackend; return $this->isBackend;
} }
@ -271,7 +271,7 @@ class Mode
* *
* @return bool true if it was an AJAX request * @return bool true if it was an AJAX request
*/ */
public function isAjax() public function isAjax(): bool
{ {
return $this->isAjax; return $this->isAjax;
} }
@ -281,7 +281,7 @@ class Mode
* *
* @return bool true if it was an mobile request * @return bool true if it was an mobile request
*/ */
public function isMobile() public function isMobile(): bool
{ {
return $this->isMobile; return $this->isMobile;
} }
@ -291,7 +291,7 @@ class Mode
* *
* @return bool true if it was an tablet request * @return bool true if it was an tablet request
*/ */
public function isTablet() public function isTablet(): bool
{ {
return $this->isTablet; return $this->isTablet;
} }

View file

@ -195,7 +195,7 @@ class Page implements ArrayAccess
* @param string $media * @param string $media
* @see Page::initHead() * @see Page::initHead()
*/ */
public function registerStylesheet($path, string $media = 'screen') public function registerStylesheet(string $path, string $media = 'screen')
{ {
$path = Network::appendQueryParam($path, ['v' => FRIENDICA_VERSION]); $path = Network::appendQueryParam($path, ['v' => FRIENDICA_VERSION]);
@ -288,7 +288,7 @@ class Page implements ArrayAccess
* *
* Taken from http://webcheatsheet.com/php/get_current_page_url.php * Taken from http://webcheatsheet.com/php/get_current_page_url.php
*/ */
private function curPageURL() private function curPageURL(): string
{ {
$pageURL = 'http'; $pageURL = 'http';
if (!empty($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on")) { if (!empty($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on")) {

152
src/App/Request.php Normal file
View file

@ -0,0 +1,152 @@
<?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/>.
*
*/
namespace Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues;
/**
* Container for the whole request
*
* @see https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface
*
* @todo future container class for whole requests, currently it's not :-)
*/
class Request
{
/**
* A comma separated list of default headers that could contain the client IP in a proxy request
*
* @var string
*/
const DEFAULT_FORWARD_FOR_HEADER = 'HTTP_X_FORWARDED_FOR';
/** @var string The remote IP address of the current request */
protected $remoteAddress;
/**
* @return string The remote IP address of the current request
*
* Do always use this instead of $_SERVER['REMOTE_ADDR']
*/
public function getRemoteAddress(): string
{
return $this->remoteAddress;
}
public function __construct(IManageConfigValues $config, array $server = [])
{
$this->remoteAddress = $this->determineRemoteAddress($config, $server);
}
/**
* Checks if given $remoteAddress matches given $trustedProxy.
* If $trustedProxy is an IPv4 IP range given in CIDR notation, true will be returned if
* $remoteAddress is an IPv4 address within that IP range.
* Otherwise, $remoteAddress will be compared to $trustedProxy literally and the result
* will be returned.
*
* @param string $trustedProxy The current, trusted proxy to check
* @param string $remoteAddress The current remote IP address
*
*
* @return boolean true if $remoteAddress matches $trustedProxy, false otherwise
*/
protected function matchesTrustedProxy(string $trustedProxy, string $remoteAddress): bool
{
$cidrre = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\/([0-9]{1,2})$/';
if (preg_match($cidrre, $trustedProxy, $match)) {
$net = $match[1];
$shiftbits = min(32, max(0, 32 - intval($match[2])));
$netnum = ip2long($net) >> $shiftbits;
$ipnum = ip2long($remoteAddress) >> $shiftbits;
return $ipnum === $netnum;
}
return $trustedProxy === $remoteAddress;
}
/**
* Checks if given $remoteAddress matches any entry in the given array $trustedProxies.
* For details regarding what "match" means, refer to `matchesTrustedProxy`.
*
* @param string[] $trustedProxies A list of the trusted proxies
* @param string $remoteAddress The current remote IP address
*
* @return boolean true if $remoteAddress matches any entry in $trustedProxies, false otherwise
*/
protected function isTrustedProxy(array $trustedProxies, string $remoteAddress): bool
{
foreach ($trustedProxies as $tp) {
if ($this->matchesTrustedProxy($tp, $remoteAddress)) {
return true;
}
}
return false;
}
/**
* Determines the remote address, if the connection came from a trusted proxy
* and `forwarded_for_headers` has been configured then the IP address
* specified in this header will be returned instead.
*
* @param IManageConfigValues $config
* @param array $server The $_SERVER array
*
* @return string
*/
protected function determineRemoteAddress(IManageConfigValues $config, array $server): string
{
$remoteAddress = $server['REMOTE_ADDR'] ?? '0.0.0.0';
$trustedProxies = preg_split('/(\s*,*\s*)*,+(\s*,*\s*)*/', $config->get('proxy', 'trusted_proxies', ''));
if (\is_array($trustedProxies) && $this->isTrustedProxy($trustedProxies, $remoteAddress)) {
$forwardedForHeaders = preg_split('/(\s*,*\s*)*,+(\s*,*\s*)*/', $config->get('proxy', 'forwarded_for_headers', static::DEFAULT_FORWARD_FOR_HEADER));
foreach ($forwardedForHeaders as $header) {
if (isset($server[$header])) {
foreach (explode(',', $server[$header]) as $IP) {
$IP = trim($IP);
// remove brackets from IPv6 addresses
if (strpos($IP, '[') === 0 && substr($IP, -1) === ']') {
$IP = substr($IP, 1, -1);
}
// skip trusted proxies in the list itself
if ($this->isTrustedProxy($trustedProxies, $IP)) {
continue;
}
if (filter_var($IP, FILTER_VALIDATE_IP) !== false) {
return $IP;
}
}
}
}
}
return $remoteAddress;
}
}

View file

@ -152,7 +152,7 @@ class Router
* *
* @throws HTTPException\InternalServerErrorException In case of invalid configs * @throws HTTPException\InternalServerErrorException In case of invalid configs
*/ */
public function loadRoutes(array $routes) public function loadRoutes(array $routes): Router
{ {
$routeCollector = ($this->routeCollector ?? new RouteCollector(new Std(), new GroupCountBased())); $routeCollector = ($this->routeCollector ?? new RouteCollector(new Std(), new GroupCountBased()));
@ -166,6 +166,13 @@ class Router
return $this; return $this;
} }
/**
* Adds multiple routes to a route collector
*
* @param RouteCollector $routeCollector Route collector instance
* @param array $routes Multiple routes to be added
* @throws HTTPException\InternalServerErrorException If route was wrong (somehow)
*/
private function addRoutes(RouteCollector $routeCollector, array $routes) private function addRoutes(RouteCollector $routeCollector, array $routes)
{ {
foreach ($routes as $route => $config) { foreach ($routes as $route => $config) {
@ -221,7 +228,7 @@ class Router
* *
* @return bool * @return bool
*/ */
private function isRoute(array $config) private function isRoute(array $config): bool
{ {
return return
// The config array should at least have one entry // The config array should at least have one entry
@ -253,7 +260,7 @@ class Router
* @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't * @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't
* @throws HTTPException\NotFoundException If no rule matched * @throws HTTPException\NotFoundException If no rule matched
*/ */
private function getModuleClass() private function getModuleClass(): string
{ {
$cmd = $this->args->getCommand(); $cmd = $this->args->getCommand();
$cmd = '/' . ltrim($cmd, '/'); $cmd = '/' . ltrim($cmd, '/');

View file

@ -70,9 +70,11 @@ class BaseCollection extends \ArrayIterator
} }
/** /**
* @return int * Getter for total count
*
* @return int Total count
*/ */
public function getTotalCount() public function getTotalCount(): int
{ {
return $this->totalCount; return $this->totalCount;
} }
@ -85,7 +87,7 @@ class BaseCollection extends \ArrayIterator
* @return array * @return array
* @see array_column() * @see array_column()
*/ */
public function column($column, $index_key = null) public function column(string $column, $index_key = null): array
{ {
return array_column($this->getArrayCopy(true), $column, $index_key); return array_column($this->getArrayCopy(true), $column, $index_key);
} }
@ -97,7 +99,7 @@ class BaseCollection extends \ArrayIterator
* @return BaseCollection * @return BaseCollection
* @see array_map() * @see array_map()
*/ */
public function map(callable $callback) public function map(callable $callback): BaseCollection
{ {
return new static(array_map($callback, $this->getArrayCopy()), $this->getTotalCount()); return new static(array_map($callback, $this->getArrayCopy()), $this->getTotalCount());
} }
@ -110,7 +112,7 @@ class BaseCollection extends \ArrayIterator
* @return BaseCollection * @return BaseCollection
* @see array_filter() * @see array_filter()
*/ */
public function filter(callable $callback = null, int $flag = 0) public function filter(callable $callback = null, int $flag = 0): BaseCollection
{ {
return new static(array_filter($this->getArrayCopy(), $callback, $flag)); return new static(array_filter($this->getArrayCopy(), $callback, $flag));
} }

View file

@ -55,14 +55,14 @@ abstract class BaseEntity extends BaseDataTransferObject
} }
/** /**
* @param $name * @param mixed $name
* @return bool * @return bool
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public function __isset($name) public function __isset($name): bool
{ {
if (!property_exists($this, $name)) { if (!property_exists($this, $name)) {
throw new HTTPException\InternalServerErrorException('Unknown property ' . $name . ' in Entity ' . static::class); throw new HTTPException\InternalServerErrorException('Unknown property ' . $name . ' of type ' . gettype($name) . ' in Entity ' . static::class);
} }
return !empty($this->$name); return !empty($this->$name);

View file

@ -110,11 +110,11 @@ abstract class BaseModel extends BaseDataTransferObject
* - $model->field (outside of class) * - $model->field (outside of class)
* - $this->field (inside of class) * - $this->field (inside of class)
* *
* @param $name * @param string $name Name of data to fetch
* @return mixed * @return mixed
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public function __get($name) public function __get(string $name)
{ {
$this->checkValid(); $this->checkValid();

View file

@ -102,6 +102,7 @@ abstract class BaseModule implements ICanHandleRequests
* e.g. from protocol implementations. * e.g. from protocol implementations.
* *
* @param string[] $request The $_REQUEST content * @param string[] $request The $_REQUEST content
* @return void
*/ */
protected function rawContent(array $request = []) protected function rawContent(array $request = [])
{ {
@ -117,6 +118,7 @@ abstract class BaseModule implements ICanHandleRequests
* XML feed or a JSON output. * XML feed or a JSON output.
* *
* @param string[] $request The $_REQUEST content * @param string[] $request The $_REQUEST content
* @return string
*/ */
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
@ -130,6 +132,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content * Doesn't display any content
* *
* @param string[] $request The $_REQUEST content * @param string[] $request The $_REQUEST content
* @return void
*/ */
protected function delete(array $request = []) protected function delete(array $request = [])
{ {
@ -142,6 +145,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content * Doesn't display any content
* *
* @param string[] $request The $_REQUEST content * @param string[] $request The $_REQUEST content
* @return void
*/ */
protected function patch(array $request = []) protected function patch(array $request = [])
{ {
@ -154,7 +158,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content * Doesn't display any content
* *
* @param string[] $request The $_REQUEST content * @param string[] $request The $_REQUEST content
* * @return void
*/ */
protected function post(array $request = []) protected function post(array $request = [])
{ {
@ -168,6 +172,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content * Doesn't display any content
* *
* @param string[] $request The $_REQUEST content * @param string[] $request The $_REQUEST content
* @return void
*/ */
protected function put(array $request = []) protected function put(array $request = [])
{ {
@ -279,12 +284,12 @@ abstract class BaseModule implements ICanHandleRequests
/** /**
* Fetch a request value and apply default values and check against minimal and maximal values * Fetch a request value and apply default values and check against minimal and maximal values
* *
* @param array $input * @param array $input Input fields
* @param string $parameter * @param string $parameter Parameter
* @param mixed $default * @param mixed $default Default
* @param mixed $minimal_value * @param mixed $minimal_value Minimal value
* @param mixed $maximum_value * @param mixed $maximum_value Maximum value
* @return mixed * @return mixed null on error anything else on success (?)
*/ */
public function getRequestValue(array $input, string $parameter, $default = null, $minimal_value = null, $maximum_value = null) public function getRequestValue(array $input, string $parameter, $default = null, $minimal_value = null, $maximum_value = null)
{ {
@ -320,7 +325,7 @@ abstract class BaseModule implements ICanHandleRequests
return $value; return $value;
} }
/* /**
* Functions used to protect against Cross-Site Request Forgery * Functions used to protect against Cross-Site Request Forgery
* The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key. * The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key.
* In this implementation, a security token is reusable (if the user submits a form, goes back and resubmits the form, maybe with small changes; * In this implementation, a security token is reusable (if the user submits a form, goes back and resubmits the form, maybe with small changes;
@ -330,8 +335,11 @@ abstract class BaseModule implements ICanHandleRequests
* If the new page contains by any chance external elements, then the used security token is exposed by the referrer. * If the new page contains by any chance external elements, then the used security token is exposed by the referrer.
* Actually, important actions should not be triggered by Links / GET-Requests at all, but sometimes they still are, * Actually, important actions should not be triggered by Links / GET-Requests at all, but sometimes they still are,
* so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types). * so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types).
*
* @param string $typename Type name
* @return string Security hash with timestamp
*/ */
public static function getFormSecurityToken($typename = '') public static function getFormSecurityToken(string $typename = ''): string
{ {
$user = User::getById(DI::app()->getLoggedInUserId(), ['guid', 'prvkey']); $user = User::getById(DI::app()->getLoggedInUserId(), ['guid', 'prvkey']);
$timestamp = time(); $timestamp = time();
@ -340,7 +348,14 @@ abstract class BaseModule implements ICanHandleRequests
return $timestamp . '.' . $sec_hash; return $timestamp . '.' . $sec_hash;
} }
public static function checkFormSecurityToken($typename = '', $formname = 'form_security_token') /**
* Checks if form's security (CSRF) token is valid.
*
* @param string $typename ???
* @param string $formname Name of form/field (???)
* @return bool Whether it is valid
*/
public static function checkFormSecurityToken(string $typename = '', string $formname = 'form_security_token'): bool
{ {
$hash = null; $hash = null;
@ -372,12 +387,12 @@ abstract class BaseModule implements ICanHandleRequests
return ($sec_hash == $x[1]); return ($sec_hash == $x[1]);
} }
public static function getFormSecurityStandardErrorMessage() public static function getFormSecurityStandardErrorMessage(): string
{ {
return DI::l10n()->t("The form security token was not correct. This probably happened because the form has been opened for too long \x28>3 hours\x29 before submitting it.") . EOL; return DI::l10n()->t("The form security token was not correct. This probably happened because the form has been opened for too long \x28>3 hours\x29 before submitting it.") . EOL;
} }
public static function checkFormSecurityTokenRedirectOnError($err_redirect, $typename = '', $formname = 'form_security_token') public static function checkFormSecurityTokenRedirectOnError(string $err_redirect, string $typename = '', string $formname = 'form_security_token')
{ {
if (!self::checkFormSecurityToken($typename, $formname)) { if (!self::checkFormSecurityToken($typename, $formname)) {
Logger::notice('checkFormSecurityToken failed: user ' . DI::app()->getLoggedInUserNickname() . ' - form element ' . $typename); Logger::notice('checkFormSecurityToken failed: user ' . DI::app()->getLoggedInUserNickname() . ' - form element ' . $typename);
@ -387,7 +402,7 @@ abstract class BaseModule implements ICanHandleRequests
} }
} }
public static function checkFormSecurityTokenForbiddenOnError($typename = '', $formname = 'form_security_token') public static function checkFormSecurityTokenForbiddenOnError(string $typename = '', string $formname = 'form_security_token')
{ {
if (!self::checkFormSecurityToken($typename, $formname)) { if (!self::checkFormSecurityToken($typename, $formname)) {
Logger::notice('checkFormSecurityToken failed: user ' . DI::app()->getLoggedInUserNickname() . ' - form element ' . $typename); Logger::notice('checkFormSecurityToken failed: user ' . DI::app()->getLoggedInUserNickname() . ' - form element ' . $typename);
@ -397,7 +412,7 @@ abstract class BaseModule implements ICanHandleRequests
} }
} }
protected static function getContactFilterTabs(string $baseUrl, string $current, bool $displayCommonTab) protected static function getContactFilterTabs(string $baseUrl, string $current, bool $displayCommonTab): array
{ {
$tabs = [ $tabs = [
[ [

View file

@ -116,8 +116,7 @@ HELP;
/** /**
* Lists plugins * Lists plugins
* *
* @return int Return code of this command * @return int|bool Return code of this command, false on error (?)
*
* @throws \Exception * @throws \Exception
*/ */
private function list() private function list()
@ -165,10 +164,9 @@ HELP;
* Enables an addon * Enables an addon
* *
* @return int Return code of this command * @return int Return code of this command
*
* @throws \Exception * @throws \Exception
*/ */
private function enable() private function enable(): int
{ {
$addonname = $this->getArgument(1); $addonname = $this->getArgument(1);
@ -190,10 +188,9 @@ HELP;
* Disables an addon * Disables an addon
* *
* @return int Return code of this command * @return int Return code of this command
*
* @throws \Exception * @throws \Exception
*/ */
private function disable() private function disable(): int
{ {
$addonname = $this->getArgument(1); $addonname = $this->getArgument(1);

View file

@ -32,7 +32,6 @@ use Friendica\Util\HTTPSignature;
use Friendica\Util\Images; use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Proxy; use Friendica\Util\Proxy;
use Friendica\Util\Strings;
/** /**
* functions for handling contact avatar caching * functions for handling contact avatar caching
@ -124,7 +123,7 @@ class Avatar
return $fields; return $fields;
} }
private static function getFilename(string $url) private static function getFilename(string $url): string
{ {
$guid = Item::guidFromUri($url, parse_url($url, PHP_URL_HOST)); $guid = Item::guidFromUri($url, parse_url($url, PHP_URL_HOST));
@ -139,21 +138,19 @@ class Avatar
return ''; return '';
} }
$path = self::BASE_PATH . $filename . $size . '.' . $image->getExt(); $path = $filename . $size . '.' . $image->getExt();
$filepath = DI::basePath() . $path; $basepath = self::basePath();
if (empty($basepath)) {
return '';
}
$dirpath = DI::basePath() . self::BASE_PATH; $filepath = $basepath . $path;
$dirpath = $basepath;
DI::profiler()->startRecording('file'); DI::profiler()->startRecording('file');
if (!file_exists($dirpath)) {
if (!mkdir($dirpath, 0775)) {
Logger::warning('Base directory could not be created', ['directory' => $dirpath]);
return '';
}
}
// Fetch the permission and group ownership of the "avatar" path and apply to all files // Fetch the permission and group ownership of the "avatar" path and apply to all files
$dir_perm = fileperms($dirpath) & 0777; $dir_perm = fileperms($dirpath) & 0777;
$file_perm = fileperms($dirpath) & 0666; $file_perm = fileperms($dirpath) & 0666;
@ -198,7 +195,7 @@ class Avatar
return ''; return '';
} }
return DI::baseUrl() . $path . '?ts=' . $timestamp; return self::baseUrl() . $path . '?ts=' . $timestamp;
} }
/** /**
@ -221,16 +218,17 @@ class Avatar
private static function getCacheFile(string $avatar): string private static function getCacheFile(string $avatar): string
{ {
$parts = parse_url($avatar); $parts = parse_url($avatar);
if (empty($parts['host']) || ($parts['host'] != DI::baseUrl()->getHostname())) { if (empty($parts['host']) || ($parts['host'] != parse_url(self::baseUrl(), PHP_URL_HOST))) {
return ''; return '';
} }
$pos = strpos($parts['path'], DI::baseUrl()->getUrlPath() . self::BASE_PATH); $avatarpath = parse_url(self::baseUrl(), PHP_URL_PATH);
$pos = strpos($parts['path'], $avatarpath);
if ($pos !== 0) { if ($pos !== 0) {
return ''; return '';
} }
$filename = DI::basePath() . $parts['path']; $filename = self::basePath() . substr($parts['path'], strlen($avatarpath));
DI::profiler()->startRecording('file'); DI::profiler()->startRecording('file');
$exists = file_exists($filename); $exists = file_exists($filename);
@ -269,4 +267,47 @@ class Avatar
Logger::debug('Unlink avatar', ['avatar' => $avatar]); Logger::debug('Unlink avatar', ['avatar' => $avatar]);
} }
} }
/**
* Fetch the avatar base path
*
* @return string
*/
private static function basePath(): string
{
$basepath = DI::config()->get('system', 'avatar_cache_path');
if (empty($basepath)) {
$basepath = DI::basePath() . self::BASE_PATH;
}
$basepath = rtrim($basepath, '/') . '/';
if (!file_exists($basepath)) {
// We only automatically create the folder when it is in the web root
if (strpos($basepath, DI::basePath()) !== 0) {
Logger::warning('Base directory does not exist', ['directory' => $basepath]);
return '';
}
if (!mkdir($basepath, 0775)) {
Logger::warning('Base directory could not be created', ['directory' => $basepath]);
return '';
}
}
return $basepath;
}
/**
* Fetch the avatar base url
*
* @return string
*/
private static function baseUrl(): string
{
$baseurl = DI::config()->get('system', 'avatar_cache_url');
if (!empty($baseurl)) {
return rtrim($baseurl, '/') . '/';
}
return DI::baseUrl() . self::BASE_PATH;
}
} }

View file

@ -52,7 +52,7 @@ class LocalRelationship extends BaseFactory implements ICanCreateFromTableRow
$row['hub-verify'] ?? '', $row['hub-verify'] ?? '',
$row['protocol'] ?? Protocol::PHANTOM, $row['protocol'] ?? Protocol::PHANTOM,
$row['rating'] ?? null, $row['rating'] ?? null,
$row['priority'] ?? null $row['priority'] ?? 0
); );
} }
} }

View file

@ -49,7 +49,7 @@ class BoundariesPager extends Pager
* @param string $last_item_id The id† of the last item in the displayed item list * @param string $last_item_id The id† of the last item in the displayed item list
* @param integer $itemsPerPage An optional number of items per page to override the default value * @param integer $itemsPerPage An optional number of items per page to override the default value
*/ */
public function __construct(L10n $l10n, $queryString, $first_item_id = null, $last_item_id = null, $itemsPerPage = 50) public function __construct(L10n $l10n, string $queryString, string $first_item_id = null, string $last_item_id = null, int $itemsPerPage = 50)
{ {
parent::__construct($l10n, $queryString, $itemsPerPage); parent::__construct($l10n, $queryString, $itemsPerPage);
@ -102,7 +102,7 @@ class BoundariesPager extends Pager
* @return string HTML string of the pager * @return string HTML string of the pager
* @throws \Exception * @throws \Exception
*/ */
public function renderMinimal(int $itemCount) public function renderMinimal(int $itemCount): string
{ {
$displayedItemCount = max(0, intval($itemCount)); $displayedItemCount = max(0, intval($itemCount));
@ -130,7 +130,7 @@ class BoundariesPager extends Pager
return Renderer::replaceMacros($tpl, ['pager' => $data]); return Renderer::replaceMacros($tpl, ['pager' => $data]);
} }
public function renderFull($itemCount) public function renderFull(int $itemCount): string
{ {
throw new \BadMethodCallException(); throw new \BadMethodCallException();
} }

View file

@ -41,7 +41,7 @@ class ContactSelector
* @param boolean $disabled optional, default false * @param boolean $disabled optional, default false
* @return string * @return string
*/ */
public static function pollInterval($current, $disabled = false) public static function pollInterval(string $current, bool $disabled = false): string
{ {
$dis = (($disabled) ? ' disabled="disabled" ' : ''); $dis = (($disabled) ? ' disabled="disabled" ' : '');
$o = ''; $o = '';
@ -84,7 +84,7 @@ class ContactSelector
* @return string Server URL * @return string Server URL
* @throws \Exception * @throws \Exception
*/ */
private static function getServerURLForProfile($profile) private static function getServerURLForProfile(string $profile): string
{ {
if (!empty(self::$server_url[$profile])) { if (!empty(self::$server_url[$profile])) {
return self::$server_url[$profile]; return self::$server_url[$profile];
@ -111,13 +111,16 @@ class ContactSelector
} }
/** /**
* Determines network name
*
* @param string $network network of the contact * @param string $network network of the contact
* @param string $profile optional, default empty * @param string $profile optional, default empty
* @param string $protocol (Optional) Protocol that is used for the transmission * @param string $protocol (Optional) Protocol that is used for the transmission
* @param int $gsid Server id
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function networkToName($network, $profile = '', $protocol = '', $gsid = 0) public static function networkToName(string $network, string $profile = '', string $protocol = '', int $gsid = null): string
{ {
$nets = [ $nets = [
Protocol::DFRN => DI::l10n()->t('DFRN'), Protocol::DFRN => DI::l10n()->t('DFRN'),
@ -179,12 +182,15 @@ class ContactSelector
} }
/** /**
* Determines network's icon name
*
* @param string $network network * @param string $network network
* @param string $profile optional, default empty * @param string $profile optional, default empty
* @return string * @param int $gsid Server id
* @return string Name for network icon
* @throws \Exception * @throws \Exception
*/ */
public static function networkToIcon($network, $profile = "", $gsid = 0) public static function networkToIcon(string $network, string $profile = "", int $gsid = null): string
{ {
$nets = [ $nets = [
Protocol::DFRN => 'friendica', Protocol::DFRN => 'friendica',

View file

@ -154,7 +154,7 @@ class Conversation
} }
// Skip when the causer of the parent is the same as the author of the announce // Skip when the causer of the parent is the same as the author of the announce
if (($verb == Activity::ANNOUNCE) && !empty($thread_parent['causer-id'] && ($thread_parent['causer-id'] == $activity['author-id']))) { if (($verb == Activity::ANNOUNCE) && !empty($thread_parent['causer-id']) && ($thread_parent['causer-id'] == $activity['author-id'])) {
continue; continue;
} }
@ -189,7 +189,7 @@ class Conversation
* @return string formatted text * @return string formatted text
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public function formatActivity(array $links, $verb, $id) public function formatActivity(array $links, string $verb, int $id): string
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
$o = ''; $o = '';
@ -275,7 +275,7 @@ class Conversation
return $o; return $o;
} }
public function statusEditor(array $x = [], $notes_cid = 0, $popup = false) public function statusEditor(array $x = [], int $notes_cid = 0, bool $popup = false): string
{ {
$user = User::getById($this->app->getLoggedInUserId(), ['uid', 'nickname', 'allow_location', 'default-location']); $user = User::getById($this->app->getLoggedInUserId(), ['uid', 'nickname', 'allow_location', 'default-location']);
if (empty($user['uid'])) { if (empty($user['uid'])) {
@ -414,8 +414,8 @@ class Conversation
* figures out how to determine page owner and other contextual items * figures out how to determine page owner and other contextual items
* that are based on unique features of the calling module. * that are based on unique features of the calling module.
* @param array $items * @param array $items
* @param $mode * @param string $mode
* @param $update * @param $update @TODO Which type?
* @param bool $preview * @param bool $preview
* @param string $order * @param string $order
* @param int $uid * @param int $uid
@ -423,7 +423,7 @@ class Conversation
* @throws ImagickException * @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public function create(array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0) public function create(array $items, string $mode, $update, bool $preview = false, string $order = 'commented', int $uid = 0): string
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
@ -784,7 +784,7 @@ class Conversation
return $o; return $o;
} }
private function getBlocklist() private function getBlocklist(): array
{ {
if (!local_user()) { if (!local_user()) {
return []; return [];
@ -816,7 +816,7 @@ class Conversation
* *
* @return array items with parents and comments * @return array items with parents and comments
*/ */
private function addRowInformation(array $row, array $activity, array $thr_parent) private function addRowInformation(array $row, array $activity, array $thr_parent): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
@ -911,7 +911,7 @@ class Conversation
* @return array items with parents and comments * @return array items with parents and comments
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode) private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
if (count($parents) > 1) { if (count($parents) > 1) {
@ -1005,7 +1005,7 @@ class Conversation
* @param bool $recursive * @param bool $recursive
* @return array * @return array
*/ */
private function getItemChildren(array &$item_list, array $parent, $recursive = true) private function getItemChildren(array &$item_list, array $parent, bool $recursive = true): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
$children = []; $children = [];
@ -1040,7 +1040,7 @@ class Conversation
* @param array $items * @param array $items
* @return array * @return array
*/ */
private function sortItemChildren(array $items) private function sortItemChildren(array $items): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
$result = $items; $result = $items;
@ -1086,7 +1086,7 @@ class Conversation
* @param array $parent A tree-like array of items * @param array $parent A tree-like array of items
* @return array * @return array
*/ */
private function smartFlattenConversation(array $parent) private function smartFlattenConversation(array $parent): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
if (!isset($parent['children']) || count($parent['children']) == 0) { if (!isset($parent['children']) || count($parent['children']) == 0) {
@ -1142,7 +1142,7 @@ class Conversation
* @return array * @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private function convSort(array $item_list, $order) private function convSort(array $item_list, string $order): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
$parents = []; $parents = [];
@ -1222,7 +1222,7 @@ class Conversation
* @param array $b * @param array $b
* @return int * @return int
*/ */
private function sortThrFeaturedReceived(array $a, array $b) private function sortThrFeaturedReceived(array $a, array $b): int
{ {
if ($b['featured'] && !$a['featured']) { if ($b['featured'] && !$a['featured']) {
return 1; return 1;
@ -1240,7 +1240,7 @@ class Conversation
* @param array $b * @param array $b
* @return int * @return int
*/ */
private function sortThrFeaturedCommented(array $a, array $b) private function sortThrFeaturedCommented(array $a, array $b): int
{ {
if ($b['featured'] && !$a['featured']) { if ($b['featured'] && !$a['featured']) {
return 1; return 1;
@ -1258,7 +1258,7 @@ class Conversation
* @param array $b * @param array $b
* @return int * @return int
*/ */
private function sortThrReceived(array $a, array $b) private function sortThrReceived(array $a, array $b): int
{ {
return strcmp($b['received'], $a['received']); return strcmp($b['received'], $a['received']);
} }
@ -1270,7 +1270,7 @@ class Conversation
* @param array $b * @param array $b
* @return int * @return int
*/ */
private function sortThrReceivedRev(array $a, array $b) private function sortThrReceivedRev(array $a, array $b): int
{ {
return strcmp($a['received'], $b['received']); return strcmp($a['received'], $b['received']);
} }
@ -1282,7 +1282,7 @@ class Conversation
* @param array $b * @param array $b
* @return int * @return int
*/ */
private function sortThrCommented(array $a, array $b) private function sortThrCommented(array $a, array $b): int
{ {
return strcmp($b['commented'], $a['commented']); return strcmp($b['commented'], $a['commented']);
} }
@ -1294,7 +1294,7 @@ class Conversation
* @param array $b * @param array $b
* @return int * @return int
*/ */
private function sortThrCreated(array $a, array $b) private function sortThrCreated(array $a, array $b): int
{ {
return strcmp($b['created'], $a['created']); return strcmp($b['created'], $a['created']);
} }

View file

@ -160,7 +160,7 @@ class Pager
* @return string HTML string of the pager * @return string HTML string of the pager
* @throws \Exception * @throws \Exception
*/ */
public function renderMinimal(int $itemCount) public function renderMinimal(int $itemCount): string
{ {
$displayedItemCount = max(0, intval($itemCount)); $displayedItemCount = max(0, intval($itemCount));
@ -199,13 +199,13 @@ class Pager
* *
* $html = $pager->renderFull(); * $html = $pager->renderFull();
* *
* @param integer $itemCount The total number of items including those note displayed on the page * @param int $itemCount The total number of items including those note displayed on the page
* @return string HTML string of the pager * @return string HTML string of the pager
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public function renderFull($itemCount) public function renderFull(int $itemCount): string
{ {
$totalItemCount = max(0, intval($itemCount)); $totalItemCount = max(0, $itemCount);
$data = []; $data = [];

View file

@ -320,7 +320,7 @@ class BBCode
$post['text'] = trim(str_replace($pictures[0][0], '', $body)); $post['text'] = trim(str_replace($pictures[0][0], '', $body));
} else { } else {
$imgdata = Images::getInfoFromURLCached($pictures[0][1]); $imgdata = Images::getInfoFromURLCached($pictures[0][1]);
if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') { if (($imgdata) && substr($imgdata['mime'], 0, 6) == 'image/') {
$post['type'] = 'photo'; $post['type'] = 'photo';
$post['image'] = $pictures[0][1]; $post['image'] = $pictures[0][1];
$post['preview'] = $pictures[0][2]; $post['preview'] = $pictures[0][2];
@ -1247,16 +1247,28 @@ class BBCode
return $text; return $text;
} }
private static function expandLinksCallback($match) /**
* Callback: Expands links from given $match array
*
* @param arrat $match Array with link match
* @return string BBCode
*/
private static function expandLinksCallback(array $match): string
{ {
if (($match[3] == '') || ($match[2] == $match[3]) || stristr($match[2], $match[3])) { if (($match[3] == '') || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
return ($match[1] . "[url]" . $match[2] . "[/url]"); return ($match[1] . '[url]' . $match[2] . '[/url]');
} else { } else {
return ($match[1] . $match[3] . " [url]" . $match[2] . "[/url]"); return ($match[1] . $match[3] . ' [url]' . $match[2] . '[/url]');
} }
} }
private static function cleanPictureLinksCallback($match) /**
* Callback: Cleans picture links
*
* @param arrat $match Array with link match
* @return string BBCode
*/
private static function cleanPictureLinksCallback(array $match): string
{ {
// When the picture link is the own photo path then we can avoid fetching the link // When the picture link is the own photo path then we can avoid fetching the link
$own_photo_url = preg_quote(Strings::normaliseLink(DI::baseUrl()->get()) . '/photos/'); $own_photo_url = preg_quote(Strings::normaliseLink(DI::baseUrl()->get()) . '/photos/');
@ -1325,7 +1337,13 @@ class BBCode
return $text; return $text;
} }
public static function cleanPictureLinks($text) /**
* Cleans picture links
*
* @param string $text HTML/BBCode string
* @return string Cleaned HTML/BBCode
*/
public static function cleanPictureLinks(string $text): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text); $return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text);
@ -1334,7 +1352,13 @@ class BBCode
return $return; return $return;
} }
public static function removeLinks(string $bbcode) /**
* Removes links
*
* @param string $text HTML/BBCode string
* @return string Cleaned HTML/BBCode
*/
public static function removeLinks(string $bbcode): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$bbcode = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $1 ', $bbcode); $bbcode = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $1 ', $bbcode);
@ -1350,10 +1374,10 @@ class BBCode
/** /**
* Replace names in mentions with nicknames * Replace names in mentions with nicknames
* *
* @param string $body * @param string $body HTML/BBCode
* @return string Body with replaced mentions * @return string Body with replaced mentions
*/ */
public static function setMentionsToNicknames(string $body):string public static function setMentionsToNicknames(string $body): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism"; $regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
@ -1366,10 +1390,10 @@ class BBCode
* Callback function to replace a Friendica style mention in a mention with the nickname * Callback function to replace a Friendica style mention in a mention with the nickname
* *
* @param array $match Matching values for the callback * @param array $match Matching values for the callback
* @return string Replaced mention * @return string Replaced mention or empty string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function mentionCallback($match) private static function mentionCallback(array $match): string
{ {
if (empty($match[2])) { if (empty($match[2])) {
return ''; return '';
@ -1407,7 +1431,7 @@ class BBCode
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function convertForUriId(int $uriid = null, string $text = null, int $simple_html = self::INTERNAL) public static function convertForUriId(int $uriid = null, string $text = null, int $simple_html = self::INTERNAL): string
{ {
$try_oembed = ($simple_html == self::INTERNAL); $try_oembed = ($simple_html == self::INTERNAL);
@ -1437,10 +1461,10 @@ class BBCode
* @param int $simple_html * @param int $simple_html
* @param bool $for_plaintext * @param bool $for_plaintext
* @param int $uriid * @param int $uriid
* @return string * @return string Converted code or empty string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function convert(string $text = null, $try_oembed = true, $simple_html = self::INTERNAL, $for_plaintext = false, $uriid = 0) public static function convert(string $text = null, bool $try_oembed = true, int $simple_html = self::INTERNAL, bool $for_plaintext = false, int $uriid = 0): string
{ {
// Accounting for null default column values // Accounting for null default column values
if (is_null($text) || $text === '') { if (is_null($text) || $text === '') {
@ -2142,7 +2166,7 @@ class BBCode
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
private static function bbCodeMention2DiasporaCallback($match) private static function bbCodeMention2DiasporaCallback(array $match): string
{ {
$contact = Contact::getByURL($match[3], false, ['addr']); $contact = Contact::getByURL($match[3], false, ['addr']);
if (empty($contact['addr'])) { if (empty($contact['addr'])) {
@ -2164,7 +2188,7 @@ class BBCode
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function toMarkdown($text, $for_diaspora = true) public static function toMarkdown(string $text, bool $for_diaspora = true): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$original_text = $text; $original_text = $text;
@ -2249,7 +2273,7 @@ class BBCode
* *
* @return array List of tag and person names * @return array List of tag and person names
*/ */
public static function getTags($string) public static function getTags(string $string): array
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$ret = []; $ret = [];
@ -2309,10 +2333,10 @@ class BBCode
/** /**
* Expand tags to URLs, checks the tag is at the start of a line or preceded by a non-word character * Expand tags to URLs, checks the tag is at the start of a line or preceded by a non-word character
* *
* @param string $body * @param string $body HTML/BBCode
* @return string body with expanded tags * @return string body with expanded tags
*/ */
public static function expandTags(string $body) public static function expandTags(string $body): string
{ {
return preg_replace_callback("/(?<=\W|^)([!#@])([^\^ \x0D\x0A,;:?'\"]*[^\^ \x0D\x0A,;:?!'\".])/", return preg_replace_callback("/(?<=\W|^)([!#@])([^\^ \x0D\x0A,;:?'\"]*[^\^ \x0D\x0A,;:?!'\".])/",
function ($match) { function ($match) {
@ -2336,7 +2360,7 @@ class BBCode
/** /**
* Perform a custom function on a text after having escaped blocks enclosed in the provided tag list. * Perform a custom function on a text after having escaped blocks enclosed in the provided tag list.
* *
* @param string $text * @param string $text HTML/BBCode
* @param array $tagList A list of tag names, e.g ['noparse', 'nobb', 'pre'] * @param array $tagList A list of tag names, e.g ['noparse', 'nobb', 'pre']
* @param callable $callback * @param callable $callback
* @return string * @return string
@ -2352,14 +2376,14 @@ class BBCode
/** /**
* Replaces mentions in the provided message body in BBCode links for the provided user and network if any * Replaces mentions in the provided message body in BBCode links for the provided user and network if any
* *
* @param $body * @param string $body HTML/BBCode
* @param $profile_uid * @param int $profile_uid Profile user id
* @param $network * @param string $network Network name
* @return string * @return string HTML/BBCode with inserted images
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function setMentions($body, $profile_uid = 0, $network = '') public static function setMentions(string $body, $profile_uid = 0, $network = '')
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$body = self::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network) { $body = self::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network) {
@ -2406,7 +2430,7 @@ class BBCode
* @return string * @return string
* @TODO Rewrite to handle over whole record array * @TODO Rewrite to handle over whole record array
*/ */
public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null) public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$header = "[share author='" . str_replace(["'", "[", "]"], ["&#x27;", "&#x5B;", "&#x5D;"], $author) . $header = "[share author='" . str_replace(["'", "[", "]"], ["&#x27;", "&#x5B;", "&#x5D;"], $author) .

View file

@ -61,7 +61,7 @@ class HTML
* inner value from an attribute value and disregard the tag children. * inner value from an attribute value and disregard the tag children.
* @return bool Whether a replacement was done * @return bool Whether a replacement was done
*/ */
private static function tagToBBCodeSub(DOMDocument $doc, string $tag, array $attributes, string $startbb, string $endbb, bool $ignoreChildren = false) private static function tagToBBCodeSub(DOMDocument $doc, string $tag, array $attributes, string $startbb, string $endbb, bool $ignoreChildren = false): bool
{ {
$savestart = str_replace('$', '\x01', $startbb); $savestart = str_replace('$', '\x01', $startbb);
$replace = false; $replace = false;
@ -141,8 +141,16 @@ class HTML
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function toBBCode($message, $basepath = '') public static function toBBCode(string $message, string $basepath = ''): string
{ {
/*
* Check if message is empty to prevent a lot code below being executed
* for just an empty message.
*/
if (empty($message)) {
return '';
}
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$message = str_replace("\r", "", $message); $message = str_replace("\r", "", $message);
@ -409,7 +417,7 @@ class HTML
* *
* @return string The expanded URL * @return string The expanded URL
*/ */
private static function qualifyURLsSub($matches, $basepath) private static function qualifyURLsSub(array $matches, string $basepath): string
{ {
$base = parse_url($basepath); $base = parse_url($basepath);
unset($base['query']); unset($base['query']);
@ -436,7 +444,7 @@ class HTML
* *
* @return string Body with expanded URLs * @return string Body with expanded URLs
*/ */
private static function qualifyURLs($body, $basepath) private static function qualifyURLs(string $body, string $basepath): string
{ {
$URLSearchString = "^\[\]"; $URLSearchString = "^\[\]";
@ -462,7 +470,7 @@ class HTML
return $body; return $body;
} }
private static function breakLines($line, $level, $wraplength = 75) private static function breakLines(string $line, int $level, int $wraplength = 75): string
{ {
if ($wraplength == 0) { if ($wraplength == 0) {
$wraplength = 2000000; $wraplength = 2000000;
@ -503,7 +511,7 @@ class HTML
return implode("\n", $newlines); return implode("\n", $newlines);
} }
private static function quoteLevel($message, $wraplength = 75) private static function quoteLevel(string $message, int $wraplength = 75): string
{ {
$lines = explode("\n", $message); $lines = explode("\n", $message);
@ -539,7 +547,7 @@ class HTML
return implode("\n", $newlines); return implode("\n", $newlines);
} }
private static function collectURLs($message) private static function collectURLs(string $message): array
{ {
$pattern = '/<a.*?href="(.*?)".*?>(.*?)<\/a>/is'; $pattern = '/<a.*?href="(.*?)".*?>(.*?)<\/a>/is';
preg_match_all($pattern, $message, $result, PREG_SET_ORDER); preg_match_all($pattern, $message, $result, PREG_SET_ORDER);
@ -585,7 +593,7 @@ class HTML
* @param bool $compact True: Completely strips image tags; False: Keeps image URLs * @param bool $compact True: Completely strips image tags; False: Keeps image URLs
* @return string * @return string
*/ */
public static function toPlaintext(string $html, $wraplength = 75, $compact = false) public static function toPlaintext(string $html, int $wraplength = 75, bool $compact = false): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$message = str_replace("\r", "", $html); $message = str_replace("\r", "", $html);
@ -705,7 +713,7 @@ class HTML
* @param string $html * @param string $html
* @return string * @return string
*/ */
public static function toMarkdown($html) public static function toMarkdown(string $html): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$converter = new HtmlConverter(['hard_break' => true]); $converter = new HtmlConverter(['hard_break' => true]);
@ -721,7 +729,7 @@ class HTML
* @param string $s * @param string $s
* @return string * @return string
*/ */
public static function toBBCodeVideo($s) public static function toBBCodeVideo(string $s): string
{ {
$s = preg_replace( $s = preg_replace(
'#<object[^>]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)</object>#ism', '#<object[^>]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)</object>#ism',
@ -751,7 +759,7 @@ class HTML
* @param string $base base url * @param string $base base url
* @return string * @return string
*/ */
public static function relToAbs($text, $base) public static function relToAbs(string $text, string $base): string
{ {
if (empty($base)) { if (empty($base)) {
return $text; return $text;
@ -790,7 +798,7 @@ class HTML
* @return string html for loader * @return string html for loader
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function scrollLoader() public static function scrollLoader(): string
{ {
$tpl = Renderer::getMarkupTemplate("scroll_loader.tpl"); $tpl = Renderer::getMarkupTemplate("scroll_loader.tpl");
return Renderer::replaceMacros($tpl, [ return Renderer::replaceMacros($tpl, [
@ -819,7 +827,7 @@ class HTML
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function micropro($contact, $redirect = false, $class = '', $textmode = false) public static function micropro(array $contact, bool $redirect = false, string $class = '', bool $textmode = false): string
{ {
// Use the contact URL if no address is available // Use the contact URL if no address is available
if (empty($contact['addr'])) { if (empty($contact['addr'])) {
@ -859,13 +867,12 @@ class HTML
* *
* @param string $s Search query. * @param string $s Search query.
* @param string $id HTML id * @param string $id HTML id
* @param string $url Search url.
* @param bool $aside Display the search widgit aside. * @param bool $aside Display the search widgit aside.
* *
* @return string Formatted HTML. * @return string Formatted HTML.
* @throws \Exception * @throws \Exception
*/ */
public static function search($s, $id = 'search-box', $aside = true) public static function search(string $s, string $id = 'search-box', bool $aside = true): string
{ {
$mode = 'text'; $mode = 'text';
@ -906,7 +913,7 @@ class HTML
* @param string $s * @param string $s
* @return string * @return string
*/ */
public static function toLink($s) public static function toLink(string $s): string
{ {
$s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\'\%\$\!\+]*)/", ' <a href="$1" target="_blank" rel="noopener noreferrer">$1</a>', $s); $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\'\%\$\!\+]*)/", ' <a href="$1" target="_blank" rel="noopener noreferrer">$1</a>', $s);
$s = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $s); $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $s);
@ -923,7 +930,7 @@ class HTML
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function applyContentFilter($html, array $reasons) public static function applyContentFilter(string $html, array $reasons): string
{ {
if (count($reasons)) { if (count($reasons)) {
$tpl = Renderer::getMarkupTemplate('wall/content_filter.tpl'); $tpl = Renderer::getMarkupTemplate('wall/content_filter.tpl');
@ -943,7 +950,7 @@ class HTML
* @param string $s * @param string $s
* @return string * @return string
*/ */
public static function unamp($s) public static function unamp(string $s): string
{ {
return str_replace('&amp;', '&', $s); return str_replace('&amp;', '&', $s);
} }

View file

@ -45,7 +45,7 @@ class Widget
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function follow($value = "") public static function follow(string $value = ''): string
{ {
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), array( return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), array(
'$connect' => DI::l10n()->t('Add New Contact'), '$connect' => DI::l10n()->t('Add New Contact'),
@ -58,8 +58,10 @@ class Widget
/** /**
* Return Find People widget * Return Find People widget
*
* @return string HTML code respresenting "People Widget"
*/ */
public static function findPeople() public static function findPeople(): string
{ {
$global_dir = Search::getGlobalDirectory(); $global_dir = Search::getGlobalDirectory();
@ -97,7 +99,7 @@ class Widget
* *
* @return array Unsupported networks * @return array Unsupported networks
*/ */
public static function unavailableNetworks() public static function unavailableNetworks(): array
{ {
// Always hide content from these networks // Always hide content from these networks
$networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::ZOT]; $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::ZOT];
@ -154,7 +156,7 @@ class Widget
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
private static function filter($type, $title, $desc, $all, $baseUrl, array $options, $selected = null) private static function filter(string $type, string $title, string $desc, string $all, string $baseUrl, array $options, string $selected = null): string
{ {
$queryString = parse_url($baseUrl, PHP_URL_QUERY); $queryString = parse_url($baseUrl, PHP_URL_QUERY);
$queryArray = []; $queryArray = [];
@ -191,7 +193,7 @@ class Widget
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
public static function groups($baseurl, $selected = '') public static function groups(string $baseurl, string $selected = ''): string
{ {
if (!local_user()) { if (!local_user()) {
return ''; return '';

View file

@ -124,7 +124,7 @@ class Addon
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function uninstall($addon) public static function uninstall(string $addon)
{ {
$addon = Strings::sanitizeFilePathItem($addon); $addon = Strings::sanitizeFilePathItem($addon);
@ -149,7 +149,7 @@ class Addon
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
public static function install($addon) public static function install(string $addon): bool
{ {
$addon = Strings::sanitizeFilePathItem($addon); $addon = Strings::sanitizeFilePathItem($addon);
@ -185,6 +185,8 @@ class Addon
/** /**
* reload all updated addons * reload all updated addons
*
* @return void
*/ */
public static function reload() public static function reload()
{ {
@ -222,7 +224,7 @@ class Addon
* @return array with the addon information * @return array with the addon information
* @throws \Exception * @throws \Exception
*/ */
public static function getInfo($addon) public static function getInfo(string $addon): array
{ {
$addon = Strings::sanitizeFilePathItem($addon); $addon = Strings::sanitizeFilePathItem($addon);
@ -287,7 +289,7 @@ class Addon
* @param string $addon * @param string $addon
* @return boolean * @return boolean
*/ */
public static function isEnabled($addon) public static function isEnabled(string $addon): bool
{ {
return in_array($addon, self::$addons); return in_array($addon, self::$addons);
} }
@ -297,7 +299,7 @@ class Addon
* *
* @return array * @return array
*/ */
public static function getEnabledList() public static function getEnabledList(): array
{ {
return self::$addons; return self::$addons;
} }
@ -308,7 +310,7 @@ class Addon
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function getVisibleList() public static function getVisibleList(): array
{ {
$visible_addons = []; $visible_addons = [];
$stmt = DBA::select('addon', ['name'], ['hidden' => false, 'installed' => true]); $stmt = DBA::select('addon', ['name'], ['hidden' => false, 'installed' => true]);

View file

@ -49,6 +49,8 @@ class Hook
/** /**
* Load hooks * Load hooks
*
* @return void
*/ */
public static function loadHooks() public static function loadHooks()
{ {
@ -69,8 +71,9 @@ class Hook
* @param string $hook * @param string $hook
* @param string $file * @param string $file
* @param string $function * @param string $function
* @return void
*/ */
public static function add($hook, $file, $function) public static function add(string $hook, string $file, string $function)
{ {
if (!array_key_exists($hook, self::$hooks)) { if (!array_key_exists($hook, self::$hooks)) {
self::$hooks[$hook] = []; self::$hooks[$hook] = [];
@ -90,7 +93,7 @@ class Hook
* @return mixed|bool * @return mixed|bool
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function register($hook, $file, $function, $priority = 0) public static function register(string $hook, string $file, string $function, int $priority = 0)
{ {
$file = str_replace(DI::app()->getBasePath() . DIRECTORY_SEPARATOR, '', $file); $file = str_replace(DI::app()->getBasePath() . DIRECTORY_SEPARATOR, '', $file);
@ -111,7 +114,7 @@ class Hook
* @return boolean * @return boolean
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function unregister($hook, $file, $function) public static function unregister(string $hook, string $file, string $function): bool
{ {
$relative_file = str_replace(DI::app()->getBasePath() . DIRECTORY_SEPARATOR, '', $file); $relative_file = str_replace(DI::app()->getBasePath() . DIRECTORY_SEPARATOR, '', $file);
@ -120,8 +123,8 @@ class Hook
self::delete($condition); self::delete($condition);
$condition = ['hook' => $hook, 'file' => $relative_file, 'function' => $function]; $condition = ['hook' => $hook, 'file' => $relative_file, 'function' => $function];
$result = self::delete($condition);
return $result; return self::delete($condition);
} }
/** /**
@ -130,7 +133,7 @@ class Hook
* @param string $name Name of the hook * @param string $name Name of the hook
* @return array * @return array
*/ */
public static function getByName($name) public static function getByName(string $name): array
{ {
$return = []; $return = [];
@ -149,9 +152,10 @@ class Hook
* @param integer $priority of the hook * @param integer $priority of the hook
* @param string $name of the hook to call * @param string $name of the hook to call
* @param mixed $data to transmit to the callback handler * @param mixed $data to transmit to the callback handler
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function fork($priority, $name, $data = null) public static function fork(int $priority, string $name, $data = null)
{ {
if (array_key_exists($name, self::$hooks)) { if (array_key_exists($name, self::$hooks)) {
foreach (self::$hooks[$name] as $hook) { foreach (self::$hooks[$name] as $hook) {
@ -184,9 +188,10 @@ class Hook
* *
* @param string $name of the hook to call * @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler * @param string|array &$data to transmit to the callback handler
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function callAll($name, &$data = null) public static function callAll(string $name, &$data = null)
{ {
if (array_key_exists($name, self::$hooks)) { if (array_key_exists($name, self::$hooks)) {
foreach (self::$hooks[$name] as $hook) { foreach (self::$hooks[$name] as $hook) {
@ -202,9 +207,10 @@ class Hook
* @param string $name of the hook to call * @param string $name of the hook to call
* @param array $hook Hook data * @param array $hook Hook data
* @param string|array &$data to transmit to the callback handler * @param string|array &$data to transmit to the callback handler
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function callSingle(App $a, $name, $hook, &$data = null) public static function callSingle(App $a, string $name, array $hook, &$data = null)
{ {
// Don't run a theme's hook if the user isn't using the theme // Don't run a theme's hook if the user isn't using the theme
if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/' . $a->getCurrentTheme()) === false) { if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/' . $a->getCurrentTheme()) === false) {
@ -229,7 +235,7 @@ class Hook
* @param string $name Name of the addon * @param string $name Name of the addon
* @return boolean * @return boolean
*/ */
public static function isAddonApp($name) public static function isAddonApp(string $name): bool
{ {
$name = Strings::sanitizeFilePathItem($name); $name = Strings::sanitizeFilePathItem($name);
@ -253,7 +259,7 @@ class Hook
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
public static function delete(array $condition) public static function delete(array $condition): bool
{ {
$result = DBA::delete('hook', $condition); $result = DBA::delete('hook', $condition);
@ -273,7 +279,7 @@ class Hook
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
private static function insert(array $condition) private static function insert(array $condition): bool
{ {
$result = DBA::insert('hook', $condition); $result = DBA::insert('hook', $condition);

View file

@ -656,7 +656,7 @@ class Installer
* @return bool true if the check was successful, otherwise false * @return bool true if the check was successful, otherwise false
* @throws Exception * @throws Exception
*/ */
public function checkDB(Database $dba) public function checkDB(Database $dba): bool
{ {
$dba->reconnect(); $dba->reconnect();

View file

@ -128,7 +128,7 @@ class L10n
private function setLangFromSession(IHandleSessions $session) private function setLangFromSession(IHandleSessions $session)
{ {
if ($session->get('language') !== $this->lang) { if ($session->get('language') !== $this->lang) {
$this->loadTranslationTable($session->get('language')); $this->loadTranslationTable($session->get('language') ?? $this->lang);
} }
} }
@ -140,10 +140,10 @@ class L10n
* Uses an App object shim since all the strings files refer to $a->strings * Uses an App object shim since all the strings files refer to $a->strings
* *
* @param string $lang language code to load * @param string $lang language code to load
* * @return void
* @throws \Exception * @throws \Exception
*/ */
private function loadTranslationTable($lang) private function loadTranslationTable(string $lang)
{ {
$lang = Strings::sanitizeFilePathItem($lang); $lang = Strings::sanitizeFilePathItem($lang);
@ -183,7 +183,7 @@ class L10n
* *
* @return string The two-letter language code * @return string The two-letter language code
*/ */
public static function detectLanguage(array $server, array $get, string $sysLang = self::DEFAULT) public static function detectLanguage(array $server, array $get, string $sysLang = self::DEFAULT): string
{ {
$lang_variable = $server['HTTP_ACCEPT_LANGUAGE'] ?? null; $lang_variable = $server['HTTP_ACCEPT_LANGUAGE'] ?? null;
@ -269,7 +269,7 @@ class L10n
* *
* @return string * @return string
*/ */
public function t($s, ...$vars) public function t(string $s, ...$vars): string
{ {
if (empty($s)) { if (empty($s)) {
return ''; return '';
@ -307,7 +307,7 @@ class L10n
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
public function tt(string $singular, string $plural, int $count) public function tt(string $singular, string $plural, int $count): string
{ {
$s = null; $s = null;
@ -352,7 +352,7 @@ class L10n
* *
* @return bool * @return bool
*/ */
private function stringPluralSelectDefault($n) private function stringPluralSelectDefault(int $n): bool
{ {
return $n != 1; return $n != 1;
} }
@ -369,7 +369,7 @@ class L10n
* *
* @return array * @return array
*/ */
public static function getAvailableLanguages() public static function getAvailableLanguages(): array
{ {
$langs = []; $langs = [];
$strings_file_paths = glob('view/lang/*/strings.php'); $strings_file_paths = glob('view/lang/*/strings.php');
@ -391,10 +391,9 @@ class L10n
* Translate days and months names. * Translate days and months names.
* *
* @param string $s String with day or month name. * @param string $s String with day or month name.
*
* @return string Translated string. * @return string Translated string.
*/ */
public function getDay($s) public function getDay(string $s): string
{ {
$ret = str_replace(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], $ret = str_replace(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
[$this->t('Monday'), $this->t('Tuesday'), $this->t('Wednesday'), $this->t('Thursday'), $this->t('Friday'), $this->t('Saturday'), $this->t('Sunday')], [$this->t('Monday'), $this->t('Tuesday'), $this->t('Wednesday'), $this->t('Thursday'), $this->t('Friday'), $this->t('Saturday'), $this->t('Sunday')],
@ -411,10 +410,9 @@ class L10n
* Translate short days and months names. * Translate short days and months names.
* *
* @param string $s String with short day or month name. * @param string $s String with short day or month name.
*
* @return string Translated string. * @return string Translated string.
*/ */
public function getDayShort($s) public function getDayShort(string $s): string
{ {
$ret = str_replace(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], $ret = str_replace(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
[$this->t('Mon'), $this->t('Tue'), $this->t('Wed'), $this->t('Thu'), $this->t('Fri'), $this->t('Sat'), $this->t('Sun')], [$this->t('Mon'), $this->t('Tue'), $this->t('Wed'), $this->t('Thu'), $this->t('Fri'), $this->t('Sat'), $this->t('Sun')],
@ -435,7 +433,7 @@ class L10n
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @hook poke_verbs pokes array * @hook poke_verbs pokes array
*/ */
public function getPokeVerbs() public function getPokeVerbs(): array
{ {
// index is present tense verb // index is present tense verb
// value is array containing past tense verb, translation of present, translation of past // value is array containing past tense verb, translation of present, translation of past
@ -461,7 +459,7 @@ class L10n
* @return static A new L10n instance * @return static A new L10n instance
* @throws \Exception * @throws \Exception
*/ */
public function withLang(string $lang) public function withLang(string $lang): L10n
{ {
// Don't create a new instance for same language // Don't create a new instance for same language
if ($lang === $this->lang) { if ($lang === $this->lang) {

View file

@ -47,7 +47,7 @@ class Logger
/** /**
* @return LoggerInterface * @return LoggerInterface
*/ */
private static function getWorker() private static function getInstance()
{ {
if (self::$type === self::TYPE_LOGGER) { if (self::$type === self::TYPE_LOGGER) {
return DI::logger(); return DI::logger();
@ -66,7 +66,7 @@ class Logger
public static function enableWorker(string $functionName) public static function enableWorker(string $functionName)
{ {
self::$type = self::TYPE_WORKER; self::$type = self::TYPE_WORKER;
self::getWorker()->setFunctionName($functionName); self::getInstance()->setFunctionName($functionName);
} }
/** /**
@ -82,15 +82,14 @@ class Logger
* *
* @see LoggerInterface::emergency() * @see LoggerInterface::emergency()
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function emergency($message, $context = []) public static function emergency(string $message, array $context = [])
{ {
self::getWorker()->emergency($message, $context); self::getInstance()->emergency($message, $context);
} }
/** /**
@ -100,15 +99,14 @@ class Logger
* Example: Entire website down, database unavailable, etc. This should * Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up. * trigger the SMS alerts and wake you up.
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function alert($message, $context = []) public static function alert(string $message, array $context = [])
{ {
self::getWorker()->alert($message, $context); self::getInstance()->alert($message, $context);
} }
/** /**
@ -117,15 +115,14 @@ class Logger
* *
* Example: Application component unavailable, unexpected exception. * Example: Application component unavailable, unexpected exception.
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function critical($message, $context = []) public static function critical(string $message, array $context = [])
{ {
self::getWorker()->critical($message, $context); self::getInstance()->critical($message, $context);
} }
/** /**
@ -133,15 +130,14 @@ class Logger
* be logged and monitored. * be logged and monitored.
* @see LoggerInterface::error() * @see LoggerInterface::error()
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function error($message, $context = []) public static function error(string $message, array $context = [])
{ {
self::getWorker()->error($message, $context); self::getInstance()->error($message, $context);
} }
/** /**
@ -151,30 +147,28 @@ class Logger
* Example: Use of deprecated APIs, poor use of an API, undesirable things * Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong. * that are not necessarily wrong.
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function warning($message, $context = []) public static function warning(string $message, array $context = [])
{ {
self::getWorker()->warning($message, $context); self::getInstance()->warning($message, $context);
} }
/** /**
* Normal but significant events. * Normal but significant events.
* @see LoggerInterface::notice() * @see LoggerInterface::notice()
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function notice($message, $context = []) public static function notice(string $message, array $context = [])
{ {
self::getWorker()->notice($message, $context); self::getInstance()->notice($message, $context);
} }
/** /**
@ -189,24 +183,23 @@ class Logger
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function info($message, $context = []) public static function info(string $message, array $context = [])
{ {
self::getWorker()->info($message, $context); self::getInstance()->info($message, $context);
} }
/** /**
* Detailed debug information. * Detailed debug information.
* @see LoggerInterface::debug() * @see LoggerInterface::debug()
* *
* @param string $message * @param string $message Message to log
* @param array $context * @param array $context Optional variables
*
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function debug($message, $context = []) public static function debug(string $message, array $context = [])
{ {
self::getWorker()->debug($message, $context); self::getInstance()->debug($message, $context);
} }
/** /**
@ -216,12 +209,13 @@ class Logger
* to isolate particular elements they are targetting * to isolate particular elements they are targetting
* personally without background noise * personally without background noise
* *
* @param string $msg * @param string $message Message to log
* @param string $level * @param string $level Logging level
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function devLog($msg, $level = LogLevel::DEBUG) public static function devLog(string $message, string $level = LogLevel::DEBUG)
{ {
DI::devLogger()->log($level, $msg); DI::devLogger()->log($level, $message);
} }
} }

View file

@ -21,6 +21,7 @@
namespace Friendica\Core\Logger\Type\Monolog; namespace Friendica\Core\Logger\Type\Monolog;
use Friendica\App\Request;
use Monolog\Handler; use Monolog\Handler;
use Monolog\Logger; use Monolog\Logger;
@ -38,15 +39,22 @@ class DevelopHandler extends Handler\AbstractHandler
private $developerIp; private $developerIp;
/** /**
* @param string $developerIp The IP of the developer who wants to debug * @var string The IP of the current request
* @param int $level The minimum logging level at which this handler will be triggered
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
*/ */
public function __construct($developerIp, $level = Logger::DEBUG, bool $bubble = true) private $remoteAddress;
/**
* @param Request $request The current http request
* @param string $developerIp The IP of the developer who wants to debug
* @param int $level The minimum logging level at which this handler will be triggered
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
*/
public function __construct(Request $request, $developerIp, int $level = Logger::DEBUG, bool $bubble = true)
{ {
parent::__construct($level, $bubble); parent::__construct($level, $bubble);
$this->developerIp = $developerIp; $this->developerIp = $developerIp;
$this->remoteAddress = $request->getRemoteAddress();
} }
/** /**
@ -59,7 +67,7 @@ class DevelopHandler extends Handler\AbstractHandler
} }
/// Just in case the remote IP is the same as the developer IP log the output /// Just in case the remote IP is the same as the developer IP log the output
if (!is_null($this->developerIp) && $_SERVER['REMOTE_ADDR'] != $this->developerIp) { if (!is_null($this->developerIp) && $this->remoteAddress != $this->developerIp) {
return false; return false;
} }

View file

@ -71,7 +71,7 @@ class Renderer
* @return string * @return string
* @throws ServiceUnavailableException * @throws ServiceUnavailableException
*/ */
public static function replaceMacros(string $template, array $vars = []) public static function replaceMacros(string $template, array $vars = []): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');

View file

@ -32,7 +32,7 @@ require_once 'boot.php';
*/ */
class Theme class Theme
{ {
public static function getAllowedList() public static function getAllowedList(): array
{ {
$allowed_themes_str = DI::config()->get('system', 'allowed_themes'); $allowed_themes_str = DI::config()->get('system', 'allowed_themes');
$allowed_themes_raw = explode(',', str_replace(' ', '', $allowed_themes_str)); $allowed_themes_raw = explode(',', str_replace(' ', '', $allowed_themes_str));
@ -69,7 +69,7 @@ class Theme
* @param string $theme the name of the theme * @param string $theme the name of the theme
* @return array * @return array
*/ */
public static function getInfo($theme) public static function getInfo(string $theme): array
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);
@ -133,7 +133,7 @@ class Theme
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function getScreenshot($theme) public static function getScreenshot(string $theme): string
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);
@ -146,7 +146,13 @@ class Theme
return DI::baseUrl() . '/images/blank.png'; return DI::baseUrl() . '/images/blank.png';
} }
public static function uninstall($theme) /**
* Uninstalls given theme name
*
* @param string $theme Name of theme
* @return bool true on success
*/
public static function uninstall(string $theme)
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);
@ -167,10 +173,18 @@ class Theme
if ($key !== false) { if ($key !== false) {
unset($allowed_themes[$key]); unset($allowed_themes[$key]);
Theme::setAllowedList($allowed_themes); Theme::setAllowedList($allowed_themes);
return true;
} }
return false;
} }
public static function install($theme) /**
* Installs given theme name
*
* @param string $theme Name of theme
* @return bool true on success
*/
public static function install(string $theme): bool
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);
@ -208,7 +222,7 @@ class Theme
* @return string Path to the file or empty string if the file isn't found * @return string Path to the file or empty string if the file isn't found
* @throws \Exception * @throws \Exception
*/ */
public static function getPathForFile($file) public static function getPathForFile(string $file): string
{ {
$a = DI::app(); $a = DI::app();
@ -237,10 +251,9 @@ class Theme
* Provide a sane default if nothing is chosen or the specified theme does not exist. * Provide a sane default if nothing is chosen or the specified theme does not exist.
* *
* @param string $theme Theme name * @param string $theme Theme name
*
* @return string * @return string
*/ */
public static function getStylesheetPath($theme) public static function getStylesheetPath(string $theme): string
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);
@ -263,10 +276,10 @@ class Theme
/** /**
* Returns the path of the provided theme * Returns the path of the provided theme
* *
* @param $theme * @param string $theme Theme name
* @return string|null * @return string|null
*/ */
public static function getConfigFile($theme) public static function getConfigFile(string $theme)
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);
@ -285,11 +298,11 @@ class Theme
/** /**
* Returns the background color of the provided theme if available. * Returns the background color of the provided theme if available.
* *
* @param string $theme * @param string $theme Theme name
* @param int|null $uid Current logged-in user id * @param int|null $uid Current logged-in user id
* @return string|null * @return string|null
*/ */
public static function getBackgroundColor(string $theme, $uid = null) public static function getBackgroundColor(string $theme, int $uid = null)
{ {
$theme = Strings::sanitizeFilePathItem($theme); $theme = Strings::sanitizeFilePathItem($theme);

View file

@ -86,7 +86,7 @@ class UserImport
* @return array|bool * @return array|bool
* @throws \Exception * @throws \Exception
*/ */
private static function dbImportAssoc($table, $arr) private static function dbImportAssoc(string $table, array $arr)
{ {
if (isset($arr['id'])) { if (isset($arr['id'])) {
unset($arr['id']); unset($arr['id']);
@ -105,10 +105,11 @@ class UserImport
* Import account file exported from mod/uexport * Import account file exported from mod/uexport
* *
* @param array $file array from $_FILES * @param array $file array from $_FILES
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function importAccount($file) public static function importAccount(array $file)
{ {
Logger::notice("Start user import from " . $file['tmp_name']); Logger::notice("Start user import from " . $file['tmp_name']);
/* /*

View file

@ -60,7 +60,7 @@ class Worker
* @return void * @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function processQueue($run_cron, Process $process) public static function processQueue(bool $run_cron, Process $process)
{ {
self::$up_start = microtime(true); self::$up_start = microtime(true);
@ -169,7 +169,7 @@ class Worker
* *
* @return boolean * @return boolean
*/ */
public static function isReady() public static function isReady(): bool
{ {
// Count active workers and compare them with a maximum value that depends on the load // Count active workers and compare them with a maximum value that depends on the load
if (self::tooMuchWorkers()) { if (self::tooMuchWorkers()) {
@ -204,7 +204,7 @@ class Worker
* @return boolean Returns "true" if tasks are existing * @return boolean Returns "true" if tasks are existing
* @throws \Exception * @throws \Exception
*/ */
public static function entriesExists() public static function entriesExists(): bool
{ {
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
$exists = DBA::exists('workerqueue', ["NOT `done` AND `pid` = 0 AND `next_try` < ?", DateTimeFormat::utcNow()]); $exists = DBA::exists('workerqueue', ["NOT `done` AND `pid` = 0 AND `next_try` < ?", DateTimeFormat::utcNow()]);
@ -218,7 +218,7 @@ class Worker
* @return integer Number of deferred entries in the worker queue * @return integer Number of deferred entries in the worker queue
* @throws \Exception * @throws \Exception
*/ */
private static function deferredEntries() private static function deferredEntries(): int
{ {
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
$count = DBA::count('workerqueue', ["NOT `done` AND `pid` = 0 AND `retrial` > ?", 0]); $count = DBA::count('workerqueue', ["NOT `done` AND `pid` = 0 AND `retrial` > ?", 0]);
@ -233,7 +233,7 @@ class Worker
* @return integer Number of non executed entries in the worker queue * @return integer Number of non executed entries in the worker queue
* @throws \Exception * @throws \Exception
*/ */
private static function totalEntries() private static function totalEntries(): int
{ {
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
$count = DBA::count('workerqueue', ['done' => false, 'pid' => 0]); $count = DBA::count('workerqueue', ['done' => false, 'pid' => 0]);
@ -248,7 +248,7 @@ class Worker
* @return integer Number of active worker processes * @return integer Number of active worker processes
* @throws \Exception * @throws \Exception
*/ */
private static function highestPriority() private static function highestPriority(): int
{ {
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
$condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()]; $condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()];
@ -269,7 +269,7 @@ class Worker
* @return integer Is there a process running with that priority? * @return integer Is there a process running with that priority?
* @throws \Exception * @throws \Exception
*/ */
private static function processWithPriorityActive($priority) private static function processWithPriorityActive(int $priority): int
{ {
$condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority]; $condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority];
return DBA::exists('workerqueue', $condition); return DBA::exists('workerqueue', $condition);
@ -281,7 +281,7 @@ class Worker
* @param mixed $file * @param mixed $file
* @return bool * @return bool
*/ */
private static function validateInclude(&$file) private static function validateInclude(&$file): bool
{ {
$orig_file = $file; $orig_file = $file;
@ -321,7 +321,7 @@ class Worker
* @return boolean "true" if further processing should be stopped * @return boolean "true" if further processing should be stopped
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function execute($queue) public static function execute(array $queue): bool
{ {
$mypid = getmypid(); $mypid = getmypid();
@ -454,7 +454,7 @@ class Worker
* @return void * @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function execFunction($queue, $funcname, $argv, $method_call) private static function execFunction(array $queue, string $funcname, array $argv, bool $method_call)
{ {
$a = DI::app(); $a = DI::app();
@ -543,7 +543,7 @@ class Worker
* @return bool Are more than 3/4 of the maximum connections used? * @return bool Are more than 3/4 of the maximum connections used?
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function maxConnectionsReached() private static function maxConnectionsReached(): bool
{ {
// Fetch the max value from the config. This is needed when the system cannot detect the correct value by itself. // Fetch the max value from the config. This is needed when the system cannot detect the correct value by itself.
$max = DI::config()->get("system", "max_connections"); $max = DI::config()->get("system", "max_connections");
@ -627,7 +627,7 @@ class Worker
* @return bool Are there too much workers running? * @return bool Are there too much workers running?
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function tooMuchWorkers() private static function tooMuchWorkers(): bool
{ {
$queues = DI::config()->get("system", "worker_queues", 10); $queues = DI::config()->get("system", "worker_queues", 10);
@ -751,7 +751,7 @@ class Worker
* @return integer Number of active worker processes * @return integer Number of active worker processes
* @throws \Exception * @throws \Exception
*/ */
private static function activeWorkers() private static function activeWorkers(): int
{ {
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
$count = DI::process()->countCommand('Worker.php'); $count = DI::process()->countCommand('Worker.php');
@ -766,7 +766,7 @@ class Worker
* @return array List of worker process ids * @return array List of worker process ids
* @throws \Exception * @throws \Exception
*/ */
private static function getWorkerPIDList() private static function getWorkerPIDList(): array
{ {
$ids = []; $ids = [];
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
@ -787,7 +787,7 @@ class Worker
/** /**
* Returns waiting jobs for the current process id * Returns waiting jobs for the current process id
* *
* @return array waiting workerqueue jobs * @return array|bool waiting workerqueue jobs or FALSE on failture
* @throws \Exception * @throws \Exception
*/ */
private static function getWaitingJobForPID() private static function getWaitingJobForPID()
@ -809,7 +809,7 @@ class Worker
* @return array array with next jobs * @return array array with next jobs
* @throws \Exception * @throws \Exception
*/ */
private static function nextProcess(int $limit) private static function nextProcess(int $limit): array
{ {
$priority = self::nextPriority(); $priority = self::nextPriority();
if (empty($priority)) { if (empty($priority)) {
@ -844,7 +844,7 @@ class Worker
/** /**
* Returns the priority of the next workerqueue job * Returns the priority of the next workerqueue job
* *
* @return string priority * @return string|bool priority or FALSE on failure
* @throws \Exception * @throws \Exception
*/ */
private static function nextPriority() private static function nextPriority()
@ -915,7 +915,7 @@ class Worker
/** /**
* Find and claim the next worker process for us * Find and claim the next worker process for us
* *
* @return boolean Have we found something? * @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function findWorkerProcesses() private static function findWorkerProcesses()
@ -993,7 +993,7 @@ class Worker
* @return array worker processes * @return array worker processes
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function workerProcess() public static function workerProcess(): array
{ {
// There can already be jobs for us in the queue. // There can already be jobs for us in the queue.
$waiting = self::getWaitingJobForPID(); $waiting = self::getWaitingJobForPID();
@ -1003,7 +1003,7 @@ class Worker
$stamp = (float)microtime(true); $stamp = (float)microtime(true);
if (!DI::lock()->acquire(self::LOCK_PROCESS)) { if (!DI::lock()->acquire(self::LOCK_PROCESS)) {
return false; return [];
} }
self::$lock_duration += (microtime(true) - $stamp); self::$lock_duration += (microtime(true) - $stamp);
@ -1011,7 +1011,9 @@ class Worker
DI::lock()->release(self::LOCK_PROCESS); DI::lock()->release(self::LOCK_PROCESS);
return self::getWaitingJobForPID(); // Prevents "Return value of Friendica\Core\Worker::workerProcess() must be of the type array, bool returned"
$process = self::getWaitingJobForPID();
return (is_array($process) ? $process : []);
} }
/** /**
@ -1097,7 +1099,7 @@ class Worker
* @return void * @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function spawnWorker($do_cron = false) public static function spawnWorker(bool $do_cron = false)
{ {
if (Worker\Daemon::isMode() && DI::config()->get('system', 'worker_fork')) { if (Worker\Daemon::isMode() && DI::config()->get('system', 'worker_fork')) {
self::forkProcess($do_cron); self::forkProcess($do_cron);
@ -1231,7 +1233,7 @@ class Worker
return $added; return $added;
} }
public static function countWorkersByCommand(string $command) public static function countWorkersByCommand(string $command): int
{ {
return DBA::count('workerqueue', ['done' => false, 'pid' => 0, 'command' => $command]); return DBA::count('workerqueue', ['done' => false, 'pid' => 0, 'command' => $command]);
} }
@ -1244,7 +1246,7 @@ class Worker
* @param integer $max_level maximum retrial level * @param integer $max_level maximum retrial level
* @return integer the next retrial level value * @return integer the next retrial level value
*/ */
private static function getNextRetrial($queue, $max_level) private static function getNextRetrial(array $queue, int $max_level): int
{ {
$created = strtotime($queue['created']); $created = strtotime($queue['created']);
$retrial_time = time() - $created; $retrial_time = time() - $created;
@ -1314,9 +1316,10 @@ class Worker
/** /**
* Check if the system is inside the defined maintenance window * Check if the system is inside the defined maintenance window
* *
* @param bool $check_last_execution Whether check last execution
* @return boolean * @return boolean
*/ */
public static function isInMaintenanceWindow(bool $check_last_execution = false) public static function isInMaintenanceWindow(bool $check_last_execution = false): bool
{ {
// Calculate the seconds of the start end end of the maintenance window // Calculate the seconds of the start end end of the maintenance window
$start = strtotime(DI::config()->get('system', 'maintenance_start')) % 86400; $start = strtotime(DI::config()->get('system', 'maintenance_start')) % 86400;

View file

@ -42,7 +42,7 @@ class DBA
*/ */
const NULL_DATETIME = '0001-01-01 00:00:00'; const NULL_DATETIME = '0001-01-01 00:00:00';
public static function connect() public static function connect(): bool
{ {
return DI::dba()->connect(); return DI::dba()->connect();
} }
@ -58,7 +58,7 @@ class DBA
/** /**
* Perform a reconnect of an existing database connection * Perform a reconnect of an existing database connection
*/ */
public static function reconnect() public static function reconnect(): bool
{ {
return DI::dba()->reconnect(); return DI::dba()->reconnect();
} }
@ -77,7 +77,7 @@ class DBA
* *
* @return string with either "pdo" or "mysqli" * @return string with either "pdo" or "mysqli"
*/ */
public static function getDriver() public static function getDriver(): string
{ {
return DI::dba()->getDriver(); return DI::dba()->getDriver();
} }
@ -90,7 +90,7 @@ class DBA
* *
* @return string * @return string
*/ */
public static function serverInfo() public static function serverInfo(): string
{ {
return DI::dba()->serverInfo(); return DI::dba()->serverInfo();
} }
@ -101,7 +101,7 @@ class DBA
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
public static function databaseName() public static function databaseName(): string
{ {
return DI::dba()->databaseName(); return DI::dba()->databaseName();
} }
@ -112,7 +112,7 @@ class DBA
* @param string $str * @param string $str
* @return string escaped string * @return string escaped string
*/ */
public static function escape($str) public static function escape(string $str): string
{ {
return DI::dba()->escape($str); return DI::dba()->escape($str);
} }
@ -122,7 +122,7 @@ class DBA
* *
* @return boolean is the database connected? * @return boolean is the database connected?
*/ */
public static function connected() public static function connected(): bool
{ {
return DI::dba()->connected(); return DI::dba()->connected();
} }
@ -138,7 +138,7 @@ class DBA
* @param string $sql An SQL string without the values * @param string $sql An SQL string without the values
* @return string The input SQL string modified if necessary. * @return string The input SQL string modified if necessary.
*/ */
public static function anyValueFallback($sql) public static function anyValueFallback(string $sql): string
{ {
return DI::dba()->anyValueFallback($sql); return DI::dba()->anyValueFallback($sql);
} }
@ -152,7 +152,7 @@ class DBA
* @param string $sql An SQL string without the values * @param string $sql An SQL string without the values
* @return string The input SQL string modified if necessary. * @return string The input SQL string modified if necessary.
*/ */
public static function cleanQuery($sql) public static function cleanQuery(string $sql): string
{ {
$search = ["\t", "\n", "\r", " "]; $search = ["\t", "\n", "\r", " "];
$replace = [' ', ' ', ' ', ' ']; $replace = [' ', ' ', ' ', ' '];
@ -169,7 +169,7 @@ class DBA
* @param array $args Parameter array * @param array $args Parameter array
* @return array universalized parameter array * @return array universalized parameter array
*/ */
public static function getParam($args) public static function getParam(array $args): array
{ {
unset($args[0]); unset($args[0]);
@ -192,7 +192,7 @@ class DBA
* @return bool|object statement object or result object * @return bool|object statement object or result object
* @throws \Exception * @throws \Exception
*/ */
public static function p($sql) public static function p(string $sql)
{ {
$params = self::getParam(func_get_args()); $params = self::getParam(func_get_args());
@ -208,8 +208,8 @@ class DBA
* @return boolean Was the query successfull? False is returned only if an error occurred * @return boolean Was the query successfull? False is returned only if an error occurred
* @throws \Exception * @throws \Exception
*/ */
public static function e($sql) { public static function e(string $sql): bool
{
$params = self::getParam(func_get_args()); $params = self::getParam(func_get_args());
return DI::dba()->e($sql, $params); return DI::dba()->e($sql, $params);
@ -218,13 +218,12 @@ class DBA
/** /**
* Check if data exists * Check if data exists
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition array of fields for condition * @param array $condition Array of fields for condition
*
* @return boolean Are there rows for that condition? * @return boolean Are there rows for that condition?
* @throws \Exception * @throws \Exception
*/ */
public static function exists($table, $condition) public static function exists(string $table, array $condition): bool
{ {
return DI::dba()->exists($table, $condition); return DI::dba()->exists($table, $condition);
} }
@ -238,7 +237,7 @@ class DBA
* @return array first row of query * @return array first row of query
* @throws \Exception * @throws \Exception
*/ */
public static function fetchFirst($sql) public static function fetchFirst(string $sql)
{ {
$params = self::getParam(func_get_args()); $params = self::getParam(func_get_args());
@ -250,7 +249,7 @@ class DBA
* *
* @return int Number of rows * @return int Number of rows
*/ */
public static function affectedRows() public static function affectedRows(): int
{ {
return DI::dba()->affectedRows(); return DI::dba()->affectedRows();
} }
@ -261,7 +260,7 @@ class DBA
* @param object Statement object * @param object Statement object
* @return int Number of columns * @return int Number of columns
*/ */
public static function columnCount($stmt) public static function columnCount($stmt): int
{ {
return DI::dba()->columnCount($stmt); return DI::dba()->columnCount($stmt);
} }
@ -271,7 +270,7 @@ class DBA
* @param PDOStatement|mysqli_result|mysqli_stmt Statement object * @param PDOStatement|mysqli_result|mysqli_stmt Statement object
* @return int Number of rows * @return int Number of rows
*/ */
public static function numRows($stmt) public static function numRows($stmt): int
{ {
return DI::dba()->numRows($stmt); return DI::dba()->numRows($stmt);
} }
@ -290,14 +289,13 @@ class DBA
/** /**
* Insert a row into a table * Insert a row into a table
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array * @param array $param parameter array
* @param int $duplicate_mode What to do on a duplicated entry * @param int $duplicate_mode What to do on a duplicated entry
*
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public static function insert($table, array $param, int $duplicate_mode = Database::INSERT_DEFAULT) public static function insert(string $table, array $param, int $duplicate_mode = Database::INSERT_DEFAULT): bool
{ {
return DI::dba()->insert($table, $param, $duplicate_mode); return DI::dba()->insert($table, $param, $duplicate_mode);
} }
@ -306,13 +304,12 @@ class DBA
* Inserts a row with the provided data in the provided table. * Inserts a row with the provided data in the provided table.
* If the data corresponds to an existing row through a UNIQUE or PRIMARY index constraints, it updates the row instead. * If the data corresponds to an existing row through a UNIQUE or PRIMARY index constraints, it updates the row instead.
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array * @param array $param parameter array
*
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public static function replace($table, $param) public static function replace(string $table, array $param): bool
{ {
return DI::dba()->replace($table, $param); return DI::dba()->replace($table, $param);
} }
@ -322,7 +319,7 @@ class DBA
* *
* @return integer Last inserted id * @return integer Last inserted id
*/ */
public static function lastInsertId() public static function lastInsertId(): int
{ {
return DI::dba()->lastInsertId(); return DI::dba()->lastInsertId();
} }
@ -332,12 +329,11 @@ class DBA
* *
* This function can be extended in the future to accept a table array as well. * This function can be extended in the future to accept a table array as well.
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
*
* @return boolean was the lock successful? * @return boolean was the lock successful?
* @throws \Exception * @throws \Exception
*/ */
public static function lock($table) public static function lock(string $table): bool
{ {
return DI::dba()->lock($table); return DI::dba()->lock($table);
} }
@ -348,7 +344,7 @@ class DBA
* @return boolean was the unlock successful? * @return boolean was the unlock successful?
* @throws \Exception * @throws \Exception
*/ */
public static function unlock() public static function unlock(): bool
{ {
return DI::dba()->unlock(); return DI::dba()->unlock();
} }
@ -358,7 +354,7 @@ class DBA
* *
* @return boolean Was the command executed successfully? * @return boolean Was the command executed successfully?
*/ */
public static function transaction() public static function transaction(): bool
{ {
return DI::dba()->transaction(); return DI::dba()->transaction();
} }
@ -368,7 +364,7 @@ class DBA
* *
* @return boolean Was the command executed successfully? * @return boolean Was the command executed successfully?
*/ */
public static function commit() public static function commit(): bool
{ {
return DI::dba()->commit(); return DI::dba()->commit();
} }
@ -378,7 +374,7 @@ class DBA
* *
* @return boolean Was the command executed successfully? * @return boolean Was the command executed successfully?
*/ */
public static function rollback() public static function rollback(): bool
{ {
return DI::dba()->rollback(); return DI::dba()->rollback();
} }
@ -386,13 +382,13 @@ class DBA
/** /**
* Delete a row from a table * Delete a row from a table
* *
* @param string|array $table Table name * @param string $table Table name
* @param array $conditions Field condition(s) * @param array $conditions Field condition(s)
* *
* @return boolean was the delete successful? * @return boolean was the delete successful?
* @throws \Exception * @throws \Exception
*/ */
public static function delete($table, array $conditions, array $options = []) public static function delete(string $table, array $conditions, array $options = []): bool
{ {
return DI::dba()->delete($table, $conditions, $options); return DI::dba()->delete($table, $conditions, $options);
} }
@ -418,7 +414,7 @@ class DBA
* Only set $old_fields to a boolean value when you are sure that you will update a single row. * Only set $old_fields to a boolean value when you are sure that you will update a single row.
* When you set $old_fields to "true" then $fields must contain all relevant fields! * When you set $old_fields to "true" then $fields must contain all relevant fields!
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields contains the fields that are updated * @param array $fields contains the fields that are updated
* @param array $condition condition array with the key values * @param array $condition condition array with the key values
* @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate, false = don't update identical fields) * @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate, false = don't update identical fields)
@ -427,7 +423,7 @@ class DBA
* @return boolean was the update successfull? * @return boolean was the update successfull?
* @throws \Exception * @throws \Exception
*/ */
public static function update($table, $fields, $condition, $old_fields = [], $params = []) public static function update(string $table, array $fields, array $condition, $old_fields = [], array $params = []): bool
{ {
return DI::dba()->update($table, $fields, $condition, $old_fields, $params); return DI::dba()->update($table, $fields, $condition, $old_fields, $params);
} }
@ -435,7 +431,7 @@ class DBA
/** /**
* Retrieve a single record from a table and returns it in an associative array * Retrieve a single record from a table and returns it in an associative array
* *
* @param string|array $table Table name or array [schema => table] * @param string|array $table Table name in format schema.table (while scheme is optiona)
* @param array $fields * @param array $fields
* @param array $condition * @param array $condition
* @param array $params * @param array $params
@ -443,7 +439,7 @@ class DBA
* @throws \Exception * @throws \Exception
* @see self::select * @see self::select
*/ */
public static function selectFirst($table, array $fields = [], array $condition = [], $params = []) public static function selectFirst($table, array $fields = [], array $condition = [], array $params = [])
{ {
return DI::dba()->selectFirst($table, $fields, $condition, $params); return DI::dba()->selectFirst($table, $fields, $condition, $params);
} }
@ -451,16 +447,16 @@ class DBA
/** /**
* Select rows from a table and fills an array with the data * Select rows from a table and fills an array with the data
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields Array of selected fields, empty for all * @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition * @param array $condition Array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
* *
* @return array Data array * @return array Data array
* @throws \Exception * @throws \Exception
* @see self::select * @see self::select
*/ */
public static function selectToArray($table, array $fields = [], array $condition = [], array $params = []) public static function selectToArray(string $table, array $fields = [], array $condition = [], array $params = [])
{ {
return DI::dba()->selectToArray($table, $fields, $condition, $params); return DI::dba()->selectToArray($table, $fields, $condition, $params);
} }
@ -468,10 +464,10 @@ class DBA
/** /**
* Select rows from a table * Select rows from a table
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields Array of selected fields, empty for all * @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition * @param array $condition Array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
* *
* @return boolean|object * @return boolean|object
* *
@ -488,7 +484,7 @@ class DBA
* $data = DBA::select($table, $fields, $condition, $params); * $data = DBA::select($table, $fields, $condition, $params);
* @throws \Exception * @throws \Exception
*/ */
public static function select($table, array $fields = [], array $condition = [], array $params = []) public static function select(string $table, array $fields = [], array $condition = [], array $params = [])
{ {
return DI::dba()->select($table, $fields, $condition, $params); return DI::dba()->select($table, $fields, $condition, $params);
} }
@ -496,9 +492,9 @@ class DBA
/** /**
* Counts the rows from a table satisfying the provided condition * Counts the rows from a table satisfying the provided condition
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition array of fields for condition * @param array $condition array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
* *
* @return int * @return int
* *
@ -512,7 +508,7 @@ class DBA
* $count = DBA::count($table, $condition); * $count = DBA::count($table, $condition);
* @throws \Exception * @throws \Exception
*/ */
public static function count($table, array $condition = [], array $params = []) public static function count(string $table, array $condition = [], array $params = []): int
{ {
return DI::dba()->count($table, $condition, $params); return DI::dba()->count($table, $condition, $params);
} }
@ -525,37 +521,30 @@ class DBA
* - [table1, table2, ...] * - [table1, table2, ...]
* - [schema1 => table1, schema2 => table2, table3, ...] * - [schema1 => table1, schema2 => table2, table3, ...]
* *
* @param string|array $tables * @param array $tables Table names
* @return string * @return string
*/ */
public static function buildTableString($tables) public static function buildTableString(array $tables): string
{ {
if (is_string($tables)) { // Quote each entry
$tables = [$tables]; return implode(',', array_map(['self', 'quoteIdentifier'], $tables));
}
$quotedTables = [];
foreach ($tables as $schema => $table) {
if (is_numeric($schema)) {
$quotedTables[] = self::quoteIdentifier($table);
} else {
$quotedTables[] = self::quoteIdentifier($schema) . '.' . self::quoteIdentifier($table);
}
}
return implode(', ', $quotedTables);
} }
/** /**
* Escape an identifier (table or field name) * Escape an identifier (table or field name) optional with a schema like (schema.)table
* *
* @param $identifier * @param $identifier Table, field name
* @return string * @return string Quotes table or field name
*/ */
public static function quoteIdentifier($identifier) public static function quoteIdentifier(string $identifier): string
{ {
return '`' . str_replace('`', '``', $identifier) . '`'; return implode(
'.',
array_map(
function (string $identifier) { return '`' . str_replace('`', '``', $identifier) . '`'; },
explode('.', $identifier)
)
);
} }
/** /**
@ -576,7 +565,7 @@ class DBA
* @param array $condition * @param array $condition
* @return string * @return string
*/ */
public static function buildCondition(array &$condition = []) public static function buildCondition(array &$condition = []): string
{ {
$condition = self::collapseCondition($condition); $condition = self::collapseCondition($condition);
@ -600,7 +589,7 @@ class DBA
* @param array $condition * @param array $condition
* @return array * @return array
*/ */
public static function collapseCondition(array $condition) public static function collapseCondition(array $condition): array
{ {
// Ensures an always true condition is returned // Ensures an always true condition is returned
if (count($condition) < 1) { if (count($condition) < 1) {
@ -675,7 +664,7 @@ class DBA
* @return array A collapsed condition * @return array A collapsed condition
* @see DBA::collapseCondition() for the condition array formats * @see DBA::collapseCondition() for the condition array formats
*/ */
public static function mergeConditions(array ...$conditions) public static function mergeConditions(array ...$conditions): array
{ {
if (count($conditions) == 1) { if (count($conditions) == 1) {
return current($conditions); return current($conditions);
@ -724,7 +713,7 @@ class DBA
* @param array $params * @param array $params
* @return string * @return string
*/ */
public static function buildParameter(array $params = []) public static function buildParameter(array $params = []): string
{ {
$groupby_string = ''; $groupby_string = '';
if (!empty($params['group_by'])) { if (!empty($params['group_by'])) {
@ -771,7 +760,7 @@ class DBA
* *
* @return array Data array * @return array Data array
*/ */
public static function toArray($stmt, $do_close = true, int $count = 0) public static function toArray($stmt, bool $do_close = true, int $count = 0): array
{ {
return DI::dba()->toArray($stmt, $do_close, $count); return DI::dba()->toArray($stmt, $do_close, $count);
} }
@ -783,7 +772,7 @@ class DBA
* @param array $fields * @param array $fields
* @return array casted fields * @return array casted fields
*/ */
public static function castFields(string $table, array $fields) public static function castFields(string $table, array $fields): array
{ {
return DI::dba()->castFields($table, $fields); return DI::dba()->castFields($table, $fields);
} }
@ -793,7 +782,7 @@ class DBA
* *
* @return string Error number (0 if no error) * @return string Error number (0 if no error)
*/ */
public static function errorNo() public static function errorNo(): int
{ {
return DI::dba()->errorNo(); return DI::dba()->errorNo();
} }
@ -803,7 +792,7 @@ class DBA
* *
* @return string Error message ('' if no error) * @return string Error message ('' if no error)
*/ */
public static function errorMessage() public static function errorMessage(): string
{ {
return DI::dba()->errorMessage(); return DI::dba()->errorMessage();
} }
@ -814,7 +803,7 @@ class DBA
* @param object $stmt statement object * @param object $stmt statement object
* @return boolean was the close successful? * @return boolean was the close successful?
*/ */
public static function close($stmt) public static function close($stmt): bool
{ {
return DI::dba()->close($stmt); return DI::dba()->close($stmt);
} }
@ -827,7 +816,7 @@ class DBA
* 'amount' => Number of concurrent database processes * 'amount' => Number of concurrent database processes
* @throws \Exception * @throws \Exception
*/ */
public static function processlist() public static function processlist(): array
{ {
return DI::dba()->processlist(); return DI::dba()->processlist();
} }
@ -847,10 +836,9 @@ class DBA
* Checks if $array is a filled array with at least one entry. * Checks if $array is a filled array with at least one entry.
* *
* @param mixed $array A filled array with at least one entry * @param mixed $array A filled array with at least one entry
*
* @return boolean Whether $array is a filled array or an object with rows * @return boolean Whether $array is a filled array or an object with rows
*/ */
public static function isResult($array) public static function isResult($array): bool
{ {
return DI::dba()->isResult($array); return DI::dba()->isResult($array);
} }
@ -862,7 +850,7 @@ class DBA
* @param boolean $add_quotation add quotation marks for string values * @param boolean $add_quotation add quotation marks for string values
* @return void * @return void
*/ */
public static function escapeArray(&$arr, $add_quotation = false) public static function escapeArray(&$arr, bool $add_quotation = false)
{ {
DI::dba()->escapeArray($arr, $add_quotation); DI::dba()->escapeArray($arr, $add_quotation);
} }

View file

@ -84,7 +84,7 @@ class DBStructure
'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge', 'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge',
'auth_codes', 'tokens', 'clients', 'profile_check', 'host']; 'auth_codes', 'tokens', 'clients', 'profile_check', 'host'];
$tables = DBA::selectToArray(['INFORMATION_SCHEMA' => 'TABLES'], ['TABLE_NAME'], $tables = DBA::selectToArray('INFORMATION_SCHEMA.TABLES', ['TABLE_NAME'],
['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']); ['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']);
if (empty($tables)) { if (empty($tables)) {
@ -119,13 +119,13 @@ class DBStructure
public static function convertToInnoDB() public static function convertToInnoDB()
{ {
$tables = DBA::selectToArray( $tables = DBA::selectToArray(
['information_schema' => 'tables'], 'information_schema.tables',
['table_name'], ['table_name'],
['engine' => 'MyISAM', 'table_schema' => DBA::databaseName()] ['engine' => 'MyISAM', 'table_schema' => DBA::databaseName()]
); );
$tables = array_merge($tables, DBA::selectToArray( $tables = array_merge($tables, DBA::selectToArray(
['information_schema' => 'tables'], 'information_schema.tables',
['table_name'], ['table_name'],
['engine' => 'InnoDB', 'ROW_FORMAT' => ['COMPACT', 'REDUNDANT'], 'table_schema' => DBA::databaseName()] ['engine' => 'InnoDB', 'ROW_FORMAT' => ['COMPACT', 'REDUNDANT'], 'table_schema' => DBA::databaseName()]
)); ));
@ -150,10 +150,9 @@ class DBStructure
* Print out database error messages * Print out database error messages
* *
* @param string $message Message to be added to the error message * @param string $message Message to be added to the error message
*
* @return string Error message * @return string Error message
*/ */
private static function printUpdateError($message) private static function printUpdateError(string $message): string
{ {
echo DI::l10n()->t("\nError %d occurred during database update:\n%s\n", echo DI::l10n()->t("\nError %d occurred during database update:\n%s\n",
DBA::errorNo(), DBA::errorMessage()); DBA::errorNo(), DBA::errorMessage());
@ -164,7 +163,7 @@ class DBStructure
public static function writeStructure() public static function writeStructure()
{ {
$tables = []; $tables = [];
foreach (self::definition(null) as $name => $definition) { foreach (self::definition('') as $name => $definition) {
$indexes = [[ $indexes = [[
'name' => 'Name', 'name' => 'Name',
'fields' => 'Fields', 'fields' => 'Fields',
@ -225,8 +224,8 @@ class DBStructure
$field['default'] = $value['default'] ?? 'NULL'; $field['default'] = $value['default'] ?? 'NULL';
$field['extra'] = $value['extra'] ?? ''; $field['extra'] = $value['extra'] ?? '';
foreach ($field as $fieldname => $fieldvalue) { foreach ($field as $fieldName => $fieldvalue) {
$lengths[$fieldname] = max($lengths[$fieldname] ?? 0, strlen($fieldvalue)); $lengths[$fieldName] = max($lengths[$fieldName] ?? 0, strlen($fieldvalue));
} }
$fields[] = $field; $fields[] = $field;
@ -263,7 +262,7 @@ class DBStructure
file_put_contents($filename, $content); file_put_contents($filename, $content);
} }
public static function printStructure($basePath) public static function printStructure(string $basePath)
{ {
$database = self::definition($basePath, false); $database = self::definition($basePath, false);
@ -288,12 +287,12 @@ class DBStructure
* On first pass, defines DB_UPDATE_VERSION constant. * On first pass, defines DB_UPDATE_VERSION constant.
* *
* @see static/dbstructure.config.php * @see static/dbstructure.config.php
* @param boolean $with_addons_structure Whether to tack on addons additional tables
* @param string $basePath The base path of this application * @param string $basePath The base path of this application
* @param boolean $with_addons_structure Whether to tack on addons additional tables
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function definition($basePath, $with_addons_structure = true) public static function definition(string $basePath, bool $with_addons_structure = true): array
{ {
if (!self::$definition) { if (!self::$definition) {
if (empty($basePath)) { if (empty($basePath)) {
@ -303,7 +302,7 @@ class DBStructure
$filename = $basePath . '/static/dbstructure.config.php'; $filename = $basePath . '/static/dbstructure.config.php';
if (!is_readable($filename)) { if (!is_readable($filename)) {
throw new Exception('Missing database structure config file static/dbstructure.config.php'); throw new Exception('Missing database structure config file static/dbstructure.config.php at basePath=' . $basePath);
} }
$definition = require $filename; $definition = require $filename;
@ -327,23 +326,23 @@ class DBStructure
/** /**
* Get field data for the given table * Get field data for the given table
* *
* @param string $table * @param string $table Tavle to load field definitions for
* @param array $data data fields * @param array $data data fields
* @return array fields for the given * @return array fields for the given
*/ */
public static function getFieldsForTable(string $table, array $data = []) public static function getFieldsForTable(string $table, array $data = []): array
{ {
$definition = DBStructure::definition('', false); $definition = DBStructure::definition('', false);
if (empty($definition[$table])) { if (empty($definition[$table])) {
return []; return [];
} }
$fieldnames = array_keys($definition[$table]['fields']); $fieldNames = array_keys($definition[$table]['fields']);
$fields = []; $fields = [];
// Assign all field that are present in the table // Assign all field that are present in the table
foreach ($fieldnames as $field) { foreach ($fieldNames as $field) {
if (isset($data[$field])) { if (isset($data[$field])) {
// Limit the length of varchar, varbinary, char and binrary fields // Limit the length of varchar, varbinary, char and binrary fields
if (is_string($data[$field]) && preg_match("/char\((\d*)\)/", $definition[$table]['fields'][$field]['type'], $result)) { if (is_string($data[$field]) && preg_match("/char\((\d*)\)/", $definition[$table]['fields'][$field]['type'], $result)) {
@ -358,45 +357,54 @@ class DBStructure
return $fields; return $fields;
} }
private static function createTable($name, $structure, $verbose, $action) /**
* Creates given table with structure
*
* @param string $name Name of table
* @param array $structure Structure of table
* @param boolean $verbose Output SQL statements
* @param boolean $action Whether to run the SQL commands
* @return Whether the SQL command ran successful
*/
private static function createTable(string $name, array $structure, bool $verbose, bool $action): bool
{ {
$r = true; $r = true;
$engine = ""; $engine = '';
$comment = ""; $comment = '';
$sql_rows = []; $sql_rows = [];
$primary_keys = []; $primary_keys = [];
$foreign_keys = []; $foreign_keys = [];
foreach ($structure["fields"] as $fieldname => $field) { foreach ($structure['fields'] as $fieldName => $field) {
$sql_rows[] = "`" . DBA::escape($fieldname) . "` " . self::FieldCommand($field); $sql_rows[] = '`' . DBA::escape($fieldName) . '` ' . self::FieldCommand($field);
if (!empty($field['primary'])) { if (!empty($field['primary'])) {
$primary_keys[] = $fieldname; $primary_keys[] = $fieldName;
} }
if (!empty($field['foreign'])) { if (!empty($field['foreign'])) {
$foreign_keys[$fieldname] = $field; $foreign_keys[$fieldName] = $field;
} }
} }
if (!empty($structure["indexes"])) { if (!empty($structure['indexes'])) {
foreach ($structure["indexes"] as $indexname => $fieldnames) { foreach ($structure['indexes'] as $indexName => $fieldNames) {
$sql_index = self::createIndex($indexname, $fieldnames, ""); $sql_index = self::createIndex($indexName, $fieldNames, '');
if (!is_null($sql_index)) { if (!is_null($sql_index)) {
$sql_rows[] = $sql_index; $sql_rows[] = $sql_index;
} }
} }
} }
foreach ($foreign_keys as $fieldname => $parameters) { foreach ($foreign_keys as $fieldName => $parameters) {
$sql_rows[] = self::foreignCommand($name, $fieldname, $parameters); $sql_rows[] = self::foreignCommand($name, $fieldName, $parameters);
} }
if (isset($structure["engine"])) { if (isset($structure['engine'])) {
$engine = " ENGINE=" . $structure["engine"]; $engine = ' ENGINE=' . $structure['engine'];
} }
if (isset($structure["comment"])) { if (isset($structure['comment'])) {
$comment = " COMMENT='" . DBA::escape($structure["comment"]) . "'"; $comment = " COMMENT='" . DBA::escape($structure['comment']) . "'";
} }
$sql = implode(",\n\t", $sql_rows); $sql = implode(",\n\t", $sql_rows);
@ -414,71 +422,77 @@ class DBStructure
return $r; return $r;
} }
private static function FieldCommand($parameters, $create = true) /**
* Returns SQL statement for field
*
* @param array $parameters Parameters for SQL statement
* @param boolean $create Whether to include PRIMARY KEY statement (unused)
* @return string SQL statement part
*/
private static function FieldCommand(array $parameters, bool $create = true): string
{ {
$fieldstruct = $parameters["type"]; $fieldstruct = $parameters['type'];
if (isset($parameters["Collation"])) { if (isset($parameters['Collation'])) {
$fieldstruct .= " COLLATE " . $parameters["Collation"]; $fieldstruct .= ' COLLATE ' . $parameters['Collation'];
} }
if (isset($parameters["not null"])) { if (isset($parameters['not null'])) {
$fieldstruct .= " NOT NULL"; $fieldstruct .= ' NOT NULL';
} }
if (isset($parameters["default"])) { if (isset($parameters['default'])) {
if (strpos(strtolower($parameters["type"]), "int") !== false) { if (strpos(strtolower($parameters['type']), 'int') !== false) {
$fieldstruct .= " DEFAULT " . $parameters["default"]; $fieldstruct .= ' DEFAULT ' . $parameters['default'];
} else { } else {
$fieldstruct .= " DEFAULT '" . $parameters["default"] . "'"; $fieldstruct .= " DEFAULT '" . $parameters['default'] . "'";
} }
} }
if (isset($parameters["extra"])) { if (isset($parameters['extra'])) {
$fieldstruct .= " " . $parameters["extra"]; $fieldstruct .= ' ' . $parameters['extra'];
} }
if (isset($parameters["comment"])) { if (isset($parameters['comment'])) {
$fieldstruct .= " COMMENT '" . DBA::escape($parameters["comment"]) . "'"; $fieldstruct .= " COMMENT '" . DBA::escape($parameters['comment']) . "'";
} }
/*if (($parameters["primary"] != "") && $create) /*if (($parameters['primary'] != '') && $create)
$fieldstruct .= " PRIMARY KEY";*/ $fieldstruct .= ' PRIMARY KEY';*/
return ($fieldstruct); return $fieldstruct;
} }
private static function createIndex($indexname, $fieldnames, $method = "ADD") private static function createIndex(string $indexName, array $fieldNames, string $method = 'ADD')
{ {
$method = strtoupper(trim($method)); $method = strtoupper(trim($method));
if ($method != "" && $method != "ADD") { if ($method != '' && $method != 'ADD') {
throw new Exception("Invalid parameter 'method' in self::createIndex(): '$method'"); throw new Exception("Invalid parameter 'method' in self::createIndex(): '$method'");
} }
if (in_array($fieldnames[0], ["UNIQUE", "FULLTEXT"])) { if (in_array($fieldNames[0], ['UNIQUE', 'FULLTEXT'])) {
$index_type = array_shift($fieldnames); $index_type = array_shift($fieldNames);
$method .= " " . $index_type; $method .= " " . $index_type;
} }
$names = ""; $names = "";
foreach ($fieldnames as $fieldname) { foreach ($fieldNames as $fieldName) {
if ($names != "") { if ($names != '') {
$names .= ","; $names .= ',';
} }
if (preg_match('|(.+)\((\d+)\)|', $fieldname, $matches)) { if (preg_match('|(.+)\((\d+)\)|', $fieldName, $matches)) {
$names .= "`" . DBA::escape($matches[1]) . "`(" . intval($matches[2]) . ")"; $names .= "`" . DBA::escape($matches[1]) . "`(" . intval($matches[2]) . ")";
} else { } else {
$names .= "`" . DBA::escape($fieldname) . "`"; $names .= "`" . DBA::escape($fieldName) . "`";
} }
} }
if ($indexname == "PRIMARY") { if ($indexName == 'PRIMARY') {
return sprintf("%s PRIMARY KEY(%s)", $method, $names); return sprintf("%s PRIMARY KEY(%s)", $method, $names);
} }
$sql = sprintf("%s INDEX `%s` (%s)", $method, DBA::escape($indexname), $names); return sprintf("%s INDEX `%s` (%s)", $method, DBA::escape($indexName), $names);
return ($sql);
} }
/** /**
@ -500,7 +514,7 @@ class DBStructure
* @return string Empty string if the update is successful, error messages otherwise * @return string Empty string if the update is successful, error messages otherwise
* @throws Exception * @throws Exception
*/ */
public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false) public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false): string
{ {
if ($enable_maintenance_mode) { if ($enable_maintenance_mode) {
DI::config()->set('system', 'maintenance', 1); DI::config()->set('system', 'maintenance', 1);
@ -524,7 +538,7 @@ class DBStructure
* @return string Empty string if the update is successful, error messages otherwise * @return string Empty string if the update is successful, error messages otherwise
* @throws Exception * @throws Exception
*/ */
public static function install(string $basePath) public static function install(string $basePath): string
{ {
return self::update($basePath, false, true, true); return self::update($basePath, false, true, true);
} }
@ -541,7 +555,7 @@ class DBStructure
* @return string Empty string if the update is successful, error messages otherwise * @return string Empty string if the update is successful, error messages otherwise
* @throws Exception * @throws Exception
*/ */
private static function update($basePath, $verbose, $action, $install = false, array $tables = null, array $definition = null) private static function update(string $basePath, bool $verbose, bool $action, bool $install = false, array $tables = null, array $definition = null): string
{ {
$in_maintenance_mode = DI::config()->get('system', 'maintenance'); $in_maintenance_mode = DI::config()->get('system', 'maintenance');
@ -606,15 +620,15 @@ class DBStructure
* or the definition differ from current status * or the definition differ from current status
* and index name doesn't start with "local_" * and index name doesn't start with "local_"
*/ */
foreach ($database[$name]["indexes"] as $indexname => $fieldnames) { foreach ($database[$name]["indexes"] as $indexName => $fieldNames) {
$current_index_definition = implode(",", $fieldnames); $current_index_definition = implode(",", $fieldNames);
if (isset($structure["indexes"][$indexname])) { if (isset($structure["indexes"][$indexName])) {
$new_index_definition = implode(",", $structure["indexes"][$indexname]); $new_index_definition = implode(",", $structure["indexes"][$indexName]);
} else { } else {
$new_index_definition = "__NOT_SET__"; $new_index_definition = "__NOT_SET__";
} }
if ($current_index_definition != $new_index_definition && substr($indexname, 0, 6) != 'local_') { if ($current_index_definition != $new_index_definition && substr($indexName, 0, 6) != 'local_') {
$sql2 = self::dropIndex($indexname); $sql2 = self::dropIndex($indexName);
if ($sql3 == "") { if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2; $sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else { } else {
@ -623,9 +637,9 @@ class DBStructure
} }
} }
// Compare the field structure field by field // Compare the field structure field by field
foreach ($structure["fields"] as $fieldname => $parameters) { foreach ($structure["fields"] as $fieldName => $parameters) {
if (!isset($database[$name]["fields"][$fieldname])) { if (!isset($database[$name]["fields"][$fieldName])) {
$sql2 = self::addTableField($fieldname, $parameters); $sql2 = self::addTableField($fieldName, $parameters);
if ($sql3 == "") { if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2; $sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else { } else {
@ -633,7 +647,7 @@ class DBStructure
} }
} else { } else {
// Compare the field definition // Compare the field definition
$field_definition = $database[$name]["fields"][$fieldname]; $field_definition = $database[$name]["fields"][$fieldName];
// Remove the relation data that is used for the referential integrity // Remove the relation data that is used for the referential integrity
unset($parameters['relation']); unset($parameters['relation']);
@ -653,7 +667,7 @@ class DBStructure
$current_field_definition = DBA::cleanQuery(implode(",", $field_definition)); $current_field_definition = DBA::cleanQuery(implode(",", $field_definition));
$new_field_definition = DBA::cleanQuery(implode(",", $parameters)); $new_field_definition = DBA::cleanQuery(implode(",", $parameters));
if ($current_field_definition != $new_field_definition) { if ($current_field_definition != $new_field_definition) {
$sql2 = self::modifyTableField($fieldname, $parameters); $sql2 = self::modifyTableField($fieldName, $parameters);
if ($sql3 == "") { if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2; $sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else { } else {
@ -670,15 +684,15 @@ class DBStructure
* Don't create keys if table is new * Don't create keys if table is new
*/ */
if (!$is_new_table) { if (!$is_new_table) {
foreach ($structure["indexes"] as $indexname => $fieldnames) { foreach ($structure["indexes"] as $indexName => $fieldNames) {
if (isset($database[$name]["indexes"][$indexname])) { if (isset($database[$name]["indexes"][$indexName])) {
$current_index_definition = implode(",", $database[$name]["indexes"][$indexname]); $current_index_definition = implode(",", $database[$name]["indexes"][$indexName]);
} else { } else {
$current_index_definition = "__NOT_SET__"; $current_index_definition = "__NOT_SET__";
} }
$new_index_definition = implode(",", $fieldnames); $new_index_definition = implode(",", $fieldNames);
if ($current_index_definition != $new_index_definition) { if ($current_index_definition != $new_index_definition) {
$sql2 = self::createIndex($indexname, $fieldnames); $sql2 = self::createIndex($indexName, $fieldNames);
if ($sql2 != "") { if ($sql2 != "") {
if ($sql3 == "") { if ($sql3 == "") {
@ -694,17 +708,17 @@ class DBStructure
// Foreign keys // Foreign keys
// Compare the field structure field by field // Compare the field structure field by field
foreach ($structure["fields"] as $fieldname => $parameters) { foreach ($structure["fields"] as $fieldName => $parameters) {
if (empty($parameters['foreign'])) { if (empty($parameters['foreign'])) {
continue; continue;
} }
$constraint = self::getConstraintName($name, $fieldname, $parameters); $constraint = self::getConstraintName($name, $fieldName, $parameters);
unset($existing_foreign_keys[$constraint]); unset($existing_foreign_keys[$constraint]);
if (empty($database[$name]['foreign_keys'][$constraint])) { if (empty($database[$name]['foreign_keys'][$constraint])) {
$sql2 = self::addForeignKey($name, $fieldname, $parameters); $sql2 = self::addForeignKey($name, $fieldName, $parameters);
if ($sql3 == "") { if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2; $sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
@ -767,9 +781,9 @@ class DBStructure
// Now have a look at the field collations // Now have a look at the field collations
// Compare the field structure field by field // Compare the field structure field by field
foreach ($structure["fields"] as $fieldname => $parameters) { foreach ($structure["fields"] as $fieldName => $parameters) {
// Compare the field definition // Compare the field definition
$field_definition = ($database[$name]["fields"][$fieldname] ?? '') ?: ['Collation' => '']; $field_definition = ($database[$name]["fields"][$fieldName] ?? '') ?: ['Collation' => ''];
// Define the default collation if not given // Define the default collation if not given
if (!isset($parameters['Collation']) && !empty($field_definition['Collation'])) { if (!isset($parameters['Collation']) && !empty($field_definition['Collation'])) {
@ -779,7 +793,7 @@ class DBStructure
} }
if ($field_definition['Collation'] != $parameters['Collation']) { if ($field_definition['Collation'] != $parameters['Collation']) {
$sql2 = self::modifyTableField($fieldname, $parameters); $sql2 = self::modifyTableField($fieldName, $parameters);
if (($sql3 == "") || (substr($sql3, -2, 2) == "; ")) { if (($sql3 == "") || (substr($sql3, -2, 2) == "; ")) {
$sql3 .= "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2; $sql3 .= "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else { } else {
@ -826,23 +840,29 @@ class DBStructure
return $errors; return $errors;
} }
private static function tableStructure($table) /**
* Returns an array with table structure information
*
* @param string $table Name of table
* @return array Table structure information
*/
private static function tableStructure(string $table): array
{ {
// This query doesn't seem to be executable as a prepared statement // This query doesn't seem to be executable as a prepared statement
$indexes = DBA::toArray(DBA::p("SHOW INDEX FROM " . DBA::quoteIdentifier($table))); $indexes = DBA::toArray(DBA::p("SHOW INDEX FROM " . DBA::quoteIdentifier($table)));
$fields = DBA::selectToArray(['INFORMATION_SCHEMA' => 'COLUMNS'], $fields = DBA::selectToArray('INFORMATION_SCHEMA.COLUMNS',
['COLUMN_NAME', 'COLUMN_TYPE', 'IS_NULLABLE', 'COLUMN_DEFAULT', 'EXTRA', ['COLUMN_NAME', 'COLUMN_TYPE', 'IS_NULLABLE', 'COLUMN_DEFAULT', 'EXTRA',
'COLUMN_KEY', 'COLLATION_NAME', 'COLUMN_COMMENT'], 'COLUMN_KEY', 'COLLATION_NAME', 'COLUMN_COMMENT'],
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?", ["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?",
DBA::databaseName(), $table]); DBA::databaseName(), $table]);
$foreign_keys = DBA::selectToArray(['INFORMATION_SCHEMA' => 'KEY_COLUMN_USAGE'], $foreign_keys = DBA::selectToArray('INFORMATION_SCHEMA.KEY_COLUMN_USAGE',
['COLUMN_NAME', 'CONSTRAINT_NAME', 'REFERENCED_TABLE_NAME', 'REFERENCED_COLUMN_NAME'], ['COLUMN_NAME', 'CONSTRAINT_NAME', 'REFERENCED_TABLE_NAME', 'REFERENCED_COLUMN_NAME'],
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `REFERENCED_TABLE_SCHEMA` IS NOT NULL", ["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `REFERENCED_TABLE_SCHEMA` IS NOT NULL",
DBA::databaseName(), $table]); DBA::databaseName(), $table]);
$table_status = DBA::selectFirst(['INFORMATION_SCHEMA' => 'TABLES'], $table_status = DBA::selectFirst('INFORMATION_SCHEMA.TABLES',
['ENGINE', 'TABLE_COLLATION', 'TABLE_COMMENT'], ['ENGINE', 'TABLE_COLLATION', 'TABLE_COMMENT'],
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?", ["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?",
DBA::databaseName(), $table]); DBA::databaseName(), $table]);
@ -909,41 +929,42 @@ class DBStructure
} }
} }
return ["fields" => $fielddata, "indexes" => $indexdata, return [
"foreign_keys" => $foreigndata, "table_status" => $table_status]; 'fields' => $fielddata,
'indexes' => $indexdata,
'foreign_keys' => $foreigndata,
'table_status' => $table_status
];
} }
private static function dropIndex($indexname) private static function dropIndex(string $indexName): string
{ {
$sql = sprintf("DROP INDEX `%s`", DBA::escape($indexname)); return sprintf("DROP INDEX `%s`", DBA::escape($indexName));
return ($sql);
} }
private static function addTableField($fieldname, $parameters) private static function addTableField(string $fieldName, array $parameters): string
{ {
$sql = sprintf("ADD `%s` %s", DBA::escape($fieldname), self::FieldCommand($parameters)); return sprintf("ADD `%s` %s", DBA::escape($fieldName), self::FieldCommand($parameters));
return ($sql);
} }
private static function modifyTableField($fieldname, $parameters) private static function modifyTableField(string $fieldName, array $parameters): string
{ {
$sql = sprintf("MODIFY `%s` %s", DBA::escape($fieldname), self::FieldCommand($parameters, false)); return sprintf("MODIFY `%s` %s", DBA::escape($fieldName), self::FieldCommand($parameters, false));
return ($sql);
} }
private static function getConstraintName(string $tablename, string $fieldname, array $parameters) private static function getConstraintName(string $tableName, string $fieldName, array $parameters): string
{ {
$foreign_table = array_keys($parameters['foreign'])[0]; $foreign_table = array_keys($parameters['foreign'])[0];
$foreign_field = array_values($parameters['foreign'])[0]; $foreign_field = array_values($parameters['foreign'])[0];
return $tablename . "-" . $fieldname. "-" . $foreign_table. "-" . $foreign_field; return $tableName . '-' . $fieldName. '-' . $foreign_table. '-' . $foreign_field;
} }
private static function foreignCommand(string $tablename, string $fieldname, array $parameters) { private static function foreignCommand(string $tableName, string $fieldName, array $parameters) {
$foreign_table = array_keys($parameters['foreign'])[0]; $foreign_table = array_keys($parameters['foreign'])[0];
$foreign_field = array_values($parameters['foreign'])[0]; $foreign_field = array_values($parameters['foreign'])[0];
$sql = "FOREIGN KEY (`" . $fieldname . "`) REFERENCES `" . $foreign_table . "` (`" . $foreign_field . "`)"; $sql = "FOREIGN KEY (`" . $fieldName . "`) REFERENCES `" . $foreign_table . "` (`" . $foreign_field . "`)";
if (!empty($parameters['foreign']['on update'])) { if (!empty($parameters['foreign']['on update'])) {
$sql .= " ON UPDATE " . strtoupper($parameters['foreign']['on update']); $sql .= " ON UPDATE " . strtoupper($parameters['foreign']['on update']);
@ -960,12 +981,12 @@ class DBStructure
return $sql; return $sql;
} }
private static function addForeignKey(string $tablename, string $fieldname, array $parameters) private static function addForeignKey(string $tableName, string $fieldName, array $parameters): string
{ {
return sprintf("ADD %s", self::foreignCommand($tablename, $fieldname, $parameters)); return sprintf("ADD %s", self::foreignCommand($tableName, $fieldName, $parameters));
} }
private static function dropForeignKey(string $constraint) private static function dropForeignKey(string $constraint): string
{ {
return sprintf("DROP FOREIGN KEY `%s`", $constraint); return sprintf("DROP FOREIGN KEY `%s`", $constraint);
} }
@ -983,7 +1004,7 @@ class DBStructure
* @return boolean Was the renaming successful? * @return boolean Was the renaming successful?
* @throws Exception * @throws Exception
*/ */
public static function rename($table, $columns, $type = self::RENAME_COLUMN) public static function rename(string $table, array $columns, int $type = self::RENAME_COLUMN): bool
{ {
if (empty($table) || empty($columns)) { if (empty($table) || empty($columns)) {
return false; return false;
@ -1019,7 +1040,7 @@ class DBStructure
return false; return false;
} }
$sql .= ";"; $sql .= ';';
$stmt = DBA::p($sql); $stmt = DBA::p($sql);
@ -1043,7 +1064,7 @@ class DBStructure
* @return boolean Does the table exist? * @return boolean Does the table exist?
* @throws Exception * @throws Exception
*/ */
public static function existsColumn($table, $columns = []) public static function existsColumn(string $table, array $columns = []): bool
{ {
if (empty($table)) { if (empty($table)) {
return false; return false;
@ -1079,39 +1100,33 @@ class DBStructure
/** /**
* Check if a foreign key exists for the given table field * Check if a foreign key exists for the given table field
* *
* @param string $table * @param string $table Table name
* @param string $field * @param string $field Field name
* @return boolean * @return boolean Wether a foreign key exists
*/ */
public static function existsForeignKeyForField(string $table, string $field) public static function existsForeignKeyForField(string $table, string $field): bool
{ {
return DBA::exists(['INFORMATION_SCHEMA' => 'KEY_COLUMN_USAGE'], return DBA::exists('INFORMATION_SCHEMA.KEY_COLUMN_USAGE',
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ? AND `REFERENCED_TABLE_SCHEMA` IS NOT NULL", ["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ? AND `REFERENCED_TABLE_SCHEMA` IS NOT NULL",
DBA::databaseName(), $table, $field]); DBA::databaseName(), $table, $field]);
} }
/** /**
* Check if a table exists * Check if a table exists
*
* @param string|array $table Table name
* *
* @param string $table Single table name (please loop yourself)
* @return boolean Does the table exist? * @return boolean Does the table exist?
* @throws Exception * @throws Exception
*/ */
public static function existsTable($table) public static function existsTable(string $table): bool
{ {
if (empty($table)) { if (empty($table)) {
return false; return false;
} }
if (is_array($table)) { $condition = ['table_schema' => DBA::databaseName(), 'table_name' => $table];
$condition = ['table_schema' => key($table), 'table_name' => current($table)];
} else {
$condition = ['table_schema' => DBA::databaseName(), 'table_name' => $table];
}
$result = DBA::exists(['information_schema' => 'tables'], $condition); return DBA::exists('information_schema.tables', $condition);
return $result;
} }
/** /**
@ -1122,7 +1137,7 @@ class DBStructure
* @return array An array of the table columns * @return array An array of the table columns
* @throws Exception * @throws Exception
*/ */
public static function getColumns($table) public static function getColumns(string $table): array
{ {
$stmtColumns = DBA::p("SHOW COLUMNS FROM `" . $table . "`"); $stmtColumns = DBA::p("SHOW COLUMNS FROM `" . $table . "`");
return DBA::toArray($stmtColumns); return DBA::toArray($stmtColumns);
@ -1130,6 +1145,9 @@ class DBStructure
/** /**
* Check if initial database values do exist - or create them * Check if initial database values do exist - or create them
*
* @param bool $verbose Whether to output messages
* @return void
*/ */
public static function checkInitialValues(bool $verbose = false) public static function checkInitialValues(bool $verbose = false)
{ {
@ -1163,9 +1181,9 @@ class DBStructure
if (self::existsTable('user') && !DBA::exists('user', ['uid' => 0])) { if (self::existsTable('user') && !DBA::exists('user', ['uid' => 0])) {
$user = [ $user = [
"verified" => true, 'verified' => true,
"page-flags" => User::PAGE_FLAGS_SOAPBOX, 'page-flags' => User::PAGE_FLAGS_SOAPBOX,
"account-type" => User::ACCOUNT_TYPE_RELAY, 'account-type' => User::ACCOUNT_TYPE_RELAY,
]; ];
DBA::insert('user', $user); DBA::insert('user', $user);
$lastid = DBA::lastInsertId(); $lastid = DBA::lastInsertId();
@ -1265,12 +1283,14 @@ class DBStructure
* *
* @return boolean * @return boolean
*/ */
private static function isUpdating() private static function isUpdating(): bool
{ {
$isUpdate = false; $isUpdate = false;
$processes = DBA::select(['information_schema' => 'processlist'], ['info'], $processes = DBA::select('information_schema.processlist', ['info'], [
['db' => DBA::databaseName(), 'command' => ['Query', 'Execute']]); 'db' => DBA::databaseName(),
'command' => ['Query', 'Execute']
]);
while ($process = DBA::fetch($processes)) { while ($process = DBA::fetch($processes)) {
$parts = explode(' ', $process['info']); $parts = explode(' ', $process['info']);

View file

@ -26,6 +26,7 @@ use Friendica\Core\System;
use Friendica\Network\HTTPException\ServiceUnavailableException; use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use InvalidArgumentException;
use mysqli; use mysqli;
use mysqli_result; use mysqli_result;
use mysqli_stmt; use mysqli_stmt;
@ -63,7 +64,7 @@ class Database
protected $server_info = ''; protected $server_info = '';
/** @var PDO|mysqli */ /** @var PDO|mysqli */
protected $connection; protected $connection;
protected $driver; protected $driver = '';
protected $pdo_emulate_prepares = false; protected $pdo_emulate_prepares = false;
private $error = false; private $error = false;
private $errorno = 0; private $errorno = 0;
@ -88,7 +89,12 @@ class Database
} }
} }
public function connect() /**
* Tries to connect to database
*
* @return bool Success
*/
public function connect(): bool
{ {
if (!is_null($this->connection) && $this->connected()) { if (!is_null($this->connection) && $this->connected()) {
return $this->connected; return $this->connected;
@ -175,7 +181,7 @@ class Database
// No suitable SQL driver was found. // No suitable SQL driver was found.
if (!$this->connected) { if (!$this->connected) {
$this->driver = null; $this->driver = '';
$this->connection = null; $this->connection = null;
} }
@ -227,7 +233,7 @@ class Database
} }
} }
$this->driver = null; $this->driver = '';
$this->connected = false; $this->connected = false;
} }
@ -255,7 +261,7 @@ class Database
* *
* @return string with either "pdo" or "mysqli" * @return string with either "pdo" or "mysqli"
*/ */
public function getDriver() public function getDriver(): string
{ {
return $this->driver; return $this->driver;
} }
@ -266,9 +272,9 @@ class Database
* This function discriminate between the deprecated mysql API and the current * This function discriminate between the deprecated mysql API and the current
* object-oriented mysqli API. Example of returned string: 5.5.46-0+deb8u1 * object-oriented mysqli API. Example of returned string: 5.5.46-0+deb8u1
* *
* @return string * @return string Database server information
*/ */
public function serverInfo() public function serverInfo(): string
{ {
if ($this->server_info == '') { if ($this->server_info == '') {
switch ($this->driver) { switch ($this->driver) {
@ -286,10 +292,10 @@ class Database
/** /**
* Returns the selected database name * Returns the selected database name
* *
* @return string * @return string Database name
* @throws \Exception * @throws \Exception
*/ */
public function databaseName() public function databaseName(): string
{ {
$ret = $this->p("SELECT DATABASE() AS `db`"); $ret = $this->p("SELECT DATABASE() AS `db`");
$data = $this->toArray($ret); $data = $this->toArray($ret);
@ -300,10 +306,10 @@ class Database
* Analyze a database query and log this if some conditions are met. * Analyze a database query and log this if some conditions are met.
* *
* @param string $query The database query that will be analyzed * @param string $query The database query that will be analyzed
* * @return void
* @throws \Exception * @throws \Exception
*/ */
private function logIndex($query) private function logIndex(string $query)
{ {
if (!$this->configCache->get('system', 'db_log_index')) { if (!$this->configCache->get('system', 'db_log_index')) {
@ -359,11 +365,10 @@ class Database
* Removes every not allowlisted character from the identifier string * Removes every not allowlisted character from the identifier string
* *
* @param string $identifier * @param string $identifier
*
* @return string sanitized identifier * @return string sanitized identifier
* @throws \Exception * @throws \Exception
*/ */
private function sanitizeIdentifier($identifier) private function sanitizeIdentifier(string $identifier): string
{ {
return preg_replace('/[^A-Za-z0-9_\-]+/', '', $identifier); return preg_replace('/[^A-Za-z0-9_\-]+/', '', $identifier);
} }
@ -383,11 +388,21 @@ class Database
} }
} }
public function isConnected() /**
* Returns connected flag
*
* @return bool Whether connection to database was success
*/
public function isConnected(): bool
{ {
return $this->connected; return $this->connected;
} }
/**
* Checks connection status
*
* @return bool Whether connection to database was success
*/
public function connected() public function connected()
{ {
$connected = false; $connected = false;
@ -424,7 +439,7 @@ class Database
* *
* @return string The input SQL string modified if necessary. * @return string The input SQL string modified if necessary.
*/ */
public function anyValueFallback($sql) public function anyValueFallback(string $sql): string
{ {
$server_info = $this->serverInfo(); $server_info = $this->serverInfo();
if (version_compare($server_info, '5.7.5', '<') || if (version_compare($server_info, '5.7.5', '<') ||
@ -442,7 +457,7 @@ class Database
* *
* @return string The replaced SQL query * @return string The replaced SQL query
*/ */
private function replaceParameters($sql, $args) private function replaceParameters(string $sql, array $args): string
{ {
$offset = 0; $offset = 0;
foreach ($args as $param => $value) { foreach ($args as $param => $value) {
@ -476,7 +491,7 @@ class Database
* @return bool|object statement object or result object * @return bool|object statement object or result object
* @throws \Exception * @throws \Exception
*/ */
public function p($sql) public function p(string $sql)
{ {
$this->profiler->startRecording('database'); $this->profiler->startRecording('database');
@ -541,7 +556,7 @@ class Database
if (!$retval = $this->connection->query($this->replaceParameters($sql, $args))) { if (!$retval = $this->connection->query($this->replaceParameters($sql, $args))) {
$errorInfo = $this->connection->errorInfo(); $errorInfo = $this->connection->errorInfo();
$this->error = $errorInfo[2]; $this->error = $errorInfo[2];
$this->errorno = $errorInfo[1]; $this->errorno = (int) $errorInfo[1];
$retval = false; $retval = false;
$is_error = true; $is_error = true;
break; break;
@ -554,7 +569,7 @@ class Database
if (!$stmt = $this->connection->prepare($sql)) { if (!$stmt = $this->connection->prepare($sql)) {
$errorInfo = $this->connection->errorInfo(); $errorInfo = $this->connection->errorInfo();
$this->error = $errorInfo[2]; $this->error = $errorInfo[2];
$this->errorno = $errorInfo[1]; $this->errorno = (int) $errorInfo[1];
$retval = false; $retval = false;
$is_error = true; $is_error = true;
break; break;
@ -574,7 +589,7 @@ class Database
if (!$stmt->execute()) { if (!$stmt->execute()) {
$errorInfo = $stmt->errorInfo(); $errorInfo = $stmt->errorInfo();
$this->error = $errorInfo[2]; $this->error = $errorInfo[2];
$this->errorno = $errorInfo[1]; $this->errorno = (int) $errorInfo[1];
$retval = false; $retval = false;
$is_error = true; $is_error = true;
} else { } else {
@ -709,7 +724,7 @@ class Database
} }
$this->error = $error; $this->error = $error;
$this->errorno = $errorno; $this->errorno = (int) $errorno;
} }
$this->profiler->stopRecording(); $this->profiler->stopRecording();
@ -741,8 +756,9 @@ class Database
* @return boolean Was the query successfull? False is returned only if an error occurred * @return boolean Was the query successfull? False is returned only if an error occurred
* @throws \Exception * @throws \Exception
*/ */
public function e($sql) public function e(string $sql): bool
{ {
$retval = false;
$this->profiler->startRecording('database_write'); $this->profiler->startRecording('database_write');
@ -804,13 +820,13 @@ class Database
/** /**
* Check if data exists * Check if data exists
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition array of fields for condition * @param array $condition Array of fields for condition
* *
* @return boolean Are there rows for that condition? * @return boolean Are there rows for that condition?
* @throws \Exception * @throws \Exception
*/ */
public function exists($table, $condition) public function exists(string $table, array $condition): bool
{ {
if (empty($table)) { if (empty($table)) {
return false; return false;
@ -850,10 +866,10 @@ class Database
* *
* @param string $sql SQL statement * @param string $sql SQL statement
* *
* @return array first row of query * @return array|bool first row of query or false on failure
* @throws \Exception * @throws \Exception
*/ */
public function fetchFirst($sql) public function fetchFirst(string $sql)
{ {
$params = DBA::getParam(func_get_args()); $params = DBA::getParam(func_get_args());
@ -875,7 +891,7 @@ class Database
* *
* @return int Number of rows * @return int Number of rows
*/ */
public function affectedRows() public function affectedRows(): int
{ {
return $this->affected_rows; return $this->affected_rows;
} }
@ -887,7 +903,7 @@ class Database
* *
* @return int Number of columns * @return int Number of columns
*/ */
public function columnCount($stmt) public function columnCount($stmt): int
{ {
if (!is_object($stmt)) { if (!is_object($stmt)) {
return 0; return 0;
@ -908,7 +924,7 @@ class Database
* *
* @return int Number of rows * @return int Number of rows
*/ */
public function numRows($stmt) public function numRows($stmt): int
{ {
if (!is_object($stmt)) { if (!is_object($stmt)) {
return 0; return 0;
@ -927,7 +943,7 @@ class Database
* *
* @param bool|PDOStatement|mysqli_stmt $stmt statement object * @param bool|PDOStatement|mysqli_stmt $stmt statement object
* *
* @return array|false current row * @return array|bool Current row or false on failure
*/ */
public function fetch($stmt) public function fetch($stmt)
{ {
@ -987,14 +1003,14 @@ class Database
/** /**
* Insert a row into a table. Field value objects will be cast as string. * Insert a row into a table. Field value objects will be cast as string.
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array * @param array $param parameter array
* @param int $duplicate_mode What to do on a duplicated entry * @param int $duplicate_mode What to do on a duplicated entry
* *
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public function insert($table, array $param, int $duplicate_mode = self::INSERT_DEFAULT) public function insert(string $table, array $param, int $duplicate_mode = self::INSERT_DEFAULT): bool
{ {
if (empty($table) || empty($param)) { if (empty($table) || empty($param)) {
$this->logger->info('Table and fields have to be set'); $this->logger->info('Table and fields have to be set');
@ -1003,7 +1019,7 @@ class Database
$param = $this->castFields($table, $param); $param = $this->castFields($table, $param);
$table_string = DBA::buildTableString($table); $table_string = DBA::buildTableString([$table]);
$fields_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], array_keys($param))); $fields_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], array_keys($param)));
@ -1038,13 +1054,12 @@ class Database
* Inserts a row with the provided data in the provided table. * Inserts a row with the provided data in the provided table.
* If the data corresponds to an existing row through a UNIQUE or PRIMARY index constraints, it updates the row instead. * If the data corresponds to an existing row through a UNIQUE or PRIMARY index constraints, it updates the row instead.
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array * @param array $param parameter array
*
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public function replace($table, array $param) public function replace(string $table, array $param): bool
{ {
if (empty($table) || empty($param)) { if (empty($table) || empty($param)) {
$this->logger->info('Table and fields have to be set'); $this->logger->info('Table and fields have to be set');
@ -1053,7 +1068,7 @@ class Database
$param = $this->castFields($table, $param); $param = $this->castFields($table, $param);
$table_string = DBA::buildTableString($table); $table_string = DBA::buildTableString([$table]);
$fields_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], array_keys($param))); $fields_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], array_keys($param)));
@ -1069,7 +1084,7 @@ class Database
* *
* @return integer Last inserted id * @return integer Last inserted id
*/ */
public function lastInsertId() public function lastInsertId(): int
{ {
switch ($this->driver) { switch ($this->driver) {
case self::PDO: case self::PDO:
@ -1087,12 +1102,11 @@ class Database
* *
* This function can be extended in the future to accept a table array as well. * This function can be extended in the future to accept a table array as well.
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
*
* @return boolean was the lock successful? * @return boolean was the lock successful?
* @throws \Exception * @throws \Exception
*/ */
public function lock($table) public function lock(string $table): bool
{ {
// See here: https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html // See here: https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html
if ($this->driver == self::PDO) { if ($this->driver == self::PDO) {
@ -1102,7 +1116,7 @@ class Database
$this->connection->autocommit(false); $this->connection->autocommit(false);
} }
$success = $this->e("LOCK TABLES " . DBA::buildTableString($table) . " WRITE"); $success = $this->e("LOCK TABLES " . DBA::buildTableString([$table]) . " WRITE");
if ($this->driver == self::PDO) { if ($this->driver == self::PDO) {
$this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares); $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares);
@ -1126,7 +1140,7 @@ class Database
* @return boolean was the unlock successful? * @return boolean was the unlock successful?
* @throws \Exception * @throws \Exception
*/ */
public function unlock() public function unlock(): bool
{ {
// See here: https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html // See here: https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html
$this->performCommit(); $this->performCommit();
@ -1177,7 +1191,12 @@ class Database
return true; return true;
} }
protected function performCommit() /**
* Performs the commit
*
* @return boolean Was the command executed successfully?
*/
protected function performCommit(): bool
{ {
switch ($this->driver) { switch ($this->driver) {
case self::PDO: case self::PDO:
@ -1199,7 +1218,7 @@ class Database
* *
* @return boolean Was the command executed successfully? * @return boolean Was the command executed successfully?
*/ */
public function commit() public function commit(): bool
{ {
if (!$this->performCommit()) { if (!$this->performCommit()) {
return false; return false;
@ -1213,7 +1232,7 @@ class Database
* *
* @return boolean Was the command executed successfully? * @return boolean Was the command executed successfully?
*/ */
public function rollback() public function rollback(): bool
{ {
$ret = false; $ret = false;
@ -1230,6 +1249,7 @@ class Database
$ret = $this->connection->rollback(); $ret = $this->connection->rollback();
break; break;
} }
$this->in_transaction = false; $this->in_transaction = false;
return $ret; return $ret;
} }
@ -1243,14 +1263,14 @@ class Database
* @return boolean was the delete successful? * @return boolean was the delete successful?
* @throws \Exception * @throws \Exception
*/ */
public function delete($table, array $conditions) public function delete(string $table, array $conditions): bool
{ {
if (empty($table) || empty($conditions)) { if (empty($table) || empty($conditions)) {
$this->logger->info('Table and conditions have to be set'); $this->logger->info('Table and conditions have to be set');
return false; return false;
} }
$table_string = DBA::buildTableString($table); $table_string = DBA::buildTableString([$table]);
$condition_string = DBA::buildCondition($conditions); $condition_string = DBA::buildCondition($conditions);
@ -1280,7 +1300,7 @@ class Database
* Only set $old_fields to a boolean value when you are sure that you will update a single row. * Only set $old_fields to a boolean value when you are sure that you will update a single row.
* When you set $old_fields to "true" then $fields must contain all relevant fields! * When you set $old_fields to "true" then $fields must contain all relevant fields!
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields contains the fields that are updated * @param array $fields contains the fields that are updated
* @param array $condition condition array with the key values * @param array $condition condition array with the key values
* @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate, false = don't update identical fields) * @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate, false = don't update identical fields)
@ -1288,8 +1308,9 @@ class Database
* *
* @return boolean was the update successfull? * @return boolean was the update successfull?
* @throws \Exception * @throws \Exception
* @todo Implement "bool $update_on_duplicate" to avoid mixed type for $old_fields
*/ */
public function update($table, $fields, $condition, $old_fields = [], $params = []) public function update(string $table, array $fields, array $condition, $old_fields = [], array $params = [])
{ {
if (empty($table) || empty($fields) || empty($condition)) { if (empty($table) || empty($fields) || empty($condition)) {
$this->logger->info('Table, fields and condition have to be set'); $this->logger->info('Table, fields and condition have to be set');
@ -1322,7 +1343,7 @@ class Database
$fields = $this->castFields($table, $fields); $fields = $this->castFields($table, $fields);
$table_string = DBA::buildTableString($table); $table_string = DBA::buildTableString([$table]);
$condition_string = DBA::buildCondition($condition); $condition_string = DBA::buildCondition($condition);
@ -1345,16 +1366,16 @@ class Database
/** /**
* Retrieve a single record from a table and returns it in an associative array * Retrieve a single record from a table and returns it in an associative array
* *
* @param string|array $table * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields * @param array $fields Array of selected fields, empty for all
* @param array $condition * @param array $condition Array of fields for condition
* @param array $params * @param array $params Array of several parameters
* *
* @return bool|array * @return bool|array
* @throws \Exception * @throws \Exception
* @see $this->select * @see $this->select
*/ */
public function selectFirst($table, array $fields = [], array $condition = [], $params = []) public function selectFirst(string $table, array $fields = [], array $condition = [], array $params = [])
{ {
$params['limit'] = 1; $params['limit'] = 1;
$result = $this->select($table, $fields, $condition, $params); $result = $this->select($table, $fields, $condition, $params);
@ -1371,16 +1392,15 @@ class Database
/** /**
* Select rows from a table and fills an array with the data * Select rows from a table and fills an array with the data
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields Array of selected fields, empty for all * @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition * @param array $condition Array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
*
* @return array Data array * @return array Data array
* @throws \Exception * @throws \Exception
* @see self::select * @see self::select
*/ */
public function selectToArray($table, array $fields = [], array $condition = [], array $params = []) public function selectToArray(string $table, array $fields = [], array $condition = [], array $params = [])
{ {
return $this->toArray($this->select($table, $fields, $condition, $params)); return $this->toArray($this->select($table, $fields, $condition, $params));
} }
@ -1390,9 +1410,9 @@ class Database
* *
* @param array $fields * @param array $fields
* @param array $options * @param array $options
* @return array * @return array Escaped fields
*/ */
private function escapeFields(array $fields, array $options) private function escapeFields(array $fields, array $options): array
{ {
// In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist. // In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist.
// This needs to done to apply the "ANY_VALUE(...)" treatment from below to them. // This needs to done to apply the "ANY_VALUE(...)" treatment from below to them.
@ -1446,14 +1466,14 @@ class Database
* *
* $data = DBA::select($table, $fields, $condition, $params); * $data = DBA::select($table, $fields, $condition, $params);
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $fields Array of selected fields, empty for all * @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition * @param array $condition Array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public function select($table, array $fields = [], array $condition = [], array $params = []) public function select(string $table, array $fields = [], array $condition = [], array $params = [])
{ {
if (empty($table)) { if (empty($table)) {
return false; return false;
@ -1466,7 +1486,7 @@ class Database
$select_string = '*'; $select_string = '*';
} }
$table_string = DBA::buildTableString($table); $table_string = DBA::buildTableString([$table]);
$condition_string = DBA::buildCondition($condition); $condition_string = DBA::buildCondition($condition);
@ -1486,11 +1506,11 @@ class Database
/** /**
* Counts the rows from a table satisfying the provided condition * Counts the rows from a table satisfying the provided condition
* *
* @param string|array $table Table name or array [schema => table] * @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition Array of fields for condition * @param array $condition Array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
* *
* @return int * @return int Count of rows
* *
* Example: * Example:
* $table = "post"; * $table = "post";
@ -1502,13 +1522,13 @@ class Database
* $count = DBA::count($table, $condition); * $count = DBA::count($table, $condition);
* @throws \Exception * @throws \Exception
*/ */
public function count($table, array $condition = [], array $params = []) public function count(string $table, array $condition = [], array $params = []): int
{ {
if (empty($table)) { if (empty($table)) {
return false; throw new InvalidArgumentException('Parameter "table" cannot be empty.');
} }
$table_string = DBA::buildTableString($table); $table_string = DBA::buildTableString([$table]);
$condition_string = DBA::buildCondition($condition); $condition_string = DBA::buildCondition($condition);
@ -1541,7 +1561,7 @@ class Database
* *
* @return array Data array * @return array Data array
*/ */
public function toArray($stmt, $do_close = true, int $count = 0) public function toArray($stmt, bool $do_close = true, int $count = 0): array
{ {
if (is_bool($stmt)) { if (is_bool($stmt)) {
return []; return [];
@ -1569,7 +1589,8 @@ class Database
* @param array $fields * @param array $fields
* @return array casted fields * @return array casted fields
*/ */
public function castFields(string $table, array $fields) { public function castFields(string $table, array $fields): array
{
// When there is no data, we don't need to do something // When there is no data, we don't need to do something
if (empty($fields)) { if (empty($fields)) {
return $fields; return $fields;
@ -1595,7 +1616,7 @@ class Database
return $fields; return $fields;
} }
foreach(array_keys($fields) as $field) { foreach (array_keys($fields) as $field) {
if (!empty($views[$table]['fields'][$field])) { if (!empty($views[$table]['fields'][$field])) {
$viewdef = $views[$table]['fields'][$field]; $viewdef = $views[$table]['fields'][$field];
if (!empty($tables[$viewdef[0]]['fields'][$viewdef[1]]['type'])) { if (!empty($tables[$viewdef[0]]['fields'][$viewdef[1]]['type'])) {
@ -1632,7 +1653,7 @@ class Database
* *
* @return string Error number (0 if no error) * @return string Error number (0 if no error)
*/ */
public function errorNo() public function errorNo(): int
{ {
return $this->errorno; return $this->errorno;
} }
@ -1642,7 +1663,7 @@ class Database
* *
* @return string Error message ('' if no error) * @return string Error message ('' if no error)
*/ */
public function errorMessage() public function errorMessage(): string
{ {
return $this->error; return $this->error;
} }
@ -1654,7 +1675,7 @@ class Database
* *
* @return boolean was the close successful? * @return boolean was the close successful?
*/ */
public function close($stmt) public function close($stmt): bool
{ {
$this->profiler->startRecording('database'); $this->profiler->startRecording('database');
@ -1696,7 +1717,7 @@ class Database
* 'amount' => Number of concurrent database processes * 'amount' => Number of concurrent database processes
* @throws \Exception * @throws \Exception
*/ */
public function processlist() public function processlist(): array
{ {
$ret = $this->p("SHOW PROCESSLIST"); $ret = $this->p("SHOW PROCESSLIST");
$data = $this->toArray($ret); $data = $this->toArray($ret);
@ -1727,7 +1748,8 @@ class Database
* Fetch a database variable * Fetch a database variable
* *
* @param string $name * @param string $name
* @return string content * @return string|null content or null if inexistent
* @throws \Exception
*/ */
public function getVariable(string $name) public function getVariable(string $name)
{ {
@ -1739,10 +1761,9 @@ class Database
* Checks if $array is a filled array with at least one entry. * Checks if $array is a filled array with at least one entry.
* *
* @param mixed $array A filled array with at least one entry * @param mixed $array A filled array with at least one entry
*
* @return boolean Whether $array is a filled array or an object with rows * @return boolean Whether $array is a filled array or an object with rows
*/ */
public function isResult($array) public function isResult($array): bool
{ {
// It could be a return value from an update statement // It could be a return value from an update statement
if (is_bool($array)) { if (is_bool($array)) {
@ -1762,10 +1783,9 @@ class Database
* @param mixed $value Array value * @param mixed $value Array value
* @param string $key Array key * @param string $key Array key
* @param boolean $add_quotation add quotation marks for string values * @param boolean $add_quotation add quotation marks for string values
*
* @return void * @return void
*/ */
private function escapeArrayCallback(&$value, $key, $add_quotation) private function escapeArrayCallback(&$value, string $key, bool $add_quotation)
{ {
if (!$add_quotation) { if (!$add_quotation) {
if (is_bool($value)) { if (is_bool($value)) {
@ -1790,10 +1810,9 @@ class Database
* *
* @param mixed $arr Array with values to be escaped * @param mixed $arr Array with values to be escaped
* @param boolean $add_quotation add quotation marks for string values * @param boolean $add_quotation add quotation marks for string values
*
* @return void * @return void
*/ */
public function escapeArray(&$arr, $add_quotation = false) public function escapeArray(&$arr, bool $add_quotation = false)
{ {
array_walk($arr, [$this, 'escapeArrayCallback'], $add_quotation); array_walk($arr, [$this, 'escapeArrayCallback'], $add_quotation);
} }
@ -1801,13 +1820,14 @@ class Database
/** /**
* Replaces a string in the provided fields of the provided table * Replaces a string in the provided fields of the provided table
* *
* @param string $table_name * @param string $table Table name
* @param array $fields List of field names in the provided table * @param array $fields List of field names in the provided table
* @param string $search * @param string $search String to search for
* @param string $replace * @param string $replace String to replace with
* @return void
* @throws \Exception * @throws \Exception
*/ */
public function replaceInTableFields(string $table_name, array $fields, string $search, string $replace) public function replaceInTableFields(string $table, array $fields, string $search, string $replace)
{ {
$search = $this->escape($search); $search = $this->escape($search);
$replace = $this->escape($replace); $replace = $this->escape($replace);
@ -1820,9 +1840,10 @@ class Database
$upds = implode(', ', $upd); $upds = implode(', ', $upd);
$r = $this->e(sprintf("UPDATE %s SET %s;", $table_name, $upds)); $r = $this->e(sprintf("UPDATE %s SET %s;", DBA::quoteIdentifier($table), $upds));
if (!$this->isResult($r)) { if (!$this->isResult($r)) {
throw new \RuntimeException("Failed updating `$table_name`: " . $this->errorMessage()); throw new \RuntimeException("Failed updating `$table`: " . $this->errorMessage());
} }
} }
} }

View file

@ -133,7 +133,7 @@ class PostUpdate
} }
$max_item_delivery_data = DBA::selectFirst('item-delivery-data', ['iid'], ['queue_count > 0 OR queue_done > 0'], ['order' => ['iid']]); $max_item_delivery_data = DBA::selectFirst('item-delivery-data', ['iid'], ['queue_count > 0 OR queue_done > 0'], ['order' => ['iid']]);
$max_iid = $max_item_delivery_data['iid']; $max_iid = $max_item_delivery_data['iid'] ?? 0;
Logger::info('Start update1297 with max iid: ' . $max_iid); Logger::info('Start update1297 with max iid: ' . $max_iid);

View file

@ -39,12 +39,12 @@ class View
* On first pass, defines DB_UPDATE_VERSION constant. * On first pass, defines DB_UPDATE_VERSION constant.
* *
* @see static/dbview.config.php * @see static/dbview.config.php
* @param boolean $with_addons_structure Whether to tack on addons additional tables
* @param string $basePath The base path of this application * @param string $basePath The base path of this application
* @param boolean $with_addons_structure Whether to tack on addons additional tables
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function definition($basePath = '', $with_addons_structure = true) public static function definition(string $basePath = '', bool $with_addons_structure = true): array
{ {
if (!self::$definition) { if (!self::$definition) {
if (empty($basePath)) { if (empty($basePath)) {
@ -75,6 +75,13 @@ class View
return $definition; return $definition;
} }
/**
* Creates a view
*
* @param bool $verbose Whether to show SQL statements
* @param bool $action Whether to execute SQL statements
* @return void
*/
public static function create(bool $verbose, bool $action) public static function create(bool $verbose, bool $action)
{ {
// Delete previously used views that aren't used anymore // Delete previously used views that aren't used anymore
@ -94,11 +101,17 @@ class View
$definition = self::definition(); $definition = self::definition();
foreach ($definition as $name => $structure) { foreach ($definition as $name => $structure) {
self::createview($name, $structure, $verbose, $action); self::createView($name, $structure, $verbose, $action);
} }
} }
public static function printStructure($basePath) /**
* Prints view structure
*
* @param string $basePath Base path
* @return void
*/
public static function printStructure(string $basePath)
{ {
$database = self::definition($basePath, false); $database = self::definition($basePath, false);
@ -112,12 +125,21 @@ class View
} }
} }
private static function createview($name, $structure, $verbose, $action) /**
* Creates view
*
* @param string $name Name of view
* @param array $structure Structure of view
* @param bool $verbose Whether to show SQL statements
* @param bool $action Whether to execute SQL statements
* @return bool Whether execution went fine
*/
private static function createView(string $name, array $structure, bool $verbose, bool $action): bool
{ {
$r = true; $r = true;
$sql_rows = []; $sql_rows = [];
foreach ($structure["fields"] as $fieldname => $origin) { foreach ($structure['fields'] as $fieldname => $origin) {
if (is_string($origin)) { if (is_string($origin)) {
$sql_rows[] = $origin . " AS `" . DBA::escape($fieldname) . "`"; $sql_rows[] = $origin . " AS `" . DBA::escape($fieldname) . "`";
} elseif (is_array($origin) && (sizeof($origin) == 2)) { } elseif (is_array($origin) && (sizeof($origin) == 2)) {
@ -159,9 +181,9 @@ class View
* @param string $view * @param string $view
* @return boolean "true" if it's a view * @return boolean "true" if it's a view
*/ */
private static function isView(string $view) private static function isView(string $view): bool
{ {
$status = DBA::selectFirst(['INFORMATION_SCHEMA' => 'TABLES'], ['TABLE_TYPE'], $status = DBA::selectFirst('INFORMATION_SCHEMA.TABLES', ['TABLE_TYPE'],
['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_NAME' => $view]); ['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_NAME' => $view]);
if (empty($status['TABLE_TYPE'])) { if (empty($status['TABLE_TYPE'])) {
@ -177,9 +199,9 @@ class View
* @param string $table * @param string $table
* @return boolean "true" if it's a table * @return boolean "true" if it's a table
*/ */
private static function isTable(string $table) private static function isTable(string $table): bool
{ {
$status = DBA::selectFirst(['INFORMATION_SCHEMA' => 'TABLES'], ['TABLE_TYPE'], $status = DBA::selectFirst('INFORMATION_SCHEMA.TABLES', ['TABLE_TYPE'],
['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_NAME' => $table]); ['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_NAME' => $table]);
if (empty($status['TABLE_TYPE'])) { if (empty($status['TABLE_TYPE'])) {

View file

@ -57,7 +57,7 @@ class Account extends BaseFactory
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws ImagickException|HTTPException\NotFoundException * @throws ImagickException|HTTPException\NotFoundException
*/ */
public function createFromContactId(int $contactId, $uid = 0): \Friendica\Object\Api\Mastodon\Account public function createFromContactId(int $contactId, int $uid = 0): \Friendica\Object\Api\Mastodon\Account
{ {
$contact = Contact::getById($contactId, ['uri-id']); $contact = Contact::getById($contactId, ['uri-id']);
if (empty($contact)) { if (empty($contact)) {
@ -74,7 +74,7 @@ class Account extends BaseFactory
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws ImagickException|HTTPException\NotFoundException * @throws ImagickException|HTTPException\NotFoundException
*/ */
public function createFromUriId(int $contactUriId, $uid = 0): \Friendica\Object\Api\Mastodon\Account public function createFromUriId(int $contactUriId, int $uid = 0): \Friendica\Object\Api\Mastodon\Account
{ {
$account = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); $account = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]);
if (empty($account)) { if (empty($account)) {

View file

@ -190,7 +190,7 @@ class Status extends BaseFactory
*/ */
public function createFromMailId(int $id): \Friendica\Object\Api\Mastodon\Status public function createFromMailId(int $id): \Friendica\Object\Api\Mastodon\Status
{ {
$item = ActivityPub\Transmitter::ItemArrayFromMail($id, true); $item = ActivityPub\Transmitter::getItemArrayFromMail($id, true);
if (empty($item)) { if (empty($item)) {
$this->mstdnErrorFactory->RecordNotFound(); $this->mstdnErrorFactory->RecordNotFound();
} }

View file

@ -70,6 +70,7 @@ class Status extends BaseFactory
/** /**
* @param int $uriId Uri-ID of the item * @param int $uriId Uri-ID of the item
* @param int $uid Item user * @param int $uid Item user
* @param bool $include_entities Whether to include entities
* *
* @return \Friendica\Object\Api\Twitter\Status * @return \Friendica\Object\Api\Twitter\Status
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
@ -90,12 +91,13 @@ class Status extends BaseFactory
/** /**
* @param int $uriId Uri-ID of the item * @param int $uriId Uri-ID of the item
* @param int $uid Item user * @param int $uid Item user
* @param bool $include_entities Whether to include entities
* *
* @return \Friendica\Object\Api\Twitter\Status * @return \Friendica\Object\Api\Twitter\Status
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws ImagickException|HTTPException\NotFoundException * @throws ImagickException|HTTPException\NotFoundException
*/ */
public function createFromUriId(int $uriId, $uid = 0, $include_entities = false): \Friendica\Object\Api\Twitter\Status public function createFromUriId(int $uriId, int $uid = 0, bool $include_entities = false): \Friendica\Object\Api\Twitter\Status
{ {
$fields = ['parent-uri-id', 'uri-id', 'uid', 'author-id', 'author-link', 'author-network', 'owner-id', 'causer-id', $fields = ['parent-uri-id', 'uri-id', 'uid', 'author-id', 'author-link', 'author-network', 'owner-id', 'causer-id',
'starred', 'app', 'title', 'body', 'raw-body', 'created', 'network','post-reason', 'language', 'gravity', 'starred', 'app', 'title', 'body', 'raw-body', 'created', 'network','post-reason', 'language', 'gravity',
@ -110,6 +112,7 @@ class Status extends BaseFactory
/** /**
* @param array $item item array * @param array $item item array
* @param int $uid Item user * @param int $uid Item user
* @param bool $include_entities Whether to include entities
* *
* @return \Friendica\Object\Api\Twitter\Status * @return \Friendica\Object\Api\Twitter\Status
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException

View file

@ -51,7 +51,7 @@ class User extends BaseFactory
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public function createFromContactId(int $contactId, $uid = 0, $skip_status = true, $include_user_entities = true) public function createFromContactId(int $contactId, int $uid = 0, bool $skip_status = true, bool $include_user_entities = true)
{ {
$cdata = Contact::getPublicAndUserContactID($contactId, $uid); $cdata = Contact::getPublicAndUserContactID($contactId, $uid);
if (!empty($cdata)) { if (!empty($cdata)) {
@ -78,7 +78,7 @@ class User extends BaseFactory
return new \Friendica\Object\Api\Twitter\User($publicContact, $apcontact, $userContact, $status, $include_user_entities); return new \Friendica\Object\Api\Twitter\User($publicContact, $apcontact, $userContact, $status, $include_user_entities);
} }
public function createFromUserId(int $uid, $skip_status = true, $include_user_entities = true) public function createFromUserId(int $uid, bool $skip_status = true, bool $include_user_entities = true)
{ {
return $this->createFromContactId(Contact::getPublicIdByUserId($uid), $uid, $skip_status, $include_user_entities); return $this->createFromContactId(Contact::getPublicIdByUserId($uid), $uid, $skip_status, $include_user_entities);
} }

View file

@ -57,7 +57,7 @@ class LegacyModule extends BaseModule
* @param string $file_path * @param string $file_path
* @throws \Exception * @throws \Exception
*/ */
private function setModuleFile($file_path) private function setModuleFile(string $file_path)
{ {
if (!is_readable($file_path)) { if (!is_readable($file_path)) {
throw new \Exception(DI::l10n()->t('Legacy module file not found: %s', $file_path)); throw new \Exception(DI::l10n()->t('Legacy module file not found: %s', $file_path));
@ -87,7 +87,7 @@ class LegacyModule extends BaseModule
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
private function runModuleFunction(string $function_suffix) private function runModuleFunction(string $function_suffix): string
{ {
$function_name = $this->moduleName . '_' . $function_suffix; $function_name = $this->moduleName . '_' . $function_suffix;

View file

@ -48,7 +48,7 @@ class APContact
* @param string $addr Address * @param string $addr Address
* @return array webfinger data * @return array webfinger data
*/ */
private static function fetchWebfingerData(string $addr) private static function fetchWebfingerData(string $addr): array
{ {
$addr_parts = explode('@', $addr); $addr_parts = explode('@', $addr);
if (count($addr_parts) != 2) { if (count($addr_parts) != 2) {
@ -116,15 +116,16 @@ class APContact
* @return array profile array * @return array profile array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
* @todo Rewrite parameter $update to avoid true|false|null (boolean is binary, null adds a third case)
*/ */
public static function getByURL($url, $update = null) public static function getByURL(string $url, $update = null): array
{ {
if (empty($url) || Network::isUrlBlocked($url)) { if (empty($url) || Network::isUrlBlocked($url)) {
Logger::info('Domain is blocked', ['url' => $url]); Logger::info('Domain is blocked', ['url' => $url]);
return []; return [];
} }
$fetched_contact = false; $fetched_contact = [];
if (empty($update)) { if (empty($update)) {
if (is_null($update)) { if (is_null($update)) {
@ -220,14 +221,14 @@ class APContact
$apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type')); $apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type'));
$apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@id'); $apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@id');
$apcontact['followers'] = JsonLD::fetchElement($compacted, 'as:followers', '@id'); $apcontact['followers'] = JsonLD::fetchElement($compacted, 'as:followers', '@id');
$apcontact['inbox'] = JsonLD::fetchElement($compacted, 'ldp:inbox', '@id'); $apcontact['inbox'] = (JsonLD::fetchElement($compacted, 'ldp:inbox', '@id') ?? '');
self::unarchiveInbox($apcontact['inbox'], false); self::unarchiveInbox($apcontact['inbox'], false);
$apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id'); $apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id');
$apcontact['sharedinbox'] = ''; $apcontact['sharedinbox'] = '';
if (!empty($compacted['as:endpoints'])) { if (!empty($compacted['as:endpoints'])) {
$apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id'); $apcontact['sharedinbox'] = (JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id') ?? '');
self::unarchiveInbox($apcontact['sharedinbox'], true); self::unarchiveInbox($apcontact['sharedinbox'], true);
} }
@ -241,9 +242,10 @@ class APContact
$apcontact['name'] = $apcontact['nick']; $apcontact['name'] = $apcontact['nick'];
} }
$apcontact['about'] = HTML::toBBCode(JsonLD::fetchElement($compacted, 'as:summary', '@value')); $apcontact['about'] = HTML::toBBCode(JsonLD::fetchElement($compacted, 'as:summary', '@value') ?? '');
$ims = JsonLD::fetchElementArray($compacted, 'vcard:hasInstantMessage'); $ims = JsonLD::fetchElementArray($compacted, 'vcard:hasInstantMessage');
if (!empty($ims)) { if (!empty($ims)) {
foreach ($ims as $link) { foreach ($ims as $link) {
if (substr($link, 0, 5) == 'xmpp:') { if (substr($link, 0, 5) == 'xmpp:') {
@ -525,8 +527,9 @@ class APContact
* *
* @param string $url inbox url * @param string $url inbox url
* @param boolean $shared Shared Inbox * @param boolean $shared Shared Inbox
* @return void
*/ */
private static function unarchiveInbox($url, $shared) private static function unarchiveInbox(string $url, bool $shared)
{ {
if (empty($url)) { if (empty($url)) {
return; return;

View file

@ -44,7 +44,7 @@ class Attach
* @return array field list * @return array field list
* @throws \Exception * @throws \Exception
*/ */
private static function getFields() private static function getFields(): array
{ {
$allfields = DBStructure::definition(DI::app()->getBasePath(), false); $allfields = DBStructure::definition(DI::app()->getBasePath(), false);
$fields = array_keys($allfields['attach']['fields']); $fields = array_keys($allfields['attach']['fields']);
@ -59,7 +59,7 @@ class Attach
* @param array $conditions Array of fields for conditions * @param array $conditions Array of fields for conditions
* @param array $params Array of several parameters * @param array $params Array of several parameters
* *
* @return array * @return array|bool
* *
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::selectToArray * @see \Friendica\Database\DBA::selectToArray
@ -102,7 +102,7 @@ class Attach
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function exists(array $conditions) public static function exists(array $conditions): bool
{ {
return DBA::exists('attach', $conditions); return DBA::exists('attach', $conditions);
} }
@ -117,7 +117,7 @@ class Attach
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::select * @see \Friendica\Database\DBA::select
*/ */
public static function getById($id) public static function getById(int $id)
{ {
return self::selectFirst([], ['id' => $id]); return self::selectFirst([], ['id' => $id]);
} }
@ -132,7 +132,7 @@ class Attach
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::select * @see \Friendica\Database\DBA::select
*/ */
public static function getByIdWithPermission($id) public static function getByIdWithPermission(int $id)
{ {
$r = self::selectFirst(['uid'], ['id' => $id]); $r = self::selectFirst(['uid'], ['id' => $id]);
if ($r === false) { if ($r === false) {
@ -156,10 +156,10 @@ class Attach
* *
* @param array $item Attachment data. Needs at least 'id', 'backend-class', 'backend-ref' * @param array $item Attachment data. Needs at least 'id', 'backend-class', 'backend-ref'
* *
* @return string file data * @return string|null file data or null on failure
* @throws \Exception * @throws \Exception
*/ */
public static function getData($item) public static function getData(array $item)
{ {
if (!empty($item['data'])) { if (!empty($item['data'])) {
return $item['data']; return $item['data'];
@ -195,10 +195,10 @@ class Attach
* @param string $deny_cid Permissions, denied contacts.optional, default = '' * @param string $deny_cid Permissions, denied contacts.optional, default = ''
* @param string $deny_gid Permissions, denied greoup.optional, default = '' * @param string $deny_gid Permissions, denied greoup.optional, default = ''
* *
* @return boolean/integer Row id on success, False on errors * @return boolean|integer Row id on success, False on errors
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function store($data, $uid, $filename, $filetype = '' , $filesize = null, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') public static function store(string $data, int $uid, string $filename, string $filetype = '' , int $filesize = null, string $allow_cid = '', string $allow_gid = '', string $deny_cid = '', string $deny_gid = '')
{ {
if ($filetype === '') { if ($filetype === '') {
$filetype = Mimetype::getContentType($filename); $filetype = Mimetype::getContentType($filename);
@ -241,17 +241,17 @@ class Attach
/** /**
* Store new file metadata in db and binary in default backend from existing file * Store new file metadata in db and binary in default backend from existing file
* *
* @param $src * @param string $src Source file name
* @param $uid * @param int $uid User id
* @param string $filename * @param string $filename Optional file name
* @param string $allow_cid * @param string $allow_cid
* @param string $allow_gid * @param string $allow_gid
* @param string $deny_cid * @param string $deny_cid
* @param string $deny_gid * @param string $deny_gid
* @return boolean True on success * @return boolean|int Insert id or false on failure
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function storeFile($src, $uid, $filename = '', $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') public static function storeFile(string $src, int $uid, string $filename = '', string $allow_cid = '', string $allow_gid = '', string $deny_cid = '', string $deny_gid = '')
{ {
if ($filename === '') { if ($filename === '') {
$filename = basename($src); $filename = basename($src);
@ -276,7 +276,7 @@ class Attach
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @see \Friendica\Database\DBA::update * @see \Friendica\Database\DBA::update
*/ */
public static function update($fields, $conditions, Image $img = null, array $old_fields = []) public static function update(array $fields, array $conditions, Image $img = null, array $old_fields = []): bool
{ {
if (!is_null($img)) { if (!is_null($img)) {
// get items to update // get items to update
@ -311,7 +311,7 @@ class Attach
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::delete * @see \Friendica\Database\DBA::delete
*/ */
public static function delete(array $conditions, array $options = []) public static function delete(array $conditions, array $options = []): bool
{ {
// get items to delete data info // get items to delete data info
$items = self::selectToArray(['backend-class','backend-ref'], $conditions); $items = self::selectToArray(['backend-class','backend-ref'], $conditions);

View file

@ -119,7 +119,7 @@ class Contact
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function selectToArray(array $fields = [], array $condition = [], array $params = []) public static function selectToArray(array $fields = [], array $condition = [], array $params = []): array
{ {
return DBA::selectToArray('contact', $fields, $condition, $params); return DBA::selectToArray('contact', $fields, $condition, $params);
} }
@ -128,7 +128,7 @@ class Contact
* @param array $fields Array of selected fields, empty for all * @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition * @param array $condition Array of fields for condition
* @param array $params Array of several parameters * @param array $params Array of several parameters
* @return array * @return array|bool
* @throws \Exception * @throws \Exception
*/ */
public static function selectFirst(array $fields = [], array $condition = [], array $params = []) public static function selectFirst(array $fields = [], array $condition = [], array $params = [])
@ -148,7 +148,7 @@ class Contact
* @return int id of the created contact * @return int id of the created contact
* @throws \Exception * @throws \Exception
*/ */
public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT) public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT): int
{ {
if (!empty($fields['baseurl']) && empty($fields['gsid'])) { if (!empty($fields['baseurl']) && empty($fields['gsid'])) {
$fields['gsid'] = GServer::getID($fields['baseurl'], true); $fields['gsid'] = GServer::getID($fields['baseurl'], true);
@ -187,6 +187,7 @@ class Contact
* *
* @return boolean was the update successfull? * @return boolean was the update successfull?
* @throws \Exception * @throws \Exception
* @todo Let's get rid of boolean type of $old_fields
*/ */
public static function update(array $fields, array $condition, $old_fields = []) public static function update(array $fields, array $condition, $old_fields = [])
{ {
@ -204,7 +205,7 @@ class Contact
* @return array|boolean Contact record if it exists, false otherwise * @return array|boolean Contact record if it exists, false otherwise
* @throws \Exception * @throws \Exception
*/ */
public static function getById($id, $fields = []) public static function getById(int $id, array $fields = [])
{ {
return DBA::selectFirst('contact', $fields, ['id' => $id]); return DBA::selectFirst('contact', $fields, ['id' => $id]);
} }
@ -217,7 +218,7 @@ class Contact
* @return array|boolean Contact record if it exists, false otherwise * @return array|boolean Contact record if it exists, false otherwise
* @throws \Exception * @throws \Exception
*/ */
public static function getByUriId($uri_id, $fields = []) public static function getByUriId(int $uri_id, array $fields = [])
{ {
return DBA::selectFirst('contact', $fields, ['uri-id' => $uri_id], ['order' => ['uid']]); return DBA::selectFirst('contact', $fields, ['uri-id' => $uri_id], ['order' => ['uid']]);
} }
@ -231,7 +232,7 @@ class Contact
* @param integer $uid User ID of the contact * @param integer $uid User ID of the contact
* @return array contact array * @return array contact array
*/ */
public static function getByURL(string $url, $update = null, array $fields = [], int $uid = 0) public static function getByURL(string $url, $update = null, array $fields = [], int $uid = 0): array
{ {
if ($update || is_null($update)) { if ($update || is_null($update)) {
$cid = self::getIdForURL($url, $uid, $update); $cid = self::getIdForURL($url, $uid, $update);
@ -302,7 +303,7 @@ class Contact
* @param array $fields Field list * @param array $fields Field list
* @return array contact array * @return array contact array
*/ */
public static function getByURLForUser(string $url, int $uid = 0, $update = false, array $fields = []) public static function getByURLForUser(string $url, int $uid = 0, $update = false, array $fields = []): array
{ {
if ($uid != 0) { if ($uid != 0) {
$contact = self::getByURL($url, $update, $fields, $uid); $contact = self::getByURL($url, $update, $fields, $uid);
@ -333,7 +334,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function isFollower($cid, $uid) public static function isFollower(int $cid, int $uid): bool
{ {
if (Contact\User::isBlocked($cid, $uid)) { if (Contact\User::isBlocked($cid, $uid)) {
return false; return false;
@ -358,7 +359,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function isFollowerByURL($url, $uid) public static function isFollowerByURL(string $url, uid $uid): bool
{ {
$cid = self::getIdForURL($url, $uid); $cid = self::getIdForURL($url, $uid);
@ -370,16 +371,16 @@ class Contact
} }
/** /**
* Tests if the given user follow the given contact * Tests if the given user shares with the given contact
* *
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
* *
* @return boolean is the contact url being followed? * @return boolean is the contact sharing with given user?
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function isSharing($cid, $uid) public static function isSharing(int $cid, int $uid): bool
{ {
if (Contact\User::isBlocked($cid, $uid)) { if (Contact\User::isBlocked($cid, $uid)) {
return false; return false;
@ -404,7 +405,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function isSharingByURL($url, $uid) public static function isSharingByURL(string $url, int $uid): bool
{ {
$cid = self::getIdForURL($url, $uid); $cid = self::getIdForURL($url, $uid);
@ -425,7 +426,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function getBasepath($url, $dont_update = false) public static function getBasepath(string $url, bool $dont_update = false): string
{ {
$contact = DBA::selectFirst('contact', ['id', 'baseurl'], ['uid' => 0, 'nurl' => Strings::normaliseLink($url)]); $contact = DBA::selectFirst('contact', ['id', 'baseurl'], ['uid' => 0, 'nurl' => Strings::normaliseLink($url)]);
if (!DBA::isResult($contact)) { if (!DBA::isResult($contact)) {
@ -459,7 +460,7 @@ class Contact
* *
* @return boolean Is it the same server? * @return boolean Is it the same server?
*/ */
public static function isLocal($url) public static function isLocal(string $url): bool
{ {
if (!parse_url($url, PHP_URL_SCHEME)) { if (!parse_url($url, PHP_URL_SCHEME)) {
$addr_parts = explode('@', $url); $addr_parts = explode('@', $url);
@ -476,7 +477,7 @@ class Contact
* *
* @return boolean Is it the same server? * @return boolean Is it the same server?
*/ */
public static function isLocalById(int $cid) public static function isLocalById(int $cid): bool
{ {
$contact = DBA::selectFirst('contact', ['url', 'baseurl'], ['id' => $cid]); $contact = DBA::selectFirst('contact', ['url', 'baseurl'], ['id' => $cid]);
if (!DBA::isResult($contact)) { if (!DBA::isResult($contact)) {
@ -500,7 +501,7 @@ class Contact
* @return integer|boolean Public contact id for given user id * @return integer|boolean Public contact id for given user id
* @throws \Exception * @throws \Exception
*/ */
public static function getPublicIdByUserId($uid) public static function getPublicIdByUserId(int $uid)
{ {
$self = DBA::selectFirst('contact', ['url'], ['self' => true, 'uid' => $uid]); $self = DBA::selectFirst('contact', ['url'], ['self' => true, 'uid' => $uid]);
if (!DBA::isResult($self)) { if (!DBA::isResult($self)) {
@ -519,7 +520,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function getPublicAndUserContactID($cid, $uid) public static function getPublicAndUserContactID(int $cid, int $uid): array
{ {
// We have to use the legacy function as long as the post update hasn't finished // We have to use the legacy function as long as the post update hasn't finished
if (DI::config()->get('system', 'post_update_version') < 1427) { if (DI::config()->get('system', 'post_update_version') < 1427) {
@ -560,7 +561,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
private static function legacyGetPublicAndUserContactID($cid, $uid) private static function legacyGetPublicAndUserContactID(int $cid, int $uid): array
{ {
if (empty($uid) || empty($cid)) { if (empty($uid) || empty($cid)) {
return []; return [];
@ -1526,7 +1527,7 @@ class Contact
* @param int $type type of contact or account * @param int $type type of contact or account
* @return string * @return string
*/ */
public static function getAccountType(int $type) public static function getAccountType(int $type): string
{ {
switch ($type) { switch ($type) {
case self::TYPE_ORGANISATION: case self::TYPE_ORGANISATION:
@ -1552,11 +1553,11 @@ class Contact
/** /**
* Blocks a contact * Blocks a contact
* *
* @param int $cid * @param int $cid Contact id to block
* @return bool * @param string $reason Block reason
* @throws \Exception * @return bool Whether it was successful
*/ */
public static function block($cid, $reason = null) public static function block(int $cid, string $reason = null): bool
{ {
$return = self::update(['blocked' => true, 'block_reason' => $reason], ['id' => $cid]); $return = self::update(['blocked' => true, 'block_reason' => $reason], ['id' => $cid]);
@ -1566,11 +1567,10 @@ class Contact
/** /**
* Unblocks a contact * Unblocks a contact
* *
* @param int $cid * @param int $cid Contact id to unblock
* @return bool * @return bool Whether it was successfull
* @throws \Exception
*/ */
public static function unblock($cid) public static function unblock(int $cid): bool
{ {
$return = self::update(['blocked' => false, 'block_reason' => null], ['id' => $cid]); $return = self::update(['blocked' => false, 'block_reason' => null], ['id' => $cid]);
@ -1580,7 +1580,7 @@ class Contact
/** /**
* Ensure that cached avatar exist * Ensure that cached avatar exist
* *
* @param integer $cid * @param integer $cid Contact id
*/ */
public static function checkAvatarCache(int $cid) public static function checkAvatarCache(int $cid)
{ {
@ -1620,7 +1620,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found * @param bool $no_update Don't perfom an update if no cached avatar was found
* @return string photo path * @return string photo path
*/ */
private static function getAvatarPath(array $contact, string $size, $no_update = false) private static function getAvatarPath(array $contact, string $size, bool $no_update = false): string
{ {
$contact = self::checkAvatarCacheByArray($contact, $no_update); $contact = self::checkAvatarCacheByArray($contact, $no_update);
@ -1654,7 +1654,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found * @param bool $no_update Don't perfom an update if no cached avatar was found
* @return string photo path * @return string photo path
*/ */
public static function getPhoto(array $contact, bool $no_update = false) public static function getPhoto(array $contact, bool $no_update = false): string
{ {
return self::getAvatarPath($contact, Proxy::SIZE_SMALL, $no_update); return self::getAvatarPath($contact, Proxy::SIZE_SMALL, $no_update);
} }
@ -1666,7 +1666,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found * @param bool $no_update Don't perfom an update if no cached avatar was found
* @return string photo path * @return string photo path
*/ */
public static function getThumb(array $contact, bool $no_update = false) public static function getThumb(array $contact, bool $no_update = false): string
{ {
return self::getAvatarPath($contact, Proxy::SIZE_THUMB, $no_update); return self::getAvatarPath($contact, Proxy::SIZE_THUMB, $no_update);
} }
@ -1678,7 +1678,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found * @param bool $no_update Don't perfom an update if no cached avatar was found
* @return string photo path * @return string photo path
*/ */
public static function getMicro(array $contact, bool $no_update = false) public static function getMicro(array $contact, bool $no_update = false): string
{ {
return self::getAvatarPath($contact, Proxy::SIZE_MICRO, $no_update); return self::getAvatarPath($contact, Proxy::SIZE_MICRO, $no_update);
} }
@ -1690,7 +1690,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found * @param bool $no_update Don't perfom an update if no cached avatar was found
* @return array contact array with avatar cache fields * @return array contact array with avatar cache fields
*/ */
private static function checkAvatarCacheByArray(array $contact, bool $no_update = false) private static function checkAvatarCacheByArray(array $contact, bool $no_update = false): array
{ {
$update = false; $update = false;
$contact_fields = []; $contact_fields = [];
@ -1796,7 +1796,7 @@ class Contact
* @param string $size Size of the avatar picture * @param string $size Size of the avatar picture
* @return string avatar URL * @return string avatar URL
*/ */
public static function getDefaultAvatar(array $contact, string $size) public static function getDefaultAvatar(array $contact, string $size): string
{ {
switch ($size) { switch ($size) {
case Proxy::SIZE_MICRO: case Proxy::SIZE_MICRO:
@ -1817,6 +1817,114 @@ class Contact
} }
if (!DI::config()->get('system', 'remote_avatar_lookup')) { if (!DI::config()->get('system', 'remote_avatar_lookup')) {
$platform = '';
$type = Contact::TYPE_PERSON;
if (!empty($contact['id'])) {
$account = DBA::selectFirst('account-user-view', ['platform', 'contact-type'], ['id' => $contact['id']]);
$platform = $account['platform'] ?? '';
$type = $account['contact-type'] ?? Contact::TYPE_PERSON;
}
if (empty($platform) && !empty($contact['uri-id'])) {
$account = DBA::selectFirst('account-user-view', ['platform', 'contact-type'], ['uri-id' => $contact['uri-id']]);
$platform = $account['platform'] ?? '';
$type = $account['contact-type'] ?? Contact::TYPE_PERSON;
}
switch ($platform) {
case 'corgidon':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/msdos621/corgidon/blob/main/public/avatars/original/missing.png
*/
$default = '/images/default/corgidon.png';
break;
case 'diaspora':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/diaspora/diaspora/
*/
$default = '/images/default/diaspora.png';
break;
case 'gotosocial':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/superseriousbusiness/gotosocial/blob/main/web/assets/default_avatars/GoToSocial_icon1.svg
*/
$default = '/images/default/gotosocial.svg';
break;
case 'hometown':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/hometown-fork/hometown/blob/hometown-dev/public/avatars/original/missing.png
*/
$default = '/images/default/hometown.png';
break;
case 'koyuspace':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/koyuspace/mastodon/blob/main/public/avatars/original/missing.png
*/
$default = '/images/default/koyuspace.png';
break;
case 'ecko':
case 'qoto':
case 'mastodon':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/mastodon/mastodon/tree/main/public/avatars/original/missing.png
*/
$default = '/images/default/mastodon.png';
break;
case 'peertube':
if ($type == Contact::TYPE_COMMUNITY) {
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/Chocobozzz/PeerTube/blob/develop/client/src/assets/images/default-avatar-video-channel.png
*/
$default = '/images/default/peertube-channel.png';
} else {
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/Chocobozzz/PeerTube/blob/develop/client/src/assets/images/default-avatar-account.png
*/
$default = '/images/default/peertube-account.png';
}
break;
case 'pleroma':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://git.pleroma.social/pleroma/pleroma/-/blob/develop/priv/static/images/avi.png
*/
$default = '/images/default/pleroma.png';
break;
case 'plume':
/**
* Picture credits
* @license GNU Affero General Public License v3.0
* @link https://github.com/Plume-org/Plume/blob/main/assets/images/default-avatar.png
*/
$default = '/images/default/plume.png';
break;
}
return DI::baseUrl() . $default; return DI::baseUrl() . $default;
} }
@ -2506,7 +2614,7 @@ class Contact
* @throws HTTPException\NotFoundException * @throws HTTPException\NotFoundException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function createFromProbeForUser(int $uid, $url, $network = '') public static function createFromProbeForUser(int $uid, string $url, string $network = ''): array
{ {
$result = ['cid' => -1, 'success' => false, 'message' => '']; $result = ['cid' => -1, 'success' => false, 'message' => ''];
@ -2695,7 +2803,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function addRelationship(array $importer, array $contact, array $datarray, $sharing = false, $note = '') public static function addRelationship(array $importer, array $contact, array $datarray, bool $sharing = false, string $note = '')
{ {
// Should always be set // Should always be set
if (empty($datarray['author-id'])) { if (empty($datarray['author-id'])) {
@ -2922,7 +3030,7 @@ class Contact
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function pruneUnavailable(array $contact_ids) public static function pruneUnavailable(array $contact_ids): array
{ {
if (empty($contact_ids)) { if (empty($contact_ids)) {
return []; return [];
@ -2950,7 +3058,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function magicLink($contact_url, $url = '') public static function magicLink(string $contact_url, string $url = ''): string
{ {
if (!Session::isAuthenticated()) { if (!Session::isAuthenticated()) {
return $url ?: $contact_url; // Equivalent to: ($url != '') ? $url : $contact_url; return $url ?: $contact_url; // Equivalent to: ($url != '') ? $url : $contact_url;
@ -2977,7 +3085,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function magicLinkById($cid, $url = '') public static function magicLinkById(int $cid, string $url = ''): string
{ {
$contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], ['id' => $cid]); $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], ['id' => $cid]);
@ -2994,7 +3102,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function magicLinkByContact($contact, $url = '') public static function magicLinkByContact(array $contact, string $url = ''): string
{ {
$destination = $url ?: $contact['url']; // Equivalent to ($url != '') ? $url : $contact['url']; $destination = $url ?: $contact['url']; // Equivalent to ($url != '') ? $url : $contact['url'];
@ -3035,7 +3143,7 @@ class Contact
* *
* @return boolean "true" if it is a forum * @return boolean "true" if it is a forum
*/ */
public static function isForum($contactid) public static function isForum(int $contactid): bool
{ {
$fields = ['contact-type']; $fields = ['contact-type'];
$condition = ['id' => $contactid]; $condition = ['id' => $contactid];
@ -3054,7 +3162,7 @@ class Contact
* @param array $contact * @param array $contact
* @return bool * @return bool
*/ */
public static function canReceivePrivateMessages(array $contact) public static function canReceivePrivateMessages(array $contact): bool
{ {
$protocol = $contact['network'] ?? $contact['protocol'] ?? Protocol::PHANTOM; $protocol = $contact['network'] ?? $contact['protocol'] ?? Protocol::PHANTOM;
$self = $contact['self'] ?? false; $self = $contact['self'] ?? false;
@ -3072,7 +3180,7 @@ class Contact
* @return array with search results * @return array with search results
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function searchByName(string $search, string $mode = '', int $uid = 0) public static function searchByName(string $search, string $mode = '', int $uid = 0): array
{ {
if (empty($search)) { if (empty($search)) {
return []; return [];
@ -3115,7 +3223,7 @@ class Contact
* @param array $urls * @param array $urls
* @return array result "count", "added" and "updated" * @return array result "count", "added" and "updated"
*/ */
public static function addByUrls(array $urls) public static function addByUrls(array $urls): array
{ {
$added = 0; $added = 0;
$updated = 0; $updated = 0;
@ -3148,7 +3256,7 @@ class Contact
* @return array The profile array * @return array The profile array
* @throws Exception * @throws Exception
*/ */
public static function getRandomContact() public static function getRandomContact(): array
{ {
$contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], [ $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], [
"`uid` = ? AND `network` = ? AND NOT `failed` AND `last-item` > ?", "`uid` = ? AND `network` = ? AND NOT `failed` AND `last-item` > ?",

View file

@ -36,7 +36,7 @@ class Group
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function getById(int $gid) public static function getById(int $gid): array
{ {
$return = []; $return = [];

View file

@ -174,7 +174,7 @@ class Relation
* @param array $rel * @param array $rel
* @return array contact list * @return array contact list
*/ */
private static function getContacts(int $uid, array $rel) private static function getContacts(int $uid, array $rel): array
{ {
$list = []; $list = [];
$profile = Profile::getByUID($uid); $profile = Profile::getByUID($uid);
@ -182,8 +182,15 @@ class Relation
return $list; return $list;
} }
$condition = ['rel' => $rel, 'uid' => $uid, 'self' => false, 'deleted' => false, $condition = [
'hidden' => false, 'archive' => false, 'pending' => false]; 'rel' => $rel,
'uid' => $uid,
'self' => false,
'deleted' => false,
'hidden' => false,
'archive' => false,
'pending' => false,
];
$condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]); $condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]);
$contacts = DBA::select('contact', ['url'], $condition); $contacts = DBA::select('contact', ['url'], $condition);
while ($contact = DBA::fetch($contacts)) { while ($contact = DBA::fetch($contacts)) {
@ -201,7 +208,7 @@ class Relation
* @param array $contact Contact array * @param array $contact Contact array
* @return boolean True if contact is discoverable * @return boolean True if contact is discoverable
*/ */
public static function isDiscoverable(string $url, array $contact = []) public static function isDiscoverable(string $url, array $contact = []): bool
{ {
$contact_discovery = DI::config()->get('system', 'contact_discovery'); $contact_discovery = DI::config()->get('system', 'contact_discovery');
@ -254,12 +261,14 @@ class Relation
} }
/** /**
* @param int $uid user * Returns an array of suggested contacts for given user id
*
* @param int $uid User id
* @param int $start optional, default 0 * @param int $start optional, default 0
* @param int $limit optional, default 80 * @param int $limit optional, default 80
* @return array * @return array
*/ */
static public function getSuggestions(int $uid, int $start = 0, int $limit = 80) static public function getSuggestions(int $uid, int $start = 0, int $limit = 80): array
{ {
$cid = Contact::getPublicIdByUserId($uid); $cid = Contact::getPublicIdByUserId($uid);
$totallimit = $start + $limit; $totallimit = $start + $limit;
@ -272,20 +281,25 @@ class Relation
// The query returns contacts where contacts interacted with whom the given user follows. // The query returns contacts where contacts interacted with whom the given user follows.
// Contacts who already are in the user's contact table are ignored. // Contacts who already are in the user's contact table are ignored.
$results = DBA::select('contact', [], $results = DBA::select('contact', [], ["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` IN
["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` IN
(SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ?) (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ?)
AND NOT `cid` IN (SELECT `id` FROM `contact` WHERE `uid` = ? AND `nurl` IN AND NOT `cid` IN (SELECT `id` FROM `contact` WHERE `uid` = ? AND `nurl` IN
(SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?)))) (SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))))
AND NOT `hidden` AND `network` IN (?, ?, ?, ?)", AND NOT `hidden` AND `network` IN (?, ?, ?, ?)",
$cid, 0, $uid, Contact::FRIEND, Contact::SHARING, $cid,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus], 0,
['order' => ['last-item' => true], 'limit' => $totallimit] $uid, Contact::FRIEND, Contact::SHARING,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus,
], [
'order' => ['last-item' => true],
'limit' => $totallimit,
]
); );
while ($contact = DBA::fetch($results)) { while ($contact = DBA::fetch($results)) {
$contacts[$contact['id']] = $contact; $contacts[$contact['id']] = $contact;
} }
DBA::close($results); DBA::close($results);
Logger::info('Contacts of contacts who are followed by the given user', ['uid' => $uid, 'cid' => $cid, 'count' => count($contacts)]); Logger::info('Contacts of contacts who are followed by the given user', ['uid' => $uid, 'cid' => $cid, 'count' => count($contacts)]);
@ -365,12 +379,12 @@ class Relation
* @return int * @return int
* @throws Exception * @throws Exception
*/ */
public static function countFollows(int $cid, array $condition = []) public static function countFollows(int $cid, array $condition = []): int
{ {
$condition = DBA::mergeConditions($condition, $condition = DBA::mergeConditions($condition, [
['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)', '`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)',
$cid] $cid,
); ]);
return DI::dba()->count('contact', $condition); return DI::dba()->count('contact', $condition);
} }
@ -556,7 +570,7 @@ class Relation
* @param int $count * @param int $count
* @param int $offset * @param int $offset
* @param bool $shuffle * @param bool $shuffle
* @return array * @return array|bool Array on success, false on failure
* @throws Exception * @throws Exception
*/ */
public static function listCommon(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) public static function listCommon(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false)
@ -581,7 +595,7 @@ class Relation
* @return int * @return int
* @throws Exception * @throws Exception
*/ */
public static function countCommonFollows(int $sourceId, int $targetId, array $condition = []) public static function countCommonFollows(int $sourceId, int $targetId, array $condition = []): int
{ {
$condition = DBA::mergeConditions($condition, $condition = DBA::mergeConditions($condition,
['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`) ['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)
@ -601,7 +615,7 @@ class Relation
* @param int $count * @param int $count
* @param int $offset * @param int $offset
* @param bool $shuffle * @param bool $shuffle
* @return array * @return array|bool Array on success, false on failure
* @throws Exception * @throws Exception
*/ */
public static function listCommonFollows(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) public static function listCommonFollows(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false)
@ -626,7 +640,7 @@ class Relation
* @return int * @return int
* @throws Exception * @throws Exception
*/ */
public static function countCommonFollowers(int $sourceId, int $targetId, array $condition = []) public static function countCommonFollowers(int $sourceId, int $targetId, array $condition = []): int
{ {
$condition = DBA::mergeConditions($condition, $condition = DBA::mergeConditions($condition,
["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`) ["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)
@ -646,7 +660,7 @@ class Relation
* @param int $count * @param int $count
* @param int $offset * @param int $offset
* @param bool $shuffle * @param bool $shuffle
* @return array * @return array|bool Array on success, false on failure
* @throws Exception * @throws Exception
*/ */
public static function listCommonFollowers(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) public static function listCommonFollowers(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false)

View file

@ -82,11 +82,11 @@ class User
/** /**
* Apply changes from contact update data to user-contact table * Apply changes from contact update data to user-contact table
* *
* @param array $fields * @param array $fields
* @param array $condition * @param array $condition
* @return void * @return void
* @throws PDOException * @throws PDOException
* @throws Exception * @throws Exception
*/ */
public static function updateByContactUpdate(array $fields, array $condition) public static function updateByContactUpdate(array $fields, array $condition)
{ {
@ -106,7 +106,7 @@ class User
DBA::close($contacts); DBA::close($contacts);
} }
DBA::commit(); DBA::commit();
} }
/** /**
@ -138,9 +138,10 @@ class User
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
* @param boolean $blocked Is the contact blocked or unblocked? * @param boolean $blocked Is the contact blocked or unblocked?
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function setBlocked($cid, $uid, $blocked) public static function setBlocked(int $cid, int $uid, bool $blocked)
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -170,7 +171,7 @@ class User
* @return boolean is the contact id blocked for the given user? * @return boolean is the contact id blocked for the given user?
* @throws \Exception * @throws \Exception
*/ */
public static function isBlocked($cid, $uid) public static function isBlocked(int $cid, int $uid): bool
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -208,9 +209,10 @@ class User
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
* @param boolean $ignored Is the contact ignored or unignored? * @param boolean $ignored Is the contact ignored or unignored?
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function setIgnored($cid, $uid, $ignored) public static function setIgnored(int $cid, int $uid, bool $ignored)
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -229,11 +231,10 @@ class User
* *
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
*
* @return boolean is the contact id ignored for the given user? * @return boolean is the contact id ignored for the given user?
* @throws \Exception * @throws \Exception
*/ */
public static function isIgnored($cid, $uid) public static function isIgnored(int $cid, int $uid): bool
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -271,9 +272,10 @@ class User
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
* @param boolean $collapsed are the contact's posts collapsed or uncollapsed? * @param boolean $collapsed are the contact's posts collapsed or uncollapsed?
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function setCollapsed($cid, $uid, $collapsed) public static function setCollapsed(int $cid, int $uid, bool $collapsed)
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -288,16 +290,15 @@ class User
* *
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
*
* @return boolean is the contact id blocked for the given user? * @return boolean is the contact id blocked for the given user?
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function isCollapsed($cid, $uid) public static function isCollapsed(int $cid, int $uid): bool
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
return; return false;
} }
$collapsed = false; $collapsed = false;
@ -318,9 +319,10 @@ class User
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
* @param boolean $blocked Is the user blocked or unblocked by the contact? * @param boolean $blocked Is the user blocked or unblocked by the contact?
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function setIsBlocked($cid, $uid, $blocked) public static function setIsBlocked(int $cid, int $uid, bool $blocked)
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -335,11 +337,10 @@ class User
* *
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
*
* @return boolean Is the user blocked or unblocked by the contact? * @return boolean Is the user blocked or unblocked by the contact?
* @throws \Exception * @throws \Exception
*/ */
public static function isIsBlocked($cid, $uid) public static function isIsBlocked(int $cid, int $uid): bool
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {

View file

@ -62,7 +62,7 @@ class Conversation
*/ */
const RELAY = 3; const RELAY = 3;
public static function getByItemUri($item_uri) public static function getByItemUri(string $item_uri)
{ {
return DBA::selectFirst('conversation', [], ['item-uri' => $item_uri]); return DBA::selectFirst('conversation', [], ['item-uri' => $item_uri]);
} }
@ -74,7 +74,7 @@ class Conversation
* @return array Item array with removed conversation data * @return array Item array with removed conversation data
* @throws \Exception * @throws \Exception
*/ */
public static function insert(array $arr) public static function insert(array $arr): array
{ {
if (in_array(($arr['network'] ?? '') ?: Protocol::PHANTOM, if (in_array(($arr['network'] ?? '') ?: Protocol::PHANTOM,
[Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::TWITTER]) && !empty($arr['uri'])) { [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::TWITTER]) && !empty($arr['uri'])) {

View file

@ -41,7 +41,7 @@ use Friendica\Util\XML;
class Event class Event
{ {
public static function getHTML(array $event, $simple = false, $uriid = 0) public static function getHTML(array $event, bool $simple = false, int $uriid = 0): string
{ {
if (empty($event)) { if (empty($event)) {
return ''; return '';
@ -127,7 +127,7 @@ class Event
* @param array $event Array which contains the event data. * @param array $event Array which contains the event data.
* @return string The event as a bbcode formatted string. * @return string The event as a bbcode formatted string.
*/ */
private static function getBBCode(array $event) private static function getBBCode(array $event): string
{ {
$o = ''; $o = '';
@ -157,11 +157,10 @@ class Event
/** /**
* Extract bbcode formatted event data from a string. * Extract bbcode formatted event data from a string.
* *
* @params: string $s The string which should be parsed for event data. * @param string $text The string which should be parsed for event data.
* @param $text
* @return array The array with the event information. * @return array The array with the event information.
*/ */
public static function fromBBCode($text) public static function fromBBCode(string $text): array
{ {
$ev = []; $ev = [];
@ -195,13 +194,13 @@ class Event
return $ev; return $ev;
} }
public static function sortByDate($event_list) public static function sortByDate(array $event_list): array
{ {
usort($event_list, ['self', 'compareDatesCallback']); usort($event_list, ['self', 'compareDatesCallback']);
return $event_list; return $event_list;
} }
private static function compareDatesCallback($event_a, $event_b) private static function compareDatesCallback(array $event_a, array $event_b)
{ {
$date_a = DateTimeFormat::local($event_a['start']); $date_a = DateTimeFormat::local($event_a['start']);
$date_b = DateTimeFormat::local($event_b['start']); $date_b = DateTimeFormat::local($event_b['start']);
@ -223,7 +222,7 @@ class Event
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function delete($event_id) public static function delete(int $event_id)
{ {
if ($event_id == 0) { if ($event_id == 0) {
return; return;
@ -242,7 +241,7 @@ class Event
* @return int The new event id. * @return int The new event id.
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function store($arr) public static function store(array $arr): int
{ {
$event = []; $event = [];
$event['id'] = intval($arr['id'] ?? 0); $event['id'] = intval($arr['id'] ?? 0);
@ -317,7 +316,7 @@ class Event
return $event['id']; return $event['id'];
} }
public static function getItemArrayForId(int $event_id, array $item = []):array public static function getItemArrayForId(int $event_id, array $item = []): array
{ {
if (empty($event_id)) { if (empty($event_id)) {
return $item; return $item;
@ -374,7 +373,7 @@ class Event
return $item; return $item;
} }
public static function getItemArrayForImportedId(int $event_id, array $item = []):array public static function getItemArrayForImportedId(int $event_id, array $item = []): array
{ {
if (empty($event_id)) { if (empty($event_id)) {
return $item; return $item;
@ -404,7 +403,7 @@ class Event
* @return array Array with translations strings. * @return array Array with translations strings.
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function getStrings() public static function getStrings(): array
{ {
// First day of the week (0 = Sunday). // First day of the week (0 = Sunday).
$firstDay = DI::pConfig()->get(local_user(), 'system', 'first_day_of_week', 0); $firstDay = DI::pConfig()->get(local_user(), 'system', 'first_day_of_week', 0);
@ -477,7 +476,7 @@ class Event
* *
* @todo We should replace this with a separate update function if there is some time left. * @todo We should replace this with a separate update function if there is some time left.
*/ */
private static function removeDuplicates(array $dates) private static function removeDuplicates(array $dates): array
{ {
$dates2 = []; $dates2 = [];
@ -500,7 +499,7 @@ class Event
* @return array Query result * @return array Query result
* @throws \Exception * @throws \Exception
*/ */
public static function getListById($owner_uid, $event_id, $sql_extra = '') public static function getListById(int $owner_uid, int $event_id, string $sql_extra = ''): array
{ {
$return = []; $return = [];
@ -536,7 +535,7 @@ class Event
* @return array Query results. * @return array Query results.
* @throws \Exception * @throws \Exception
*/ */
public static function getListByDate($owner_uid, $event_params, $sql_extra = '') public static function getListByDate(int $owner_uid, array $event_params, string $sql_extra = ''): array
{ {
$return = []; $return = [];
@ -570,7 +569,7 @@ class Event
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function prepareListForTemplate(array $event_result) public static function prepareListForTemplate(array $event_result): array
{ {
$event_list = []; $event_list = [];
@ -651,12 +650,12 @@ class Event
* @param array $events Query result for events. * @param array $events Query result for events.
* @param string $format The output format (ical/csv). * @param string $format The output format (ical/csv).
* *
* @param $timezone * @param string $timezone Timezone (missing parameter!)
* @return string Content according to selected export format. * @return string Content according to selected export format.
* *
* @todo Implement timezone support * @todo Implement timezone support
*/ */
private static function formatListForExport(array $events, $format) private static function formatListForExport(array $events, string $format): string
{ {
$o = ''; $o = '';
@ -757,7 +756,7 @@ class Event
* @return array Query results. * @return array Query results.
* @throws \Exception * @throws \Exception
*/ */
private static function getListByUserId($uid = 0) private static function getListByUserId(int $uid = 0): array
{ {
$return = []; $return = [];
@ -797,7 +796,7 @@ class Event
* @throws \Exception * @throws \Exception
* @todo Respect authenticated users with events_by_uid(). * @todo Respect authenticated users with events_by_uid().
*/ */
public static function exportListByUserId($uid, $format = 'ical') public static function exportListByUserId(int $uid, string $format = 'ical'): array
{ {
$process = false; $process = false;
@ -845,7 +844,8 @@ class Event
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function getItemHTML(array $item) { public static function getItemHTML(array $item): string
{
$same_date = false; $same_date = false;
$finish = false; $finish = false;
@ -933,10 +933,11 @@ class Event
* @return array The array with the location data. * @return array The array with the location data.
* 'name' => The name of the location,<br> * 'name' => The name of the location,<br>
* 'address' => The address of the location,<br> * 'address' => The address of the location,<br>
* 'coordinates' => Latitude and longitude (e.g. '48.864716,2.349014').<br> * 'coordinates' => Latitude and longitude (e.g. '48.864716,2.349014').<br>
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function locationToArray($s = '') { private static function locationToArray(string $s = ''): array
{
if ($s == '') { if ($s == '') {
return []; return [];
} }
@ -981,7 +982,7 @@ class Event
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
public static function createBirthday($contact, $birthday) public static function createBirthday(array $contact, string $birthday): bool
{ {
// Check for duplicates // Check for duplicates
$condition = [ $condition = [
@ -1011,8 +1012,7 @@ class Event
'type' => 'birthday', 'type' => 'birthday',
]; ];
self::store($values); // Check if self::store() was success
return (self::store($values) > 0);
return true;
} }
} }

View file

@ -40,7 +40,7 @@ class FContact
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function getByURL($handle, $update = null) public static function getByURL(string $handle, $update = null): array
{ {
$person = DBA::selectFirst('fcontact', [], ['network' => Protocol::DIASPORA, 'addr' => $handle]); $person = DBA::selectFirst('fcontact', [], ['network' => Protocol::DIASPORA, 'addr' => $handle]);
if (!DBA::isResult($person)) { if (!DBA::isResult($person)) {
@ -90,7 +90,7 @@ class FContact
* @param array $arr The fcontact data * @param array $arr The fcontact data
* @throws \Exception * @throws \Exception
*/ */
public static function updateFromProbeArray($arr) public static function updateFromProbeArray(array $arr)
{ {
$uriid = ItemURI::insert(['uri' => $arr['url'], 'guid' => $arr['guid']]); $uriid = ItemURI::insert(['uri' => $arr['url'], 'guid' => $arr['guid']]);
@ -122,12 +122,12 @@ class FContact
* get a url (scheme://domain.tld/u/user) from a given Diaspora* * get a url (scheme://domain.tld/u/user) from a given Diaspora*
* fcontact guid * fcontact guid
* *
* @param mixed $fcontact_guid Hexadecimal string guid * @param string $fcontact_guid Hexadecimal string guid
* *
* @return string the contact url or null * @return string|null the contact url or null
* @throws \Exception * @throws \Exception
*/ */
public static function getUrlByGuid($fcontact_guid) public static function getUrlByGuid(string $fcontact_guid)
{ {
Logger::info('fcontact', ['guid' => $fcontact_guid]); Logger::info('fcontact', ['guid' => $fcontact_guid]);

View file

@ -35,10 +35,9 @@ class FileTag
* URL encode <, >, left and right brackets * URL encode <, >, left and right brackets
* *
* @param string $s String to be URL encoded. * @param string $s String to be URL encoded.
*
* @return string The URL encoded string. * @return string The URL encoded string.
*/ */
private static function encode($s) private static function encode(string $s): string
{ {
return str_replace(['<', '>', '[', ']'], ['%3c', '%3e', '%5b', '%5d'], $s); return str_replace(['<', '>', '[', ']'], ['%3c', '%3e', '%5b', '%5d'], $s);
} }
@ -47,10 +46,9 @@ class FileTag
* URL decode <, >, left and right brackets * URL decode <, >, left and right brackets
* *
* @param string $s The URL encoded string to be decoded * @param string $s The URL encoded string to be decoded
*
* @return string The decoded string. * @return string The decoded string.
*/ */
private static function decode($s) private static function decode(string $s): string
{ {
return str_replace(['%3c', '%3e', '%5b', '%5d'], ['<', '>', '[', ']'], $s); return str_replace(['%3c', '%3e', '%5b', '%5d'], ['<', '>', '[', ']'], $s);
} }
@ -62,10 +60,9 @@ class FileTag
* *
* @param array $array A list of tags. * @param array $array A list of tags.
* @param string $type Optional file type. * @param string $type Optional file type.
*
* @return string A list of file tags. * @return string A list of file tags.
*/ */
public static function arrayToFile(array $array, string $type = 'file') public static function arrayToFile(array $array, string $type = 'file'): string
{ {
$tag_list = ''; $tag_list = '';
if ($type == 'file') { if ($type == 'file') {
@ -92,10 +89,9 @@ class FileTag
* *
* @param string $file File tags * @param string $file File tags
* @param string $type Optional file type. * @param string $type Optional file type.
*
* @return array List of tag names. * @return array List of tag names.
*/ */
public static function fileToArray(string $file, string $type = 'file') public static function fileToArray(string $file, string $type = 'file'): array
{ {
$matches = []; $matches = [];
$return = []; $return = [];

View file

@ -30,6 +30,7 @@ use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Database\DBStructure;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Register; use Friendica\Module\Register;
use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientAccept;
@ -96,7 +97,7 @@ class GServer
* *
* @param string $url * @param string $url
* @param boolean $no_check Don't check if the server hadn't been found * @param boolean $no_check Don't check if the server hadn't been found
* @return int gserver id * @return int|null gserver id or NULL on empty URL or failed check
*/ */
public static function getID(string $url, bool $no_check = false) public static function getID(string $url, bool $no_check = false)
{ {
@ -156,7 +157,7 @@ class GServer
* *
* @return boolean 'true' if server seems vital * @return boolean 'true' if server seems vital
*/ */
public static function reachable(string $profile, string $server = '', string $network = '', bool $force = false) public static function reachable(string $profile, string $server = '', string $network = '', bool $force = false): bool
{ {
if ($server == '') { if ($server == '') {
$contact = Contact::getByURL($profile, null, ['baseurl']); $contact = Contact::getByURL($profile, null, ['baseurl']);
@ -172,7 +173,7 @@ class GServer
return self::check($server, $network, $force); return self::check($server, $network, $force);
} }
public static function getNextUpdateDate(bool $success, string $created = '', string $last_contact = '') public static function getNextUpdateDate(bool $success, string $created = '', string $last_contact = ''): string
{ {
// On successful contact process check again next week // On successful contact process check again next week
if ($success) { if ($success) {
@ -231,7 +232,7 @@ class GServer
* *
* @return boolean 'true' if server seems vital * @return boolean 'true' if server seems vital
*/ */
public static function check(string $server_url, string $network = '', bool $force = false, bool $only_nodeinfo = false) public static function check(string $server_url, string $network = '', bool $force = false, bool $only_nodeinfo = false): bool
{ {
$server_url = self::cleanURL($server_url); $server_url = self::cleanURL($server_url);
if ($server_url == '') { if ($server_url == '') {
@ -243,7 +244,7 @@ class GServer
if ($gserver['created'] <= DBA::NULL_DATETIME) { if ($gserver['created'] <= DBA::NULL_DATETIME) {
$fields = ['created' => DateTimeFormat::utcNow()]; $fields = ['created' => DateTimeFormat::utcNow()];
$condition = ['nurl' => Strings::normaliseLink($server_url)]; $condition = ['nurl' => Strings::normaliseLink($server_url)];
DBA::update('gserver', $fields, $condition); self::update($fields, $condition);
} }
if (!$force && (strtotime($gserver['next_contact']) > time())) { if (!$force && (strtotime($gserver['next_contact']) > time())) {
@ -268,7 +269,7 @@ class GServer
$gserver = DBA::selectFirst('gserver', [], ['nurl' => Strings::normaliseLink($url)]); $gserver = DBA::selectFirst('gserver', [], ['nurl' => Strings::normaliseLink($url)]);
if (DBA::isResult($gserver)) { if (DBA::isResult($gserver)) {
$next_update = self::getNextUpdateDate(false, $gserver['created'], $gserver['last_contact']); $next_update = self::getNextUpdateDate(false, $gserver['created'], $gserver['last_contact']);
DBA::update('gserver', ['failed' => true, 'last_failure' => DateTimeFormat::utcNow(), self::update(['failed' => true, 'last_failure' => DateTimeFormat::utcNow(),
'next_contact' => $next_update, 'detection-method' => null], 'next_contact' => $next_update, 'detection-method' => null],
['nurl' => Strings::normaliseLink($url)]); ['nurl' => Strings::normaliseLink($url)]);
Logger::info('Set failed status for existing server', ['url' => $url]); Logger::info('Set failed status for existing server', ['url' => $url]);
@ -286,7 +287,7 @@ class GServer
* @param string $url * @param string $url
* @return string cleaned URL * @return string cleaned URL
*/ */
public static function cleanURL(string $url) public static function cleanURL(string $url): string
{ {
$url = trim($url, '/'); $url = trim($url, '/');
$url = str_replace('/index.php', '', $url); $url = str_replace('/index.php', '', $url);
@ -305,7 +306,7 @@ class GServer
* @param string $url * @param string $url
* @return string base URL * @return string base URL
*/ */
private static function getBaseURL(string $url) private static function getBaseURL(string $url): string
{ {
$urlparts = parse_url(self::cleanURL($url)); $urlparts = parse_url(self::cleanURL($url));
unset($urlparts['path']); unset($urlparts['path']);
@ -322,7 +323,7 @@ class GServer
* *
* @return boolean 'true' if server could be detected * @return boolean 'true' if server could be detected
*/ */
public static function detect(string $url, string $network = '', bool $only_nodeinfo = false) public static function detect(string $url, string $network = '', bool $only_nodeinfo = false): bool
{ {
Logger::info('Detect server type', ['server' => $url]); Logger::info('Detect server type', ['server' => $url]);
$serverdata = ['detection-method' => self::DETECT_MANUAL]; $serverdata = ['detection-method' => self::DETECT_MANUAL];
@ -338,7 +339,7 @@ class GServer
// If the URL missmatches, then we mark the old entry as failure // If the URL missmatches, then we mark the old entry as failure
if ($url != $original_url) { if ($url != $original_url) {
/// @todo What to do with "next_contact" here? /// @todo What to do with "next_contact" here?
DBA::update('gserver', ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()], self::update(['failed' => true, 'last_failure' => DateTimeFormat::utcNow()],
['nurl' => Strings::normaliseLink($original_url)]); ['nurl' => Strings::normaliseLink($original_url)]);
} }
@ -535,13 +536,13 @@ class GServer
$serverdata['last_contact'] = DateTimeFormat::utcNow(); $serverdata['last_contact'] = DateTimeFormat::utcNow();
$serverdata['failed'] = false; $serverdata['failed'] = false;
$gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]); $gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => $serverdata['nurl']]);
if (!DBA::isResult($gserver)) { if (!DBA::isResult($gserver)) {
$serverdata['created'] = DateTimeFormat::utcNow(); $serverdata['created'] = DateTimeFormat::utcNow();
$ret = DBA::insert('gserver', $serverdata); $ret = DBA::insert('gserver', $serverdata);
$id = DBA::lastInsertId(); $id = DBA::lastInsertId();
} else { } else {
$ret = DBA::update('gserver', $serverdata, ['nurl' => $serverdata['nurl']]); $ret = self::update($serverdata, ['nurl' => $serverdata['nurl']]);
$gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => $serverdata['nurl']]); $gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => $serverdata['nurl']]);
if (DBA::isResult($gserver)) { if (DBA::isResult($gserver)) {
$id = $gserver['id']; $id = $gserver['id'];
@ -555,14 +556,14 @@ class GServer
$max_users = max($apcontacts, $contacts); $max_users = max($apcontacts, $contacts);
if ($max_users > $serverdata['registered-users']) { if ($max_users > $serverdata['registered-users']) {
Logger::info('Update registered users', ['id' => $id, 'url' => $serverdata['nurl'], 'registered-users' => $max_users]); Logger::info('Update registered users', ['id' => $id, 'url' => $serverdata['nurl'], 'registered-users' => $max_users]);
DBA::update('gserver', ['registered-users' => $max_users], ['id' => $id]); self::update(['registered-users' => $max_users], ['id' => $id]);
} }
if (empty($serverdata['active-month-users'])) { if (empty($serverdata['active-month-users'])) {
$contacts = DBA::count('contact', ["`uid` = ? AND `gsid` = ? AND NOT `failed` AND `last-item` > ?", 0, $id, DateTimeFormat::utc('now - 30 days')]); $contacts = DBA::count('contact', ["`uid` = ? AND `gsid` = ? AND NOT `failed` AND `last-item` > ?", 0, $id, DateTimeFormat::utc('now - 30 days')]);
if ($contacts > 0) { if ($contacts > 0) {
Logger::info('Update monthly users', ['id' => $id, 'url' => $serverdata['nurl'], 'monthly-users' => $contacts]); Logger::info('Update monthly users', ['id' => $id, 'url' => $serverdata['nurl'], 'monthly-users' => $contacts]);
DBA::update('gserver', ['active-month-users' => $contacts], ['id' => $id]); self::update(['active-month-users' => $contacts], ['id' => $id]);
} }
} }
@ -570,7 +571,7 @@ class GServer
$contacts = DBA::count('contact', ["`uid` = ? AND `gsid` = ? AND NOT `failed` AND `last-item` > ?", 0, $id, DateTimeFormat::utc('now - 180 days')]); $contacts = DBA::count('contact', ["`uid` = ? AND `gsid` = ? AND NOT `failed` AND `last-item` > ?", 0, $id, DateTimeFormat::utc('now - 180 days')]);
if ($contacts > 0) { if ($contacts > 0) {
Logger::info('Update halfyear users', ['id' => $id, 'url' => $serverdata['nurl'], 'halfyear-users' => $contacts]); Logger::info('Update halfyear users', ['id' => $id, 'url' => $serverdata['nurl'], 'halfyear-users' => $contacts]);
DBA::update('gserver', ['active-halfyear-users' => $contacts], ['id' => $id]); self::update(['active-halfyear-users' => $contacts], ['id' => $id]);
} }
} }
} }
@ -586,6 +587,7 @@ class GServer
* Fetch relay data from a given server url * Fetch relay data from a given server url
* *
* @param string $server_url address of the server * @param string $server_url address of the server
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function discoverRelay(string $server_url) private static function discoverRelay(string $server_url)
@ -618,7 +620,7 @@ class GServer
if (($gserver['relay-subscribe'] != $data['subscribe']) || ($gserver['relay-scope'] != $data['scope'])) { if (($gserver['relay-subscribe'] != $data['subscribe']) || ($gserver['relay-scope'] != $data['scope'])) {
$fields = ['relay-subscribe' => $data['subscribe'], 'relay-scope' => $data['scope']]; $fields = ['relay-subscribe' => $data['subscribe'], 'relay-scope' => $data['scope']];
DBA::update('gserver', $fields, ['id' => $gserver['id']]); self::update($fields, ['id' => $gserver['id']]);
} }
DBA::delete('gserver-tag', ['gserver-id' => $gserver['id']]); DBA::delete('gserver-tag', ['gserver-id' => $gserver['id']]);
@ -682,10 +684,9 @@ class GServer
* Fetch server data from '/statistics.json' on the given server * Fetch server data from '/statistics.json' on the given server
* *
* @param string $url URL of the given server * @param string $url URL of the given server
*
* @return array server data * @return array server data
*/ */
private static function fetchStatistics(string $url) private static function fetchStatistics(string $url): array
{ {
$curlResult = DI::httpClient()->get($url . '/statistics.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/statistics.json', HttpClientAccept::JSON);
if (!$curlResult->isSuccess()) { if (!$curlResult->isSuccess()) {
@ -758,7 +759,7 @@ class GServer
* @return array Server data * @return array Server data
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function fetchNodeinfo(string $url, ICanHandleHttpResponses $httpResult) private static function fetchNodeinfo(string $url, ICanHandleHttpResponses $httpResult): array
{ {
if (!$httpResult->isSuccess()) { if (!$httpResult->isSuccess()) {
return []; return [];
@ -811,7 +812,7 @@ class GServer
* @return array Server data * @return array Server data
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function parseNodeinfo1(string $nodeinfo_url) private static function parseNodeinfo1(string $nodeinfo_url): array
{ {
$curlResult = DI::httpClient()->get($nodeinfo_url, HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($nodeinfo_url, HttpClientAccept::JSON);
if (!$curlResult->isSuccess()) { if (!$curlResult->isSuccess()) {
@ -904,7 +905,7 @@ class GServer
* @return array Server data * @return array Server data
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
private static function parseNodeinfo2(string $nodeinfo_url) private static function parseNodeinfo2(string $nodeinfo_url): array
{ {
$curlResult = DI::httpClient()->get($nodeinfo_url, HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($nodeinfo_url, HttpClientAccept::JSON);
if (!$curlResult->isSuccess()) { if (!$curlResult->isSuccess()) {
@ -917,8 +918,11 @@ class GServer
return []; return [];
} }
$server = ['detection-method' => self::DETECT_NODEINFO_2, $server = [
'register_policy' => Register::CLOSED]; 'detection-method' => self::DETECT_NODEINFO_2,
'register_policy' => Register::CLOSED,
'platform' => 'unknown',
];
if (!empty($nodeinfo['openRegistrations'])) { if (!empty($nodeinfo['openRegistrations'])) {
$server['register_policy'] = Register::OPEN; $server['register_policy'] = Register::OPEN;
@ -1001,10 +1005,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function fetchSiteinfo(string $url, array $serverdata) private static function fetchSiteinfo(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/siteinfo.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/siteinfo.json', HttpClientAccept::JSON);
if (!$curlResult->isSuccess()) { if (!$curlResult->isSuccess()) {
@ -1085,10 +1088,9 @@ class GServer
* Checks if the server contains a valid host meta file * Checks if the server contains a valid host meta file
* *
* @param string $url URL of the given server * @param string $url URL of the given server
*
* @return boolean 'true' if the server seems to be vital * @return boolean 'true' if the server seems to be vital
*/ */
private static function validHostMeta(string $url) private static function validHostMeta(string $url): bool
{ {
$xrd_timeout = DI::config()->get('system', 'xrd_timeout'); $xrd_timeout = DI::config()->get('system', 'xrd_timeout');
$curlResult = DI::httpClient()->get($url . '/.well-known/host-meta', HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout]); $curlResult = DI::httpClient()->get($url . '/.well-known/host-meta', HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout]);
@ -1131,10 +1133,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectNetworkViaContacts(string $url, array $serverdata) private static function detectNetworkViaContacts(string $url, array $serverdata): array
{ {
$contacts = []; $contacts = [];
@ -1176,10 +1177,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function checkPoCo(string $url, array $serverdata) private static function checkPoCo(string $url, array $serverdata): array
{ {
$serverdata['poco'] = ''; $serverdata['poco'] = '';
@ -1208,10 +1208,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
public static function checkMastodonDirectory(string $url, array $serverdata) public static function checkMastodonDirectory(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/v1/directory?limit=1', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/directory?limit=1', HttpClientAccept::JSON);
if (!$curlResult->isSuccess()) { if (!$curlResult->isSuccess()) {
@ -1238,7 +1237,7 @@ class GServer
* *
* @return array server data * @return array server data
*/ */
private static function detectPeertube(string $url, array $serverdata) private static function detectPeertube(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/v1/config', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/config', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1282,10 +1281,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectNextcloud(string $url, array $serverdata) private static function detectNextcloud(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/status.php', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/status.php', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1310,7 +1308,15 @@ class GServer
return $serverdata; return $serverdata;
} }
private static function fetchWeeklyUsage(string $url, array $serverdata) { /**
* Fetches weekly usage data
*
* @param string $url URL of the given server
* @param array $serverdata array with server data
* @return array server data
*/
private static function fetchWeeklyUsage(string $url, array $serverdata): array
{
$curlResult = DI::httpClient()->get($url . '/api/v1/instance/activity', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/instance/activity', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
return $serverdata; return $serverdata;
@ -1346,10 +1352,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectFromContacts(string $url, array $serverdata) private static function detectFromContacts(string $url, array $serverdata): array
{ {
$gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => Strings::normaliseLink($url)]); $gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => Strings::normaliseLink($url)]);
if (empty($gserver)) { if (empty($gserver)) {
@ -1374,10 +1379,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectMastodonAlikes(string $url, array $serverdata) private static function detectMastodonAlikes(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/v1/instance', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/instance', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1439,10 +1443,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectHubzilla(string $url, array $serverdata) private static function detectHubzilla(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/statusnet/config.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/statusnet/config.json', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1517,10 +1520,9 @@ class GServer
* Converts input value to a boolean value * Converts input value to a boolean value
* *
* @param string|integer $val * @param string|integer $val
*
* @return boolean * @return boolean
*/ */
private static function toBoolean($val) private static function toBoolean($val): bool
{ {
if (($val == 'true') || ($val == 1)) { if (($val == 'true') || ($val == 1)) {
return true; return true;
@ -1536,10 +1538,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectPumpIO(string $url, array $serverdata) private static function detectPumpIO(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/.well-known/host-meta.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/.well-known/host-meta.json', HttpClientAccept::JSON);
if (!$curlResult->isSuccess()) { if (!$curlResult->isSuccess()) {
@ -1549,7 +1550,6 @@ class GServer
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBody(), true);
if (empty($data['links'])) { if (empty($data['links'])) {
return $serverdata; return $serverdata;
} }
// We are looking for some endpoints that are typical for pump.io // We are looking for some endpoints that are typical for pump.io
@ -1586,10 +1586,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectGNUSocial(string $url, array $serverdata) private static function detectGNUSocial(string $url, array $serverdata): array
{ {
// Test for GNU Social // Test for GNU Social
$curlResult = DI::httpClient()->get($url . '/api/gnusocial/version.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/gnusocial/version.json', HttpClientAccept::JSON);
@ -1641,10 +1640,9 @@ class GServer
* *
* @param string $url URL of the given server * @param string $url URL of the given server
* @param array $serverdata array with server data * @param array $serverdata array with server data
*
* @return array server data * @return array server data
*/ */
private static function detectFriendica(string $url, array $serverdata) private static function detectFriendica(string $url, array $serverdata): array
{ {
// There is a bug in some versions of Friendica that will return an ActivityStream actor when the content type "application/json" is requested. // There is a bug in some versions of Friendica that will return an ActivityStream actor when the content type "application/json" is requested.
// Because of this me must not use ACCEPT_JSON here. // Because of this me must not use ACCEPT_JSON here.
@ -1717,10 +1715,9 @@ class GServer
* @param object $curlResult result of curl execution * @param object $curlResult result of curl execution
* @param array $serverdata array with server data * @param array $serverdata array with server data
* @param string $url Server URL * @param string $url Server URL
*
* @return array server data * @return array server data
*/ */
private static function analyseRootBody($curlResult, array $serverdata, string $url) private static function analyseRootBody($curlResult, array $serverdata, string $url): array
{ {
if (empty($curlResult->getBody())) { if (empty($curlResult->getBody())) {
return $serverdata; return $serverdata;
@ -1859,7 +1856,7 @@ class GServer
* *
* @return array server data * @return array server data
*/ */
private static function analyseRootHeader($curlResult, array $serverdata) private static function analyseRootHeader($curlResult, array $serverdata): array
{ {
if ($curlResult->getHeader('server') == 'Mastodon') { if ($curlResult->getHeader('server') == 'Mastodon') {
$serverdata['platform'] = 'mastodon'; $serverdata['platform'] = 'mastodon';
@ -1926,7 +1923,7 @@ class GServer
Worker::add(PRIORITY_LOW, 'UpdateServerDirectory', $gserver); Worker::add(PRIORITY_LOW, 'UpdateServerDirectory', $gserver);
$fields = ['last_poco_query' => DateTimeFormat::utcNow()]; $fields = ['last_poco_query' => DateTimeFormat::utcNow()];
DBA::update('gserver', $fields, ['nurl' => $gserver['nurl']]); self::update($fields, ['nurl' => $gserver['nurl']]);
if (--$no_of_queries == 0) { if (--$no_of_queries == 0) {
break; break;
@ -2044,17 +2041,17 @@ class GServer
} }
Logger::info('Protocol for server', ['protocol' => $protocol, 'old' => $old, 'id' => $gsid, 'url' => $gserver['url'], 'callstack' => System::callstack(20)]); Logger::info('Protocol for server', ['protocol' => $protocol, 'old' => $old, 'id' => $gsid, 'url' => $gserver['url'], 'callstack' => System::callstack(20)]);
DBA::update('gserver', ['protocol' => $protocol], ['id' => $gsid]); self::update(['protocol' => $protocol], ['id' => $gsid]);
} }
/** /**
* Fetch the protocol of the given server * Fetch the protocol of the given server
* *
* @param int $gsid Server id * @param int $gsid Server id
* @return int * @return ?int One of Post\DeliveryData protocol constants or null if unknown or gserver is missing
* @throws Exception * @throws Exception
*/ */
public static function getProtocol(int $gsid) public static function getProtocol(int $gsid): ?int
{ {
if (empty($gsid)) { if (empty($gsid)) {
return null; return null;
@ -2067,4 +2064,19 @@ class GServer
return null; return null;
} }
/**
* Enforces gserver table field maximum sizes to avoid "Data too long" database errors
*
* @param array $fields
* @param array $condition
* @return bool
* @throws Exception
*/
public static function update(array $fields, array $condition): bool
{
$fields = DBStructure::getFieldsForTable('gserver', $fields);
return DBA::update('gserver', $fields, $condition);
}
} }

View file

@ -39,7 +39,14 @@ class Group
const FOLLOWERS = '~'; const FOLLOWERS = '~';
const MUTUALS = '&'; const MUTUALS = '&';
public static function getByUserId($uid, $includesDeleted = false) /**
* Fetches group record by user id and maybe includes deleted groups as well
*
* @param int $uid User id to fetch group(s) for
* @param bool $includesDeleted Whether deleted groups should be included
* @return array|bool Array on success, bool on error
*/
public static function getByUserId(int $uid, bool $includesDeleted = false)
{ {
$conditions = ['uid' => $uid, 'cid' => null]; $conditions = ['uid' => $uid, 'cid' => null];
@ -51,15 +58,18 @@ class Group
} }
/** /**
* @param int $group_id * Checks whether given group id is found in database
*
* @param int $group_id Groupd it
* @param int $uid Optional user id
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
public static function exists($group_id, $uid = null) public static function exists(int $group_id, int $uid = null): bool
{ {
$condition = ['id' => $group_id, 'deleted' => false]; $condition = ['id' => $group_id, 'deleted' => false];
if (isset($uid)) { if (!is_null($uid)) {
$condition = [ $condition = [
'uid' => $uid 'uid' => $uid
]; ];
@ -73,12 +83,12 @@ class Group
* *
* Note: If we found a deleted group with the same name, we restore it * Note: If we found a deleted group with the same name, we restore it
* *
* @param int $uid * @param int $uid User id to create group for
* @param string $name * @param string $name Name of group
* @return boolean * @return int|boolean Id of newly created group or false on error
* @throws \Exception * @throws \Exception
*/ */
public static function create($uid, $name) public static function create(int $uid, string $name)
{ {
$return = false; $return = false;
if (!empty($uid) && !empty($name)) { if (!empty($uid) && !empty($name)) {
@ -114,7 +124,7 @@ class Group
* @return bool Was the update successful? * @return bool Was the update successful?
* @throws \Exception * @throws \Exception
*/ */
public static function update($id, $name) public static function update(int $id, string $name): bool
{ {
return DBA::update('group', ['name' => $name], ['id' => $id]); return DBA::update('group', ['name' => $name], ['id' => $id]);
} }
@ -122,11 +132,11 @@ class Group
/** /**
* Get a list of group ids a contact belongs to * Get a list of group ids a contact belongs to
* *
* @param int $cid * @param int $cid Contact id
* @return array * @return array Group ids
* @throws \Exception * @throws \Exception
*/ */
public static function getIdsByContactId($cid) public static function getIdsByContactId(int $cid): array
{ {
$return = []; $return = [];
@ -185,12 +195,12 @@ class Group
* *
* Returns false if no group has been found. * Returns false if no group has been found.
* *
* @param int $uid * @param int $uid User id
* @param string $name * @param string $name Group name
* @return int|boolean * @return int|boolean Groups' id number or false on error
* @throws \Exception * @throws \Exception
*/ */
public static function getIdByName($uid, $name) public static function getIdByName(int $uid, string $name)
{ {
if (!$uid || !strlen($name)) { if (!$uid || !strlen($name)) {
return false; return false;
@ -211,7 +221,7 @@ class Group
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function remove($gid) public static function remove(int $gid): bool
{ {
if (!$gid) { if (!$gid) {
return false; return false;
@ -314,13 +324,14 @@ class Group
* Adds contacts to a group * Adds contacts to a group
* *
* @param int $gid * @param int $gid
* @param array $contacts * @param array $contacts Array with contact ids
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function addMembers(int $gid, array $contacts) public static function addMembers(int $gid, array $contacts)
{ {
if (!$gid || !$contacts) { if (!$gid || !$contacts) {
return false; return;
} }
// @TODO Backward compatibility with user contacts, remove by version 2022.03 // @TODO Backward compatibility with user contacts, remove by version 2022.03
@ -342,8 +353,9 @@ class Group
/** /**
* Removes contacts from a group * Removes contacts from a group
* *
* @param int $gid * @param int $gid Group id
* @param array $contacts * @param array $contacts Contact ids
* @return bool
* @throws \Exception * @throws \Exception
*/ */
public static function removeMembers(int $gid, array $contacts) public static function removeMembers(int $gid, array $contacts)
@ -369,19 +381,20 @@ class Group
$contactIds[] = $cdata['user']; $contactIds[] = $cdata['user'];
} }
DBA::delete('group_member', ['gid' => $gid, 'contact-id' => $contactIds]); // Return status of deletion
return DBA::delete('group_member', ['gid' => $gid, 'contact-id' => $contactIds]);
} }
/** /**
* Returns the combined list of contact ids from a group id list * Returns the combined list of contact ids from a group id list
* *
* @param int $uid * @param int $uid User id
* @param array $group_ids * @param array $group_ids Groups ids
* @param boolean $check_dead * @param boolean $check_dead Whether check "dead" records (?)
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function expand($uid, array $group_ids, $check_dead = false) public static function expand(int $uid, array $group_ids, bool $check_dead = false): array
{ {
if (!is_array($group_ids) || !count($group_ids)) { if (!is_array($group_ids) || !count($group_ids)) {
return []; return [];
@ -454,13 +467,13 @@ class Group
/** /**
* Returns a templated group selection list * Returns a templated group selection list
* *
* @param int $uid * @param int $uid User id
* @param int $gid An optional pre-selected group * @param int $gid An optional pre-selected group
* @param string $label An optional label of the list * @param string $label An optional label of the list
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
public static function displayGroupSelection($uid, $gid = 0, $label = '') public static function displayGroupSelection(int $uid, int $gid = 0, string $label = ''): string
{ {
$display_groups = [ $display_groups = [
[ [
@ -502,12 +515,12 @@ class Group
* 'standard' => include link 'Edit groups' * 'standard' => include link 'Edit groups'
* 'extended' => include link 'Create new group' * 'extended' => include link 'Create new group'
* 'full' => include link 'Create new group' and provide for each group a link to edit this group * 'full' => include link 'Create new group' and provide for each group a link to edit this group
* @param string $group_id * @param string|int $group_id Distinct group id or 'everyone'
* @param int $cid * @param int $cid Contact id
* @return string * @return string Sidebar widget HTML code
* @throws \Exception * @throws \Exception
*/ */
public static function sidebarWidget($every = 'contact', $each = 'group', $editmode = 'standard', $group_id = '', $cid = 0) public static function sidebarWidget(string $every = 'contact', string $each = 'group', string $editmode = 'standard', $group_id = '', int $cid = 0)
{ {
if (!local_user()) { if (!local_user()) {
return ''; return '';
@ -589,7 +602,7 @@ class Group
* @param integer $id Contact ID * @param integer $id Contact ID
* @return integer Group IO * @return integer Group IO
*/ */
public static function getIdForForum(int $id) public static function getIdForForum(int $id): int
{ {
Logger::info('Get id for forum id', ['id' => $id]); Logger::info('Get id for forum id', ['id' => $id]);
$contact = Contact::getById($id, ['uid', 'name', 'contact-type', 'manually-approve']); $contact = Contact::getById($id, ['uid', 'name', 'contact-type', 'manually-approve']);
@ -617,6 +630,7 @@ class Group
* Fetch the followers of a given contact id and store them as group members * Fetch the followers of a given contact id and store them as group members
* *
* @param integer $id Contact ID * @param integer $id Contact ID
* @return void
*/ */
public static function updateMembersForForum(int $id) public static function updateMembersForForum(int $id)
{ {

View file

@ -96,8 +96,8 @@ class Item
'event-created', 'event-edited', 'event-start', 'event-finish', 'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type', 'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-ignore', 'event-id', 'event-nofinish', 'event-ignore', 'event-id',
"question-id", "question-multiple", "question-voters", "question-end-time", 'question-id', 'question-multiple', 'question-voters', 'question-end-time',
"has-categories", "has-media", 'has-categories', 'has-media',
'delivery_queue_count', 'delivery_queue_done', 'delivery_queue_failed' 'delivery_queue_count', 'delivery_queue_done', 'delivery_queue_failed'
]; ];
@ -226,7 +226,7 @@ class Item
foreach ($notify_items as $notify_item) { foreach ($notify_items as $notify_item) {
$post = Post::selectFirst(['uri-id', 'uid'], ['id' => $notify_item]); $post = Post::selectFirst(['uri-id', 'uid'], ['id' => $notify_item]);
Worker::add(PRIORITY_HIGH, "Notifier", Delivery::POST, (int)$post['uri-id'], (int)$post['uid']); Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::POST, (int)$post['uri-id'], (int)$post['uid']);
} }
return $rows; return $rows;
@ -237,9 +237,10 @@ class Item
* *
* @param array $condition The condition for finding the item entries * @param array $condition The condition for finding the item entries
* @param integer $priority Priority for the notification * @param integer $priority Priority for the notification
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function markForDeletion($condition, $priority = PRIORITY_HIGH) public static function markForDeletion(array $condition, int $priority = PRIORITY_HIGH)
{ {
$items = Post::select(['id'], $condition); $items = Post::select(['id'], $condition);
while ($item = Post::fetch($items)) { while ($item = Post::fetch($items)) {
@ -253,9 +254,10 @@ class Item
* *
* @param array $condition The condition for finding the item entries * @param array $condition The condition for finding the item entries
* @param integer $uid User who wants to delete this item * @param integer $uid User who wants to delete this item
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function deleteForUser($condition, $uid) public static function deleteForUser(array $condition, int $uid)
{ {
if ($uid == 0) { if ($uid == 0) {
return; return;
@ -282,11 +284,10 @@ class Item
* *
* @param integer $item_id * @param integer $item_id
* @param integer $priority Priority for the notification * @param integer $priority Priority for the notification
*
* @return boolean success * @return boolean success
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function markForDeletionById($item_id, $priority = PRIORITY_HIGH) public static function markForDeletionById(int $item_id, int $priority = PRIORITY_HIGH): bool
{ {
Logger::info('Mark item for deletion by id', ['id' => $item_id, 'callstack' => System::callstack()]); Logger::info('Mark item for deletion by id', ['id' => $item_id, 'callstack' => System::callstack()]);
// locate item to be deleted // locate item to be deleted
@ -331,7 +332,7 @@ class Item
// If item has attachments, drop them // If item has attachments, drop them
$attachments = Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT]); $attachments = Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT]);
foreach($attachments as $attachment) { foreach($attachments as $attachment) {
if (preg_match("|attach/(\d+)|", $attachment['url'], $matches)) { if (preg_match('|attach/(\d+)|', $attachment['url'], $matches)) {
Attach::delete(['id' => $matches[1], 'uid' => $item['uid']]); Attach::delete(['id' => $matches[1], 'uid' => $item['uid']]);
} }
} }
@ -360,7 +361,7 @@ class Item
// send the notification upstream/downstream // send the notification upstream/downstream
if ($priority) { if ($priority) {
Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", Delivery::DELETION, (int)$item['uri-id'], (int)$item['uid']); Worker::add(['priority' => $priority, 'dont_fork' => true], 'Notifier', Delivery::DELETION, (int)$item['uri-id'], (int)$item['uid']);
} }
} elseif ($item['uid'] != 0) { } elseif ($item['uid'] != 0) {
Post\User::update($item['uri-id'], $item['uid'], ['hidden' => true]); Post\User::update($item['uri-id'], $item['uid'], ['hidden' => true]);
@ -372,7 +373,14 @@ class Item
return true; return true;
} }
public static function guid($item, $notify) /**
* Get guid from given item record
*
* @param array $item Item record
* @param bool Whether to notify (?)
* @return string Guid
*/
public static function guid(array $item, bool $notify): string
{ {
if (!empty($item['guid'])) { if (!empty($item['guid'])) {
return trim($item['guid']); return trim($item['guid']);
@ -425,7 +433,13 @@ class Item
return $guid; return $guid;
} }
private static function contactId($item) /**
* Returns contact id from given item record
*
* @param array $item Item record
* @return int Contact id
*/
private static function contactId(array $item): int
{ {
if (!empty($item['contact-id']) && DBA::exists('contact', ['self' => true, 'id' => $item['contact-id']])) { if (!empty($item['contact-id']) && DBA::exists('contact', ['self' => true, 'id' => $item['contact-id']])) {
return $item['contact-id']; return $item['contact-id'];
@ -451,17 +465,17 @@ class Item
* @param array $item The item fields that are to be inserted * @param array $item The item fields that are to be inserted
* @throws \Exception * @throws \Exception
*/ */
private static function spool($orig_item) private static function spool(array $item)
{ {
// Now we store the data in the spool directory // Now we store the data in the spool directory
// We use "microtime" to keep the arrival order and "mt_rand" to avoid duplicates // We use "microtime" to keep the arrival order and "mt_rand" to avoid duplicates
$file = 'item-' . round(microtime(true) * 10000) . '-' . mt_rand() . '.msg'; $file = 'item-' . round(microtime(true) * 10000) . '-' . mt_rand() . '.msg';
$spoolpath = System::getSpoolPath(); $spoolpath = System::getSpoolPath();
if ($spoolpath != "") { if ($spoolpath != '') {
$spool = $spoolpath . '/' . $file; $spool = $spoolpath . '/' . $file;
file_put_contents($spool, json_encode($orig_item)); file_put_contents($spool, json_encode($item));
Logger::warning("Item wasn't stored - Item was spooled into file", ['file' => $file]); Logger::warning("Item wasn't stored - Item was spooled into file", ['file' => $file]);
} }
} }
@ -469,10 +483,10 @@ class Item
/** /**
* Check if the item array is a duplicate * Check if the item array is a duplicate
* *
* @param array $item * @param array $item Item record
* @return boolean is it a duplicate? * @return boolean is it a duplicate?
*/ */
private static function isDuplicate(array $item) private static function isDuplicate(array $item): bool
{ {
// Checking if there is already an item with the same guid // Checking if there is already an item with the same guid
$condition = ['guid' => $item['guid'], 'network' => $item['network'], 'uid' => $item['uid']]; $condition = ['guid' => $item['guid'], 'network' => $item['network'], 'uid' => $item['uid']];
@ -521,10 +535,10 @@ class Item
/** /**
* Check if the item array is valid * Check if the item array is valid
* *
* @param array $item * @param array $item Item record
* @return boolean item is valid * @return boolean item is valid
*/ */
public static function isValid(array $item) public static function isValid(array $item): bool
{ {
// When there is no content then we don't post it // When there is no content then we don't post it
if (($item['body'] . $item['title'] == '') && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) { if (($item['body'] . $item['title'] == '') && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) {
@ -591,10 +605,10 @@ class Item
/** /**
* Check if the item array is too old * Check if the item array is too old
* *
* @param array $item * @param array $item Item record
* @return boolean item is too old * @return boolean item is too old
*/ */
public static function isTooOld(array $item) public static function isTooOld(array $item): bool
{ {
// check for create date and expire time // check for create date and expire time
$expire_interval = DI::config()->get('system', 'dbclean-expire-days', 0); $expire_interval = DI::config()->get('system', 'dbclean-expire-days', 0);
@ -623,15 +637,20 @@ class Item
/** /**
* Return the id of the given item array if it has been stored before * Return the id of the given item array if it has been stored before
* *
* @param array $item * @param array $item Item record
* @return integer item id * @return integer Item id or zero on error
*/ */
private static function getDuplicateID(array $item) private static function getDuplicateID(array $item): int
{ {
if (empty($item['network']) || in_array($item['network'], Protocol::FEDERATED)) { if (empty($item['network']) || in_array($item['network'], Protocol::FEDERATED)) {
$condition = ["`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?, ?)", $condition = ['`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?, ?)',
$item['uri-id'], $item['uid'], $item['uri-id'],
Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS]; $item['uid'],
Protocol::ACTIVITYPUB,
Protocol::DIASPORA,
Protocol::DFRN,
Protocol::OSTATUS
];
$existing = Post::selectFirst(['id', 'network'], $condition); $existing = Post::selectFirst(['id', 'network'], $condition);
if (DBA::isResult($existing)) { if (DBA::isResult($existing)) {
// We only log the entries with a different user id than 0. Otherwise we would have too many false positives // We only log the entries with a different user id than 0. Otherwise we would have too many false positives
@ -640,12 +659,12 @@ class Item
'uri-id' => $item['uri-id'], 'uri-id' => $item['uri-id'],
'uid' => $item['uid'], 'uid' => $item['uid'],
'network' => $item['network'], 'network' => $item['network'],
'existing_id' => $existing["id"], 'existing_id' => $existing['id'],
'existing_network' => $existing["network"] 'existing_network' => $existing['network']
]); ]);
} }
return $existing["id"]; return $existing['id'];
} }
} }
return 0; return 0;
@ -658,7 +677,7 @@ class Item
* @return array item array with parent data * @return array item array with parent data
* @throws \Exception * @throws \Exception
*/ */
private static function getTopLevelParent(array $item) private static function getTopLevelParent(array $item): array
{ {
$fields = ['uid', 'uri', 'parent-uri', 'id', 'deleted', $fields = ['uid', 'uri', 'parent-uri', 'id', 'deleted',
'uri-id', 'parent-uri-id', 'uri-id', 'parent-uri-id',
@ -709,7 +728,7 @@ class Item
* @param array $item * @param array $item
* @return integer gravity * @return integer gravity
*/ */
private static function getGravity(array $item) private static function getGravity(array $item): int
{ {
$activity = DI::activity(); $activity = DI::activity();
@ -724,11 +743,20 @@ class Item
} elseif ($activity->match($item['verb'], Activity::ANNOUNCE)) { } elseif ($activity->match($item['verb'], Activity::ANNOUNCE)) {
return GRAVITY_ACTIVITY; return GRAVITY_ACTIVITY;
} }
Logger::info('Unknown gravity for verb', ['verb' => $item['verb']]); Logger::info('Unknown gravity for verb', ['verb' => $item['verb']]);
return GRAVITY_UNKNOWN; // Should not happen return GRAVITY_UNKNOWN; // Should not happen
} }
public static function insert(array $item, int $notify = 0, bool $post_local = true) /**
* Inserts item record
*
* @param array $item Item array to be inserted
* @param int $notify Notification (type?)
* @param bool $post_local (???)
* @return int Zero means error, otherwise primary key (id) is being returned
*/
public static function insert(array $item, int $notify = 0, bool $post_local = true): int
{ {
$orig_item = $item; $orig_item = $item;
@ -869,7 +897,7 @@ class Item
Contact::checkAvatarCache($item['owner-id']); Contact::checkAvatarCache($item['owner-id']);
// The contact-id should be set before "self::insert" was called - but there seems to be issues sometimes // The contact-id should be set before "self::insert" was called - but there seems to be issues sometimes
$item["contact-id"] = self::contactId($item); $item['contact-id'] = self::contactId($item);
if (!empty($item['direction']) && in_array($item['direction'], [Conversation::PUSH, Conversation::RELAY]) && if (!empty($item['direction']) && in_array($item['direction'], [Conversation::PUSH, Conversation::RELAY]) &&
empty($item['origin']) &&self::isTooOld($item)) { empty($item['origin']) &&self::isTooOld($item)) {
@ -944,8 +972,8 @@ class Item
$item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']); $item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']);
// Is this item available in the global items (with uid=0)? // Is this item available in the global items (with uid=0)?
if ($item["uid"] == 0) { if ($item['uid'] == 0) {
$item["global"] = true; $item['global'] = true;
// Set the global flag on all items if this was a global item entry // Set the global flag on all items if this was a global item entry
Post::update(['global' => true], ['uri-id' => $item['uri-id']]); Post::update(['global' => true], ['uri-id' => $item['uri-id']]);
@ -954,8 +982,8 @@ class Item
} }
// ACL settings // ACL settings
if (!empty($item["allow_cid"] . $item["allow_gid"] . $item["deny_cid"] . $item["deny_gid"])) { if (!empty($item['allow_cid'] . $item['allow_gid'] . $item['deny_cid'] . $item['deny_gid'])) {
$item["private"] = self::PRIVATE; $item['private'] = self::PRIVATE;
} }
if ($notify && $post_local) { if ($notify && $post_local) {
@ -1323,7 +1351,7 @@ class Item
* @param string $signed_text Original text (for Diaspora signatures), JSON encoded. * @param string $signed_text Original text (for Diaspora signatures), JSON encoded.
* @throws \Exception * @throws \Exception
*/ */
public static function distribute($itemid, $signed_text = '') public static function distribute(int $itemid, string $signed_text = '')
{ {
$condition = ["`id` IN (SELECT `parent` FROM `post-user-view` WHERE `id` = ?)", $itemid]; $condition = ["`id` IN (SELECT `parent` FROM `post-user-view` WHERE `id` = ?)", $itemid];
$parent = Post::selectFirst(['owner-id'], $condition); $parent = Post::selectFirst(['owner-id'], $condition);
@ -1417,7 +1445,7 @@ class Item
* @param integer $source_uid User id of the source post * @param integer $source_uid User id of the source post
* @return integer stored item id * @return integer stored item id
*/ */
public static function storeForUserByUriId(int $uri_id, int $uid, array $fields = [], int $source_uid = 0) public static function storeForUserByUriId(int $uri_id, int $uid, array $fields = [], int $source_uid = 0): int
{ {
if ($uid == $source_uid) { if ($uid == $source_uid) {
Logger::warning('target UID must not be be equal to the source UID', ['uri-id' => $uri_id, 'uid' => $uid]); Logger::warning('target UID must not be be equal to the source UID', ['uri-id' => $uri_id, 'uid' => $uid]);
@ -1525,7 +1553,7 @@ class Item
* @return integer stored item id * @return integer stored item id
* @throws \Exception * @throws \Exception
*/ */
private static function storeForUser(array $item, int $uid) private static function storeForUser(array $item, int $uid): int
{ {
if (Post::exists(['uri-id' => $item['uri-id'], 'uid' => $uid])) { if (Post::exists(['uri-id' => $item['uri-id'], 'uid' => $uid])) {
if (!empty($item['event-id'])) { if (!empty($item['event-id'])) {
@ -1613,7 +1641,7 @@ class Item
* @param integer $itemid Item ID that should be added * @param integer $itemid Item ID that should be added
* @throws \Exception * @throws \Exception
*/ */
private static function addShadow($itemid) private static function addShadow(int $itemid)
{ {
$fields = ['uid', 'private', 'visible', 'deleted', 'network', 'uri-id']; $fields = ['uid', 'private', 'visible', 'deleted', 'network', 'uri-id'];
$condition = ['id' => $itemid, 'gravity' => GRAVITY_PARENT]; $condition = ['id' => $itemid, 'gravity' => GRAVITY_PARENT];
@ -1676,7 +1704,7 @@ class Item
* @param integer $itemid Item ID that should be added * @param integer $itemid Item ID that should be added
* @throws \Exception * @throws \Exception
*/ */
private static function addShadowPost($itemid) private static function addShadowPost(int $itemid)
{ {
$item = Post::selectFirst(self::ITEM_FIELDLIST, ['id' => $itemid]); $item = Post::selectFirst(self::ITEM_FIELDLIST, ['id' => $itemid]);
if (!DBA::isResult($item)) { if (!DBA::isResult($item)) {
@ -1740,7 +1768,7 @@ class Item
* @return string detected language * @return string detected language
* @throws \Text_LanguageDetect_Exception * @throws \Text_LanguageDetect_Exception
*/ */
private static function getLanguage(array $item) private static function getLanguage(array $item): string
{ {
if (!empty($item['language'])) { if (!empty($item['language'])) {
return $item['language']; return $item['language'];
@ -1784,7 +1812,7 @@ class Item
return ''; return '';
} }
public static function getLanguageMessage(array $item) public static function getLanguageMessage(array $item): string
{ {
$iso639 = new \Matriphe\ISO639\ISO639; $iso639 = new \Matriphe\ISO639\ISO639;
@ -1802,24 +1830,24 @@ class Item
* Posts that are created on this system are using System::createUUID. * Posts that are created on this system are using System::createUUID.
* Received ActivityPub posts are using Processor::getGUIDByURL. * Received ActivityPub posts are using Processor::getGUIDByURL.
* *
* @param string $uri uri of an item entry * @param string $uri uri of an item entry
* @param string $host hostname for the GUID prefix * @param string|null $host hostname for the GUID prefix
* @return string unique guid * @return string Unique guid
*/ */
public static function guidFromUri($uri, $host) public static function guidFromUri(string $uri, string $host = null): string
{ {
// Our regular guid routine is using this kind of prefix as well // Our regular guid routine is using this kind of prefix as well
// We have to avoid that different routines could accidentally create the same value // We have to avoid that different routines could accidentally create the same value
$parsed = parse_url($uri); $parsed = parse_url($uri);
// Remove the scheme to make sure that "https" and "http" doesn't make a difference // Remove the scheme to make sure that "https" and "http" doesn't make a difference
unset($parsed["scheme"]); unset($parsed['scheme']);
// Glue it together to be able to make a hash from it // Glue it together to be able to make a hash from it
$host_id = implode("/", $parsed); $host_id = implode('/', $parsed);
// Use a mixture of several hashes to provide some GUID like experience // Use a mixture of several hashes to provide some GUID like experience
return hash("crc32", $host) . '-'. hash('joaat', $host_id) . '-'. hash('fnv164', $host_id); return hash('crc32', $host) . '-'. hash('joaat', $host_id) . '-'. hash('fnv164', $host_id);
} }
/** /**
@ -1831,9 +1859,9 @@ class Item
* @return string * @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function newURI($uid, $guid = "") public static function newURI(int $uid, string $guid = ''): string
{ {
if ($guid == "") { if ($guid == '') {
$guid = System::createUUID(); $guid = System::createUUID();
} }
@ -1850,7 +1878,7 @@ class Item
* @param array $arr Contains the just posted item record * @param array $arr Contains the just posted item record
* @throws \Exception * @throws \Exception
*/ */
private static function updateContact($arr) private static function updateContact(array $arr)
{ {
// Unarchive the author // Unarchive the author
$contact = DBA::selectFirst('contact', [], ['id' => $arr["author-id"]]); $contact = DBA::selectFirst('contact', [], ['id' => $arr["author-id"]]);
@ -1897,7 +1925,7 @@ class Item
} }
} }
public static function setHashtags($body) public static function setHashtags(string $body): string
{ {
$body = BBCode::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) { $body = BBCode::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) {
$tags = BBCode::getTags($body); $tags = BBCode::getTags($body);
@ -1971,7 +1999,7 @@ class Item
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
private static function tagDeliver($uid, $item_id) private static function tagDeliver(int $uid, int $item_id): bool
{ {
$mention = false; $mention = false;
@ -2066,7 +2094,7 @@ class Item
self::performActivity($item['id'], 'announce', $item['uid']); self::performActivity($item['id'], 'announce', $item['uid']);
} }
public static function isRemoteSelf($contact, &$datarray) public static function isRemoteSelf(array $contact, array &$datarray): bool
{ {
if (!$contact['remote_self']) { if (!$contact['remote_self']) {
return false; return false;
@ -2160,7 +2188,7 @@ class Item
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function fixPrivatePhotos($s, $uid, $item = null, $cid = 0) public static function fixPrivatePhotos(string $s, int $uid, array $item = null, int $cid = 0): string
{ {
if (DI::config()->get('system', 'disable_embedded')) { if (DI::config()->get('system', 'disable_embedded')) {
return $s; return $s;
@ -2254,13 +2282,14 @@ class Item
return $new_body; return $new_body;
} }
private static function hasPermissions($obj) private static function hasPermissions(array $obj)
{ {
return !empty($obj['allow_cid']) || !empty($obj['allow_gid']) || return !empty($obj['allow_cid']) || !empty($obj['allow_gid']) ||
!empty($obj['deny_cid']) || !empty($obj['deny_gid']); !empty($obj['deny_cid']) || !empty($obj['deny_gid']);
} }
private static function samePermissions($uid, $obj1, $obj2) // @TODO $uid is unused parameter
private static function samePermissions($uid, array $obj1, array $obj2): bool
{ {
// first part is easy. Check that these are exactly the same. // first part is easy. Check that these are exactly the same.
if (($obj1['allow_cid'] == $obj2['allow_cid']) if (($obj1['allow_cid'] == $obj2['allow_cid'])
@ -2288,7 +2317,7 @@ class Item
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function enumeratePermissions(array $obj, bool $check_dead = false) public static function enumeratePermissions(array $obj, bool $check_dead = false): array
{ {
$aclFormater = DI::aclFormatter(); $aclFormater = DI::aclFormatter();
@ -2376,7 +2405,7 @@ class Item
Logger::notice('User ' . $uid . ": expired $expired items; expire items: $expire_items, expire notes: $expire_notes, expire starred: $expire_starred, expire photos: $expire_photos"); Logger::notice('User ' . $uid . ": expired $expired items; expire items: $expire_items, expire notes: $expire_notes, expire starred: $expire_starred, expire photos: $expire_photos");
} }
public static function firstPostDate($uid, $wall = false) public static function firstPostDate(int $uid, bool $wall = false)
{ {
$user = User::getById($uid, ['register_date']); $user = User::getById($uid, ['register_date']);
if (empty($user)) { if (empty($user)) {
@ -2417,7 +2446,7 @@ class Item
* array $arr * array $arr
* 'post_id' => ID of posted item * 'post_id' => ID of posted item
*/ */
public static function performActivity(int $item_id, string $verb, int $uid, string $allow_cid = null, string $allow_gid = null, string $deny_cid = null, string $deny_gid = null) public static function performActivity(int $item_id, string $verb, int $uid, string $allow_cid = null, string $allow_gid = null, string $deny_cid = null, string $deny_gid = null): bool
{ {
if (empty($uid)) { if (empty($uid)) {
return false; return false;
@ -2611,7 +2640,7 @@ class Item
* @param integer $owner_id User ID for which the permissions should be fetched * @param integer $owner_id User ID for which the permissions should be fetched
* @return array condition * @return array condition
*/ */
public static function getPermissionsConditionArrayByUserId(int $owner_id) public static function getPermissionsConditionArrayByUserId(int $owner_id): array
{ {
$local_user = local_user(); $local_user = local_user();
$remote_user = Session::getRemoteContactID($owner_id); $remote_user = Session::getRemoteContactID($owner_id);
@ -2643,7 +2672,7 @@ class Item
* @param string $table * @param string $table
* @return string * @return string
*/ */
public static function getPermissionsSQLByUserId(int $owner_id, string $table = '') public static function getPermissionsSQLByUserId(int $owner_id, string $table = ''): string
{ {
$local_user = local_user(); $local_user = local_user();
$remote_user = Session::getRemoteContactID($owner_id); $remote_user = Session::getRemoteContactID($owner_id);
@ -2691,7 +2720,7 @@ class Item
* @param \Friendica\Core\L10n $l10n * @param \Friendica\Core\L10n $l10n
* @return string * @return string
*/ */
public static function postType(array $item, \Friendica\Core\L10n $l10n) public static function postType(array $item, \Friendica\Core\L10n $l10n): string
{ {
if (!empty($item['event-id'])) { if (!empty($item['event-id'])) {
return $l10n->t('event'); return $l10n->t('event');
@ -2757,10 +2786,10 @@ class Item
* Given an item array, convert the body element from bbcode to html and add smilie icons. * Given an item array, convert the body element from bbcode to html and add smilie icons.
* If attach is true, also add icons for item attachments. * If attach is true, also add icons for item attachments.
* *
* @param array $item * @param array $item Record from item table
* @param boolean $attach * @param boolean $attach If true, add icons for item attachments as well
* @param boolean $is_preview * @param boolean $is_preview Whether this is a preview
* @param boolean $only_cache * @param boolean $only_cache Whether only cached HTML should be updated
* @return string item body html * @return string item body html
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
@ -2769,7 +2798,7 @@ class Item
* @hook prepare_body ('item'=>item array, 'html'=>body string, 'is_preview'=>boolean, 'filter_reasons'=>string array) after first bbcode to html * @hook prepare_body ('item'=>item array, 'html'=>body string, 'is_preview'=>boolean, 'filter_reasons'=>string array) after first bbcode to html
* @hook prepare_body_final ('item'=>item array, 'html'=>body string) after attach icons and blockquote special case handling (spoiler, author) * @hook prepare_body_final ('item'=>item array, 'html'=>body string) after attach icons and blockquote special case handling (spoiler, author)
*/ */
public static function prepareBody(array &$item, $attach = false, $is_preview = false, $only_cache = false) public static function prepareBody(array &$item, bool $attach = false, bool $is_preview = false, bool $only_cache = false): string
{ {
$a = DI::app(); $a = DI::app();
Hook::callAll('prepare_body_init', $item); Hook::callAll('prepare_body_init', $item);
@ -2802,7 +2831,8 @@ class Item
$shared_uri_id = 0; $shared_uri_id = 0;
$shared_links = []; $shared_links = [];
} }
$attachments = Post\Media::splitAttachments($item['uri-id'], $item['guid'] ?? '', $shared_links, $item['has-media']);
$attachments = Post\Media::splitAttachments($item['uri-id'], $item['guid'] ?? '', $shared_links, $item['has-media'] ?? false);
$item['body'] = self::replaceVisualAttachments($attachments, $item['body'] ?? ''); $item['body'] = self::replaceVisualAttachments($attachments, $item['body'] ?? '');
$item['body'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']); $item['body'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']);
@ -2811,7 +2841,7 @@ class Item
$s = $item["rendered-html"]; $s = $item["rendered-html"];
if ($only_cache) { if ($only_cache) {
return; return '';
} }
// Compile eventual content filter reasons // Compile eventual content filter reasons
@ -2891,7 +2921,7 @@ class Item
* @param int $type * @param int $type
* @return bool * @return bool
*/ */
public static function containsLink(string $body, string $url, int $type = 0) public static function containsLink(string $body, string $url, int $type = 0): bool
{ {
// Make sure that for example site parameters aren't used when testing if the link is contained in the body // Make sure that for example site parameters aren't used when testing if the link is contained in the body
$urlparts = parse_url($url); $urlparts = parse_url($url);
@ -2924,7 +2954,7 @@ class Item
* @param string $body * @param string $body
* @return string modified body * @return string modified body
*/ */
private static function replaceVisualAttachments(array $attachments, string $body) private static function replaceVisualAttachments(array $attachments, string $body): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
@ -2955,7 +2985,7 @@ class Item
* @param string $content * @param string $content
* @return string modified content * @return string modified content
*/ */
private static function addVisualAttachments(array $attachments, array $item, string $content, bool $shared) private static function addVisualAttachments(array $attachments, array $item, string $content, bool $shared): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$leading = ''; $leading = '';
@ -3047,7 +3077,7 @@ class Item
* @param array $ignore_links A list of URLs to ignore * @param array $ignore_links A list of URLs to ignore
* @return string modified content * @return string modified content
*/ */
private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links) private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
// Don't show a preview when there is a visual attachment (audio or video) // Don't show a preview when there is a visual attachment (audio or video)
@ -3161,7 +3191,7 @@ class Item
* @param string $content * @param string $content
* @return string modified content * @return string modified content
*/ */
private static function addNonVisualAttachments(array $attachments, array $item, string $content) private static function addNonVisualAttachments(array $attachments, array $item, string $content): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
$trailing = ''; $trailing = '';
@ -3193,7 +3223,7 @@ class Item
return $content; return $content;
} }
private static function addQuestions(array $item, string $content) private static function addQuestions(array $item, string $content): string
{ {
DI::profiler()->startRecording('rendering'); DI::profiler()->startRecording('rendering');
if (!empty($item['question-id'])) { if (!empty($item['question-id'])) {
@ -3244,7 +3274,7 @@ class Item
* @return boolean|array False if item has not plink, otherwise array('href'=>plink url, 'title'=>translated title) * @return boolean|array False if item has not plink, otherwise array('href'=>plink url, 'title'=>translated title)
* @throws \Exception * @throws \Exception
*/ */
public static function getPlink($item) public static function getPlink(array $item)
{ {
if (!empty($item['plink']) && Network::isValidHttpUrl($item['plink'])) { if (!empty($item['plink']) && Network::isValidHttpUrl($item['plink'])) {
$plink = $item['plink']; $plink = $item['plink'];
@ -3291,7 +3321,7 @@ class Item
* *
* @return boolean "true" when it is a forum post * @return boolean "true" when it is a forum post
*/ */
public static function isForumPost(int $uri_id) public static function isForumPost(int $uri_id): bool
{ {
foreach (Tag::getByURIId($uri_id, [Tag::EXCLUSIVE_MENTION]) as $tag) { foreach (Tag::getByURIId($uri_id, [Tag::EXCLUSIVE_MENTION]) as $tag) {
if (DBA::exists('contact', ['uid' => 0, 'nurl' => Strings::normaliseLink($tag['url']), 'contact-type' => Contact::TYPE_COMMUNITY])) { if (DBA::exists('contact', ['uid' => 0, 'nurl' => Strings::normaliseLink($tag['url']), 'contact-type' => Contact::TYPE_COMMUNITY])) {
@ -3309,7 +3339,7 @@ class Item
* *
* @return integer item id * @return integer item id
*/ */
public static function searchByLink($uri, $uid = 0) public static function searchByLink(string $uri, int $uid = 0): int
{ {
$ssl_uri = str_replace('http://', 'https://', $uri); $ssl_uri = str_replace('http://', 'https://', $uri);
$uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)]; $uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)];
@ -3334,7 +3364,7 @@ class Item
* *
* @return string URI * @return string URI
*/ */
public static function getURIByLink(string $uri) public static function getURIByLink(string $uri): string
{ {
$ssl_uri = str_replace('http://', 'https://', $uri); $ssl_uri = str_replace('http://', 'https://', $uri);
$uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)]; $uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)];
@ -3360,7 +3390,7 @@ class Item
* *
* @return integer item id * @return integer item id
*/ */
public static function fetchByLink(string $uri, int $uid = 0) public static function fetchByLink(string $uri, int $uid = 0): int
{ {
Logger::info('Trying to fetch link', ['uid' => $uid, 'uri' => $uri]); Logger::info('Trying to fetch link', ['uid' => $uid, 'uri' => $uri]);
$item_id = self::searchByLink($uri, $uid); $item_id = self::searchByLink($uri, $uid);
@ -3406,7 +3436,7 @@ class Item
* *
* @return array with share information * @return array with share information
*/ */
public static function getShareArray($item) public static function getShareArray(array $item): array
{ {
if (!preg_match("/(.*?)\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", $item['body'], $matches)) { if (!preg_match("/(.*?)\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", $item['body'], $matches)) {
return []; return [];
@ -3429,7 +3459,7 @@ class Item
* *
* @return array item array with data from the original item * @return array item array with data from the original item
*/ */
public static function addShareDataFromOriginal(array $item) public static function addShareDataFromOriginal(array $item): array
{ {
$shared = self::getShareArray($item); $shared = self::getShareArray($item);
if (empty($shared)) { if (empty($shared)) {
@ -3490,7 +3520,7 @@ class Item
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
protected static function isAllowedByUser(array $item, int $user_id) protected static function isAllowedByUser(array $item, int $user_id): bool
{ {
if (!empty($item['author-id']) && Contact\User::isBlocked($item['author-id'], $user_id)) { if (!empty($item['author-id']) && Contact\User::isBlocked($item['author-id'], $user_id)) {
Logger::notice('Author is blocked by user', ['author-link' => $item['author-link'], 'uid' => $user_id, 'item-uri' => $item['uri']]); Logger::notice('Author is blocked by user', ['author-link' => $item['author-link'], 'uid' => $user_id, 'item-uri' => $item['uri']]);
@ -3522,7 +3552,7 @@ class Item
* @param array $item * @param array $item
* @return string body * @return string body
*/ */
public static function improveSharedDataInBody(array $item) public static function improveSharedDataInBody(array $item): string
{ {
$shared = BBCode::fetchShareAttributes($item['body']); $shared = BBCode::fetchShareAttributes($item['body']);
if (empty($shared['link'])) { if (empty($shared['link'])) {

View file

@ -30,7 +30,6 @@ class ItemURI
* Insert an item-uri record and return its id * Insert an item-uri record and return its id
* *
* @param array $fields Item-uri fields * @param array $fields Item-uri fields
*
* @return int|null item-uri id * @return int|null item-uri id
* @throws \Exception * @throws \Exception
*/ */
@ -61,12 +60,15 @@ class ItemURI
* Searched for an id of a given uri. Adds it, if not existing yet. * Searched for an id of a given uri. Adds it, if not existing yet.
* *
* @param string $uri * @param string $uri
*
* @return integer item-uri id * @return integer item-uri id
* @throws \Exception * @throws \Exception
*/ */
public static function getIdByURI($uri) public static function getIdByURI(string $uri): int
{ {
if (empty($uri)) {
return 0;
}
// If the URI gets too long we only take the first parts and hope for best // If the URI gets too long we only take the first parts and hope for best
$uri = substr($uri, 0, 255); $uri = substr($uri, 0, 255);
@ -82,11 +84,10 @@ class ItemURI
* Searched for an id of a given guid. * Searched for an id of a given guid.
* *
* @param string $guid * @param string $guid
*
* @return integer item-uri id * @return integer item-uri id
* @throws \Exception * @throws \Exception
*/ */
public static function getIdByGUID($guid) public static function getIdByGUID(string $guid): int
{ {
// If the GUID gets too long we only take the first parts and hope for best // If the GUID gets too long we only take the first parts and hope for best
$guid = substr($guid, 0, 255); $guid = substr($guid, 0, 255);

View file

@ -45,7 +45,7 @@ class ParsedLogIterator implements \Iterator
private $filters = []; private $filters = [];
/** @var string search term */ /** @var string search term */
private $search = ""; private $search = '';
/** /**
@ -60,7 +60,7 @@ class ParsedLogIterator implements \Iterator
* @param string $filename File to open * @param string $filename File to open
* @return $this * @return $this
*/ */
public function open(string $filename) public function open(string $filename): ParsedLogIterator
{ {
$this->reader->open($filename); $this->reader->open($filename);
return $this; return $this;
@ -70,7 +70,7 @@ class ParsedLogIterator implements \Iterator
* @param int $limit Max num of lines to read * @param int $limit Max num of lines to read
* @return $this * @return $this
*/ */
public function withLimit(int $limit) public function withLimit(int $limit): ParsedLogIterator
{ {
$this->limit = $limit; $this->limit = $limit;
return $this; return $this;
@ -80,7 +80,7 @@ class ParsedLogIterator implements \Iterator
* @param array $filters filters per column * @param array $filters filters per column
* @return $this * @return $this
*/ */
public function withFilters(array $filters) public function withFilters(array $filters): ParsedLogIterator
{ {
$this->filters = $filters; $this->filters = $filters;
return $this; return $this;
@ -90,7 +90,7 @@ class ParsedLogIterator implements \Iterator
* @param string $search string to search to filter lines * @param string $search string to search to filter lines
* @return $this * @return $this
*/ */
public function withSearch(string $search) public function withSearch(string $search): ParsedLogIterator
{ {
$this->search = $search; $this->search = $search;
return $this; return $this;
@ -100,18 +100,19 @@ class ParsedLogIterator implements \Iterator
* Check if parsed log line match filters. * Check if parsed log line match filters.
* Always match if no filters are set. * Always match if no filters are set.
* *
* @param ParsedLogLine $parsedlogline * @param ParsedLogLine $parsedlogline ParsedLogLine instance
* @return bool * @return bool Wether the parse log line matches
*/ */
private function filter($parsedlogline) private function filter(ParsedLogLine $parsedlogline): bool
{ {
$match = true; $match = true;
foreach ($this->filters as $filter => $filtervalue) { foreach ($this->filters as $filter => $filtervalue) {
switch ($filter) { switch ($filter) {
case "level": case 'level':
$match = $match && ($parsedlogline->level == strtoupper($filtervalue)); $match = $match && ($parsedlogline->level == strtoupper($filtervalue));
break; break;
case "context":
case 'context':
$match = $match && ($parsedlogline->context == $filtervalue); $match = $match && ($parsedlogline->context == $filtervalue);
break; break;
} }
@ -126,9 +127,9 @@ class ParsedLogIterator implements \Iterator
* @param ParsedLogLine $parsedlogline * @param ParsedLogLine $parsedlogline
* @return bool * @return bool
*/ */
private function search($parsedlogline) private function search(ParsedLogLine $parsedlogline): bool
{ {
if ($this->search != "") { if ($this->search != '') {
return strstr($parsedlogline->logline, $this->search) !== false; return strstr($parsedlogline->logline, $this->search) !== false;
} }
return true; return true;
@ -138,7 +139,6 @@ class ParsedLogIterator implements \Iterator
* Read a line from reader and parse. * Read a line from reader and parse.
* Returns null if limit is reached or the reader is invalid. * Returns null if limit is reached or the reader is invalid.
* *
* @param ParsedLogLine $parsedlogline
* @return ?ParsedLogLine * @return ?ParsedLogLine
*/ */
private function read() private function read()
@ -191,7 +191,7 @@ class ParsedLogIterator implements \Iterator
* @see ReversedFileReader::key() * @see ReversedFileReader::key()
* @return int * @return int
*/ */
public function key() public function key(): int
{ {
return $this->reader->key(); return $this->reader->key();
} }
@ -213,8 +213,8 @@ class ParsedLogIterator implements \Iterator
* @see Iterator::valid() * @see Iterator::valid()
* @return bool * @return bool
*/ */
public function valid() public function valid(): bool
{ {
return ! is_null($this->value); return !is_null($this->value);
} }
} }

View file

@ -45,7 +45,7 @@ class Mail
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function insert($msg, $notification = true) public static function insert(array $msg, bool $notification = true)
{ {
if (!isset($msg['reply'])) { if (!isset($msg['reply'])) {
$msg['reply'] = DBA::exists('mail', ['parent-uri' => $msg['parent-uri']]); $msg['reply'] = DBA::exists('mail', ['parent-uri' => $msg['parent-uri']]);
@ -125,7 +125,7 @@ class Mail
* @return int * @return int
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function send($recipient = 0, $body = '', $subject = '', $replyto = '') public static function send(int $recipient = 0, string $body = '', string $subject = '', string $replyto = ''): int
{ {
$a = DI::app(); $a = DI::app();
@ -255,7 +255,7 @@ class Mail
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function sendWall(array $recipient = [], $body = '', $subject = '', $replyto = '') public static function sendWall(array $recipient = [], string $body = '', string $subject = '', string $replyto = ''): int
{ {
if (!$recipient) { if (!$recipient) {
return -1; return -1;

View file

@ -22,6 +22,7 @@
namespace Friendica\Model; namespace Friendica\Model;
use Friendica\Core\Addon; use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use stdClass; use stdClass;
@ -101,7 +102,7 @@ class Nodeinfo
* *
* @return array with supported services * @return array with supported services
*/ */
public static function getServices() public static function getServices(): array
{ {
$services = [ $services = [
'inbound' => [], 'inbound' => [],
@ -156,9 +157,19 @@ class Nodeinfo
return $services; return $services;
} }
public static function getOrganization($config) /**
* Gathers organization information and returns it as an array
*
* @param IManageConfigValues $config Configuration instance
* @return array Organization information
*/
public static function getOrganization(IManageConfigValues $config): array
{ {
$organization = ['name' => null, 'contact' => null, 'account' => null]; $organization = [
'name' => null,
'contact' => null,
'account' => null
];
if (!empty($config->get('config', 'admin_email'))) { if (!empty($config->get('config', 'admin_email'))) {
$adminList = explode(',', str_replace(' ', '', $config->get('config', 'admin_email'))); $adminList = explode(',', str_replace(' ', '', $config->get('config', 'admin_email')));

View file

@ -36,20 +36,19 @@ class OpenWebAuthToken
* @param int $uid The user ID. * @param int $uid The user ID.
* @param string $token * @param string $token
* @param string $meta * @param string $meta
*
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function create($type, $uid, $token, $meta) public static function create(string $type, uid $uid, string $token, string $meta)
{ {
$fields = [ $fields = [
"type" => $type, 'type' => $type,
"uid" => $uid, 'uid' => $uid,
"token" => $token, 'token' => $token,
"meta" => $meta, 'meta' => $meta,
"created" => DateTimeFormat::utcNow() 'created' => DateTimeFormat::utcNow()
]; ];
return DBA::insert("openwebauth-token", $fields); return DBA::insert('openwebauth-token', $fields);
} }
/** /**
@ -62,15 +61,15 @@ class OpenWebAuthToken
* @return string|boolean The meta enry or false if not found. * @return string|boolean The meta enry or false if not found.
* @throws \Exception * @throws \Exception
*/ */
public static function getMeta($type, $uid, $token) public static function getMeta(string $type, int $uid, string $token)
{ {
$condition = ["type" => $type, "uid" => $uid, "token" => $token]; $condition = ['type' => $type, 'uid' => $uid, 'token' => $token];
$entry = DBA::selectFirst("openwebauth-token", ["id", "meta"], $condition); $entry = DBA::selectFirst('openwebauth-token', ['id', 'meta'], $condition);
if (DBA::isResult($entry)) { if (DBA::isResult($entry)) {
DBA::delete("openwebauth-token", ["id" => $entry["id"]]); DBA::delete('openwebauth-token', ['id' => $entry['id']]);
return $entry["meta"]; return $entry['meta'];
} }
return false; return false;
} }
@ -80,12 +79,13 @@ class OpenWebAuthToken
* *
* @param string $type Verify type. * @param string $type Verify type.
* @param string $interval SQL compatible time interval * @param string $interval SQL compatible time interval
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function purge($type, $interval) public static function purge(string $type, string $interval)
{ {
$condition = ["`type` = ? AND `created` < ?", $type, DateTimeFormat::utcNow() . " - INTERVAL " . $interval]; $condition = ["`type` = ? AND `created` < ?", $type, DateTimeFormat::utcNow() . ' - INTERVAL ' . $interval];
DBA::delete("openwebauth-token", $condition); DBA::delete('openwebauth-token', $condition);
} }
} }

View file

@ -94,7 +94,7 @@ class Photo
$fields = self::getFields(); $fields = self::getFields();
} }
return DBA::selectFirst("photo", $fields, $conditions, $params); return DBA::selectFirst('photo', $fields, $conditions, $params);
} }
/** /**
@ -110,10 +110,10 @@ class Photo
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::select * @see \Friendica\Database\DBA::select
*/ */
public static function getPhotosForUser($uid, $resourceid, array $conditions = [], array $params = []) public static function getPhotosForUser(int $uid, string $resourceid, array $conditions = [], array $params = [])
{ {
$conditions["resource-id"] = $resourceid; $conditions['resource-id'] = $resourceid;
$conditions["uid"] = $uid; $conditions['uid'] = $uid;
return self::selectToArray([], $conditions, $params); return self::selectToArray([], $conditions, $params);
} }
@ -132,11 +132,11 @@ class Photo
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::select * @see \Friendica\Database\DBA::select
*/ */
public static function getPhotoForUser($uid, $resourceid, $scale = 0, array $conditions = [], array $params = []) public static function getPhotoForUser(int $uid, $resourceid, $scale = 0, array $conditions = [], array $params = [])
{ {
$conditions["resource-id"] = $resourceid; $conditions['resource-id'] = $resourceid;
$conditions["uid"] = $uid; $conditions['uid'] = $uid;
$conditions["scale"] = $scale; $conditions['scale'] = $scale;
return self::selectFirst([], $conditions, $params); return self::selectFirst([], $conditions, $params);
} }
@ -156,19 +156,19 @@ class Photo
*/ */
public static function getPhoto(string $resourceid, int $scale = 0) public static function getPhoto(string $resourceid, int $scale = 0)
{ {
$r = self::selectFirst(["uid"], ["resource-id" => $resourceid]); $r = self::selectFirst(['uid'], ['resource-id' => $resourceid]);
if (!DBA::isResult($r)) { if (!DBA::isResult($r)) {
return false; return false;
} }
$uid = $r["uid"]; $uid = $r['uid'];
$accessible = $uid ? (bool)DI::pConfig()->get($uid, 'system', 'accessible-photos', false) : false; $accessible = $uid ? (bool)DI::pConfig()->get($uid, 'system', 'accessible-photos', false) : false;
$sql_acl = Security::getPermissionsSQLByUserId($uid, $accessible); $sql_acl = Security::getPermissionsSQLByUserId($uid, $accessible);
$conditions = ["`resource-id` = ? AND `scale` <= ? " . $sql_acl, $resourceid, $scale]; $conditions = ["`resource-id` = ? AND `scale` <= ? " . $sql_acl, $resourceid, $scale];
$params = ["order" => ["scale" => true]]; $params = ['order' => ['scale' => true]];
$photo = self::selectFirst([], $conditions, $params); $photo = self::selectFirst([], $conditions, $params);
return $photo; return $photo;
@ -182,9 +182,9 @@ class Photo
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function exists(array $conditions) public static function exists(array $conditions): bool
{ {
return DBA::exists("photo", $conditions); return DBA::exists('photo', $conditions);
} }
@ -193,7 +193,7 @@ class Photo
* *
* @param array $photo Photo data. Needs at least 'id', 'type', 'backend-class', 'backend-ref' * @param array $photo Photo data. Needs at least 'id', 'type', 'backend-class', 'backend-ref'
* *
* @return \Friendica\Object\Image * @return \Friendica\Object\Image|null Image object or null on error
*/ */
public static function getImageDataForPhoto(array $photo) public static function getImageDataForPhoto(array $photo)
{ {
@ -248,11 +248,11 @@ class Photo
* @return array field list * @return array field list
* @throws \Exception * @throws \Exception
*/ */
private static function getFields() private static function getFields(): array
{ {
$allfields = DBStructure::definition(DI::app()->getBasePath(), false); $allfields = DBStructure::definition(DI::app()->getBasePath(), false);
$fields = array_keys($allfields["photo"]["fields"]); $fields = array_keys($allfields['photo']['fields']);
array_splice($fields, array_search("data", $fields), 1); array_splice($fields, array_search('data', $fields), 1);
return $fields; return $fields;
} }
@ -265,14 +265,14 @@ class Photo
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function createPhotoForSystemResource($filename, $mimetype = '') public static function createPhotoForSystemResource(string $filename, string $mimetype = ''): array
{ {
if (empty($mimetype)) { if (empty($mimetype)) {
$mimetype = Images::guessTypeByExtension($filename); $mimetype = Images::guessTypeByExtension($filename);
} }
$fields = self::getFields(); $fields = self::getFields();
$values = array_fill(0, count($fields), ""); $values = array_fill(0, count($fields), '');
$photo = array_combine($fields, $values); $photo = array_combine($fields, $values);
$photo['backend-class'] = SystemResource::NAME; $photo['backend-class'] = SystemResource::NAME;
@ -293,14 +293,14 @@ class Photo
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function createPhotoForExternalResource($url, $uid = 0, $mimetype = '') public static function createPhotoForExternalResource(string $url, int $uid = 0, string $mimetype = ''): array
{ {
if (empty($mimetype)) { if (empty($mimetype)) {
$mimetype = Images::guessTypeByExtension($url); $mimetype = Images::guessTypeByExtension($url);
} }
$fields = self::getFields(); $fields = self::getFields();
$values = array_fill(0, count($fields), ""); $values = array_fill(0, count($fields), '');
$photo = array_combine($fields, $values); $photo = array_combine($fields, $values);
$photo['backend-class'] = ExternalResource::NAME; $photo['backend-class'] = ExternalResource::NAME;
@ -314,14 +314,14 @@ class Photo
/** /**
* store photo metadata in db and binary in default backend * store photo metadata in db and binary in default backend
* *
* @param Image $Image Image object with data * @param Image $image Image object with data
* @param integer $uid User ID * @param integer $uid User ID
* @param integer $cid Contact ID * @param integer $cid Contact ID
* @param integer $rid Resource ID * @param string $rid Resource ID
* @param string $filename Filename * @param string $filename Filename
* @param string $album Album name * @param string $album Album name
* @param integer $scale Scale * @param integer $scale Scale
* @param integer $profile Is a profile image? optional, default = 0 * @param integer $type Photo type, optional, default: Photo::DEFAULT
* @param string $allow_cid Permissions, allowed contacts. optional, default = "" * @param string $allow_cid Permissions, allowed contacts. optional, default = ""
* @param string $allow_gid Permissions, allowed groups. optional, default = "" * @param string $allow_gid Permissions, allowed groups. optional, default = ""
* @param string $deny_cid Permissions, denied contacts.optional, default = "" * @param string $deny_cid Permissions, denied contacts.optional, default = ""
@ -331,71 +331,71 @@ class Photo
* @return boolean True on success * @return boolean True on success
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function store(Image $Image, $uid, $cid, $rid, $filename, $album, $scale, $type = self::DEFAULT, $allow_cid = "", $allow_gid = "", $deny_cid = "", $deny_gid = "", $desc = "") public static function store(Image $image, int $uid, int $cid, string $rid, string $filename, string $album, int $scale, int $type = self::DEFAULT, string $allow_cid = '', string $allow_gid = '', string $deny_cid = '', string $deny_gid = '', string $desc = ''): bool
{ {
$photo = self::selectFirst(["guid"], ["`resource-id` = ? AND `guid` != ?", $rid, ""]); $photo = self::selectFirst(['guid'], ["`resource-id` = ? AND `guid` != ?", $rid, '']);
if (DBA::isResult($photo)) { if (DBA::isResult($photo)) {
$guid = $photo["guid"]; $guid = $photo['guid'];
} else { } else {
$guid = System::createGUID(); $guid = System::createGUID();
} }
$existing_photo = self::selectFirst(["id", "created", "backend-class", "backend-ref"], ["resource-id" => $rid, "uid" => $uid, "contact-id" => $cid, "scale" => $scale]); $existing_photo = self::selectFirst(['id', 'created', 'backend-class', 'backend-ref'], ['resource-id' => $rid, 'uid' => $uid, 'contact-id' => $cid, 'scale' => $scale]);
$created = DateTimeFormat::utcNow(); $created = DateTimeFormat::utcNow();
if (DBA::isResult($existing_photo)) { if (DBA::isResult($existing_photo)) {
$created = $existing_photo["created"]; $created = $existing_photo['created'];
} }
// Get defined storage backend. // Get defined storage backend.
// if no storage backend, we use old "data" column in photo table. // if no storage backend, we use old "data" column in photo table.
// if is an existing photo, reuse same backend // if is an existing photo, reuse same backend
$data = ""; $data = '';
$backend_ref = ""; $backend_ref = '';
$storage = ""; $storage = '';
try { try {
if (DBA::isResult($existing_photo)) { if (DBA::isResult($existing_photo)) {
$backend_ref = (string)$existing_photo["backend-ref"]; $backend_ref = (string)$existing_photo['backend-ref'];
$storage = DI::storageManager()->getWritableStorageByName($existing_photo["backend-class"] ?? ''); $storage = DI::storageManager()->getWritableStorageByName($existing_photo['backend-class'] ?? '');
} else { } else {
$storage = DI::storage(); $storage = DI::storage();
} }
$backend_ref = $storage->put($Image->asString(), $backend_ref); $backend_ref = $storage->put($image->asString(), $backend_ref);
} catch (InvalidClassStorageException $storageException) { } catch (InvalidClassStorageException $storageException) {
$data = $Image->asString(); $data = $image->asString();
} }
$fields = [ $fields = [
"uid" => $uid, 'uid' => $uid,
"contact-id" => $cid, 'contact-id' => $cid,
"guid" => $guid, 'guid' => $guid,
"resource-id" => $rid, 'resource-id' => $rid,
"hash" => md5($Image->asString()), 'hash' => md5($image->asString()),
"created" => $created, 'created' => $created,
"edited" => DateTimeFormat::utcNow(), 'edited' => DateTimeFormat::utcNow(),
"filename" => basename($filename), 'filename' => basename($filename),
"type" => $Image->getType(), 'type' => $image->getType(),
"album" => $album, 'album' => $album,
"height" => $Image->getHeight(), 'height' => $image->getHeight(),
"width" => $Image->getWidth(), 'width' => $image->getWidth(),
"datasize" => strlen($Image->asString()), 'datasize' => strlen($image->asString()),
"data" => $data, 'data' => $data,
"scale" => $scale, 'scale' => $scale,
"photo-type" => $type, 'photo-type' => $type,
"profile" => false, 'profile' => false,
"allow_cid" => $allow_cid, 'allow_cid' => $allow_cid,
"allow_gid" => $allow_gid, 'allow_gid' => $allow_gid,
"deny_cid" => $deny_cid, 'deny_cid' => $deny_cid,
"deny_gid" => $deny_gid, 'deny_gid' => $deny_gid,
"desc" => $desc, 'desc' => $desc,
"backend-class" => (string)$storage, 'backend-class' => (string)$storage,
"backend-ref" => $backend_ref 'backend-ref' => $backend_ref
]; ];
if (DBA::isResult($existing_photo)) { if (DBA::isResult($existing_photo)) {
$r = DBA::update("photo", $fields, ["id" => $existing_photo["id"]]); $r = DBA::update('photo', $fields, ['id' => $existing_photo['id']]);
} else { } else {
$r = DBA::insert("photo", $fields); $r = DBA::insert('photo', $fields);
} }
return $r; return $r;
@ -413,7 +413,7 @@ class Photo
* @throws \Exception * @throws \Exception
* @see \Friendica\Database\DBA::delete * @see \Friendica\Database\DBA::delete
*/ */
public static function delete(array $conditions, array $options = []) public static function delete(array $conditions, array $options = []): bool
{ {
// get photo to delete data info // get photo to delete data info
$photos = DBA::select('photo', ['id', 'backend-class', 'backend-ref'], $conditions); $photos = DBA::select('photo', ['id', 'backend-class', 'backend-ref'], $conditions);
@ -423,7 +423,7 @@ class Photo
$backend_class = DI::storageManager()->getWritableStorageByName($photo['backend-class'] ?? ''); $backend_class = DI::storageManager()->getWritableStorageByName($photo['backend-class'] ?? '');
$backend_class->delete($photo['backend-ref'] ?? ''); $backend_class->delete($photo['backend-ref'] ?? '');
// Delete the photos after they had been deleted successfully // Delete the photos after they had been deleted successfully
DBA::delete("photo", ['id' => $photo['id']]); DBA::delete('photo', ['id' => $photo['id']]);
} catch (InvalidClassStorageException $storageException) { } catch (InvalidClassStorageException $storageException) {
DI::logger()->debug('Storage class not found.', ['conditions' => $conditions, 'exception' => $storageException]); DI::logger()->debug('Storage class not found.', ['conditions' => $conditions, 'exception' => $storageException]);
} catch (ReferenceStorageException $referenceStorageException) { } catch (ReferenceStorageException $referenceStorageException) {
@ -433,34 +433,34 @@ class Photo
DBA::close($photos); DBA::close($photos);
return DBA::delete("photo", $conditions, $options); return DBA::delete('photo', $conditions, $options);
} }
/** /**
* Update a photo * Update a photo
* *
* @param array $fields Contains the fields that are updated * @param array $fields Contains the fields that are updated
* @param array $conditions Condition array with the key values * @param array $conditions Condition array with the key values
* @param Image $img Image to update. Optional, default null. * @param Image $image Image to update. Optional, default null.
* @param array|boolean $old_fields Array with the old field values that are about to be replaced (true = update on duplicate) * @param array $old_fields Array with the old field values that are about to be replaced (true = update on duplicate)
* *
* @return boolean Was the update successfull? * @return boolean Was the update successfull?
* *
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @see \Friendica\Database\DBA::update * @see \Friendica\Database\DBA::update
*/ */
public static function update($fields, $conditions, Image $img = null, array $old_fields = []) public static function update(array $fields, array $conditions, Image $image = null, array $old_fields = []): bool
{ {
if (!is_null($img)) { if (!is_null($image)) {
// get photo to update // get photo to update
$photos = self::selectToArray(['backend-class', 'backend-ref'], $conditions); $photos = self::selectToArray(['backend-class', 'backend-ref'], $conditions);
foreach($photos as $photo) { foreach($photos as $photo) {
try { try {
$backend_class = DI::storageManager()->getWritableStorageByName($photo['backend-class'] ?? ''); $backend_class = DI::storageManager()->getWritableStorageByName($photo['backend-class'] ?? '');
$fields["backend-ref"] = $backend_class->put($img->asString(), $photo['backend-ref']); $fields['backend-ref'] = $backend_class->put($image->asString(), $photo['backend-ref']);
} catch (InvalidClassStorageException $storageException) { } catch (InvalidClassStorageException $storageException) {
$fields["data"] = $img->asString(); $fields['data'] = $image->asString();
} }
} }
$fields['updated'] = DateTimeFormat::utcNow(); $fields['updated'] = DateTimeFormat::utcNow();
@ -468,7 +468,7 @@ class Photo
$fields['edited'] = DateTimeFormat::utcNow(); $fields['edited'] = DateTimeFormat::utcNow();
return DBA::update("photo", $fields, $conditions, $old_fields); return DBA::update('photo', $fields, $conditions, $old_fields);
} }
/** /**
@ -476,20 +476,20 @@ class Photo
* @param integer $uid user id * @param integer $uid user id
* @param integer $cid contact id * @param integer $cid contact id
* @param boolean $quit_on_error optional, default false * @param boolean $quit_on_error optional, default false
* @return array * @return array|bool Array on success, false on error
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function importProfilePhoto($image_url, $uid, $cid, $quit_on_error = false) public static function importProfilePhoto(string $image_url, int $uid, int $cid, bool $quit_on_error = false)
{ {
$thumb = ""; $thumb = '';
$micro = ""; $micro = '';
$photo = DBA::selectFirst( $photo = DBA::selectFirst(
"photo", ["resource-id"], ["uid" => $uid, "contact-id" => $cid, "scale" => 4, "photo-type" => self::CONTACT_AVATAR] 'photo', ['resource-id'], ['uid' => $uid, 'contact-id' => $cid, 'scale' => 4, 'photo-type' => self::CONTACT_AVATAR]
); );
if (!empty($photo['resource-id'])) { if (!empty($photo['resource-id'])) {
$resource_id = $photo["resource-id"]; $resource_id = $photo['resource-id'];
} else { } else {
$resource_id = self::newResource(); $resource_id = self::newResource();
} }
@ -507,66 +507,66 @@ class Photo
$type = ''; $type = '';
} }
if ($quit_on_error && ($img_str == "")) { if ($quit_on_error && ($img_str == '')) {
return false; return false;
} }
$type = Images::getMimeTypeByData($img_str, $image_url, $type); $type = Images::getMimeTypeByData($img_str, $image_url, $type);
$Image = new Image($img_str, $type); $image = new Image($img_str, $type);
if ($Image->isValid()) { if ($image->isValid()) {
$Image->scaleToSquare(300); $image->scaleToSquare(300);
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
$maximagesize = DI::config()->get('system', 'maximagesize'); $maximagesize = DI::config()->get('system', 'maximagesize');
if (!empty($maximagesize) && ($filesize > $maximagesize)) { if (!empty($maximagesize) && ($filesize > $maximagesize)) {
Logger::info('Avatar exceeds image limit', ['uid' => $uid, 'cid' => $cid, 'maximagesize' => $maximagesize, 'size' => $filesize, 'type' => $Image->getType()]); Logger::info('Avatar exceeds image limit', ['uid' => $uid, 'cid' => $cid, 'maximagesize' => $maximagesize, 'size' => $filesize, 'type' => $image->getType()]);
if ($Image->getType() == 'image/gif') { if ($image->getType() == 'image/gif') {
$Image->toStatic(); $image->toStatic();
$Image = new Image($Image->asString(), 'image/png'); $image = new Image($image->asString(), 'image/png');
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
Logger::info('Converted gif to a static png', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $Image->getType()]); Logger::info('Converted gif to a static png', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $image->getType()]);
} }
if ($filesize > $maximagesize) { if ($filesize > $maximagesize) {
foreach ([160, 80] as $pixels) { foreach ([160, 80] as $pixels) {
if ($filesize > $maximagesize) { if ($filesize > $maximagesize) {
Logger::info('Resize', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'max' => $maximagesize, 'pixels' => $pixels, 'type' => $Image->getType()]); Logger::info('Resize', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'max' => $maximagesize, 'pixels' => $pixels, 'type' => $image->getType()]);
$Image->scaleDown($pixels); $image->scaleDown($pixels);
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
} }
} }
} }
Logger::info('Avatar is resized', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $Image->getType()]); Logger::info('Avatar is resized', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $image->getType()]);
} }
$r = self::store($Image, $uid, $cid, $resource_id, $filename, self::CONTACT_PHOTOS, 4, self::CONTACT_AVATAR); $r = self::store($image, $uid, $cid, $resource_id, $filename, self::CONTACT_PHOTOS, 4, self::CONTACT_AVATAR);
if ($r === false) { if ($r === false) {
$photo_failure = true; $photo_failure = true;
} }
$Image->scaleDown(80); $image->scaleDown(80);
$r = self::store($Image, $uid, $cid, $resource_id, $filename, self::CONTACT_PHOTOS, 5, self::CONTACT_AVATAR); $r = self::store($image, $uid, $cid, $resource_id, $filename, self::CONTACT_PHOTOS, 5, self::CONTACT_AVATAR);
if ($r === false) { if ($r === false) {
$photo_failure = true; $photo_failure = true;
} }
$Image->scaleDown(48); $image->scaleDown(48);
$r = self::store($Image, $uid, $cid, $resource_id, $filename, self::CONTACT_PHOTOS, 6, self::CONTACT_AVATAR); $r = self::store($image, $uid, $cid, $resource_id, $filename, self::CONTACT_PHOTOS, 6, self::CONTACT_AVATAR);
if ($r === false) { if ($r === false) {
$photo_failure = true; $photo_failure = true;
} }
$suffix = "?ts=" . time(); $suffix = '?ts=' . time();
$image_url = DI::baseUrl() . "/photo/" . $resource_id . "-4." . $Image->getExt() . $suffix; $image_url = DI::baseUrl() . '/photo/' . $resource_id . '-4.' . $image->getExt() . $suffix;
$thumb = DI::baseUrl() . "/photo/" . $resource_id . "-5." . $Image->getExt() . $suffix; $thumb = DI::baseUrl() . '/photo/' . $resource_id . '-5.' . $image->getExt() . $suffix;
$micro = DI::baseUrl() . "/photo/" . $resource_id . "-6." . $Image->getExt() . $suffix; $micro = DI::baseUrl() . '/photo/' . $resource_id . '-6.' . $image->getExt() . $suffix;
} else { } else {
$photo_failure = true; $photo_failure = true;
} }
@ -590,31 +590,33 @@ class Photo
* @param string $hemi hemi * @param string $hemi hemi
* @return float * @return float
*/ */
public static function getGps($exifCoord, $hemi) public static function getGps(array $exifCoord, string $hemi): float
{ {
$degrees = count($exifCoord) > 0 ? self::gps2Num($exifCoord[0]) : 0; $degrees = count($exifCoord) > 0 ? self::gps2Num($exifCoord[0]) : 0;
$minutes = count($exifCoord) > 1 ? self::gps2Num($exifCoord[1]) : 0; $minutes = count($exifCoord) > 1 ? self::gps2Num($exifCoord[1]) : 0;
$seconds = count($exifCoord) > 2 ? self::gps2Num($exifCoord[2]) : 0; $seconds = count($exifCoord) > 2 ? self::gps2Num($exifCoord[2]) : 0;
$flip = ($hemi == "W" || $hemi == "S") ? -1 : 1; $flip = ($hemi == 'W' || $hemi == 'S') ? -1 : 1;
return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600))); return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600)));
} }
/** /**
* Change GPS to float number
*
* @param string $coordPart coordPart * @param string $coordPart coordPart
* @return float * @return float
*/ */
private static function gps2Num($coordPart) private static function gps2Num(string $coordPart): float
{ {
$parts = explode("/", $coordPart); $parts = explode('/', $coordPart);
if (count($parts) <= 0) { if (count($parts) <= 0) {
return 0; return 0;
} }
if (count($parts) == 1) { if (count($parts) == 1) {
return $parts[0]; return (float)$parts[0];
} }
return floatval($parts[0]) / floatval($parts[1]); return floatval($parts[0]) / floatval($parts[1]);
@ -631,17 +633,18 @@ class Photo
* @return array Returns array of the photo albums * @return array Returns array of the photo albums
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function getAlbums($uid, $update = false) public static function getAlbums(int $uid, bool $update = false): array
{ {
$sql_extra = Security::getPermissionsSQLByUserId($uid); $sql_extra = Security::getPermissionsSQLByUserId($uid);
$avatar_type = (local_user() && (local_user() == $uid)) ? self::USER_AVATAR : self::DEFAULT; $avatar_type = (local_user() && (local_user() == $uid)) ? self::USER_AVATAR : self::DEFAULT;
$banner_type = (local_user() && (local_user() == $uid)) ? self::USER_BANNER : self::DEFAULT; $banner_type = (local_user() && (local_user() == $uid)) ? self::USER_BANNER : self::DEFAULT;
$key = "photo_albums:".$uid.":".local_user().":".remote_user(); $key = 'photo_albums:' . $uid . ':' . local_user() . ':' . remote_user();
$albums = DI::cache()->get($key); $albums = DI::cache()->get($key);
if (is_null($albums) || $update) { if (is_null($albums) || $update) {
if (!DI::config()->get("system", "no_count", false)) { if (!DI::config()->get('system', 'no_count', false)) {
/// @todo This query needs to be renewed. It is really slow /// @todo This query needs to be renewed. It is really slow
// At this time we just store the data in the cache // At this time we just store the data in the cache
$albums = DBA::toArray(DBA::p("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, ANY_VALUE(`created`) AS `created` $albums = DBA::toArray(DBA::p("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, ANY_VALUE(`created`) AS `created`
@ -674,19 +677,19 @@ class Photo
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function clearAlbumCache($uid) public static function clearAlbumCache(int $uid)
{ {
$key = "photo_albums:".$uid.":".local_user().":".remote_user(); $key = 'photo_albums:' . $uid . ':' . local_user() . ':' . remote_user();
DI::cache()->set($key, null, Duration::DAY); DI::cache()->set($key, null, Duration::DAY);
} }
/** /**
* Generate a unique photo ID. * Generate a unique photo ID.
* *
* @return string * @return string Resource GUID
* @throws \Exception * @throws \Exception
*/ */
public static function newResource() public static function newResource(): string
{ {
return System::createGUID(32, false); return System::createGUID(32, false);
} }
@ -697,7 +700,7 @@ class Photo
* @param string $image_uri The URI of the photo * @param string $image_uri The URI of the photo
* @return string The rid of the photo, or an empty string if the URI is not local * @return string The rid of the photo, or an empty string if the URI is not local
*/ */
public static function ridFromURI(string $image_uri) public static function ridFromURI(string $image_uri): string
{ {
if (!stristr($image_uri, DI::baseUrl() . '/photo/')) { if (!stristr($image_uri, DI::baseUrl() . '/photo/')) {
return ''; return '';
@ -809,7 +812,7 @@ class Photo
* @param string $name Picture link * @param string $name Picture link
* @return array * @return array
*/ */
public static function getResourceData(string $name):array public static function getResourceData(string $name): array
{ {
$base = DI::baseUrl()->get(); $base = DI::baseUrl()->get();
@ -840,8 +843,9 @@ class Photo
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function isLocal($name) public static function isLocal(string $name): bool
{ {
// @TODO Maybe a proper check here on true condition?
return (bool)self::getIdForName($name); return (bool)self::getIdForName($name);
} }
@ -851,7 +855,7 @@ class Photo
* @param string $name Picture link * @param string $name Picture link
* @return int * @return int
*/ */
public static function getIdForName($name) public static function getIdForName(string $name): int
{ {
$data = self::getResourceData($name); $data = self::getResourceData($name);
if (empty($data)) { if (empty($data)) {
@ -872,7 +876,7 @@ class Photo
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function isLocalPage($name) public static function isLocalPage(string $name): bool
{ {
$base = DI::baseUrl()->get(); $base = DI::baseUrl()->get();
@ -885,17 +889,23 @@ class Photo
return DBA::exists('photo', ['resource-id' => $guid]); return DBA::exists('photo', ['resource-id' => $guid]);
} }
private static function fitImageSize($Image) /**
* Tries to resize image to wanted maximum size
*
* @param Image $image Image instance
* @return Image|null Image instance on success, null on error
*/
private static function fitImageSize(Image $image)
{ {
$max_length = DI::config()->get('system', 'max_image_length'); $max_length = DI::config()->get('system', 'max_image_length');
if ($max_length > 0) { if ($max_length > 0) {
$Image->scaleDown($max_length); $image->scaleDown($max_length);
Logger::info('File upload: Scaling picture to new size', ['max-length' => $max_length]); Logger::info('File upload: Scaling picture to new size', ['max-length' => $max_length]);
} }
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
$maximagesize = DI::config()->get('system', 'maximagesize'); $maximagesize = DI::config()->get('system', 'maximagesize');
@ -904,10 +914,10 @@ class Photo
foreach ([5120, 2560, 1280, 640] as $pixels) { foreach ([5120, 2560, 1280, 640] as $pixels) {
if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) { if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) {
Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]); Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]);
$Image->scaleDown($pixels); $image->scaleDown($pixels);
$filesize = strlen($Image->asString()); $filesize = strlen($image->asString());
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
} }
} }
if ($filesize > $maximagesize) { if ($filesize > $maximagesize) {
@ -916,10 +926,16 @@ class Photo
} }
} }
return $Image; return $image;
} }
private static function loadImageFromURL(string $image_url) /**
* Fetches image from URL and returns an array with instance and local file name
*
* @param string $image_url URL to image
* @return array With: 'image' and 'filename' fields or empty array on error
*/
private static function loadImageFromURL(string $image_url): array
{ {
$filename = basename($image_url); $filename = basename($image_url);
if (!empty($image_url)) { if (!empty($image_url)) {
@ -939,17 +955,23 @@ class Photo
$type = Images::getMimeTypeByData($img_str, $image_url, $type); $type = Images::getMimeTypeByData($img_str, $image_url, $type);
$Image = new Image($img_str, $type); $image = new Image($img_str, $type);
$Image = self::fitImageSize($Image); $image = self::fitImageSize($image);
if (empty($Image)) { if (empty($image)) {
return []; return [];
} }
return ['image' => $Image, 'filename' => $filename]; return ['image' => $image, 'filename' => $filename];
} }
private static function uploadImage(array $files) /**
* Inserts uploaded image into database and removes local temporary file
*
* @param array $files File array
* @return array With 'image' for Image instance and 'filename' for local file name or empty array on error
*/
private static function uploadImage(array $files): array
{ {
Logger::info('starting new upload'); Logger::info('starting new upload');
@ -1008,34 +1030,36 @@ class Photo
Logger::info('File upload', ['src' => $src, 'filename' => $filename, 'size' => $filesize, 'type' => $filetype]); Logger::info('File upload', ['src' => $src, 'filename' => $filename, 'size' => $filesize, 'type' => $filetype]);
$imagedata = @file_get_contents($src); $imagedata = @file_get_contents($src);
$Image = new Image($imagedata, $filetype); $image = new Image($imagedata, $filetype);
if (!$Image->isValid()) { if (!$image->isValid()) {
Logger::notice('Image is unvalid', ['files' => $files]); Logger::notice('Image is unvalid', ['files' => $files]);
return []; return [];
} }
$Image->orient($src); $image->orient($src);
@unlink($src); @unlink($src);
$Image = self::fitImageSize($Image); $image = self::fitImageSize($image);
if (empty($Image)) { if (empty($image)) {
return []; return [];
} }
return ['image' => $Image, 'filename' => $filename]; return ['image' => $image, 'filename' => $filename];
} }
/** /**
* Handles uploaded image and assigns it to given user id
*
* @param int $uid User ID * @param int $uid User ID
* @param array $files uploaded file array * @param array $files uploaded file array
* @param string $album * @param string $album Album name (optional)
* @param string|null $allow_cid * @param string|null $allow_cid
* @param string|null $allow_gid * @param string|null $allow_gid
* @param string $deny_cid * @param string $deny_cid
* @param string $deny_gid * @param string $deny_gid
* @param string $desc * @param string $desc Description (optional)
* @param string $resource_id * @param string $resource_id GUID (optional)
* @return array photo record * @return array photo record or empty array on error
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function upload(int $uid, array $files, string $album = '', string $allow_cid = null, string $allow_gid = null, string $deny_cid = '', string $deny_gid = '', string $desc = '', string $resource_id = ''): array public static function upload(int $uid, array $files, string $album = '', string $allow_cid = null, string $allow_gid = null, string $deny_cid = '', string $deny_gid = '', string $desc = '', string $resource_id = ''): array
@ -1052,10 +1076,10 @@ class Photo
return []; return [];
} }
$Image = $data['image']; $image = $data['image'];
$filename = $data['filename']; $filename = $data['filename'];
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
$resource_id = $resource_id ?: self::newResource(); $resource_id = $resource_id ?: self::newResource();
$album = $album ?: DI::l10n()->t('Wall Photos'); $album = $album ?: DI::l10n()->t('Wall Photos');
@ -1067,23 +1091,23 @@ class Photo
$smallest = 0; $smallest = 0;
$r = self::store($Image, $user['uid'], 0, $resource_id, $filename, $album, 0, self::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); $r = self::store($image, $user['uid'], 0, $resource_id, $filename, $album, 0, self::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) { if (!$r) {
Logger::notice('Photo could not be stored'); Logger::notice('Photo could not be stored');
return []; return [];
} }
if ($width > 640 || $height > 640) { if ($width > 640 || $height > 640) {
$Image->scaleDown(640); $image->scaleDown(640);
$r = self::store($Image, $user['uid'], 0, $resource_id, $filename, $album, 1, self::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); $r = self::store($image, $user['uid'], 0, $resource_id, $filename, $album, 1, self::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if ($r) { if ($r) {
$smallest = 1; $smallest = 1;
} }
} }
if ($width > 320 || $height > 320) { if ($width > 320 || $height > 320) {
$Image->scaleDown(320); $image->scaleDown(320);
$r = self::store($Image, $user['uid'], 0, $resource_id, $filename, $album, 2, self::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); $r = self::store($image, $user['uid'], 0, $resource_id, $filename, $album, 2, self::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if ($r && ($smallest == 0)) { if ($r && ($smallest == 0)) {
$smallest = 2; $smallest = 2;
} }
@ -1105,8 +1129,8 @@ class Photo
$picture['height'] = $photo['height']; $picture['height'] = $photo['height'];
$picture['type'] = $photo['type']; $picture['type'] = $photo['type'];
$picture['albumpage'] = DI::baseUrl() . '/photos/' . $user['nickname'] . '/image/' . $resource_id; $picture['albumpage'] = DI::baseUrl() . '/photos/' . $user['nickname'] . '/image/' . $resource_id;
$picture['picture'] = DI::baseUrl() . '/photo/{$resource_id}-0.' . $Image->getExt(); $picture['picture'] = DI::baseUrl() . '/photo/{$resource_id}-0.' . $image->getExt();
$picture['preview'] = DI::baseUrl() . '/photo/{$resource_id}-{$smallest}.' . $Image->getExt(); $picture['preview'] = DI::baseUrl() . '/photo/{$resource_id}-{$smallest}.' . $image->getExt();
Logger::info('upload done', ['picture' => $picture]); Logger::info('upload done', ['picture' => $picture]);
return $picture; return $picture;
@ -1139,10 +1163,10 @@ class Photo
return ''; return '';
} }
$Image = $data['image']; $image = $data['image'];
$filename = $data['filename']; $filename = $data['filename'];
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
$resource_id = self::newResource(); $resource_id = self::newResource();
$album = DI::l10n()->t(self::PROFILE_PHOTOS); $album = DI::l10n()->t(self::PROFILE_PHOTOS);
@ -1151,28 +1175,28 @@ class Photo
logger::info('starting new profile image upload'); logger::info('starting new profile image upload');
if ($width > 300 || $height > 300) { if ($width > 300 || $height > 300) {
$Image->scaleDown(300); $image->scaleDown(300);
} }
$r = self::store($Image, $uid, 0, $resource_id, $filename, $album, 4, self::USER_AVATAR); $r = self::store($image, $uid, 0, $resource_id, $filename, $album, 4, self::USER_AVATAR);
if (!$r) { if (!$r) {
logger::notice('profile image upload with scale 4 (300) failed'); logger::notice('profile image upload with scale 4 (300) failed');
} }
if ($width > 80 || $height > 80) { if ($width > 80 || $height > 80) {
$Image->scaleDown(80); $image->scaleDown(80);
} }
$r = self::store($Image, $uid, 0, $resource_id, $filename, $album, 5, self::USER_AVATAR); $r = self::store($image, $uid, 0, $resource_id, $filename, $album, 5, self::USER_AVATAR);
if (!$r) { if (!$r) {
logger::notice('profile image upload with scale 5 (80) failed'); logger::notice('profile image upload with scale 5 (80) failed');
} }
if ($width > 48 || $height > 48) { if ($width > 48 || $height > 48) {
$Image->scaleDown(48); $image->scaleDown(48);
} }
$r = self::store($Image, $uid, 0, $resource_id, $filename, $album, 6, self::USER_AVATAR); $r = self::store($image, $uid, 0, $resource_id, $filename, $album, 6, self::USER_AVATAR);
if (!$r) { if (!$r) {
logger::notice('profile image upload with scale 6 (48) failed'); logger::notice('profile image upload with scale 6 (48) failed');
} }
@ -1217,19 +1241,19 @@ class Photo
return ''; return '';
} }
$Image = $data['image']; $image = $data['image'];
$filename = $data['filename']; $filename = $data['filename'];
$width = $Image->getWidth(); $width = $image->getWidth();
$height = $Image->getHeight(); $height = $image->getHeight();
$resource_id = self::newResource(); $resource_id = self::newResource();
$album = DI::l10n()->t(self::BANNER_PHOTOS); $album = DI::l10n()->t(self::BANNER_PHOTOS);
if ($width > 960) { if ($width > 960) {
$Image->scaleDown(960); $image->scaleDown(960);
} }
$r = self::store($Image, $uid, 0, $resource_id, $filename, $album, 3, self::USER_BANNER); $r = self::store($image, $uid, 0, $resource_id, $filename, $album, 3, self::USER_BANNER);
if (!$r) { if (!$r) {
logger::notice('profile banner upload with scale 3 (960) failed'); logger::notice('profile banner upload with scale 3 (960) failed');
} }
@ -1247,3 +1271,4 @@ class Photo
return $resource_id; return $resource_id;
} }
} }

View file

@ -39,7 +39,7 @@ class Post
* @return int ID of inserted post * @return int ID of inserted post
* @throws \Exception * @throws \Exception
*/ */
public static function insert(int $uri_id, array $data = []) public static function insert(int $uri_id, array $data = []): int
{ {
if (empty($uri_id)) { if (empty($uri_id)) {
throw new BadMethodCallException('Empty URI_id'); throw new BadMethodCallException('Empty URI_id');
@ -107,8 +107,10 @@ class Post
* @param object $stmt statement object * @param object $stmt statement object
* @param bool $do_close * @param bool $do_close
* @return array Data array * @return array Data array
* @todo Find proper type-hint for $stmt and maybe avoid boolean
*/ */
public static function toArray($stmt, $do_close = true) { public static function toArray($stmt, bool $do_close = true)
{
if (is_bool($stmt)) { if (is_bool($stmt)) {
return $stmt; return $stmt;
} }
@ -131,7 +133,8 @@ class Post
* @return boolean Are there rows for that condition? * @return boolean Are there rows for that condition?
* @throws \Exception * @throws \Exception
*/ */
public static function exists($condition) { public static function exists(array $condition): bool
{
return DBA::exists('post-user-view', $condition); return DBA::exists('post-user-view', $condition);
} }
@ -151,7 +154,7 @@ class Post
* $count = Post::count($condition); * $count = Post::count($condition);
* @throws \Exception * @throws \Exception
*/ */
public static function count(array $condition = [], array $params = []) public static function count(array $condition = [], array $params = []): int
{ {
return DBA::count('post-user-view', $condition, $params); return DBA::count('post-user-view', $condition, $params);
} }
@ -172,7 +175,7 @@ class Post
* $count = Post::count($condition); * $count = Post::count($condition);
* @throws \Exception * @throws \Exception
*/ */
public static function countThread(array $condition = [], array $params = []) public static function countThread(array $condition = [], array $params = []): int
{ {
return DBA::count('post-thread-user-view', $condition, $params); return DBA::count('post-thread-user-view', $condition, $params);
} }
@ -193,7 +196,7 @@ class Post
* $count = Post::count($condition); * $count = Post::count($condition);
* @throws \Exception * @throws \Exception
*/ */
public static function countPosts(array $condition = [], array $params = []) public static function countPosts(array $condition = [], array $params = []): int
{ {
return DBA::count('post-view', $condition, $params); return DBA::count('post-view', $condition, $params);
} }
@ -209,7 +212,7 @@ class Post
* @throws \Exception * @throws \Exception
* @see DBA::select * @see DBA::select
*/ */
public static function selectFirst(array $fields = [], array $condition = [], $params = []) public static function selectFirst(array $fields = [], array $condition = [], array $params = [])
{ {
$params['limit'] = 1; $params['limit'] = 1;
@ -234,7 +237,7 @@ class Post
* @throws \Exception * @throws \Exception
* @see DBA::select * @see DBA::select
*/ */
public static function selectFirstPost(array $fields = [], array $condition = [], $params = []) public static function selectFirstPost(array $fields = [], array $condition = [], array $params = [])
{ {
$params['limit'] = 1; $params['limit'] = 1;
@ -259,7 +262,7 @@ class Post
* @throws \Exception * @throws \Exception
* @see DBA::select * @see DBA::select
*/ */
public static function selectFirstThread(array $fields = [], array $condition = [], $params = []) public static function selectFirstThread(array $fields = [], array $condition = [], array $params = [])
{ {
$params['limit'] = 1; $params['limit'] = 1;
@ -284,7 +287,7 @@ class Post
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function selectToArray(array $fields = [], array $condition = [], $params = []) public static function selectToArray(array $fields = [], array $condition = [], array $params = [])
{ {
$result = self::select($fields, $condition, $params); $result = self::select($fields, $condition, $params);
@ -312,7 +315,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
private static function selectView(string $view, array $selected = [], array $condition = [], $params = []) private static function selectView(string $view, array $selected = [], array $condition = [], array $params = [])
{ {
if (empty($selected)) { if (empty($selected)) {
$selected = array_merge(Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST); $selected = array_merge(Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST);
@ -337,7 +340,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public static function select(array $selected = [], array $condition = [], $params = []) public static function select(array $selected = [], array $condition = [], array $params = [])
{ {
return self::selectView('post-user-view', $selected, $condition, $params); return self::selectView('post-user-view', $selected, $condition, $params);
} }
@ -352,7 +355,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public static function selectPosts(array $selected = [], array $condition = [], $params = []) public static function selectPosts(array $selected = [], array $condition = [], array $params = [])
{ {
return self::selectView('post-view', $selected, $condition, $params); return self::selectView('post-view', $selected, $condition, $params);
} }
@ -367,7 +370,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public static function selectThread(array $selected = [], array $condition = [], $params = []) public static function selectThread(array $selected = [], array $condition = [], array $params = [])
{ {
return self::selectView('post-thread-user-view', $selected, $condition, $params); return self::selectView('post-thread-user-view', $selected, $condition, $params);
} }
@ -384,7 +387,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
private static function selectViewForUser(string $view, $uid, array $selected = [], array $condition = [], $params = []) private static function selectViewForUser(string $view, int $uid, array $selected = [], array $condition = [], array $params = [])
{ {
if (empty($selected)) { if (empty($selected)) {
$selected = Item::DISPLAY_FIELDLIST; $selected = Item::DISPLAY_FIELDLIST;
@ -425,7 +428,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public static function selectForUser($uid, array $selected = [], array $condition = [], $params = []) public static function selectForUser(int $uid, array $selected = [], array $condition = [], array $params = [])
{ {
return self::selectViewForUser('post-user-view', $uid, $selected, $condition, $params); return self::selectViewForUser('post-user-view', $uid, $selected, $condition, $params);
} }
@ -441,7 +444,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public static function selectPostsForUser($uid, array $selected = [], array $condition = [], $params = []) public static function selectPostsForUser(int $uid, array $selected = [], array $condition = [], array $params = [])
{ {
return self::selectViewForUser('post-view', $uid, $selected, $condition, $params); return self::selectViewForUser('post-view', $uid, $selected, $condition, $params);
} }
@ -457,7 +460,7 @@ class Post
* @return boolean|object * @return boolean|object
* @throws \Exception * @throws \Exception
*/ */
public static function selectThreadForUser($uid, array $selected = [], array $condition = [], $params = []) public static function selectThreadForUser(int $uid, array $selected = [], array $condition = [], array $params = [])
{ {
return self::selectViewForUser('post-thread-user-view', $uid, $selected, $condition, $params); return self::selectViewForUser('post-thread-user-view', $uid, $selected, $condition, $params);
} }
@ -473,7 +476,7 @@ class Post
* @throws \Exception * @throws \Exception
* @see DBA::select * @see DBA::select
*/ */
public static function selectFirstForUser($uid, array $selected = [], array $condition = [], $params = []) public static function selectFirstForUser(int $uid, array $selected = [], array $condition = [], array $params = [])
{ {
$params['limit'] = 1; $params['limit'] = 1;
@ -640,7 +643,7 @@ class Post
* @return boolean was the delete successful? * @return boolean was the delete successful?
* @throws \Exception * @throws \Exception
*/ */
public static function delete(array $conditions, array $options = []) public static function delete(array $conditions, array $options = []): bool
{ {
return DBA::delete('post', $conditions, $options); return DBA::delete('post', $conditions, $options);
} }

View file

@ -40,36 +40,44 @@ class Link
/** /**
* Check if the link is stored * Check if the link is stored
* *
* @param int $uri_id * @param int $uriId
* @param string $url * @param string $url URL
* @return bool * @return bool Whether record has been found
*/ */
public static function exists(int $uri_id, string $url) public static function exists(int $uriId, string $url): bool
{ {
return DBA::exists('post-link', ['uri-id' => $uri_id, 'url' => $url]); return DBA::exists('post-link', ['uri-id' => $uriId, 'url' => $url]);
} }
public static function getByLink(int $uri_id, string $url, $size = '') /**
* Returns URL by URI id and other URL
*
* @param int $uriId
* @param string $url
* @param string $size
* @return string Found link URL + id on success, $url on failture
*/
public static function getByLink(int $uriId, string $url, string $size = ''): string
{ {
if (empty($uri_id) || empty($url) || Proxy::isLocalImage($url)) { if (empty($uriId) || empty($url) || Proxy::isLocalImage($url)) {
return $url; return $url;
} }
if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'])) { if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'])) {
Logger::info('Bad URL, quitting', ['uri-id' => $uri_id, 'url' => $url, 'callstack' => System::callstack(20)]); Logger::info('Bad URL, quitting', ['uri-id' => $uriId, 'url' => $url, 'callstack' => System::callstack(20)]);
return $url; return $url;
} }
$link = DBA::selectFirst('post-link', ['id'], ['uri-id' => $uri_id, 'url' => $url]); $link = DBA::selectFirst('post-link', ['id'], ['uri-id' => $uriId, 'url' => $url]);
if (!empty($link['id'])) { if (!empty($link['id'])) {
$id = $link['id']; $id = $link['id'];
Logger::info('Found', ['id' => $id, 'uri-id' => $uri_id, 'url' => $url]); Logger::info('Found', ['id' => $id, 'uri-id' => $uriId, 'url' => $url]);
} else { } else {
$mime = self::fetchMimeType($url); $mime = self::fetchMimeType($url);
DBA::insert('post-link', ['uri-id' => $uri_id, 'url' => $url, 'mimetype' => $mime], Database::INSERT_IGNORE); DBA::insert('post-link', ['uri-id' => $uriId, 'url' => $url, 'mimetype' => $mime], Database::INSERT_IGNORE);
$id = DBA::lastInsertId(); $id = DBA::lastInsertId();
Logger::info('Inserted', ['id' => $id, 'uri-id' => $uri_id, 'url' => $url]); Logger::info('Inserted', ['id' => $id, 'uri-id' => $uriId, 'url' => $url]);
} }
if (empty($id)) { if (empty($id)) {
@ -81,15 +89,19 @@ class Link
case Proxy::SIZE_MICRO: case Proxy::SIZE_MICRO:
$url .= Proxy::PIXEL_MICRO . '/'; $url .= Proxy::PIXEL_MICRO . '/';
break; break;
case Proxy::SIZE_THUMB: case Proxy::SIZE_THUMB:
$url .= Proxy::PIXEL_THUMB . '/'; $url .= Proxy::PIXEL_THUMB . '/';
break; break;
case Proxy::SIZE_SMALL: case Proxy::SIZE_SMALL:
$url .= Proxy::PIXEL_SMALL . '/'; $url .= Proxy::PIXEL_SMALL . '/';
break; break;
case Proxy::SIZE_MEDIUM: case Proxy::SIZE_MEDIUM:
$url .= Proxy::PIXEL_MEDIUM . '/'; $url .= Proxy::PIXEL_MEDIUM . '/';
break; break;
case Proxy::SIZE_LARGE: case Proxy::SIZE_LARGE:
$url .= Proxy::PIXEL_LARGE . '/'; $url .= Proxy::PIXEL_LARGE . '/';
break; break;
@ -97,43 +109,50 @@ class Link
return $url . $id; return $url . $id;
} }
private static function fetchMimeType(string $url, string $accept = HttpClientAccept::DEFAULT) /**
* Fetches MIME type by URL and Accept: header
*
* @param string $url URL to fetch
* @param string $accept Comma-separated list of expected response MIME type(s)
* @return string Discovered MIME type or empty string on failure
*/
private static function fetchMimeType(string $url, string $accept = HttpClientAccept::DEFAULT): string
{ {
$timeout = DI::config()->get('system', 'xrd_timeout'); $timeout = DI::config()->get('system', 'xrd_timeout');
$curlResult = DI::httpClient()->head($url, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]); $curlResult = DI::httpClient()->head($url, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]);
if ($curlResult->isSuccess()) {
if (empty($media['mimetype'])) { if ($curlResult->isSuccess() && empty($media['mimetype'])) {
return $curlResult->getHeader('Content-Type')[0] ?? ''; return $curlResult->getHeader('Content-Type')[0] ?? '';
}
} }
return ''; return '';
} }
/** /**
* Add external links and replace them in the body * Add external links and replace them in the body
* *
* @param integer $uriid * @param integer $uriId
* @param string $body * @param string $body Item body formatted with BBCodes
* @return string Body with replaced links * @return string Body with replaced links
*/ */
public static function insertFromBody(int $uriid, string $body) public static function insertFromBody(int $uriId, string $body): string
{ {
if (preg_match_all("/\[img\=([0-9]*)x([0-9]*)\](http.*?)\[\/img\]/ism", $body, $pictures, PREG_SET_ORDER)) { if (preg_match_all("/\[img\=([0-9]*)x([0-9]*)\](http.*?)\[\/img\]/ism", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) { foreach ($pictures as $picture) {
$body = str_replace($picture[3], self::getByLink($uriid, $picture[3]), $body); $body = str_replace($picture[3], self::getByLink($uriId, $picture[3]), $body);
} }
} }
if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) { if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) { foreach ($pictures as $picture) {
$body = str_replace($picture[1], self::getByLink($uriid, $picture[1]), $body); $body = str_replace($picture[1], self::getByLink($uriId, $picture[1]), $body);
} }
} }
if (preg_match_all("/\[img\](http[^\[\]]*)\[\/img\]/ism", $body, $pictures, PREG_SET_ORDER)) { if (preg_match_all("/\[img\](http[^\[\]]*)\[\/img\]/ism", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) { foreach ($pictures as $picture) {
$body = str_replace($picture[1], self::getByLink($uriid, $picture[1]), $body); $body = str_replace($picture[1], self::getByLink($uriId, $picture[1]), $body);
} }
} }

View file

@ -109,7 +109,7 @@ class Media
* @param array $media * @param array $media
* @return array cleaned media array * @return array cleaned media array
*/ */
private static function unsetEmptyFields(array $media) private static function unsetEmptyFields(array $media): array
{ {
$fields = ['mimetype', 'height', 'width', 'size', 'preview', 'preview-height', 'preview-width', 'description']; $fields = ['mimetype', 'height', 'width', 'size', 'preview', 'preview-height', 'preview-width', 'description'];
foreach ($fields as $field) { foreach ($fields as $field) {
@ -145,7 +145,7 @@ class Media
* @param string $title * @param string $title
* @return string "[attach]" element * @return string "[attach]" element
*/ */
public static function getAttachElement(string $href, int $length, string $type, string $title = '') public static function getAttachElement(string $href, int $length, string $type, string $title = ''): string
{ {
$media = self::fetchAdditionalData(['type' => self::DOCUMENT, 'url' => $href, $media = self::fetchAdditionalData(['type' => self::DOCUMENT, 'url' => $href,
'size' => $length, 'mimetype' => $type, 'description' => $title]); 'size' => $length, 'mimetype' => $type, 'description' => $title]);
@ -160,7 +160,7 @@ class Media
* @param array $media * @param array $media
* @return array media array with additional data * @return array media array with additional data
*/ */
public static function fetchAdditionalData(array $media) public static function fetchAdditionalData(array $media): array
{ {
if (Network::isLocalLink($media['url'])) { if (Network::isLocalLink($media['url'])) {
$media = self::fetchLocalData($media); $media = self::fetchLocalData($media);
@ -192,7 +192,7 @@ class Media
if (($media['type'] == self::IMAGE) || ($filetype == 'image')) { if (($media['type'] == self::IMAGE) || ($filetype == 'image')) {
$imagedata = Images::getInfoFromURLCached($media['url']); $imagedata = Images::getInfoFromURLCached($media['url']);
if (!empty($imagedata)) { if ($imagedata) {
$media['mimetype'] = $imagedata['mime']; $media['mimetype'] = $imagedata['mime'];
$media['size'] = $imagedata['size']; $media['size'] = $imagedata['size'];
$media['width'] = $imagedata[0]; $media['width'] = $imagedata[0];
@ -202,7 +202,7 @@ class Media
} }
if (!empty($media['preview'])) { if (!empty($media['preview'])) {
$imagedata = Images::getInfoFromURLCached($media['preview']); $imagedata = Images::getInfoFromURLCached($media['preview']);
if (!empty($imagedata)) { if ($imagedata) {
$media['preview-width'] = $imagedata[0]; $media['preview-width'] = $imagedata[0];
$media['preview-height'] = $imagedata[1]; $media['preview-height'] = $imagedata[1];
} }
@ -235,7 +235,7 @@ class Media
* @param array $media * @param array $media
* @return array media with added data * @return array media with added data
*/ */
private static function fetchLocalData(array $media) private static function fetchLocalData(array $media): array
{ {
if (!preg_match('|.*?/photo/(.*[a-fA-F0-9])\-(.*[0-9])\..*[\w]|', $media['url'] ?? '', $matches)) { if (!preg_match('|.*?/photo/(.*[a-fA-F0-9])\-(.*[0-9])\..*[\w]|', $media['url'] ?? '', $matches)) {
return $media; return $media;
@ -266,7 +266,7 @@ class Media
* @param array $data * @param array $data
* @return array data array with the detected type * @return array data array with the detected type
*/ */
public static function addType(array $data) public static function addType(array $data): array
{ {
if (empty($data['mimetype'])) { if (empty($data['mimetype'])) {
Logger::info('No MimeType provided', ['media' => $data]); Logger::info('No MimeType provided', ['media' => $data]);
@ -318,7 +318,7 @@ class Media
* @param string $preview Preview picture * @param string $preview Preview picture
* @return boolean * @return boolean
*/ */
private static function isPictureLink(string $page, string $preview) private static function isPictureLink(string $page, string $preview): bool
{ {
return preg_match('#/photos/.*/image/#ism', $page) && preg_match('#/photo/.*-1\.#ism', $preview); return preg_match('#/photos/.*/image/#ism', $page) && preg_match('#/photo/.*-1\.#ism', $preview);
} }
@ -330,7 +330,7 @@ class Media
* @param string $body * @param string $body
* @return string Body without media links * @return string Body without media links
*/ */
public static function insertFromBody(int $uriid, string $body) public static function insertFromBody(int $uriid, string $body): string
{ {
// Simplify image codes // Simplify image codes
$unshared_body = $body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body); $unshared_body = $body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
@ -413,6 +413,7 @@ class Media
* *
* @param integer $uriid * @param integer $uriid
* @param string $body * @param string $body
* @return void
*/ */
public static function insertFromRelevantUrl(int $uriid, string $body) public static function insertFromRelevantUrl(int $uriid, string $body)
{ {
@ -448,6 +449,7 @@ class Media
* *
* @param integer $uriid * @param integer $uriid
* @param string $body * @param string $body
* @return void
*/ */
public static function insertFromAttachmentData(int $uriid, string $body) public static function insertFromAttachmentData(int $uriid, string $body)
{ {
@ -506,9 +508,9 @@ class Media
/** /**
* Retrieves the media attachments associated with the provided item ID. * Retrieves the media attachments associated with the provided item ID.
* *
* @param int $uri_id * @param int $uri_id URI id
* @param array $types * @param array $types Media types
* @return array * @return array|bool Array on success, false on error
* @throws \Exception * @throws \Exception
*/ */
public static function getByURIId(int $uri_id, array $types = []) public static function getByURIId(int $uri_id, array $types = [])
@ -525,12 +527,12 @@ class Media
/** /**
* Checks if media attachments are associated with the provided item ID. * Checks if media attachments are associated with the provided item ID.
* *
* @param int $uri_id * @param int $uri_id URI id
* @param array $types * @param array $types Media types
* @return array * @return bool Whether media attachment exists
* @throws \Exception * @throws \Exception
*/ */
public static function existsByURIId(int $uri_id, array $types = []) public static function existsByURIId(int $uri_id, array $types = []): bool
{ {
$condition = ['uri-id' => $uri_id]; $condition = ['uri-id' => $uri_id];
@ -544,13 +546,13 @@ class Media
/** /**
* Split the attachment media in the three segments "visual", "link" and "additional" * Split the attachment media in the three segments "visual", "link" and "additional"
* *
* @param int $uri_id * @param int $uri_id URI id
* @param string $guid * @param string $guid GUID
* @param array $links list of links that shouldn't be added * @param array $links list of links that shouldn't be added
* @param bool $has_media * @param bool $has_media
* @return array attachments * @return array attachments
*/ */
public static function splitAttachments(int $uri_id, string $guid = '', array $links = [], bool $has_media = true) public static function splitAttachments(int $uri_id, string $guid = '', array $links = [], bool $has_media = true): array
{ {
$attachments = ['visual' => [], 'link' => [], 'additional' => []]; $attachments = ['visual' => [], 'link' => [], 'additional' => []];
@ -648,7 +650,7 @@ class Media
* @param string $body * @param string $body
* @return string body * @return string body
*/ */
public static function addAttachmentsToBody(int $uriid, string $body = '') public static function addAttachmentsToBody(int $uriid, string $body = ''): string
{ {
if (empty($body)) { if (empty($body)) {
$item = Post::selectFirst(['body'], ['uri-id' => $uriid]); $item = Post::selectFirst(['body'], ['uri-id' => $uriid]);
@ -701,7 +703,7 @@ class Media
* @param string $size One of the Proxy::SIZE_* constants * @param string $size One of the Proxy::SIZE_* constants
* @return string preview link * @return string preview link
*/ */
public static function getPreviewUrlForId(int $id, string $size = ''):string public static function getPreviewUrlForId(int $id, string $size = ''): string
{ {
$url = DI::baseUrl() . '/photo/preview/'; $url = DI::baseUrl() . '/photo/preview/';
switch ($size) { switch ($size) {
@ -731,7 +733,7 @@ class Media
* @param string $size One of the Proxy::SIZE_* constants * @param string $size One of the Proxy::SIZE_* constants
* @return string media link * @return string media link
*/ */
public static function getUrlForId(int $id, string $size = ''):string public static function getUrlForId(int $id, string $size = ''): string
{ {
$url = DI::baseUrl() . '/photo/media/'; $url = DI::baseUrl() . '/photo/media/';
switch ($size) { switch ($size) {

View file

@ -54,10 +54,10 @@ class Profile
* *
* @param integer User ID * @param integer User ID
* *
* @return array Profile data * @return array|bool Profile data or false on error
* @throws \Exception * @throws \Exception
*/ */
public static function getByUID($uid) public static function getByUID(int $uid)
{ {
return DBA::selectFirst('profile', [], ['uid' => $uid]); return DBA::selectFirst('profile', [], ['uid' => $uid]);
} }
@ -69,7 +69,7 @@ class Profile
* @param int $id The contact owner ID * @param int $id The contact owner ID
* @param array $fields The selected fields * @param array $fields The selected fields
* *
* @return array Profile data for the ID * @return array|bool Profile data for the ID or false on error
* @throws \Exception * @throws \Exception
*/ */
public static function getById(int $uid, int $id, array $fields = []) public static function getById(int $uid, int $id, array $fields = [])
@ -81,7 +81,7 @@ class Profile
* Returns profile data for the contact owner * Returns profile data for the contact owner
* *
* @param int $uid The User ID * @param int $uid The User ID
* @param array $fields The fields to retrieve * @param array|bool $fields The fields to retrieve or false on error
* *
* @return array Array of profile data * @return array Array of profile data
* @throws \Exception * @throws \Exception
@ -94,9 +94,9 @@ class Profile
/** /**
* Update a profile entry and distribute the changes if needed * Update a profile entry and distribute the changes if needed
* *
* @param array $fields * @param array $fields Profile fields to update
* @param integer $uid * @param integer $uid User id
* @return boolean * @return boolean Whether update was successful
*/ */
public static function update(array $fields, int $uid): bool public static function update(array $fields, int $uid): bool
{ {
@ -136,8 +136,10 @@ class Profile
/** /**
* Publish a changed profile * Publish a changed profile
* @param int $uid *
* @param int $uid User id
* @param bool $force Force publishing to the directory * @param bool $force Force publishing to the directory
* @return void
*/ */
public static function publishUpdate(int $uid, bool $force = false) public static function publishUpdate(int $uid, bool $force = false)
{ {
@ -160,10 +162,9 @@ class Profile
* Returns a formatted location string from the given profile array * Returns a formatted location string from the given profile array
* *
* @param array $profile Profile array (Generated from the "profile" table) * @param array $profile Profile array (Generated from the "profile" table)
*
* @return string Location string * @return string Location string
*/ */
public static function formatLocation(array $profile) public static function formatLocation(array $profile): string
{ {
$location = ''; $location = '';
@ -237,7 +238,7 @@ class Profile
if (!local_user()) { if (!local_user()) {
$a->setCurrentTheme($profile['theme']); $a->setCurrentTheme($profile['theme']);
$a->setCurrentMobileTheme(DI::pConfig()->get($a->getProfileOwner(), 'system', 'mobile_theme')); $a->setCurrentMobileTheme(DI::pConfig()->get($a->getProfileOwner(), 'system', 'mobile_theme') ?? '');
} }
/* /*

View file

@ -34,9 +34,10 @@ class PushSubscriber
* *
* @param integer $uid User ID * @param integer $uid User ID
* @param int $default_priority * @param int $default_priority
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function publishFeed($uid, $default_priority = PRIORITY_HIGH) public static function publishFeed(int $uid, int $default_priority = PRIORITY_HIGH)
{ {
$condition = ['push' => 0, 'uid' => $uid]; $condition = ['push' => 0, 'uid' => $uid];
DBA::update('push_subscriber', ['push' => 1, 'next_try' => DBA::NULL_DATETIME], $condition); DBA::update('push_subscriber', ['push' => 1, 'next_try' => DBA::NULL_DATETIME], $condition);
@ -48,9 +49,10 @@ class PushSubscriber
* start workers to transmit the feed data * start workers to transmit the feed data
* *
* @param int $default_priority * @param int $default_priority
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function requeue($default_priority = PRIORITY_HIGH) public static function requeue(int $default_priority = PRIORITY_HIGH)
{ {
// We'll push to each subscriber that has push > 0, // We'll push to each subscriber that has push > 0,
// i.e. there has been an update (set in notifier.php). // i.e. there has been an update (set in notifier.php).
@ -80,9 +82,10 @@ class PushSubscriber
* @param string $hub_callback Callback address * @param string $hub_callback Callback address
* @param string $hub_topic Feed topic * @param string $hub_topic Feed topic
* @param string $hub_secret Subscription secret * @param string $hub_secret Subscription secret
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function renew($uid, $nick, $subscribe, $hub_callback, $hub_topic, $hub_secret) public static function renew(int $uid, string $nick, int $subscribe, string $hub_callback, string $hub_topic, string $hub_secret)
{ {
// fetch the old subscription if it exists // fetch the old subscription if it exists
$subscriber = DBA::selectFirst('push_subscriber', ['last_update', 'push'], ['callback_url' => $hub_callback]); $subscriber = DBA::selectFirst('push_subscriber', ['last_update', 'push'], ['callback_url' => $hub_callback]);
@ -119,9 +122,10 @@ class PushSubscriber
* Delay the push subscriber * Delay the push subscriber
* *
* @param integer $id Subscriber ID * @param integer $id Subscriber ID
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function delay($id) public static function delay(int $id)
{ {
$subscriber = DBA::selectFirst('push_subscriber', ['push', 'callback_url', 'renewed', 'nickname'], ['id' => $id]); $subscriber = DBA::selectFirst('push_subscriber', ['push', 'callback_url', 'renewed', 'nickname'], ['id' => $id]);
if (!DBA::isResult($subscriber)) { if (!DBA::isResult($subscriber)) {
@ -158,9 +162,10 @@ class PushSubscriber
* *
* @param integer $id Subscriber ID * @param integer $id Subscriber ID
* @param string $last_update Date of last transmitted item * @param string $last_update Date of last transmitted item
* @return void
* @throws \Exception * @throws \Exception
*/ */
public static function reset($id, $last_update) public static function reset(int $id, string $last_update)
{ {
$subscriber = DBA::selectFirst('push_subscriber', ['callback_url', 'nickname'], ['id' => $id]); $subscriber = DBA::selectFirst('push_subscriber', ['callback_url', 'nickname'], ['id' => $id]);
if (!DBA::isResult($subscriber)) { if (!DBA::isResult($subscriber)) {

View file

@ -34,13 +34,12 @@ class Register
/** /**
* Return the list of pending registrations * Return the list of pending registrations
* *
* @param int $start Start count (Default is 0) * @param int $start Start count (Default is 0)
* @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE) * @param int $count Count of the items per page (Default is @see Pager::ITEMS_PER_PAGE)
* * @return array|bool Array on succes, false on failure
* @return array
* @throws \Exception * @throws \Exception
*/ */
public static function getPending($start = 0, $count = Pager::ITEMS_PER_PAGE) public static function getPending(int $start = 0, int $count = Pager::ITEMS_PER_PAGE)
{ {
return DBA::selectToArray('pending-view', [], [], ['limit' => [$start, $count]]); return DBA::selectToArray('pending-view', [], [], ['limit' => [$start, $count]]);
} }
@ -50,8 +49,7 @@ class Register
* *
* @param int $uid The user id * @param int $uid The user id
* *
* @return array The pending user information * @return array|bool Array on succes, false on failure
*
* @throws \Exception * @throws \Exception
*/ */
public static function getPendingForUser(int $uid) public static function getPendingForUser(int $uid)
@ -65,7 +63,7 @@ class Register
* @return int * @return int
* @throws \Exception * @throws \Exception
*/ */
public static function getPendingCount() public static function getPendingCount(): int
{ {
return DBA::count('pending-view', ['self' => true]); return DBA::count('pending-view', ['self' => true]);
} }
@ -74,10 +72,10 @@ class Register
* Returns the register record associated with the provided hash * Returns the register record associated with the provided hash
* *
* @param string $hash * @param string $hash
* @return array * @return array|bool Array on succes, false on failure
* @throws \Exception * @throws \Exception
*/ */
public static function getByHash($hash) public static function getByHash(string $hash)
{ {
return DBA::selectFirst('register', [], ['hash' => $hash]); return DBA::selectFirst('register', [], ['hash' => $hash]);
} }
@ -89,7 +87,7 @@ class Register
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function existsByHash($hash) public static function existsByHash(string $hash): bool
{ {
return DBA::exists('register', ['hash' => $hash]); return DBA::exists('register', ['hash' => $hash]);
} }
@ -100,7 +98,7 @@ class Register
* @return string * @return string
* @throws \Exception * @throws \Exception
*/ */
public static function createForInvitation() public static function createForInvitation(): string
{ {
$code = Strings::getRandomName(8) . random_int(1000, 9999); $code = Strings::getRandomName(8) . random_int(1000, 9999);
@ -124,7 +122,7 @@ class Register
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function createForApproval($uid, $language, $note = '') public static function createForApproval(int $uid, string $language, string $note = ''): bool
{ {
$hash = Strings::getRandomHex(); $hash = Strings::getRandomHex();
@ -151,7 +149,7 @@ class Register
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public static function deleteByHash($hash) public static function deleteByHash(string $hash): bool
{ {
return DBA::delete('register', ['hash' => $hash]); return DBA::delete('register', ['hash' => $hash]);
} }

View file

@ -32,10 +32,9 @@ class Search
* Returns the list of user defined tags (e.g. #Friendica) * Returns the list of user defined tags (e.g. #Friendica)
* *
* @return array * @return array
*
* @throws \Exception * @throws \Exception
*/ */
public static function getUserTags() public static function getUserTags(): array
{ {
$termsStmt = DBA::p("SELECT DISTINCT(`term`) FROM `search`"); $termsStmt = DBA::p("SELECT DISTINCT(`term`) FROM `search`");

View file

@ -25,6 +25,7 @@ use Friendica\Core\Logger;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Factory\Api\Mastodon\Notification as NotificationFactory;
use Friendica\Navigation\Notifications\Entity; use Friendica\Navigation\Notifications\Entity;
use Friendica\Object\Api\Mastodon\Notification; use Friendica\Object\Api\Mastodon\Notification;
use Minishlink\WebPush\VAPID; use Minishlink\WebPush\VAPID;
@ -37,8 +38,7 @@ class Subscription
* @param int $applicationid * @param int $applicationid
* @param int $uid * @param int $uid
* @param array $fields * @param array $fields
* * @return array|bool Array on success, false on failure
* @return bool Does it exist?
*/ */
public static function select(int $applicationid, int $uid, array $fields = []) public static function select(int $applicationid, int $uid, array $fields = [])
{ {
@ -53,7 +53,7 @@ class Subscription
* *
* @return bool Does it exist? * @return bool Does it exist?
*/ */
public static function exists(int $applicationid, int $uid) public static function exists(int $applicationid, int $uid): bool
{ {
return DBA::exists('subscription', ['application-id' => $applicationid, 'uid' => $uid]); return DBA::exists('subscription', ['application-id' => $applicationid, 'uid' => $uid]);
} }
@ -64,10 +64,9 @@ class Subscription
* @param int $applicationid * @param int $applicationid
* @param int $uid * @param int $uid
* @param array $fields subscription fields * @param array $fields subscription fields
*
* @return bool result of update * @return bool result of update
*/ */
public static function update(int $applicationid, int $uid, array $fields) public static function update(int $applicationid, int $uid, array $fields): bool
{ {
return DBA::update('subscription', $fields, ['application-id' => $applicationid, 'uid' => $uid]); return DBA::update('subscription', $fields, ['application-id' => $applicationid, 'uid' => $uid]);
} }
@ -76,10 +75,9 @@ class Subscription
* Insert or replace a subscription record * Insert or replace a subscription record
* *
* @param array $fields subscription fields * @param array $fields subscription fields
*
* @return bool result of replace * @return bool result of replace
*/ */
public static function replace(array $fields) public static function replace(array $fields): bool
{ {
return DBA::replace('subscription', $fields); return DBA::replace('subscription', $fields);
} }
@ -91,7 +89,7 @@ class Subscription
* @param int $uid * @param int $uid
* @return bool * @return bool
*/ */
public static function delete(int $applicationid, int $uid) public static function delete(int $applicationid, int $uid): bool
{ {
return DBA::delete('subscription', ['application-id' => $applicationid, 'uid' => $uid]); return DBA::delete('subscription', ['application-id' => $applicationid, 'uid' => $uid]);
} }
@ -136,25 +134,25 @@ class Subscription
/** /**
* Prepare push notification * Prepare push notification
* *
* @param int $nid * @param Notification $Notification
* @return void * @return void
*/ */
public static function pushByNotification(Entity\Notification $Notification) public static function pushByNotification(Entity\Notification $notification)
{ {
$type = \Friendica\Factory\Api\Mastodon\Notification::getType($Notification); $type = NotificationFactory::getType($notification);
if (DI::notify()->NotifyOnDesktop($Notification, $type)) { if (DI::notify()->NotifyOnDesktop($notification, $type)) {
DI::notify()->createFromNotification($Notification); DI::notify()->createFromNotification($notification);
} }
if (empty($type)) { if (empty($type)) {
return; return;
} }
$subscriptions = DBA::select('subscription', [], ['uid' => $Notification->uid, $type => true]); $subscriptions = DBA::select('subscription', [], ['uid' => $notification->uid, $type => true]);
while ($subscription = DBA::fetch($subscriptions)) { while ($subscription = DBA::fetch($subscriptions)) {
Logger::info('Push notification', ['id' => $subscription['id'], 'uid' => $subscription['uid'], 'type' => $type]); Logger::info('Push notification', ['id' => $subscription['id'], 'uid' => $subscription['uid'], 'type' => $type]);
Worker::add(PRIORITY_HIGH, 'PushSubscription', $subscription['id'], $Notification->id); Worker::add(PRIORITY_HIGH, 'PushSubscription', $subscription['id'], $notification->id);
} }
DBA::close($subscriptions); DBA::close($subscriptions);
} }

View file

@ -73,13 +73,14 @@ class Tag
/** /**
* Store tag/mention elements * Store tag/mention elements
* *
* @param integer $uriid * @param integer $uriId
* @param integer $type * @param integer $type Tag type
* @param string $name * @param string $name Tag name
* @param string $url * @param string $url Contact URL (optional)
* @param integer $target * @param integer $target Target (default: null)
* @return void
*/ */
public static function store(int $uriid, int $type, string $name, string $url = '', int $target = null) public static function store(int $uriId, int $type, string $name, string $url = '', int $target = null)
{ {
if ($type == self::HASHTAG) { if ($type == self::HASHTAG) {
// Trim Unicode non-word characters // Trim Unicode non-word characters
@ -88,7 +89,7 @@ class Tag
$tags = explode(self::TAG_CHARACTER[self::HASHTAG], $name); $tags = explode(self::TAG_CHARACTER[self::HASHTAG], $name);
if (count($tags) > 1) { if (count($tags) > 1) {
foreach ($tags as $tag) { foreach ($tags as $tag) {
self::store($uriid, $type, $tag, $url); self::store($uriId, $type, $tag, $url);
} }
return; return;
} }
@ -142,7 +143,7 @@ class Tag
} }
} }
$fields = ['uri-id' => $uriid, 'type' => $type, 'tid' => $tagid, 'cid' => $cid]; $fields = ['uri-id' => $uriId, 'type' => $type, 'tid' => $tagid, 'cid' => $cid];
if (in_array($type, [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION])) { if (in_array($type, [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION])) {
$condition = $fields; $condition = $fields;
@ -155,7 +156,7 @@ class Tag
DBA::insert('post-tag', $fields, Database::INSERT_IGNORE); DBA::insert('post-tag', $fields, Database::INSERT_IGNORE);
Logger::info('Stored tag/mention', ['uri-id' => $uriid, 'tag-id' => $tagid, 'contact-id' => $cid, 'name' => $name, 'type' => $type, 'callstack' => System::callstack(8)]); Logger::info('Stored tag/mention', ['uri-id' => $uriId, 'tag-id' => $tagid, 'contact-id' => $cid, 'name' => $name, 'type' => $type, 'callstack' => System::callstack(8)]);
} }
/** /**
@ -213,14 +214,14 @@ class Tag
} }
/** /**
* Get a tag id for a given tag name and url * Get a tag id for a given tag name and URL
* *
* @param string $name * @param string $name Name of tag
* @param string $url * @param string $url
* @param int $type * @param int $type Type of tag
* @return void * @return int Tag id
*/ */
public static function getID(string $name, string $url = '', int $type = null) public static function getID(string $name, string $url = '', int $type = null): int
{ {
$fields = ['name' => substr($name, 0, 96), 'url' => $url]; $fields = ['name' => substr($name, 0, 96), 'url' => $url];
@ -242,6 +243,9 @@ class Tag
return $tid; return $tid;
} }
// Also log type
$fields['type'] = $type;
Logger::error('No tag id created', $fields); Logger::error('No tag id created', $fields);
return 0; return 0;
} }
@ -249,20 +253,21 @@ class Tag
/** /**
* Store tag/mention elements * Store tag/mention elements
* *
* @param integer $uriid * @param integer $uriId
* @param string $hash * @param string $hash
* @param string $name * @param string $name
* @param string $url * @param string $url
* @param boolean $probing * @param boolean $probing Whether probing is active
* @return void
*/ */
public static function storeByHash(int $uriid, string $hash, string $name, string $url = '', $probing = true) public static function storeByHash(int $uriId, string $hash, string $name, string $url = '', bool $probing = true)
{ {
$type = self::getTypeForHash($hash); $type = self::getTypeForHash($hash);
if ($type == self::UNKNOWN) { if ($type == self::UNKNOWN) {
return; return;
} }
self::store($uriid, $type, $name, $url, $probing); self::store($uriId, $type, $name, $url, $probing);
} }
/** /**
@ -273,7 +278,7 @@ class Tag
* *
* @return array Tag list * @return array Tag list
*/ */
public static function getFromBody(string $body, string $tags = null) public static function getFromBody(string $body, string $tags = null): array
{ {
if (is_null($tags)) { if (is_null($tags)) {
$tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION]; $tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION];
@ -289,14 +294,15 @@ class Tag
/** /**
* Store tags and mentions from the body * Store tags and mentions from the body
* *
* @param integer $uriid URI-Id * @param integer $uriId URI-Id
* @param string $body Body of the post * @param string $body Body of the post
* @param string $tags Accepted tags * @param string $tags Accepted tags
* @param boolean $probing Perform a probing for contacts, adding them if needed * @param boolean $probing Perform a probing for contacts, adding them if needed
* @return void
*/ */
public static function storeFromBody(int $uriid, string $body, string $tags = null, $probing = true) public static function storeFromBody(int $uriId, string $body, string $tags = null, bool $probing = true)
{ {
Logger::info('Check for tags', ['uri-id' => $uriid, 'hash' => $tags, 'callstack' => System::callstack()]); Logger::info('Check for tags', ['uri-id' => $uriId, 'hash' => $tags, 'callstack' => System::callstack()]);
if (is_null($tags)) { if (is_null($tags)) {
$tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION]; $tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION];
@ -312,13 +318,13 @@ class Tag
} }
foreach (self::getFromBody($body, $tags) as $tag) { foreach (self::getFromBody($body, $tags) as $tag) {
self::storeByHash($uriid, $tag[1], $tag[3], $tag[2], $probing); self::storeByHash($uriId, $tag[1], $tag[3], $tag[2], $probing);
} }
// Search for hashtags in the shared body (but only if hashtags are wanted) // Search for hashtags in the shared body (but only if hashtags are wanted)
if (!empty($share_body) && (strpos($tags, self::TAG_CHARACTER[self::HASHTAG]) !== false)) { if (!empty($share_body) && (strpos($tags, self::TAG_CHARACTER[self::HASHTAG]) !== false)) {
foreach (self::getFromBody($share_body, self::TAG_CHARACTER[self::HASHTAG]) as $tag) { foreach (self::getFromBody($share_body, self::TAG_CHARACTER[self::HASHTAG]) as $tag) {
self::storeByHash($uriid, $tag[1], $tag[3], $tag[2], $probing); self::storeByHash($uriId, $tag[1], $tag[3], $tag[2], $probing);
} }
} }
} }
@ -328,50 +334,52 @@ class Tag
* This function is needed in the intermediate phase. * This function is needed in the intermediate phase.
* Later we can call item::setHashtags in advance to have all tags converted. * Later we can call item::setHashtags in advance to have all tags converted.
* *
* @param integer $uriid URI-Id * @param integer $uriId URI-Id
* @param string $body Body of the post * @param string $body Body of the post
* @return void
*/ */
public static function storeRawTagsFromBody(int $uriid, string $body) public static function storeRawTagsFromBody(int $uriId, string $body)
{ {
Logger::info('Check for tags', ['uri-id' => $uriid, 'callstack' => System::callstack()]); Logger::info('Check for tags', ['uri-id' => $uriId, 'callstack' => System::callstack()]);
$result = BBCode::getTags($body); $result = BBCode::getTags($body);
if (empty($result)) { if (empty($result)) {
return; return;
} }
Logger::info('Found tags', ['uri-id' => $uriid, 'result' => $result]); Logger::info('Found tags', ['uri-id' => $uriId, 'result' => $result]);
foreach ($result as $tag) { foreach ($result as $tag) {
if (substr($tag, 0, 1) != self::TAG_CHARACTER[self::HASHTAG]) { if (substr($tag, 0, 1) != self::TAG_CHARACTER[self::HASHTAG]) {
continue; continue;
} }
self::storeByHash($uriid, substr($tag, 0, 1), substr($tag, 1)); self::storeByHash($uriId, substr($tag, 0, 1), substr($tag, 1));
} }
} }
/** /**
* Checks for stored hashtags and mentions for the given post * Checks for stored hashtags and mentions for the given post
* *
* @param integer $uriid * @param integer $uriId
* @return bool * @return bool
*/ */
public static function existsForPost(int $uriid) public static function existsForPost(int $uriId): bool
{ {
return DBA::exists('post-tag', ['uri-id' => $uriid, 'type' => [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]); return DBA::exists('post-tag', ['uri-id' => $uriId, 'type' => [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]);
} }
/** /**
* Remove tag/mention * Remove tag/mention
* *
* @param integer $uriid * @param integer $uriId
* @param integer $type * @param integer $type Type
* @param string $name * @param string $name Name
* @param string $url * @param string $url URL
* @return void
*/ */
public static function remove(int $uriid, int $type, string $name, string $url = '') public static function remove(int $uriId, int $type, string $name, string $url = '')
{ {
$condition = ['uri-id' => $uriid, 'type' => $type, 'url' => $url]; $condition = ['uri-id' => $uriId, 'type' => $type, 'url' => $url];
if ($type == self::HASHTAG) { if ($type == self::HASHTAG) {
$condition['name'] = $name; $condition['name'] = $name;
} }
@ -381,35 +389,36 @@ class Tag
return; return;
} }
Logger::info('Removing tag/mention', ['uri-id' => $uriid, 'tid' => $tag['tid'], 'name' => $name, 'url' => $url, 'callstack' => System::callstack(8)]); Logger::info('Removing tag/mention', ['uri-id' => $uriId, 'tid' => $tag['tid'], 'name' => $name, 'url' => $url, 'callstack' => System::callstack(8)]);
DBA::delete('post-tag', ['uri-id' => $uriid, 'type' => $type, 'tid' => $tag['tid'], 'cid' => $tag['cid']]); DBA::delete('post-tag', ['uri-id' => $uriId, 'type' => $type, 'tid' => $tag['tid'], 'cid' => $tag['cid']]);
} }
/** /**
* Remove tag/mention * Remove tag/mention
* *
* @param integer $uriid * @param integer $uriId
* @param string $hash * @param string $hash
* @param string $name * @param string $name
* @param string $url * @param string $url
* @return void
*/ */
public static function removeByHash(int $uriid, string $hash, string $name, string $url = '') public static function removeByHash(int $uriId, string $hash, string $name, string $url = '')
{ {
$type = self::getTypeForHash($hash); $type = self::getTypeForHash($hash);
if ($type == self::UNKNOWN) { if ($type == self::UNKNOWN) {
return; return;
} }
self::remove($uriid, $type, $name, $url); self::remove($uriId, $type, $name, $url);
} }
/** /**
* Get the type for the given hash * Get the type for the given hash
* *
* @param string $hash * @param string $hash
* @return integer type * @return integer Tag type
*/ */
private static function getTypeForHash(string $hash) private static function getTypeForHash(string $hash): int
{ {
if ($hash == self::TAG_CHARACTER[self::MENTION]) { if ($hash == self::TAG_CHARACTER[self::MENTION]) {
return self::MENTION; return self::MENTION;
@ -427,22 +436,23 @@ class Tag
/** /**
* Create implicit mentions for a given post * Create implicit mentions for a given post
* *
* @param integer $uri_id * @param integer $uriId
* @param integer $parent_uri_id * @param integer $parentUriId
* @return void
*/ */
public static function createImplicitMentions(int $uri_id, int $parent_uri_id) public static function createImplicitMentions(int $uriId, int $parentUriId)
{ {
// Always mention the direct parent author // Always mention the direct parent author
$parent = Post::selectFirst(['author-link', 'author-name'], ['uri-id' => $parent_uri_id]); $parent = Post::selectFirst(['author-link', 'author-name'], ['uri-id' => $parentUriId]);
self::store($uri_id, self::IMPLICIT_MENTION, $parent['author-name'], $parent['author-link']); self::store($uriId, self::IMPLICIT_MENTION, $parent['author-name'], $parent['author-link']);
if (DI::config()->get('system', 'disable_implicit_mentions')) { if (DI::config()->get('system', 'disable_implicit_mentions')) {
return; return;
} }
$tags = DBA::select('tag-view', ['name', 'url'], ['uri-id' => $parent_uri_id, 'type' => [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]); $tags = DBA::select('tag-view', ['name', 'url'], ['uri-id' => $parentUriId, 'type' => [self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]);
while ($tag = DBA::fetch($tags)) { while ($tag = DBA::fetch($tags)) {
self::store($uri_id, self::IMPLICIT_MENTION, $tag['name'], $tag['url']); self::store($uriId, self::IMPLICIT_MENTION, $tag['name'], $tag['url']);
} }
DBA::close($tags); DBA::close($tags);
} }
@ -450,30 +460,29 @@ class Tag
/** /**
* Retrieves the terms from the provided type(s) associated with the provided item ID. * Retrieves the terms from the provided type(s) associated with the provided item ID.
* *
* @param int $item_id * @param int $uriId
* @param int|array $type * @param array $type Tag type(s)
* @return array * @return array|bool Array on success, false on error
* @throws \Exception * @throws \Exception
*/ */
public static function getByURIId(int $uri_id, array $type = [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]) public static function getByURIId(int $uriId, array $type = [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION])
{ {
$condition = ['uri-id' => $uri_id, 'type' => $type]; $condition = ['uri-id' => $uriId, 'type' => $type];
return DBA::selectToArray('tag-view', ['type', 'name', 'url', 'tag-type'], $condition); return DBA::selectToArray('tag-view', ['type', 'name', 'url', 'tag-type'], $condition);
} }
/** /**
* Return a string with all tags and mentions * Return a string with all tags and mentions
* *
* @param integer $uri_id * @param integer $uriId
* @param array $type * @param array $type Tag type(s)
* @return string tags and mentions * @return string tags and mentions
* @throws \Exception * @throws \Exception
*/ */
public static function getCSVByURIId(int $uri_id, array $type = [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]) public static function getCSVByURIId(int $uriId, array $type = [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]): string
{ {
$tag_list = []; $tag_list = [];
$tags = self::getByURIId($uri_id, $type); foreach (self::getByURIId($uriId, $type) as $tag) {
foreach ($tags as $tag) {
$tag_list[] = self::TAG_CHARACTER[$tag['type']] . '[url=' . $tag['url'] . ']' . $tag['name'] . '[/url]'; $tag_list[] = self::TAG_CHARACTER[$tag['type']] . '[url=' . $tag['url'] . ']' . $tag['name'] . '[/url]';
} }
@ -489,7 +498,7 @@ class Tag
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function populateFromItem(&$item) public static function populateFromItem(array &$item): array
{ {
$return = [ $return = [
'tags' => [], 'tags' => [],
@ -498,7 +507,7 @@ class Tag
'implicit_mentions' => [], 'implicit_mentions' => [],
]; ];
$searchpath = DI::baseUrl() . "/search?tag="; $searchpath = DI::baseUrl() . '/search?tag=';
$taglist = DBA::select('tag-view', ['type', 'name', 'url', 'cid'], $taglist = DBA::select('tag-view', ['type', 'name', 'url', 'cid'],
['uri-id' => $item['uri-id'], 'type' => [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]); ['uri-id' => $item['uri-id'], 'type' => [self::HASHTAG, self::MENTION, self::EXCLUSIVE_MENTION, self::IMPLICIT_MENTION]]);
@ -519,6 +528,7 @@ class Tag
$return['hashtags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>'; $return['hashtags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>';
$return['tags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>'; $return['tags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>';
break; break;
case self::MENTION: case self::MENTION:
case self::EXCLUSIVE_MENTION: case self::EXCLUSIVE_MENTION:
if (!empty($tag['cid'])) { if (!empty($tag['cid'])) {
@ -529,9 +539,13 @@ class Tag
$return['mentions'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>'; $return['mentions'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>';
$return['tags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>'; $return['tags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>';
break; break;
case self::IMPLICIT_MENTION: case self::IMPLICIT_MENTION:
$return['implicit_mentions'][] = $prefix . $tag['name']; $return['implicit_mentions'][] = $prefix . $tag['name'];
break; break;
default:
Logger:warning('Unknown tag type found', $tag);
} }
} }
DBA::close($taglist); DBA::close($taglist);
@ -546,11 +560,13 @@ class Tag
* @param integer $uid * @param integer $uid
* @return integer number of posts * @return integer number of posts
*/ */
public static function countByTag(string $search, int $uid = 0) public static function countByTag(string $search, int $uid = 0): int
{ {
$condition = ["`name` = ? AND (`uid` = ? OR (`uid` = ? AND NOT `global`)) $condition = ["`name` = ? AND (`uid` = ? OR (`uid` = ? AND NOT `global`))
AND (`network` IN (?, ?, ?, ?) OR (`uid` = ? AND `uid` != ?))", AND (`network` IN (?, ?, ?, ?) OR (`uid` = ? AND `uid` != ?))",
$search, 0, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, $uid, 0]; $search, 0, $uid,
Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, $uid, 0,
];
return DBA::count('tag-search-view', $condition); return DBA::count('tag-search-view', $condition);
} }
@ -558,18 +574,20 @@ class Tag
/** /**
* Search posts for given tag * Search posts for given tag
* *
* @param string $search * @param string $search Tag to search for
* @param integer $uid * @param integer $uid User Id
* @param integer $start * @param integer $start Starting record
* @param integer $limit * @param integer $limit Maximum count of records
* @param integer $last_uriid * @param integer $last_uriid
* @return array with URI-ID * @return array with URI-ID
*/ */
public static function getURIIdListByTag(string $search, int $uid = 0, int $start = 0, int $limit = 100, int $last_uriid = 0) public static function getURIIdListByTag(string $search, int $uid = 0, int $start = 0, int $limit = 100, int $last_uriid = 0): array
{ {
$condition = ["`name` = ? AND (`uid` = ? OR (`uid` = ? AND NOT `global`)) $condition = ["`name` = ? AND (`uid` = ? OR (`uid` = ? AND NOT `global`))
AND (`network` IN (?, ?, ?, ?) OR (`uid` = ? AND `uid` != ?))", AND (`network` IN (?, ?, ?, ?) OR (`uid` = ? AND `uid` != ?))",
$search, 0, $uid, Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, $uid, 0]; $search, 0, $uid,
Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, $uid, 0,
];
if (!empty($last_uriid)) { if (!empty($last_uriid)) {
$condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $last_uriid]); $condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $last_uriid]);
@ -582,13 +600,13 @@ class Tag
$tags = DBA::select('tag-search-view', ['uri-id'], $condition, $params); $tags = DBA::select('tag-search-view', ['uri-id'], $condition, $params);
$uriids = []; $uriIds = [];
while ($tag = DBA::fetch($tags)) { while ($tag = DBA::fetch($tags)) {
$uriids[] = $tag['uri-id']; $uriIds[] = $tag['uri-id'];
} }
DBA::close($tags); DBA::close($tags);
return $uriids; return $uriIds;
} }
/** /**
@ -599,7 +617,7 @@ class Tag
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function getGlobalTrendingHashtags(int $period, $limit = 10) public static function getGlobalTrendingHashtags(int $period, $limit = 10): array
{ {
$tags = DI::cache()->get('global_trending_tags-' . $period . '-' . $limit); $tags = DI::cache()->get('global_trending_tags-' . $period . '-' . $limit);
if (!empty($tags)) { if (!empty($tags)) {
@ -612,9 +630,9 @@ class Tag
/** /**
* Fetch the blocked tags as SQL * Fetch the blocked tags as SQL
* *
* @return string * @return string SQL for blocked tag names or empty string
*/ */
private static function getBlockedSQL() private static function getBlockedSQL(): string
{ {
$blocked_txt = DI::config()->get('system', 'blocked_tags'); $blocked_txt = DI::config()->get('system', 'blocked_tags');
if (empty($blocked_txt)) { if (empty($blocked_txt)) {
@ -623,7 +641,7 @@ class Tag
$blocked = explode(',', $blocked_txt); $blocked = explode(',', $blocked_txt);
array_walk($blocked, function(&$value) { $value = "'" . DBA::escape(trim($value)) . "'";}); array_walk($blocked, function(&$value) { $value = "'" . DBA::escape(trim($value)) . "'";});
return " AND NOT `name` IN (" . implode(',', $blocked) . ")"; return ' AND NOT `name` IN (' . implode(',', $blocked) . ')';
} }
/** /**
@ -634,12 +652,15 @@ class Tag
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function setGlobalTrendingHashtags(int $period, int $limit = 10) public static function setGlobalTrendingHashtags(int $period, int $limit = 10): array
{ {
// Get a uri-id that is at least X hours old. /*
// We use the uri-id in the query for the hash tags since this is much faster * Get a uri-id that is at least X hours old.
* We use the uri-id in the query for the hash tags since this is much faster
*/
$post = Post::selectFirstThread(['uri-id'], ["`uid` = ? AND `received` < ?", 0, DateTimeFormat::utc('now - ' . $period . ' hour')], $post = Post::selectFirstThread(['uri-id'], ["`uid` = ? AND `received` < ?", 0, DateTimeFormat::utc('now - ' . $period . ' hour')],
['order' => ['received' => true]]); ['order' => ['received' => true]]);
if (empty($post['uri-id'])) { if (empty($post['uri-id'])) {
return []; return [];
} }
@ -650,7 +671,9 @@ class Tag
FROM `tag-search-view` FROM `tag-search-view`
WHERE `private` = ? AND `uid` = ? AND `uri-id` > ? $block_sql WHERE `private` = ? AND `uid` = ? AND `uri-id` > ? $block_sql
GROUP BY `term` ORDER BY `authors` DESC, `score` DESC LIMIT ?", GROUP BY `term` ORDER BY `authors` DESC, `score` DESC LIMIT ?",
Item::PUBLIC, 0, $post['uri-id'], $limit); Item::PUBLIC, 0, $post['uri-id'],
$limit
);
if (DBA::isResult($tagsStmt)) { if (DBA::isResult($tagsStmt)) {
$tags = DBA::toArray($tagsStmt); $tags = DBA::toArray($tagsStmt);
@ -669,7 +692,7 @@ class Tag
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function getLocalTrendingHashtags(int $period, $limit = 10) public static function getLocalTrendingHashtags(int $period, $limit = 10): array
{ {
$tags = DI::cache()->get('local_trending_tags-' . $period . '-' . $limit); $tags = DI::cache()->get('local_trending_tags-' . $period . '-' . $limit);
if (!empty($tags)) { if (!empty($tags)) {
@ -687,7 +710,7 @@ class Tag
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
public static function setLocalTrendingHashtags(int $period, int $limit = 10) public static function setLocalTrendingHashtags(int $period, int $limit = 10): array
{ {
// Get a uri-id that is at least X hours old. // Get a uri-id that is at least X hours old.
// We use the uri-id in the query for the hash tags since this is much faster // We use the uri-id in the query for the hash tags since this is much faster
@ -703,7 +726,9 @@ class Tag
FROM `tag-search-view` FROM `tag-search-view`
WHERE `private` = ? AND `wall` AND `origin` AND `uri-id` > ? $block_sql WHERE `private` = ? AND `wall` AND `origin` AND `uri-id` > ? $block_sql
GROUP BY `term` ORDER BY `authors` DESC, `score` DESC LIMIT ?", GROUP BY `term` ORDER BY `authors` DESC, `score` DESC LIMIT ?",
Item::PUBLIC, $post['uri-id'], $limit); Item::PUBLIC, $post['uri-id'],
$limit
);
if (DBA::isResult($tagsStmt)) { if (DBA::isResult($tagsStmt)) {
$tags = DBA::toArray($tagsStmt); $tags = DBA::toArray($tagsStmt);
@ -717,11 +742,11 @@ class Tag
/** /**
* Check if the provided tag is of one of the provided term types. * Check if the provided tag is of one of the provided term types.
* *
* @param string $tag * @param string $tag Tag name
* @param int ...$types * @param int ...$types
* @return bool * @return bool
*/ */
public static function isType($tag, ...$types) public static function isType(string $tag, ...$types): bool
{ {
$tag_chars = []; $tag_chars = [];
foreach ($types as $type) { foreach ($types as $type) {
@ -739,7 +764,7 @@ class Tag
* @param string $tag * @param string $tag
* @return array User list * @return array User list
*/ */
private static function getUIDListByTag(string $tag) private static function getUIDListByTag(string $tag): array
{ {
$uids = []; $uids = [];
$searches = DBA::select('search', ['uid'], ['term' => $tag]); $searches = DBA::select('search', ['uid'], ['term' => $tag]);
@ -754,13 +779,13 @@ class Tag
/** /**
* Fetch user who subscribed to the tags of the given item * Fetch user who subscribed to the tags of the given item
* *
* @param integer $uri_id * @param integer $uriId
* @return array User list * @return array User list
*/ */
public static function getUIDListByURIId(int $uri_id) public static function getUIDListByURIId(int $uriId): array
{ {
$uids = []; $uids = [];
$tags = self::getByURIId($uri_id, [self::HASHTAG]); $tags = self::getByURIId($uriId, [self::HASHTAG]);
foreach ($tags as $tag) { foreach ($tags as $tag) {
$uids = array_merge($uids, self::getUIDListByTag(self::TAG_CHARACTER[self::HASHTAG] . $tag['name'])); $uids = array_merge($uids, self::getUIDListByTag(self::TAG_CHARACTER[self::HASHTAG] . $tag['name']));

View file

@ -117,16 +117,18 @@ class User
switch ($accounttype) { switch ($accounttype) {
case 'person': case 'person':
return User::ACCOUNT_TYPE_PERSON; return User::ACCOUNT_TYPE_PERSON;
case 'organisation': case 'organisation':
return User::ACCOUNT_TYPE_ORGANISATION; return User::ACCOUNT_TYPE_ORGANISATION;
case 'news': case 'news':
return User::ACCOUNT_TYPE_NEWS; return User::ACCOUNT_TYPE_NEWS;
case 'community': case 'community':
return User::ACCOUNT_TYPE_COMMUNITY; return User::ACCOUNT_TYPE_COMMUNITY;
default:
return null;
break;
} }
return null;
} }
/** /**
@ -134,7 +136,7 @@ class User
* *
* @return array system account * @return array system account
*/ */
public static function getSystemAccount() public static function getSystemAccount(): array
{ {
$system = Contact::selectFirst([], ['self' => true, 'uid' => 0]); $system = Contact::selectFirst([], ['self' => true, 'uid' => 0]);
if (!DBA::isResult($system)) { if (!DBA::isResult($system)) {
@ -244,7 +246,7 @@ class User
* *
* @return string actor account name * @return string actor account name
*/ */
public static function getActorName() public static function getActorName(): string
{ {
$system_actor_name = DI::config()->get('system', 'actor_name'); $system_actor_name = DI::config()->get('system', 'actor_name');
if (!empty($system_actor_name)) { if (!empty($system_actor_name)) {
@ -278,7 +280,7 @@ class User
* @return boolean * @return boolean
* @throws Exception * @throws Exception
*/ */
public static function exists($uid) public static function exists(int $uid): bool
{ {
return DBA::exists('user', ['uid' => $uid]); return DBA::exists('user', ['uid' => $uid]);
} }
@ -289,7 +291,7 @@ class User
* @return array|boolean User record if it exists, false otherwise * @return array|boolean User record if it exists, false otherwise
* @throws Exception * @throws Exception
*/ */
public static function getById($uid, array $fields = []) public static function getById(int $uid, array $fields = [])
{ {
return !empty($uid) ? DBA::selectFirst('user', $fields, ['uid' => $uid]) : []; return !empty($uid) ? DBA::selectFirst('user', $fields, ['uid' => $uid]) : [];
} }
@ -321,7 +323,7 @@ class User
* @return array|boolean User record if it exists, false otherwise * @return array|boolean User record if it exists, false otherwise
* @throws Exception * @throws Exception
*/ */
public static function getByNickname($nickname, array $fields = []) public static function getByNickname(string $nickname, array $fields = [])
{ {
return DBA::selectFirst('user', $fields, ['nickname' => $nickname]); return DBA::selectFirst('user', $fields, ['nickname' => $nickname]);
} }
@ -334,7 +336,7 @@ class User
* @return integer user id * @return integer user id
* @throws Exception * @throws Exception
*/ */
public static function getIdForURL(string $url) public static function getIdForURL(string $url): int
{ {
// Avoid database queries when the local node hostname isn't even part of the url. // Avoid database queries when the local node hostname isn't even part of the url.
if (!Contact::isLocal($url)) { if (!Contact::isLocal($url)) {
@ -362,14 +364,12 @@ class User
/** /**
* Get a user based on its email * Get a user based on its email
* *
* @param string $email * @param string $email
* @param array $fields * @param array $fields
*
* @return array|boolean User record if it exists, false otherwise * @return array|boolean User record if it exists, false otherwise
*
* @throws Exception * @throws Exception
*/ */
public static function getByEmail($email, array $fields = []) public static function getByEmail(string $email, array $fields = [])
{ {
return DBA::selectFirst('user', $fields, ['email' => $email]); return DBA::selectFirst('user', $fields, ['email' => $email]);
} }
@ -380,7 +380,7 @@ class User
* @param array $fields * @param array $fields
* @return array user * @return array user
*/ */
public static function getFirstAdmin(array $fields = []) public static function getFirstAdmin(array $fields = []) : array
{ {
if (!empty(DI::config()->get('config', 'admin_nickname'))) { if (!empty(DI::config()->get('config', 'admin_nickname'))) {
return self::getByNickname(DI::config()->get('config', 'admin_nickname'), $fields); return self::getByNickname(DI::config()->get('config', 'admin_nickname'), $fields);
@ -469,7 +469,7 @@ class User
* @return boolean|array * @return boolean|array
* @throws Exception * @throws Exception
*/ */
public static function getOwnerDataByNick($nick) public static function getOwnerDataByNick(string $nick)
{ {
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]); $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]);
@ -488,7 +488,7 @@ class User
* @return int group id * @return int group id
* @throws Exception * @throws Exception
*/ */
public static function getDefaultGroup($uid) public static function getDefaultGroup(int $uid): int
{ {
$user = DBA::selectFirst('user', ['def_gid'], ['uid' => $uid]); $user = DBA::selectFirst('user', ['def_gid'], ['uid' => $uid]);
if (DBA::isResult($user)) { if (DBA::isResult($user)) {
@ -512,7 +512,7 @@ class User
* @throws HTTPException\ForbiddenException * @throws HTTPException\ForbiddenException
* @throws HTTPException\NotFoundException * @throws HTTPException\NotFoundException
*/ */
public static function getIdFromPasswordAuthentication($user_info, $password, $third_party = false) public static function getIdFromPasswordAuthentication($user_info, string $password, bool $third_party = false): int
{ {
// Addons registered with the "authenticate" hook may create the user on the // Addons registered with the "authenticate" hook may create the user on the
// fly. `getAuthenticationInfo` will fail if the user doesn't exist yet. If // fly. `getAuthenticationInfo` will fail if the user doesn't exist yet. If
@ -580,7 +580,7 @@ class User
* @return int User Id if authentication is successful * @return int User Id if authentication is successful
* @throws HTTPException\ForbiddenException * @throws HTTPException\ForbiddenException
*/ */
public static function getIdFromAuthenticateHooks($username, $password) public static function getIdFromAuthenticateHooks(string $username, string $password): int
{ {
$addon_auth = [ $addon_auth = [
'username' => $username, 'username' => $username,
@ -613,7 +613,7 @@ class User
* - User array with at least the uid and the hashed password * - User array with at least the uid and the hashed password
* *
* @param mixed $user_info * @param mixed $user_info
* @return array * @return array|null Null if not found/determined
* @throws HTTPException\NotFoundException * @throws HTTPException\NotFoundException
*/ */
public static function getAuthenticationInfo($user_info) public static function getAuthenticationInfo($user_info)
@ -671,7 +671,7 @@ class User
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public static function generateNewPassword() public static function generateNewPassword(): string
{ {
return ucfirst(Strings::getRandomName(8)) . random_int(1000, 9999); return ucfirst(Strings::getRandomName(8)) . random_int(1000, 9999);
} }
@ -683,7 +683,7 @@ class User
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public static function isPasswordExposed($password) public static function isPasswordExposed(string $password): bool
{ {
$cache = new CacheItemPool(); $cache = new CacheItemPool();
$cache->changeConfig([ $cache->changeConfig([
@ -712,7 +712,7 @@ class User
* @param string $password * @param string $password
* @return string * @return string
*/ */
private static function hashPasswordLegacy($password) private static function hashPasswordLegacy(string $password): string
{ {
return hash('whirlpool', $password); return hash('whirlpool', $password);
} }
@ -724,7 +724,7 @@ class User
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public static function hashPassword($password) public static function hashPassword(string $password): string
{ {
if (!trim($password)) { if (!trim($password)) {
throw new Exception(DI::l10n()->t('Password can\'t be empty')); throw new Exception(DI::l10n()->t('Password can\'t be empty'));
@ -741,7 +741,7 @@ class User
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public static function updatePassword($uid, $password) public static function updatePassword(int $uid, string $password): bool
{ {
$password = trim($password); $password = trim($password);
@ -771,7 +771,7 @@ class User
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
private static function updatePasswordHashed($uid, $pasword_hashed) private static function updatePasswordHashed(int $uid, string $pasword_hashed): bool
{ {
$fields = [ $fields = [
'password' => $pasword_hashed, 'password' => $pasword_hashed,
@ -792,7 +792,7 @@ class User
* @param string $nickname The nickname that should be checked * @param string $nickname The nickname that should be checked
* @return boolean True is the nickname is blocked on the node * @return boolean True is the nickname is blocked on the node
*/ */
public static function isNicknameBlocked($nickname) public static function isNicknameBlocked(string $nickname): bool
{ {
$forbidden_nicknames = DI::config()->get('system', 'forbidden_nicknames', ''); $forbidden_nicknames = DI::config()->get('system', 'forbidden_nicknames', '');
if (!empty($forbidden_nicknames)) { if (!empty($forbidden_nicknames)) {
@ -829,7 +829,7 @@ class User
* @return string avatar link * @return string avatar link
* @throws Exception * @throws Exception
*/ */
public static function getAvatarUrl(array $user, string $size = ''):string public static function getAvatarUrl(array $user, string $size = ''): string
{ {
if (empty($user['nickname'])) { if (empty($user['nickname'])) {
DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]); DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]);
@ -871,7 +871,7 @@ class User
* @return string banner link * @return string banner link
* @throws Exception * @throws Exception
*/ */
public static function getBannerUrl(array $user):string public static function getBannerUrl(array $user): string
{ {
if (empty($user['nickname'])) { if (empty($user['nickname'])) {
DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]); DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]);
@ -913,7 +913,7 @@ class User
* @throws ImagickException * @throws ImagickException
* @throws Exception * @throws Exception
*/ */
public static function create(array $data) public static function create(array $data): array
{ {
$return = ['user' => null, 'password' => '']; $return = ['user' => null, 'password' => ''];
@ -1164,32 +1164,32 @@ class User
$type = Images::getMimeTypeByData($img_str, $photo, $type); $type = Images::getMimeTypeByData($img_str, $photo, $type);
$Image = new Image($img_str, $type); $image = new Image($img_str, $type);
if ($Image->isValid()) { if ($image->isValid()) {
$Image->scaleToSquare(300); $image->scaleToSquare(300);
$resource_id = Photo::newResource(); $resource_id = Photo::newResource();
// Not using Photo::PROFILE_PHOTOS here, so that it is discovered as translateble string // Not using Photo::PROFILE_PHOTOS here, so that it is discovered as translateble string
$profile_album = DI::l10n()->t('Profile Photos'); $profile_album = DI::l10n()->t('Profile Photos');
$r = Photo::store($Image, $uid, 0, $resource_id, $filename, $profile_album, 4); $r = Photo::store($image, $uid, 0, $resource_id, $filename, $profile_album, 4);
if ($r === false) { if ($r === false) {
$photo_failure = true; $photo_failure = true;
} }
$Image->scaleDown(80); $image->scaleDown(80);
$r = Photo::store($Image, $uid, 0, $resource_id, $filename, $profile_album, 5); $r = Photo::store($image, $uid, 0, $resource_id, $filename, $profile_album, 5);
if ($r === false) { if ($r === false) {
$photo_failure = true; $photo_failure = true;
} }
$Image->scaleDown(48); $image->scaleDown(48);
$r = Photo::store($Image, $uid, 0, $resource_id, $filename, $profile_album, 6); $r = Photo::store($image, $uid, 0, $resource_id, $filename, $profile_album, 6);
if ($r === false) { if ($r === false) {
$photo_failure = true; $photo_failure = true;
@ -1255,7 +1255,7 @@ class User
* @throws Exception * @throws Exception
*/ */
public static function block(int $uid, bool $block = true) public static function block(int $uid, bool $block = true): bool
{ {
return DBA::update('user', ['blocked' => $block], ['uid' => $uid]); return DBA::update('user', ['blocked' => $block], ['uid' => $uid]);
} }
@ -1270,7 +1270,7 @@ class User
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws Exception * @throws Exception
*/ */
public static function allow(string $hash) public static function allow(string $hash): bool
{ {
$register = Register::getByHash($hash); $register = Register::getByHash($hash);
if (!DBA::isResult($register)) { if (!DBA::isResult($register)) {
@ -1316,7 +1316,7 @@ class User
* @return bool True, if the deny was successfull * @return bool True, if the deny was successfull
* @throws Exception * @throws Exception
*/ */
public static function deny(string $hash) public static function deny(string $hash): bool
{ {
$register = Register::getByHash($hash); $register = Register::getByHash($hash);
if (!DBA::isResult($register)) { if (!DBA::isResult($register)) {
@ -1342,13 +1342,12 @@ class User
* @param string $email The user's email address * @param string $email The user's email address
* @param string $nick The user's nick name * @param string $nick The user's nick name
* @param string $lang The user's language (default is english) * @param string $lang The user's language (default is english)
*
* @return bool True, if the user was created successfully * @return bool True, if the user was created successfully
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws ErrorException * @throws ErrorException
* @throws ImagickException * @throws ImagickException
*/ */
public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT) public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT): bool
{ {
if (empty($name) || if (empty($name) ||
empty($email) || empty($email) ||
@ -1418,7 +1417,7 @@ class User
* @return NULL|boolean from notification() and email() inherited * @return NULL|boolean from notification() and email() inherited
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password) public static function sendRegisterPendingEmail(array $user, string $sitename, string $siteurl, string $password)
{ {
$body = Strings::deindent(DI::l10n()->t( $body = Strings::deindent(DI::l10n()->t(
' '
@ -1461,7 +1460,7 @@ class User
* @return NULL|boolean from notification() and email() inherited * @return NULL|boolean from notification() and email() inherited
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public static function sendRegisterOpenEmail(L10n $l10n, $user, $sitename, $siteurl, $password) public static function sendRegisterOpenEmail(L10n $l10n, array $user, string $sitename, string $siteurl, string $password)
{ {
$preamble = Strings::deindent($l10n->t( $preamble = Strings::deindent($l10n->t(
' '
@ -1520,7 +1519,7 @@ class User
* @return bool * @return bool
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public static function remove(int $uid) public static function remove(int $uid): bool
{ {
if (empty($uid)) { if (empty($uid)) {
return false; return false;
@ -1574,7 +1573,7 @@ class User
* ] * ]
* @throws Exception * @throws Exception
*/ */
public static function identities($uid) public static function identities(int $uid): array
{ {
if (empty($uid)) { if (empty($uid)) {
return []; return [];
@ -1646,7 +1645,7 @@ class User
* @param int $uid * @param int $uid
* @return bool * @return bool
*/ */
public static function hasIdentities(int $uid):bool public static function hasIdentities(int $uid): bool
{ {
if (empty($uid)) { if (empty($uid)) {
return false; return false;
@ -1679,7 +1678,7 @@ class User
* *
* @throws Exception * @throws Exception
*/ */
public static function getStatistics() public static function getStatistics(): array
{ {
$statistics = [ $statistics = [
'total_users' => 0, 'total_users' => 0,
@ -1731,11 +1730,10 @@ class User
* @param string $type The type of users, which should get (all, bocked, removed) * @param string $type The type of users, which should get (all, bocked, removed)
* @param string $order Order of the user list (Default is 'contact.name') * @param string $order Order of the user list (Default is 'contact.name')
* @param bool $descending Order direction (Default is ascending) * @param bool $descending Order direction (Default is ascending)
* * @return array|bool The list of the users
* @return array The list of the users
* @throws Exception * @throws Exception
*/ */
public static function getList($start = 0, $count = Pager::ITEMS_PER_PAGE, $type = 'all', $order = 'name', bool $descending = false) public static function getList(int $start = 0, int $count = Pager::ITEMS_PER_PAGE, string $type = 'all', string $order = 'name', bool $descending = false)
{ {
$param = ['limit' => [$start, $count], 'order' => [$order => $descending]]; $param = ['limit' => [$start, $count], 'order' => [$order => $descending]];
$condition = []; $condition = [];
@ -1744,11 +1742,13 @@ class User
$condition['account_removed'] = false; $condition['account_removed'] = false;
$condition['blocked'] = false; $condition['blocked'] = false;
break; break;
case 'blocked': case 'blocked':
$condition['account_removed'] = false; $condition['account_removed'] = false;
$condition['blocked'] = true; $condition['blocked'] = true;
$condition['verified'] = true; $condition['verified'] = true;
break; break;
case 'removed': case 'removed':
$condition['account_removed'] = true; $condition['account_removed'] = true;
break; break;

View file

@ -52,12 +52,12 @@ class Cookie
private $data; private $data;
/** /**
* @param App\Request $request The current http request
* @param IManageConfigValues $config * @param IManageConfigValues $config
* @param App\BaseURL $baseURL * @param App\BaseURL $baseURL
* @param array $SERVER The $_SERVER array
* @param array $COOKIE The $_COOKIE array * @param array $COOKIE The $_COOKIE array
*/ */
public function __construct(IManageConfigValues $config, App\BaseURL $baseURL, array $SERVER = [], array $COOKIE = []) public function __construct(App\Request $request, IManageConfigValues $config, App\BaseURL $baseURL, array $COOKIE = [])
{ {
$this->sslEnabled = $baseURL->getSSLPolicy() === App\BaseURL::SSL_POLICY_FULL; $this->sslEnabled = $baseURL->getSSLPolicy() === App\BaseURL::SSL_POLICY_FULL;
$this->sitePrivateKey = $config->get('system', 'site_prvkey'); $this->sitePrivateKey = $config->get('system', 'site_prvkey');
@ -66,7 +66,7 @@ class Cookie
self::DEFAULT_EXPIRE); self::DEFAULT_EXPIRE);
$this->lifetime = $authCookieDays * 24 * 60 * 60; $this->lifetime = $authCookieDays * 24 * 60 * 60;
$this->remoteAddr = ($SERVER['REMOTE_ADDR'] ?? null) ?: '0.0.0.0'; $this->remoteAddr = $request->getRemoteAddress();
$this->data = json_decode($COOKIE[self::NAME] ?? '[]', true) ?: []; $this->data = json_decode($COOKIE[self::NAME] ?? '[]', true) ?: [];
} }

View file

@ -34,7 +34,7 @@ class Verb
* @return integer verb id * @return integer verb id
* @throws \Exception * @throws \Exception
*/ */
public static function getID(string $verb) public static function getID(string $verb): int
{ {
if (empty($verb)) { if (empty($verb)) {
return 0; return 0;
@ -56,7 +56,7 @@ class Verb
* @param integer $id * @param integer $id
* @return string verb * @return string verb
*/ */
public static function getByID(int $id) public static function getByID(int $id): string
{ {
if (empty($id)) { if (empty($id)) {
return ''; return '';

View file

@ -54,12 +54,12 @@ class Summary extends BaseAdmin
$warningtext[] = DI::l10n()->t('Template engine (%s) error: %s', $templateEngine::$name, $error); $warningtext[] = DI::l10n()->t('Template engine (%s) error: %s', $templateEngine::$name, $error);
} }
if (DBA::count(['information_schema' => 'tables'], ['engine' => 'myisam', 'table_schema' => DBA::databaseName()])) { if (DBA::count('information_schema.tables', ['engine' => 'myisam', 'table_schema' => DBA::databaseName()])) {
$warningtext[] = DI::l10n()->t('Your DB still runs with MyISAM tables. You should change the engine type to InnoDB. As Friendica will use InnoDB only features in the future, you should change this! See <a href="%s">here</a> for a guide that may be helpful converting the table engines. You may also use the command <tt>php bin/console.php dbstructure toinnodb</tt> of your Friendica installation for an automatic conversion.<br />', 'https://dev.mysql.com/doc/refman/5.7/en/converting-tables-to-innodb.html'); $warningtext[] = DI::l10n()->t('Your DB still runs with MyISAM tables. You should change the engine type to InnoDB. As Friendica will use InnoDB only features in the future, you should change this! See <a href="%s">here</a> for a guide that may be helpful converting the table engines. You may also use the command <tt>php bin/console.php dbstructure toinnodb</tt> of your Friendica installation for an automatic conversion.<br />', 'https://dev.mysql.com/doc/refman/5.7/en/converting-tables-to-innodb.html');
} }
// are there InnoDB tables in Antelope in the DB? If so, trigger a warning message // are there InnoDB tables in Antelope in the DB? If so, trigger a warning message
if (DBA::count(['information_schema' => 'tables'], ['ENGINE' => 'InnoDB', 'ROW_FORMAT' => ['COMPACT', 'REDUNDANT'], 'table_schema' => DBA::databaseName()])) { if (DBA::count('information_schema.tables', ['ENGINE' => 'InnoDB', 'ROW_FORMAT' => ['COMPACT', 'REDUNDANT'], 'table_schema' => DBA::databaseName()])) {
$warningtext[] = DI::l10n()->t('Your DB still runs with InnoDB tables in the Antelope file format. You should change the file format to Barracuda. Friendica is using features that are not provided by the Antelope format. See <a href="%s">here</a> for a guide that may be helpful converting the table engines. You may also use the command <tt>php bin/console.php dbstructure toinnodb</tt> of your Friendica installation for an automatic conversion.<br />', 'https://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html'); $warningtext[] = DI::l10n()->t('Your DB still runs with InnoDB tables in the Antelope file format. You should change the file format to Barracuda. Friendica is using features that are not provided by the Antelope format. See <a href="%s">here</a> for a guide that may be helpful converting the table engines. You may also use the command <tt>php bin/console.php dbstructure toinnodb</tt> of your Friendica installation for an automatic conversion.<br />', 'https://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html');
} }

View file

@ -43,7 +43,10 @@ require_once 'boot.php';
abstract class BaseAdmin extends BaseModule abstract class BaseAdmin extends BaseModule
{ {
/** /**
* Checks admin access and throws exceptions if not logged-in administrator
*
* @param bool $interactive * @param bool $interactive
* @return void
* @throws HTTPException\ForbiddenException * @throws HTTPException\ForbiddenException
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */

View file

@ -48,7 +48,7 @@ class BaseSettings extends BaseModule
'label' => DI::l10n()->t('Two-factor authentication'), 'label' => DI::l10n()->t('Two-factor authentication'),
'url' => 'settings/2fa', 'url' => 'settings/2fa',
'selected' => ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === '2fa') ? 'active' : ''), 'selected' => ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === '2fa') ? 'active' : ''),
'accesskey' => 'o', 'accesskey' => '2',
]; ];
$tabs[] = [ $tabs[] = [

View file

@ -59,12 +59,13 @@ class Notify extends BaseModule
} }
} }
private static function dispatchPublic($postdata) private static function dispatchPublic(array $postdata)
{ {
$msg = Diaspora::decodeRaw($postdata, '', true); $msg = Diaspora::decodeRaw($postdata, '', true);
if (!$msg) { if (!is_array($msg)) {
// We have to fail silently to be able to hand it over to the salmon parser // We have to fail silently to be able to hand it over to the salmon parser
return false; Logger::warning('Diaspora::decodeRaw() has failed for some reason.');
return;
} }
// Fetch the corresponding public contact // Fetch the corresponding public contact
@ -88,10 +89,10 @@ class Notify extends BaseModule
System::xmlExit($ret, 'Done'); System::xmlExit($ret, 'Done');
} }
private static function dispatchPrivate($user, $postdata) private static function dispatchPrivate(array $user, string $postdata)
{ {
$msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? ''); $msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? '');
if (!$msg) { if (!is_array($msg)) {
System::xmlExit(4, 'Unable to parse message'); System::xmlExit(4, 'Unable to parse message');
} }

View file

@ -34,6 +34,6 @@ class Poll extends BaseModule
protected function rawContent(array $request = []) protected function rawContent(array $request = [])
{ {
$last_update = $request['last_update'] ?? ''; $last_update = $request['last_update'] ?? '';
System::httpExit(OStatus::feed($this->parameters['nickname'], $last_update, 10), Response::TYPE_ATOM); System::httpExit(OStatus::feed($this->parameters['nickname'], $last_update, 10) ?? '', Response::TYPE_ATOM);
} }
} }

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